Skip to content

Commit afadcd2

Browse files
author
Max Shaposhnik
authored
CHE-3065 Add uncaught exceptions handler in threads being run by ExecutorService (eclipse-che#3174)
1 parent ac14c9e commit afadcd2

23 files changed

Lines changed: 118 additions & 5 deletions

File tree

core/che-core-api-core/src/main/java/org/eclipse/che/api/core/notification/WSocketEventBusClient.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
*******************************************************************************/
1111
package org.eclipse.che.api.core.notification;
1212

13+
import org.eclipse.che.commons.lang.concurrent.LoggingUncaughtExceptionHandler;
1314
import org.eclipse.che.commons.lang.Pair;
1415

1516
import com.google.common.util.concurrent.ThreadFactoryBuilder;
@@ -108,6 +109,9 @@ public void onEvent(Object event) {
108109
}
109110
if (!cfg.isEmpty()) {
110111
executor = Executors.newCachedThreadPool(new ThreadFactoryBuilder().setNameFormat("WSocketEventBusClient-%d")
112+
.setUncaughtExceptionHandler(
113+
LoggingUncaughtExceptionHandler
114+
.getInstance())
111115
.setDaemon(true).build());
112116
for (Map.Entry<URI, Set<String>> entry : cfg.entrySet()) {
113117
executor.execute(new ConnectTask(entry.getKey(), entry.getValue()));

core/che-core-api-core/src/main/java/org/eclipse/che/api/core/util/FileCleaner.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import org.eclipse.che.commons.lang.IoUtil;
1717
import org.eclipse.che.commons.lang.Pair;
18+
import org.eclipse.che.commons.lang.concurrent.LoggingUncaughtExceptionHandler;
1819
import org.slf4j.Logger;
1920
import org.slf4j.LoggerFactory;
2021

@@ -43,6 +44,9 @@ public class FileCleaner {
4344

4445
private static ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor(new ThreadFactoryBuilder()
4546
.setNameFormat("FileCleaner")
47+
.setUncaughtExceptionHandler(
48+
LoggingUncaughtExceptionHandler
49+
.getInstance())
4650
.setDaemon(true).build());
4751

4852
static {

core/che-core-api-core/src/main/java/org/eclipse/che/everrest/ServerContainerInitializeListener.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import com.google.common.base.MoreObjects;
1414
import com.google.common.util.concurrent.ThreadFactoryBuilder;
1515

16+
import org.eclipse.che.commons.lang.concurrent.LoggingUncaughtExceptionHandler;
1617
import org.eclipse.che.commons.env.EnvironmentContext;
1718
import org.eclipse.che.commons.subject.Subject;
1819
import org.everrest.core.DependencySupplier;
@@ -174,7 +175,11 @@ protected ExecutorService createExecutor(final ServletContext servletContext) {
174175
final EverrestConfiguration everrestConfiguration = getEverrestConfiguration(servletContext);
175176
final String threadNameFormat = "everrest.WSConnection." + servletContext.getServletContextName() + "-%d";
176177
return Executors.newFixedThreadPool(everrestConfiguration.getAsynchronousPoolSize(),
177-
new ThreadFactoryBuilder().setNameFormat(threadNameFormat).setDaemon(true).build());
178+
new ThreadFactoryBuilder().setNameFormat(threadNameFormat)
179+
.setUncaughtExceptionHandler(
180+
LoggingUncaughtExceptionHandler.getInstance())
181+
.setDaemon(true)
182+
.build());
178183
}
179184

180185
protected SecurityContext createSecurityContext(final HandshakeRequest req) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2012-2016 Codenvy, S.A.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* which accompanies this distribution, and is available at
6+
* http://www.eclipse.org/legal/epl-v10.html
7+
*
8+
* Contributors:
9+
* Codenvy, S.A. - initial API and implementation
10+
*******************************************************************************/
11+
package org.eclipse.che.commons.lang.concurrent;
12+
13+
import org.slf4j.Logger;
14+
import org.slf4j.LoggerFactory;
15+
16+
/**
17+
* Writes uncaught exceptions in threads being run by {@link java.util.concurrent.ExecutorService} into application log.
18+
*
19+
* @author Max Shaposhnik
20+
*/
21+
public class LoggingUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
22+
23+
private static final Logger LOG = LoggerFactory.getLogger(LoggingUncaughtExceptionHandler.class);
24+
25+
private static final LoggingUncaughtExceptionHandler INSTANCE = new LoggingUncaughtExceptionHandler();
26+
27+
@Override
28+
public void uncaughtException(Thread t, Throwable e) {
29+
LOG.error(String.format("Runtime exception caught in thread %s. Message: %s", t.getName(), e.getLocalizedMessage()), e);
30+
}
31+
32+
public static LoggingUncaughtExceptionHandler getInstance() {
33+
return INSTANCE;
34+
}
35+
36+
private LoggingUncaughtExceptionHandler() {
37+
}
38+
39+
}

core/commons/che-core-commons-schedule/pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@
4545
<groupId>org.eclipse.che.core</groupId>
4646
<artifactId>che-core-commons-inject</artifactId>
4747
</dependency>
48+
<dependency>
49+
<groupId>org.eclipse.che.core</groupId>
50+
<artifactId>che-core-commons-lang</artifactId>
51+
</dependency>
4852
<dependency>
4953
<groupId>org.slf4j</groupId>
5054
<artifactId>slf4j-api</artifactId>

core/commons/che-core-commons-schedule/src/main/java/org/eclipse/che/commons/schedule/executor/ThreadPullLauncher.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
*******************************************************************************/
1111
package org.eclipse.che.commons.schedule.executor;
1212

13+
import org.eclipse.che.commons.lang.concurrent.LoggingUncaughtExceptionHandler;
1314
import org.eclipse.che.commons.schedule.Launcher;
1415
import org.eclipse.che.inject.ConfigurationException;
1516

@@ -44,7 +45,10 @@ public class ThreadPullLauncher implements Launcher {
4445
@Inject
4546
public ThreadPullLauncher(@Named("schedule.core_pool_size") Integer corePoolSize) {
4647
this.service = new CronThreadPoolExecutor(corePoolSize,
47-
new ThreadFactoryBuilder().setNameFormat("Annotated-scheduler-%d").setDaemon(false)
48+
new ThreadFactoryBuilder().setNameFormat("Annotated-scheduler-%d")
49+
.setUncaughtExceptionHandler(
50+
LoggingUncaughtExceptionHandler.getInstance())
51+
.setDaemon(false)
4852
.build());
4953
}
5054

plugins/plugin-docker/che-plugin-docker-client/src/main/java/org/eclipse/che/plugin/docker/client/CgroupOOMDetector.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import com.google.common.util.concurrent.ThreadFactoryBuilder;
1414
import com.sun.jna.ptr.LongByReference;
1515

16+
import org.eclipse.che.commons.lang.concurrent.LoggingUncaughtExceptionHandler;
1617
import org.eclipse.che.api.core.util.SystemInfo;
1718
import org.eclipse.che.commons.lang.Size;
1819
import org.slf4j.Logger;
@@ -55,6 +56,8 @@ public CgroupOOMDetector(URI dockerDaemonUri, DockerConnector dockerConnector) {
5556
this.dockerConnector = dockerConnector;
5657
this.oomDetectors = new ConcurrentHashMap<>();
5758
this.executor = Executors.newCachedThreadPool(new ThreadFactoryBuilder().setNameFormat("CgroupOOMDetector-%d")
59+
.setUncaughtExceptionHandler(
60+
LoggingUncaughtExceptionHandler.getInstance())
5861
.setDaemon(true)
5962
.build());
6063
}

plugins/plugin-docker/che-plugin-docker-client/src/main/java/org/eclipse/che/plugin/docker/client/DockerConnector.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.google.gson.JsonParseException;
2020

2121
import org.eclipse.che.api.core.util.FileCleaner;
22+
import org.eclipse.che.commons.lang.concurrent.LoggingUncaughtExceptionHandler;
2223
import org.eclipse.che.commons.annotation.Nullable;
2324
import org.eclipse.che.commons.lang.TarUtils;
2425
import org.eclipse.che.commons.lang.ws.rs.ExtMediaType;
@@ -147,6 +148,8 @@ public DockerConnector(DockerConnectorConfiguration connectorConfiguration,
147148
this.authResolver = authResolver;
148149
this.apiVersionPathPrefix = dockerApiVersionPathPrefixProvider.get();
149150
executor = Executors.newCachedThreadPool(new ThreadFactoryBuilder()
151+
.setUncaughtExceptionHandler(
152+
LoggingUncaughtExceptionHandler.getInstance())
150153
.setNameFormat("DockerApiConnector-%d")
151154
.setDaemon(true)
152155
.build());

plugins/plugin-docker/che-plugin-docker-machine/src/main/java/org/eclipse/che/plugin/docker/machine/DockerInstanceStopDetector.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import com.google.common.util.concurrent.ThreadFactoryBuilder;
1616

1717
import org.eclipse.che.api.core.notification.EventService;
18+
import org.eclipse.che.commons.lang.concurrent.LoggingUncaughtExceptionHandler;
1819
import org.eclipse.che.api.machine.server.event.InstanceStateEvent;
1920
import org.eclipse.che.commons.lang.Pair;
2021
import org.eclipse.che.plugin.docker.client.DockerConnector;
@@ -74,6 +75,8 @@ public DockerInstanceStopDetector(EventService eventService, DockerConnector doc
7475
.build();
7576
this.executorService = Executors.newSingleThreadExecutor(
7677
new ThreadFactoryBuilder().setNameFormat("DockerInstanceStopDetector-%d")
78+
.setUncaughtExceptionHandler(
79+
LoggingUncaughtExceptionHandler.getInstance())
7780
.setDaemon(true)
7881
.build());
7982
}

plugins/plugin-docker/che-plugin-docker-machine/src/main/java/org/eclipse/che/plugin/docker/machine/MachineProviderImpl.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.eclipse.che.api.core.model.machine.ServerConf;
2222
import org.eclipse.che.api.core.util.FileCleaner;
2323
import org.eclipse.che.api.core.util.LineConsumer;
24+
import org.eclipse.che.commons.lang.concurrent.LoggingUncaughtExceptionHandler;
2425
import org.eclipse.che.api.core.util.SystemInfo;
2526
import org.eclipse.che.api.environment.server.MachineInstanceProvider;
2627
import org.eclipse.che.api.environment.server.model.CheServiceImpl;
@@ -235,6 +236,8 @@ public MachineProviderImpl(DockerConnector docker,
235236

236237
// TODO single point of failure in case of highly loaded system
237238
executor = Executors.newCachedThreadPool(new ThreadFactoryBuilder().setNameFormat("MachineLogsStreamer-%d")
239+
.setUncaughtExceptionHandler(
240+
LoggingUncaughtExceptionHandler.getInstance())
238241
.setDaemon(true)
239242
.build());
240243
}

0 commit comments

Comments
 (0)