Repository: tomee Updated Branches: refs/heads/master 91e9840fe -> d90248796
dont trigger TomEEClusterListener if not needed + avoid infinite loop in Memoizer cause of NoClassDefFoundError Project: http://git-wip-us.apache.org/repos/asf/tomee/repo Commit: http://git-wip-us.apache.org/repos/asf/tomee/commit/15767f98 Tree: http://git-wip-us.apache.org/repos/asf/tomee/tree/15767f98 Diff: http://git-wip-us.apache.org/repos/asf/tomee/diff/15767f98 Branch: refs/heads/master Commit: 15767f98b8b0155816064d66a1a5e28e268fdaa4 Parents: 1ffd201 Author: Romain Manni-Bucau <rmannibu...@apache.org> Authored: Wed Mar 4 11:33:02 2015 +0100 Committer: Romain Manni-Bucau <rmannibu...@apache.org> Committed: Wed Mar 4 11:33:02 2015 +0100 ---------------------------------------------------------------------- .../java/org/apache/openejb/util/Memoizer.java | 3 + .../maven/plugins/TomEEEmbeddedMojo.java | 6 ++ .../tomee/catalina/GlobalListenerSupport.java | 5 +- .../tomee/catalina/SimpleTomEETcpCluster.java | 6 +- .../tomee/catalina/TomcatWebAppBuilder.java | 7 +- .../catalina/cluster/TomEEClusterListener.java | 74 +++++++++++--------- 6 files changed, 64 insertions(+), 37 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tomee/blob/15767f98/container/openejb-core/src/main/java/org/apache/openejb/util/Memoizer.java ---------------------------------------------------------------------- diff --git a/container/openejb-core/src/main/java/org/apache/openejb/util/Memoizer.java b/container/openejb-core/src/main/java/org/apache/openejb/util/Memoizer.java index e53ee71..a94df8c 100644 --- a/container/openejb-core/src/main/java/org/apache/openejb/util/Memoizer.java +++ b/container/openejb-core/src/main/java/org/apache/openejb/util/Memoizer.java @@ -62,6 +62,9 @@ public class Memoizer<K, V> implements Computable<K, V> { try { return future.get(); } catch (final ExecutionException e) { + if (e.getCause() != null && NoClassDefFoundError.class.isInstance(e.getCause())) { + return null; + } e.printStackTrace(); } } http://git-wip-us.apache.org/repos/asf/tomee/blob/15767f98/maven/tomee-embedded-maven-plugin/src/main/java/org/apache/openejb/maven/plugins/TomEEEmbeddedMojo.java ---------------------------------------------------------------------- diff --git a/maven/tomee-embedded-maven-plugin/src/main/java/org/apache/openejb/maven/plugins/TomEEEmbeddedMojo.java b/maven/tomee-embedded-maven-plugin/src/main/java/org/apache/openejb/maven/plugins/TomEEEmbeddedMojo.java index fa22a0c..371b7a2 100644 --- a/maven/tomee-embedded-maven-plugin/src/main/java/org/apache/openejb/maven/plugins/TomEEEmbeddedMojo.java +++ b/maven/tomee-embedded-maven-plugin/src/main/java/org/apache/openejb/maven/plugins/TomEEEmbeddedMojo.java @@ -208,6 +208,9 @@ public class TomEEEmbeddedMojo extends AbstractMojo { @Override public void run() { if (container.getTomcat() != null && container.getTomcat().getServer().getState() != LifecycleState.DESTROYED) { + final Thread thread = Thread.currentThread(); + final ClassLoader old = thread.getContextClassLoader(); + thread.setContextClassLoader(ParentClassLoaderFinder.Helper.get()); try { if (!classpathAsWar) { container.undeploy(warFile.getAbsolutePath()); @@ -215,10 +218,13 @@ public class TomEEEmbeddedMojo extends AbstractMojo { container.stop(); } catch (final Exception e) { getLog().error("can't stop TomEE", e); + } finally { + thread.setContextClassLoader(old); } } } }; + hook.setName("TomEE-Embedded-ShutdownHook"); try { container.start(); http://git-wip-us.apache.org/repos/asf/tomee/blob/15767f98/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/GlobalListenerSupport.java ---------------------------------------------------------------------- diff --git a/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/GlobalListenerSupport.java b/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/GlobalListenerSupport.java index f0b5527..c867689 100644 --- a/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/GlobalListenerSupport.java +++ b/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/GlobalListenerSupport.java @@ -155,7 +155,10 @@ public class GlobalListenerSupport implements PropertyChangeListener, LifecycleL if (Lifecycle.BEFORE_STOP_EVENT.equals(type)) { TomcatHelper.setStopping(true); - TomEEClusterListener.stop(); + final TomEEClusterListener tomEEClusterListener = SystemInstance.get().getComponent(TomEEClusterListener.class); + if (tomEEClusterListener != null) { + tomEEClusterListener.stop(); + } } if (Lifecycle.AFTER_STOP_EVENT.equals(type)) { http://git-wip-us.apache.org/repos/asf/tomee/blob/15767f98/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/SimpleTomEETcpCluster.java ---------------------------------------------------------------------- diff --git a/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/SimpleTomEETcpCluster.java b/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/SimpleTomEETcpCluster.java index 4870b40..cc1f928 100644 --- a/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/SimpleTomEETcpCluster.java +++ b/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/SimpleTomEETcpCluster.java @@ -19,6 +19,7 @@ package org.apache.tomee.catalina; import org.apache.catalina.Valve; import org.apache.catalina.ha.ClusterListener; import org.apache.catalina.ha.tcp.SimpleTcpCluster; +import org.apache.openejb.loader.SystemInstance; import org.apache.tomee.catalina.cluster.TomEEClusterListener; import java.util.Arrays; @@ -48,7 +49,8 @@ public class SimpleTomEETcpCluster extends SimpleTcpCluster { @Override protected void checkDefaults() { final List<ClusterListener> currentListeners = clusterListeners; - if (currentListeners.size() == 1 && currentListeners.iterator().next() == TomEEClusterListener.INSTANCE) { + final TomEEClusterListener tomEEClusterListener = SystemInstance.get().getComponent(TomEEClusterListener.class); + if (currentListeners.size() == 1 && currentListeners.iterator().next() == tomEEClusterListener) { currentListeners.clear(); } @@ -61,6 +63,6 @@ public class SimpleTomEETcpCluster extends SimpleTcpCluster { } super.checkDefaults(); - addClusterListener(TomEEClusterListener.INSTANCE); // since that's a singleton and all listeners have to be unique (contains()) we can always add it + addClusterListener(tomEEClusterListener); // since that's a singleton and all listeners have to be unique (contains()) we can always add it } } http://git-wip-us.apache.org/repos/asf/tomee/blob/15767f98/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java ---------------------------------------------------------------------- diff --git a/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java b/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java index bb6b5e5..0bfe3c2 100644 --- a/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java +++ b/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java @@ -350,7 +350,12 @@ public class TomcatWebAppBuilder implements WebAppBuilder, ContextListener, Pare if (current instanceof CatalinaCluster) { final CatalinaCluster haCluster = (CatalinaCluster) current; - haCluster.addClusterListener(TomEEClusterListener.INSTANCE); // better to be a singleton + TomEEClusterListener listener = SystemInstance.get().getComponent(TomEEClusterListener.class); + if (listener == null) { + listener = new TomEEClusterListener(); + SystemInstance.get().setComponent(TomEEClusterListener.class, listener); + } + haCluster.addClusterListener(listener); // better to be a singleton clusters.add(haCluster); } } http://git-wip-us.apache.org/repos/asf/tomee/blob/15767f98/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cluster/TomEEClusterListener.java ---------------------------------------------------------------------- diff --git a/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cluster/TomEEClusterListener.java b/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cluster/TomEEClusterListener.java index 4ba9af7..26e0037 100644 --- a/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cluster/TomEEClusterListener.java +++ b/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cluster/TomEEClusterListener.java @@ -27,31 +27,20 @@ import org.apache.openejb.core.LocalInitialContextFactory; import org.apache.openejb.loader.Files; import org.apache.openejb.loader.IO; import org.apache.openejb.loader.SystemInstance; +import org.apache.openejb.util.DaemonThreadFactory; import org.apache.openejb.util.LogCategory; import org.apache.openejb.util.Logger; -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NamingException; import java.io.File; import java.util.Properties; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; public class TomEEClusterListener extends ClusterListener { - public static final TomEEClusterListener INSTANCE = new TomEEClusterListener(); - - private static final Logger LOGGER = Logger.getInstance(LogCategory.OPENEJB, TomEEClusterListener.class); - private static final Properties IC_PROPS = new Properties(); - - // async processing to avoid to make the cluster hanging - private static final ExecutorService SERVICE = Executors.newSingleThreadExecutor(); - - static { - IC_PROPS.setProperty(Context.INITIAL_CONTEXT_FACTORY, LocalInitialContextFactory.class.getName()); - } - @Override public void messageReceived(final ClusterMessage clusterMessage) { final Class<?> type = clusterMessage.getClass(); @@ -76,33 +65,33 @@ public class TomEEClusterListener extends ClusterListener { file = dump.getAbsolutePath(); ioFile = new File(file); - LOGGER.info("dumped archive: " + msg.getFile() + " to " + file); + Static.STATIC.LOGGER.info("dumped archive: " + msg.getFile() + " to " + file); } catch (final Exception e) { - LOGGER.error("can't dump archive: "+ file, e); + Static.STATIC.LOGGER.error("can't dump archive: "+ file, e); } } if (ioFile.exists()) { - SERVICE.submit(new DeployTask(file)); + Static.STATIC.SERVICE.submit(new DeployTask(file)); } else { - LOGGER.warning("can't find '" + file); + Static.STATIC.LOGGER.warning("can't find '" + file); } } else { - LOGGER.info("application already deployed: " + file); + Static.STATIC.LOGGER.info("application already deployed: " + file); } } else if (UndeployMessage.class.equals(type)) { final String file = ((UndeployMessage) clusterMessage).getFile(); if (isDeployed(file)) { - SERVICE.submit(new UndeployTask(file)); + Static.STATIC.SERVICE.submit(new UndeployTask(file)); } else { final File alternativeFile = new File(deployedDir(), new File(file).getName()); if (isDeployed(alternativeFile.getAbsolutePath())) { - SERVICE.submit(new UndeployTask(alternativeFile.getAbsolutePath())); + Static.STATIC.SERVICE.submit(new UndeployTask(alternativeFile.getAbsolutePath())); } - LOGGER.info("app '" + file + "' was not deployed"); + Static.STATIC.LOGGER.info("app '" + file + "' was not deployed"); } } else { - LOGGER.warning("message type not supported: " + type); + Static.STATIC.LOGGER.warning("message type not supported: " + type); } } @@ -115,7 +104,7 @@ public class TomEEClusterListener extends ClusterListener { } private static Deployer deployer() throws NamingException { - return (Deployer) new InitialContext(IC_PROPS).lookup("openejb/DeployerBusinessRemote"); + return (Deployer) new InitialContext(Static.STATIC.IC_PROPS).lookup("openejb/DeployerBusinessRemote"); } @Override @@ -126,11 +115,11 @@ public class TomEEClusterListener extends ClusterListener { } public static void stop() { - SERVICE.shutdown(); + Static.STATIC.SERVICE.shutdown(); try { - SERVICE.awaitTermination(1, TimeUnit.MINUTES); + Static.STATIC.SERVICE.awaitTermination(1, TimeUnit.MINUTES); } catch (final InterruptedException e) { - SERVICE.shutdownNow(); + Static.STATIC.SERVICE.shutdownNow(); } } @@ -151,9 +140,9 @@ public class TomEEClusterListener extends ClusterListener { try { deployer().deploy(app, REMOTE_DEPLOY_PROPERTIES); } catch (final OpenEJBException e) { - LOGGER.warning("can't deploy: " + app, e); + Static.STATIC.LOGGER.warning("can't deploy: " + app, e); } catch (final NamingException e) { - LOGGER.warning("can't find deployer", e); + Static.STATIC.LOGGER.warning("can't find deployer", e); } } } @@ -172,13 +161,32 @@ public class TomEEClusterListener extends ClusterListener { try { deployer().undeploy(app); } catch (final UndeployException e) { - LOGGER.error("can't undeploy app", e); + Static.STATIC.LOGGER.error("can't undeploy app", e); } catch (final NoSuchApplicationException e) { - LOGGER.warning("no app toi deploy", e); + Static.STATIC.LOGGER.warning("no app toi deploy", e); } catch (final NamingException e) { - LOGGER.warning("can't find deployer", e); + Static.STATIC.LOGGER.warning("can't find deployer", e); } } } } + + // lazy init of logger (can fail with shutdown hooks to kill the container) and executor + private static final class Static { + private static final Static STATIC = new Static(); + + private static final Logger LOGGER = Logger.getInstance(LogCategory.OPENEJB, TomEEClusterListener.class); + private static final Properties IC_PROPS = new Properties(); + + // async processing to avoid to make the cluster hanging + private static final ExecutorService SERVICE = Executors.newSingleThreadExecutor(new DaemonThreadFactory("TomEE-Cluster-Listener-thread-")); + + static { + IC_PROPS.setProperty(Context.INITIAL_CONTEXT_FACTORY, LocalInitialContextFactory.class.getName()); + } + + private Static() { + // no-op + } + } }