From 921278186d0cd72cbcd14abfdbc5fc5e83e27fcc Mon Sep 17 00:00:00 2001 From: purplefox Date: Mon, 13 Jan 2014 08:55:48 +0000 Subject: [PATCH] Make sure findLoadedClass is called, also allow for serialization of platform blocking actions --- src/dist/scripts/vertx | 2 + .../platform/impl/DefaultPlatformManager.java | 11 ++++- .../java/platform/impl/ModuleClassLoader.java | 41 +++++++++---------- 3 files changed, 31 insertions(+), 23 deletions(-) diff --git a/src/dist/scripts/vertx b/src/dist/scripts/vertx index 36f3bfbca01..f01c13fe561 100755 --- a/src/dist/scripts/vertx +++ b/src/dist/scripts/vertx @@ -8,6 +8,8 @@ # Add default JVM options here. You can also use JAVA_OPTS and VERTX_OPTS to pass JVM options to this script. +# VERTX_OPTS="-Dvertx.serialiseBlockingActions=true" + # If you're deploying and undeploying a lot of verticles with dynamic languages it's recommended to enable GC'ing # of generated classes and prevent OOM due to a lot of gc # JVM_OPTS="-XX:+CMSClassUnloadingEnabled -XX:-UseGCOverheadLimit" diff --git a/vertx-platform/src/main/java/org/vertx/java/platform/impl/DefaultPlatformManager.java b/vertx-platform/src/main/java/org/vertx/java/platform/impl/DefaultPlatformManager.java index bbb766f456e..b6eba7df73c 100644 --- a/vertx-platform/src/main/java/org/vertx/java/platform/impl/DefaultPlatformManager.java +++ b/vertx-platform/src/main/java/org/vertx/java/platform/impl/DefaultPlatformManager.java @@ -46,6 +46,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.Executor; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; @@ -73,6 +74,7 @@ public class DefaultPlatformManager implements PlatformManagerInternal, ModuleRe private static final String FILE_SEP = System.getProperty("file.separator"); private static final String MODULE_NAME_SYS_PROP = System.getProperty("vertx.modulename"); private static final String CLASSPATH_FILE = "vertx_classpath.txt"; + private static final String SERIALISE_BLOCKING_PROP_NAME = "vertx.serialiseBlockingActions"; private final VertxInternal vertx; // deployment name --> deployment @@ -94,6 +96,7 @@ public class DefaultPlatformManager implements PlatformManagerInternal, ModuleRe protected HAManager haManager; private boolean stopped; private final Queue tempDeployments = new ConcurrentLinkedQueue<>(); + private Executor backgroundExec; protected DefaultPlatformManager() { this(new DefaultVertx()); @@ -118,6 +121,12 @@ private DefaultPlatformManager(DefaultVertx vertx) { this.vertx = new WrappedVertx(vertx); this.clusterManager = vertx.clusterManager(); + if (System.getProperty(SERIALISE_BLOCKING_PROP_NAME, "false").equalsIgnoreCase("true")) { + this.backgroundExec = new OrderedExecutorFactory(vertx.getBackgroundPool()).getExecutor(); + } else { + this.backgroundExec = vertx.getBackgroundPool(); + } + String modDir = System.getProperty(MODS_DIR_PROP_NAME); if (modDir != null && !modDir.trim().equals("")) { modRoot = new File(modDir); @@ -426,7 +435,7 @@ public void run() { private void runInBackground(final Runnable runnable, final Handler> doneHandler) { final DefaultContext context = vertx.getOrCreateContext(); - vertx.getBackgroundPool().execute(new Runnable() { + backgroundExec.execute(new Runnable() { public void run() { try { vertx.setContext(context); diff --git a/vertx-platform/src/main/java/org/vertx/java/platform/impl/ModuleClassLoader.java b/vertx-platform/src/main/java/org/vertx/java/platform/impl/ModuleClassLoader.java index 74a930c7f49..893436b92e8 100644 --- a/vertx-platform/src/main/java/org/vertx/java/platform/impl/ModuleClassLoader.java +++ b/vertx-platform/src/main/java/org/vertx/java/platform/impl/ModuleClassLoader.java @@ -58,10 +58,6 @@ public class ModuleClassLoader extends URLClassLoader { private final boolean loadFromModuleFirst; private Set modGraph; - // We use a single static object as a lock to prevent classes from being loaded from any modules concurrently - // Otherwise we can get deadlock when classes are loaded from similar sets of modules in different order - private static final Object lock = new Object(); - public ModuleClassLoader(String modID, ClassLoader platformClassLoader, URL[] classpath, boolean loadFromModuleFirst) { super(classpath); @@ -90,26 +86,27 @@ public void close() { @Override protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { - synchronized (lock) { - Class c; - if (loadFromModuleFirst) { - try { - c = loadFromModule(name); - } catch (ClassNotFoundException e) { - c = platformClassLoader.loadClass(name); - } - } else { - try { - c = platformClassLoader.loadClass(name); - } catch (ClassNotFoundException e) { - c = loadFromModule(name); - } + Class c = findLoadedClass(name); + if (c != null) { + return c; + } + if (loadFromModuleFirst) { + try { + c = loadFromModule(name); + } catch (ClassNotFoundException e) { + c = platformClassLoader.loadClass(name); } - if (resolve) { - resolveClass(c); + } else { + try { + c = platformClassLoader.loadClass(name); + } catch (ClassNotFoundException e) { + c = loadFromModule(name); } - return c; } + if (resolve) { + resolveClass(c); + } + return c; } private Class loadFromModule(String name) throws ClassNotFoundException { @@ -127,7 +124,7 @@ private Class loadFromModule(String name) throws ClassNotFoundException { return c; } - protected Class doLoadClass(String name) { + protected synchronized Class doLoadClass(String name) { Class c = findLoadedClass(name); if (c == null) { try {