Author: gertv
Date: Fri Jul 15 15:07:19 2011
New Revision: 1147181
URL: http://svn.apache.org/viewvc?rev=1147181&view=rev
Log:
SM-1847: Executor service silently swallows any Errors being thrown fron
Runnable task
Added:
servicemix/utils/trunk/src/test/java/org/apache/servicemix/executors/impl/LogThrowableInExecutorTest.java
Modified:
servicemix/utils/trunk/src/main/java/org/apache/servicemix/executors/impl/ExecutorImpl.java
Modified:
servicemix/utils/trunk/src/main/java/org/apache/servicemix/executors/impl/ExecutorImpl.java
URL:
http://svn.apache.org/viewvc/servicemix/utils/trunk/src/main/java/org/apache/servicemix/executors/impl/ExecutorImpl.java?rev=1147181&r1=1147180&r2=1147181&view=diff
==============================================================================
---
servicemix/utils/trunk/src/main/java/org/apache/servicemix/executors/impl/ExecutorImpl.java
(original)
+++
servicemix/utils/trunk/src/main/java/org/apache/servicemix/executors/impl/ExecutorImpl.java
Fri Jul 15 15:07:19 2011
@@ -18,6 +18,8 @@ package org.apache.servicemix.executors.
import org.apache.servicemix.executors.Executor;
import org.apache.servicemix.executors.ExecutorAwareRunnable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
@@ -31,6 +33,8 @@ import java.util.concurrent.TimeUnit;
*/
public class ExecutorImpl implements Executor {
+ private static final Logger LOGGER =
LoggerFactory.getLogger(ExecutorImpl.class);
+
private final ThreadPoolExecutor threadPool;
private ExecutorFactoryImpl executorFactory;
@@ -46,11 +50,24 @@ public class ExecutorImpl implements Exe
public void execute(Runnable command) {
if (config.isBypassIfSynchronous() && command instanceof
ExecutorAwareRunnable) {
if (((ExecutorAwareRunnable) command).shouldRunSynchronously()) {
- command.run();
+ wrap(command).run();
return;
}
}
- threadPool.execute(command);
+ threadPool.execute(wrap(command));
+ }
+
+ private Runnable wrap(final Runnable wrapped) {
+ return new Runnable() {
+ public void run() {
+ try {
+ wrapped.run();
+ } catch (Throwable t) {
+ LOGGER.error("Exception caught while executing submitted
job", t);
+ throw new RuntimeException("Exception caught while
executing in submitted job", t);
+ }
+ }
+ };
}
public void shutdown() {
Added:
servicemix/utils/trunk/src/test/java/org/apache/servicemix/executors/impl/LogThrowableInExecutorTest.java
URL:
http://svn.apache.org/viewvc/servicemix/utils/trunk/src/test/java/org/apache/servicemix/executors/impl/LogThrowableInExecutorTest.java?rev=1147181&view=auto
==============================================================================
---
servicemix/utils/trunk/src/test/java/org/apache/servicemix/executors/impl/LogThrowableInExecutorTest.java
(added)
+++
servicemix/utils/trunk/src/test/java/org/apache/servicemix/executors/impl/LogThrowableInExecutorTest.java
Fri Jul 15 15:07:19 2011
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.executors.impl;
+
+import junit.framework.TestCase;
+import org.apache.log4j.AppenderSkeleton;
+import org.apache.log4j.Logger;
+import org.apache.log4j.spi.LoggingEvent;
+import org.apache.servicemix.executors.Executor;
+import org.apache.servicemix.executors.ExecutorFactory;
+import org.apache.servicemix.executors.impl.ExecutorFactoryImpl;
+import org.apache.servicemix.executors.impl.ExecutorImpl;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Test case to ensure that Executor will always log throwables from the
executed Runnable (SM-1847)
+ */
+public class LogThrowableInExecutorTest extends TestCase {
+
+ private static final String MESSAGE = "I'm a bad Runnable throwing errors
at people";
+
+ public void testThrowableLogged() throws InterruptedException {
+ final List<LoggingEvent> events = new LinkedList<LoggingEvent>();
+
+ // unit tests use LOG4J as the backend for SLF4J so add the appender
to LOG4J
+ Logger.getLogger(ExecutorImpl.class).addAppender(new
AppenderSkeleton() {
+ @Override
+ protected void append(LoggingEvent event) {
+ events.add(event);
+ }
+
+ @Override
+ public boolean requiresLayout() {
+ return false;
+ }
+
+ @Override
+ public void close() {
+ //graciously do nothing
+ }
+ });
+
+ ExecutorFactory factory = new ExecutorFactoryImpl();
+ Executor executor = factory.createExecutor("test");
+ executor.execute(new Runnable() {
+ public void run() {
+ throw new Error(MESSAGE);
+ }
+ });
+
+ // let's wait to make sure the runnable is done
+ Thread.sleep(500);
+
+ assertEquals("Should have logged 1 message", 1, events.size());
+ assertTrue("Exception message should have been logged",
+ events.get(0).getThrowableStrRep()[0].contains(MESSAGE));
+
+ }
+
+}