org.bsc.maven
maven-processor-plugin
diff --git a/src/main/asciidoc/dataobjects.adoc b/src/main/asciidoc/dataobjects.adoc
index 95a2138a9..bab5b58a6 100644
--- a/src/main/asciidoc/dataobjects.adoc
+++ b/src/main/asciidoc/dataobjects.adoc
@@ -357,23 +357,12 @@ Set the send timeout.
|[[config]]`@config`|`Json object`|+++
Set the JSON configuration that will be passed to the verticle(s) when it's deployed
+++
-|[[extraClasspath]]`@extraClasspath`|`Array of String`|+++
-Set any extra classpath to be used when deploying the verticle.
-
- Ignored if no isolation group is set.
-+++
|[[ha]]`@ha`|`Boolean`|+++
Set whether the verticle(s) will be deployed as HA.
+++
|[[instances]]`@instances`|`Number (int)`|+++
Set the number of instances that should be deployed.
+++
-|[[isolatedClasses]]`@isolatedClasses`|`Array of String`|+++
-Set the isolated class names.
-+++
-|[[isolationGroup]]`@isolationGroup`|`String`|+++
-Set the isolation group that will be used when deploying the verticle(s)
-+++
|[[maxWorkerExecuteTime]]`@maxWorkerExecuteTime`|`Number (long)`|+++
Sets the value of max worker execute time, in link.
diff --git a/src/main/asciidoc/index.adoc b/src/main/asciidoc/index.adoc
index d99a09ce9..89ce299d1 100644
--- a/src/main/asciidoc/index.adoc
+++ b/src/main/asciidoc/index.adoc
@@ -554,39 +554,6 @@ and multiple cores on your machine, so you want to deploy multiple instances to
include::override/verticle-configuration.adoc[]
-=== Verticle Isolation Groups
-
-By default, Vert.x has a _flat classpath_. I.e, when Vert.x deploys verticles it does so with the current classloader -
-it doesn't create a new one. In the majority of cases this is the simplest, clearest, and sanest thing to do.
-
-However, in some cases you may want to deploy a verticle so the classes of that verticle are isolated from others in
-your application.
-
-This might be the case, for example, if you want to deploy two different versions of a verticle with the same class name
-in the same Vert.x instance, or if you have two different verticles which use different versions of the same jar library.
-
-When using an isolation group you provide a list of the class names that you want isolated using
-{@link io.vertx.core.DeploymentOptions#setIsolatedClasses(java.util.List)}- an entry can be a fully qualified
-classname such as `com.mycompany.myproject.engine.MyClass` or it can be a wildcard which will match any classes in a package and any
-sub-packages, e.g. `com.mycompany.myproject.*` would match any classes in the package `com.mycompany.myproject` or
-any sub-packages.
-
-Please note that _only_ the classes that match will be isolated - any other classes will be loaded by the current
-class loader.
-
-Extra classpath entries can also be provided with {@link io.vertx.core.DeploymentOptions#setExtraClasspath} so if
-you want to load classes or resources that aren't already present on the main classpath you can add this.
-
-WARNING: Use this feature with caution. Class-loaders can be a can of worms, and can make debugging difficult, amongst
-other things.
-
-Here's an example of using an isolation group to isolate a verticle deployment.
-
-[source,$lang]
-----
-{@link examples.CoreExamples#example14}
-----
-
=== High Availability
Verticles can be deployed with High Availability (HA) enabled. In that context, when a verticle is deployed on
diff --git a/src/main/generated/io/vertx/core/DeploymentOptionsConverter.java b/src/main/generated/io/vertx/core/DeploymentOptionsConverter.java
index 4862b055d..4ef5ea882 100644
--- a/src/main/generated/io/vertx/core/DeploymentOptionsConverter.java
+++ b/src/main/generated/io/vertx/core/DeploymentOptionsConverter.java
@@ -20,16 +20,6 @@ public class DeploymentOptionsConverter {
obj.setConfig(((JsonObject)member.getValue()).copy());
}
break;
- case "extraClasspath":
- if (member.getValue() instanceof JsonArray) {
- java.util.ArrayList list = new java.util.ArrayList<>();
- ((Iterable)member.getValue()).forEach( item -> {
- if (item instanceof String)
- list.add((String)item);
- });
- obj.setExtraClasspath(list);
- }
- break;
case "ha":
if (member.getValue() instanceof Boolean) {
obj.setHa((Boolean)member.getValue());
@@ -40,21 +30,6 @@ public class DeploymentOptionsConverter {
obj.setInstances(((Number)member.getValue()).intValue());
}
break;
- case "isolatedClasses":
- if (member.getValue() instanceof JsonArray) {
- java.util.ArrayList list = new java.util.ArrayList<>();
- ((Iterable)member.getValue()).forEach( item -> {
- if (item instanceof String)
- list.add((String)item);
- });
- obj.setIsolatedClasses(list);
- }
- break;
- case "isolationGroup":
- if (member.getValue() instanceof String) {
- obj.setIsolationGroup((String)member.getValue());
- }
- break;
case "maxWorkerExecuteTime":
if (member.getValue() instanceof Number) {
obj.setMaxWorkerExecuteTime(((Number)member.getValue()).longValue());
@@ -92,21 +67,8 @@ public class DeploymentOptionsConverter {
if (obj.getConfig() != null) {
json.put("config", obj.getConfig());
}
- if (obj.getExtraClasspath() != null) {
- JsonArray array = new JsonArray();
- obj.getExtraClasspath().forEach(item -> array.add(item));
- json.put("extraClasspath", array);
- }
json.put("ha", obj.isHa());
json.put("instances", obj.getInstances());
- if (obj.getIsolatedClasses() != null) {
- JsonArray array = new JsonArray();
- obj.getIsolatedClasses().forEach(item -> array.add(item));
- json.put("isolatedClasses", array);
- }
- if (obj.getIsolationGroup() != null) {
- json.put("isolationGroup", obj.getIsolationGroup());
- }
json.put("maxWorkerExecuteTime", obj.getMaxWorkerExecuteTime());
if (obj.getMaxWorkerExecuteTimeUnit() != null) {
json.put("maxWorkerExecuteTimeUnit", obj.getMaxWorkerExecuteTimeUnit().name());
diff --git a/src/main/java/examples/CoreExamples.java b/src/main/java/examples/CoreExamples.java
index 8b835f264..051719e93 100644
--- a/src/main/java/examples/CoreExamples.java
+++ b/src/main/java/examples/CoreExamples.java
@@ -262,13 +262,6 @@ public class CoreExamples {
vertx.deployVerticle("com.mycompany.MyOrderProcessorVerticle", options);
}
- public void example14(Vertx vertx) {
- DeploymentOptions options = new DeploymentOptions().setIsolationGroup("mygroup");
- options.setIsolatedClasses(Arrays.asList("com.mycompany.myverticle.*",
- "com.mycompany.somepkg.SomeClass", "org.somelibrary.*"));
- vertx.deployVerticle("com.mycompany.myverticle.VerticleClass", options);
- }
-
public void example15(Vertx vertx) {
long timerID = vertx.setTimer(1000, id -> {
System.out.println("And one second later this is printed");
diff --git a/src/main/java/io/vertx/core/DeploymentOptions.java b/src/main/java/io/vertx/core/DeploymentOptions.java
index 091e7ab31..3c8cb3dec 100644
--- a/src/main/java/io/vertx/core/DeploymentOptions.java
+++ b/src/main/java/io/vertx/core/DeploymentOptions.java
@@ -12,6 +12,7 @@
package io.vertx.core;
import io.vertx.codegen.annotations.DataObject;
+import io.vertx.codegen.annotations.GenIgnore;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
@@ -30,7 +31,6 @@ import java.util.concurrent.TimeUnit;
public class DeploymentOptions {
public static final boolean DEFAULT_WORKER = false;
- public static final String DEFAULT_ISOLATION_GROUP = null;
public static final boolean DEFAULT_HA = false;
public static final int DEFAULT_INSTANCES = 1;
@@ -52,7 +52,7 @@ public class DeploymentOptions {
public DeploymentOptions() {
this.worker = DEFAULT_WORKER;
this.config = null;
- this.isolationGroup = DEFAULT_ISOLATION_GROUP;
+ this.isolationGroup = null;
this.ha = DEFAULT_HA;
this.instances = DEFAULT_INSTANCES;
this.workerPoolName = null;
@@ -98,7 +98,7 @@ public class DeploymentOptions {
public void fromJson(JsonObject json) {
this.config = json.getJsonObject("config");
this.worker = json.getBoolean("worker", DEFAULT_WORKER);
- this.isolationGroup = json.getString("isolationGroup", DEFAULT_ISOLATION_GROUP);
+ this.isolationGroup = json.getString("isolationGroup", null);
this.ha = json.getBoolean("ha", DEFAULT_HA);
JsonArray arr = json.getJsonArray("extraClasspath", null);
if (arr != null) {
@@ -153,19 +153,27 @@ public class DeploymentOptions {
/**
* Get the isolation group that will be used when deploying the verticle(s)
+ *
+ * IMPORTANT this feature is removed when running with Java 11 or above.
*
* @return the isolation group
*/
+ @GenIgnore
+ @Deprecated
public String getIsolationGroup() {
return isolationGroup;
}
/**
* Set the isolation group that will be used when deploying the verticle(s)
+ *
+ * IMPORTANT this feature is removed when running with Java 11 or above.
*
* @param isolationGroup - the isolation group
* @return a reference to this, so the API can be used fluently
*/
+ @GenIgnore
+ @Deprecated
public DeploymentOptions setIsolationGroup(String isolationGroup) {
this.isolationGroup = isolationGroup;
return this;
@@ -195,9 +203,13 @@ public class DeploymentOptions {
* Get any extra classpath to be used when deploying the verticle.
*
* Ignored if no isolation group is set.
+ *
+ * IMPORTANT this feature is removed when running with Java 11 or above.
*
* @return any extra classpath
*/
+ @GenIgnore
+ @Deprecated
public List getExtraClasspath() {
return extraClasspath;
}
@@ -206,9 +218,13 @@ public class DeploymentOptions {
* Set any extra classpath to be used when deploying the verticle.
*
* Ignored if no isolation group is set.
+ *
+ * IMPORTANT this feature is removed when running with Java 11 or above.
*
* @return a reference to this, so the API can be used fluently
*/
+ @GenIgnore
+ @Deprecated
public DeploymentOptions setExtraClasspath(List extraClasspath) {
this.extraClasspath = extraClasspath;
return this;
@@ -237,19 +253,27 @@ public class DeploymentOptions {
/**
* Get the list of isolated class names, the names can be a Java class fully qualified name such as
* 'com.mycompany.myproject.engine.MyClass' or a wildcard matching such as `com.mycompany.myproject.*`.
+ *
+ * IMPORTANT this feature is removed when running with Java 11 or above.
*
* @return the list of isolated classes
*/
+ @GenIgnore
+ @Deprecated
public List getIsolatedClasses() {
return isolatedClasses;
}
/**
* Set the isolated class names.
+ *
+ * IMPORTANT this feature is removed when running with Java 11 or above.
*
* @param isolatedClasses the list of isolated class names
* @return a reference to this, so the API can be used fluently
*/
+ @GenIgnore
+ @Deprecated
public DeploymentOptions setIsolatedClasses(List isolatedClasses) {
this.isolatedClasses = isolatedClasses;
return this;
@@ -348,6 +372,21 @@ public class DeploymentOptions {
return this;
}
+ /**
+ * Throw {@code IllegalArgumentException} when loader isolation configuration has been defined.
+ */
+ public void checkIsolationNotDefined() {
+ if (getExtraClasspath() != null) {
+ throw new IllegalArgumentException("Can't specify extraClasspath for already created verticle");
+ }
+ if (getIsolationGroup() != null) {
+ throw new IllegalArgumentException("Can't specify isolationGroup for already created verticle");
+ }
+ if (getIsolatedClasses() != null) {
+ throw new IllegalArgumentException("Can't specify isolatedClasses for already created verticle");
+ }
+ }
+
/**
* Convert this to JSON
*
diff --git a/src/main/java/io/vertx/core/impl/ClassLoaderHolder.java b/src/main/java/io/vertx/core/impl/ClassLoaderHolder.java
new file mode 100644
index 000000000..2566dfc5d
--- /dev/null
+++ b/src/main/java/io/vertx/core/impl/ClassLoaderHolder.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2011-2019 Contributors to the Eclipse Foundation
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+ * which is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+ */
+package io.vertx.core.impl;
+
+/**
+ * @author Julien Viet
+ */
+class ClassLoaderHolder {
+
+ final String group;
+ final ClassLoader loader;
+ int refCount;
+
+ ClassLoaderHolder(String group, ClassLoader loader) {
+ this.group = group;
+ this.loader = loader;
+ }
+}
diff --git a/src/main/java/io/vertx/core/impl/DeploymentManager.java b/src/main/java/io/vertx/core/impl/DeploymentManager.java
index fb0df3d30..19037f502 100644
--- a/src/main/java/io/vertx/core/impl/DeploymentManager.java
+++ b/src/main/java/io/vertx/core/impl/DeploymentManager.java
@@ -61,15 +61,7 @@ public class DeploymentManager {
if (options.getInstances() < 1) {
throw new IllegalArgumentException("Can't specify < 1 instances to deploy");
}
- if (options.getExtraClasspath() != null) {
- throw new IllegalArgumentException("Can't specify extraClasspath for already created verticle");
- }
- if (options.getIsolationGroup() != null) {
- throw new IllegalArgumentException("Can't specify isolationGroup for already created verticle");
- }
- if (options.getIsolatedClasses() != null) {
- throw new IllegalArgumentException("Can't specify isolatedClasses for already created verticle");
- }
+ options.checkIsolationNotDefined();
ContextInternal currentContext = vertx.getOrCreateContext();
ClassLoader cl = getCurrentClassLoader();
return doDeploy(options, v -> "java:" + v.getClass().getName(), currentContext, currentContext, cl, verticleSupplier)
diff --git a/src/main/java/io/vertx/core/impl/IsolatingClassLoader.java b/src/main/java/io/vertx/core/impl/IsolatingClassLoader.java
index 58f707812..e8420cf0e 100644
--- a/src/main/java/io/vertx/core/impl/IsolatingClassLoader.java
+++ b/src/main/java/io/vertx/core/impl/IsolatingClassLoader.java
@@ -26,12 +26,10 @@ public class IsolatingClassLoader extends URLClassLoader {
private volatile boolean closed;
private List isolatedClasses;
- int refCount;
public IsolatingClassLoader(URL[] urls, ClassLoader parent, List isolatedClasses) {
super(urls, parent);
this.isolatedClasses = isolatedClasses;
- this.refCount = 0;
}
@Override
diff --git a/src/main/java/io/vertx/core/impl/LoaderManager.java b/src/main/java/io/vertx/core/impl/LoaderManager.java
new file mode 100644
index 000000000..e3ca659c5
--- /dev/null
+++ b/src/main/java/io/vertx/core/impl/LoaderManager.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2011-2019 Contributors to the Eclipse Foundation
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+ * which is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+ */
+package io.vertx.core.impl;
+
+import io.vertx.core.DeploymentOptions;
+
+import java.io.Closeable;
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Supports isolated classloader for Java 8.
+ *
+ * For Java 11 and above, the JVM uses a no-op implementation thanks to Multi-Release Jar.
+ */
+class LoaderManager {
+
+ private final Map classLoaders = new HashMap<>();
+
+ /**
+ * IMPORTANT - Isolation groups are not supported on Java 9+ because the application classloader is not
+ * an URLClassLoader anymore. Thus we can't extract the list of jars to configure the IsolatedClassLoader.
+ */
+ ClassLoaderHolder getClassLoader(DeploymentOptions options) {
+ String isolationGroup = options.getIsolationGroup();
+ ClassLoaderHolder holder;
+ if (isolationGroup == null) {
+ return null;
+ } else {
+ // IMPORTANT - Isolation groups are not supported on Java 9+, because the system classloader is not an URLClassLoader
+ // anymore. Thus we can't extract the paths from the classpath and isolate the loading.
+ synchronized (this) {
+ holder = classLoaders.get(isolationGroup);
+ if (holder == null) {
+ ClassLoader current = VerticleManager.getCurrentClassLoader();
+ if (!(current instanceof URLClassLoader)) {
+ throw new IllegalStateException("Current classloader must be URLClassLoader");
+ }
+ holder = new ClassLoaderHolder(isolationGroup, LoaderManager.buildLoader((URLClassLoader) current, options));
+ classLoaders.put(isolationGroup, holder);
+ }
+ holder.refCount++;
+ }
+ }
+ return holder;
+ }
+
+ void release(ClassLoaderHolder holder) {
+ synchronized (this) {
+ if (--holder.refCount == 0) {
+ classLoaders.remove(holder.group);
+ if (holder.loader instanceof Closeable) {
+ try {
+ ((Closeable)holder.loader).close();
+ } catch (IOException e) {
+ // log.debug("Issue when closing isolation group loader", e);
+ }
+ }
+ }
+ }
+ }
+
+ private static ClassLoader buildLoader(URLClassLoader parent, DeploymentOptions options) {
+ List urls = new ArrayList<>();
+ // Add any extra URLs to the beginning of the classpath
+ List extraClasspath = options.getExtraClasspath();
+ if (extraClasspath != null) {
+ for (String pathElement: extraClasspath) {
+ File file = new File(pathElement);
+ try {
+ URL url = file.toURI().toURL();
+ urls.add(url);
+ } catch (MalformedURLException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+ }
+ // And add the URLs of the Vert.x classloader
+ urls.addAll(Arrays.asList(parent.getURLs()));
+ return new IsolatingClassLoader(urls.toArray(new URL[urls.size()]), parent,
+ options.getIsolatedClasses());
+ }
+}
diff --git a/src/main/java/io/vertx/core/impl/VerticleManager.java b/src/main/java/io/vertx/core/impl/VerticleManager.java
index 71f8fd3b2..0fb81030b 100644
--- a/src/main/java/io/vertx/core/impl/VerticleManager.java
+++ b/src/main/java/io/vertx/core/impl/VerticleManager.java
@@ -17,15 +17,8 @@ import io.vertx.core.ServiceHelper;
import io.vertx.core.Verticle;
import io.vertx.core.spi.VerticleFactory;
-import java.io.File;
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -41,7 +34,7 @@ public class VerticleManager {
private final VertxInternal vertx;
private final DeploymentManager deploymentManager;
- private final Map classloaders = new HashMap<>();
+ private final LoaderManager loaderManager = new LoaderManager();
private final Map> verticleFactories = new ConcurrentHashMap<>();
private final List defaultFactories = new ArrayList<>();
@@ -152,8 +145,23 @@ public class VerticleManager {
public Future deployVerticle(String identifier,
DeploymentOptions options) {
ContextInternal callingContext = vertx.getOrCreateContext();
- ClassLoader cl = getClassLoader(options);
- return doDeployVerticle(identifier, options, callingContext, callingContext, cl);
+ ClassLoaderHolder holder = loaderManager.getClassLoader(options);
+ ClassLoader loader = holder != null ? holder.loader : getCurrentClassLoader();
+ Future deployment = doDeployVerticle(identifier, options, callingContext, callingContext, loader);
+ if (holder != null) {
+ deployment.onComplete(ar -> {
+ if (ar.succeeded()) {
+ Deployment result = ar.result();
+ result.undeployHandler(v -> {
+ loaderManager.release(holder);
+ });
+ } else {
+ // ??? not tested
+ throw new UnsupportedOperationException();
+ }
+ });
+ }
+ return deployment;
}
private Future doDeployVerticle(String identifier,
@@ -204,88 +212,14 @@ public class VerticleManager {
} catch (Exception e) {
return Future.failedFuture(e);
}
- Future fut = p.future().compose(callable -> deploymentManager.doDeploy(options, v -> identifier, parentContext, callingContext, cl, callable));
- String group = options.getIsolationGroup();
- if (group != null) {
- fut.onComplete(ar -> {
- if (ar.succeeded()) {
- Deployment result = ar.result();
- result.undeployHandler(v -> {
- synchronized (VerticleManager.this) {
- IsolatingClassLoader icl = classloaders.get(group);
- if (--icl.refCount == 0) {
- classloaders.remove(group);
- try {
- icl.close();
- } catch (IOException e) {
- // log.debug("Issue when closing isolation group loader", e);
- }
- }
- }
- });
- } else {
- // ??? not tested
- throw new UnsupportedOperationException();
- }
- });
- }
- return fut;
+ return p.future()
+ .compose(callable -> deploymentManager.doDeploy(options, v -> identifier, parentContext, callingContext, cl, callable));
}
- /**
- * IMPORTANT - Isolation groups are not supported on Java 9+ because the application classloader is not
- * an URLClassLoader anymore. Thus we can't extract the list of jars to configure the IsolatedClassLoader.
- *
- */
- private ClassLoader getClassLoader(DeploymentOptions options) {
- String isolationGroup = options.getIsolationGroup();
- ClassLoader cl;
- if (isolationGroup == null) {
- cl = getCurrentClassLoader();
- } else {
- // IMPORTANT - Isolation groups are not supported on Java 9+, because the system classloader is not an URLClassLoader
- // anymore. Thus we can't extract the paths from the classpath and isolate the loading.
- synchronized (this) {
- IsolatingClassLoader icl = classloaders.get(isolationGroup);
- if (icl == null) {
- ClassLoader current = getCurrentClassLoader();
- if (!(current instanceof URLClassLoader)) {
- throw new IllegalStateException("Current classloader must be URLClassLoader");
- }
- List urls = new ArrayList<>();
- // Add any extra URLs to the beginning of the classpath
- List extraClasspath = options.getExtraClasspath();
- if (extraClasspath != null) {
- for (String pathElement: extraClasspath) {
- File file = new File(pathElement);
- try {
- URL url = file.toURI().toURL();
- urls.add(url);
- } catch (MalformedURLException e) {
- throw new IllegalStateException(e);
- }
- }
- }
- // And add the URLs of the Vert.x classloader
- URLClassLoader urlc = (URLClassLoader)current;
- urls.addAll(Arrays.asList(urlc.getURLs()));
-
- // Create an isolating cl with the urls
- icl = new IsolatingClassLoader(urls.toArray(new URL[urls.size()]), getCurrentClassLoader(),
- options.getIsolatedClasses());
- classloaders.put(isolationGroup, icl);
- }
- icl.refCount++;
- cl = icl;
- }
- }
- return cl;
- }
-
- private ClassLoader getCurrentClassLoader() {
+ static ClassLoader getCurrentClassLoader() {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
if (cl == null) {
- cl = getClass().getClassLoader();
+ cl = VerticleManager.class.getClassLoader();
}
return cl;
}
diff --git a/src/main/java11/io/vertx/core/DeploymentOptions.java b/src/main/java11/io/vertx/core/DeploymentOptions.java
new file mode 100644
index 000000000..d50949891
--- /dev/null
+++ b/src/main/java11/io/vertx/core/DeploymentOptions.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 2011-2019 Contributors to the Eclipse Foundation
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+ * which is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+ */
+
+package io.vertx.core;
+
+import io.vertx.codegen.annotations.DataObject;
+import io.vertx.core.json.JsonArray;
+import io.vertx.core.json.JsonObject;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Options for configuring a verticle deployment.
+ *
+ *
+ *
+ * @author Tim Fox
+ */
+@DataObject(generateConverter = true, publicConverter = false)
+public class DeploymentOptions {
+
+ public static final boolean DEFAULT_WORKER = false;
+ public static final boolean DEFAULT_HA = false;
+ public static final int DEFAULT_INSTANCES = 1;
+
+ private JsonObject config;
+ private boolean worker;
+ private String workerPoolName;
+ private int workerPoolSize;
+ private long maxWorkerExecuteTime;
+ private boolean ha;
+ private int instances;
+ private TimeUnit maxWorkerExecuteTimeUnit;
+
+ /**
+ * Default constructor
+ */
+ public DeploymentOptions() {
+ this.worker = DEFAULT_WORKER;
+ this.config = null;
+ this.ha = DEFAULT_HA;
+ this.instances = DEFAULT_INSTANCES;
+ this.workerPoolName = null;
+ this.workerPoolSize = VertxOptions.DEFAULT_WORKER_POOL_SIZE;
+ this.maxWorkerExecuteTime = VertxOptions.DEFAULT_MAX_WORKER_EXECUTE_TIME;
+ this.maxWorkerExecuteTimeUnit = VertxOptions.DEFAULT_MAX_WORKER_EXECUTE_TIME_UNIT;
+ }
+
+ /**
+ * Copy constructor
+ *
+ * @param other the instance to copy
+ */
+ public DeploymentOptions(DeploymentOptions other) {
+ this.config = other.getConfig() == null ? null : other.getConfig().copy();
+ this.worker = other.isWorker();
+ this.ha = other.isHa();
+ this.instances = other.instances;
+ this.workerPoolName = other.workerPoolName;
+ setWorkerPoolSize(other.workerPoolSize);
+ setMaxWorkerExecuteTime(other.maxWorkerExecuteTime);
+ this.maxWorkerExecuteTimeUnit = other.maxWorkerExecuteTimeUnit;
+ }
+
+ /**
+ * Constructor for creating a instance from JSON
+ *
+ * @param json the JSON
+ */
+ public DeploymentOptions(JsonObject json) {
+ this();
+ DeploymentOptionsConverter.fromJson(json, this);
+ }
+
+ /**
+ * Initialise the fields of this instance from the specified JSON
+ *
+ * @param json the JSON
+ */
+ public void fromJson(JsonObject json) {
+ this.config = json.getJsonObject("config");
+ this.worker = json.getBoolean("worker", DEFAULT_WORKER);
+ this.ha = json.getBoolean("ha", DEFAULT_HA);
+ this.instances = json.getInteger("instances", DEFAULT_INSTANCES);
+ }
+
+ /**
+ * Get the JSON configuration that will be passed to the verticle(s) when deployed.
+ *
+ * @return the JSON config
+ */
+ public JsonObject getConfig() {
+ return config;
+ }
+
+ /**
+ * Set the JSON configuration that will be passed to the verticle(s) when it's deployed
+ *
+ * @param config the JSON config
+ * @return a reference to this, so the API can be used fluently
+ */
+ public DeploymentOptions setConfig(JsonObject config) {
+ this.config = config;
+ return this;
+ }
+
+ /**
+ * Should the verticle(s) be deployed as a worker verticle?
+ *
+ * @return true if will be deployed as worker, false otherwise
+ */
+ public boolean isWorker() {
+ return worker;
+ }
+
+ /**
+ * Set whether the verticle(s) should be deployed as a worker verticle
+ *
+ * @param worker true for worker, false otherwise
+ * @return a reference to this, so the API can be used fluently
+ */
+ public DeploymentOptions setWorker(boolean worker) {
+ this.worker = worker;
+ return this;
+ }
+
+ /**
+ * Will the verticle(s) be deployed as HA (highly available) ?
+ *
+ * @return true if HA, false otherwise
+ */
+ public boolean isHa() {
+ return ha;
+ }
+
+ /**
+ * Set whether the verticle(s) will be deployed as HA.
+ *
+ * @param ha true if to be deployed as HA, false otherwise
+ * @return a reference to this, so the API can be used fluently
+ */
+ public DeploymentOptions setHa(boolean ha) {
+ this.ha = ha;
+ return this;
+ }
+
+ /**
+ * Get the number of instances that should be deployed.
+ *
+ * @return the number of instances
+ */
+ public int getInstances() {
+ return instances;
+ }
+
+ /**
+ * Set the number of instances that should be deployed.
+ *
+ * @param instances the number of instances
+ * @return a reference to this, so the API can be used fluently
+ */
+ public DeploymentOptions setInstances(int instances) {
+ this.instances = instances;
+ return this;
+ }
+
+ /**
+ * @return the worker pool name
+ */
+ public String getWorkerPoolName() {
+ return workerPoolName;
+ }
+
+ /**
+ * Set the worker pool name to use for this verticle. When no name is set, the Vert.x
+ * worker pool will be used, when a name is set, the verticle will use a named worker pool.
+ *
+ * @param workerPoolName the worker pool name
+ * @return a reference to this, so the API can be used fluently
+ */
+ public DeploymentOptions setWorkerPoolName(String workerPoolName) {
+ this.workerPoolName = workerPoolName;
+ return this;
+ }
+
+ /**
+ * Get the maximum number of worker threads to be used by the worker pool when the verticle is deployed
+ * with a {@link #setWorkerPoolName}. When the verticle does not use a named worker pool, this option
+ * has no effect.
+ *
+ * Worker threads are used for running blocking code and worker verticles.
+ *
+ * @return the maximum number of worker threads
+ */
+ public int getWorkerPoolSize() {
+ return workerPoolSize;
+ }
+
+ /**
+ * Set the maximum number of worker threads to be used by the Vert.x instance.
+ *
+ * @param workerPoolSize the number of threads
+ * @return a reference to this, so the API can be used fluently
+ */
+ public DeploymentOptions setWorkerPoolSize(int workerPoolSize) {
+ if (workerPoolSize < 1) {
+ throw new IllegalArgumentException("workerPoolSize must be > 0");
+ }
+ this.workerPoolSize = workerPoolSize;
+ return this;
+ }
+
+ /**
+ * Get the value of max worker execute time, in {@link DeploymentOptions#setMaxWorkerExecuteTimeUnit maxWorkerExecuteTimeUnit}.
+ *
+ * Vert.x will automatically log a warning if it detects that worker threads haven't returned within this time.
+ *
+ * This can be used to detect where the user is blocking a worker thread for too long. Although worker threads
+ * can be blocked longer than event loop threads, they shouldn't be blocked for long periods of time.
+ *
+ * @return The value of max worker execute time, the default value of {@link DeploymentOptions#setMaxWorkerExecuteTimeUnit} {@code maxWorkerExecuteTimeUnit} is {@link TimeUnit#NANOSECONDS}
+ */
+ public long getMaxWorkerExecuteTime() {
+ return maxWorkerExecuteTime;
+ }
+
+ /**
+ * Sets the value of max worker execute time, in {@link DeploymentOptions#setMaxWorkerExecuteTimeUnit maxWorkerExecuteTimeUnit}.
+ *
+ * The default value of {@link DeploymentOptions#setMaxWorkerExecuteTimeUnit maxWorkerExecuteTimeUnit} is {@link TimeUnit#NANOSECONDS}
+ *
+ * @param maxWorkerExecuteTime the value of max worker execute time, in in {@link DeploymentOptions#setMaxWorkerExecuteTimeUnit maxWorkerExecuteTimeUnit}.
+ * @return a reference to this, so the API can be used fluently
+ */
+ public DeploymentOptions setMaxWorkerExecuteTime(long maxWorkerExecuteTime) {
+ if (maxWorkerExecuteTime < 1) {
+ throw new IllegalArgumentException("maxWorkerExecuteTime must be > 0");
+ }
+ this.maxWorkerExecuteTime = maxWorkerExecuteTime;
+ return this;
+ }
+
+ /**
+ * @return the time unit of {@code maxWorkerExecuteTime}
+ */
+ public TimeUnit getMaxWorkerExecuteTimeUnit() {
+ return maxWorkerExecuteTimeUnit;
+ }
+
+ /**
+ * Set the time unit of {@code maxWorkerExecuteTime}
+ * @param maxWorkerExecuteTimeUnit the time unit of {@code maxWorkerExecuteTime}
+ * @return a reference to this, so the API can be used fluently
+ */
+ public DeploymentOptions setMaxWorkerExecuteTimeUnit(TimeUnit maxWorkerExecuteTimeUnit) {
+ this.maxWorkerExecuteTimeUnit = maxWorkerExecuteTimeUnit;
+ return this;
+ }
+
+ /**
+ * Does nothing.
+ */
+ public void checkIsolationNotDefined() {
+ }
+
+ /**
+ * Convert this to JSON
+ *
+ * @return the JSON
+ */
+ public JsonObject toJson() {
+ JsonObject json = new JsonObject();
+ DeploymentOptionsConverter.toJson(this, json);
+ return json;
+ }
+}
diff --git a/src/main/java11/io/vertx/core/impl/LoaderManager.java b/src/main/java11/io/vertx/core/impl/LoaderManager.java
new file mode 100644
index 000000000..caaa617d0
--- /dev/null
+++ b/src/main/java11/io/vertx/core/impl/LoaderManager.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2011-2019 Contributors to the Eclipse Foundation
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+ * which is available at https://www.apache.org/licenses/LICENSE-2.0.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+ */
+package io.vertx.core.impl;
+
+import io.vertx.core.DeploymentOptions;
+
+/**
+ * No-op implementation for Java 11 and above.
+ */
+class LoaderManager {
+
+ /**
+ * @return {@code null}
+ */
+ ClassLoaderHolder getClassLoader(DeploymentOptions options) {
+ return null;
+ }
+
+ void release(ClassLoaderHolder holder) {
+ }
+}
diff --git a/src/test/java/io/vertx/core/DeploymentTest.java b/src/test/java/io/vertx/core/DeploymentTest.java
index 75f827cf4..d9b42c527 100644
--- a/src/test/java/io/vertx/core/DeploymentTest.java
+++ b/src/test/java/io/vertx/core/DeploymentTest.java
@@ -146,8 +146,6 @@ public class DeploymentTest extends VertxTestBase {
JsonObject config = new JsonObject().put("foo", "bar");
Random rand = new Random();
boolean worker = rand.nextBoolean();
- boolean multiThreaded = rand.nextBoolean();
- String isolationGroup = TestUtils.randomAlphaString(100);
boolean ha = rand.nextBoolean();
List cp = Arrays.asList("foo", "bar");
List isol = Arrays.asList("com.foo.MyClass", "org.foo.*");
@@ -158,22 +156,15 @@ public class DeploymentTest extends VertxTestBase {
JsonObject json = new JsonObject();
json.put("config", config);
json.put("worker", worker);
- json.put("multiThreaded", multiThreaded);
- json.put("isolationGroup", isolationGroup);
json.put("ha", ha);
- json.put("extraClasspath", new JsonArray(cp));
- json.put("isolatedClasses", new JsonArray(isol));
json.put("workerPoolName", poolName);
json.put("workerPoolSize", poolSize);
json.put("maxWorkerExecuteTime", maxWorkerExecuteTime);
json.put("maxWorkerExecuteTimeUnit", maxWorkerExecuteTimeUnit);
DeploymentOptions options = new DeploymentOptions(json);
assertEquals(worker, options.isWorker());
- assertEquals(isolationGroup, options.getIsolationGroup());
assertEquals("bar", options.getConfig().getString("foo"));
assertEquals(ha, options.isHa());
- assertEquals(cp, options.getExtraClasspath());
- assertEquals(isol, options.getIsolatedClasses());
assertEquals(poolName, options.getWorkerPoolName());
assertEquals(poolSize, options.getWorkerPoolSize());
assertEquals(maxWorkerExecuteTime, options.getMaxWorkerExecuteTime());
@@ -186,8 +177,6 @@ public class DeploymentTest extends VertxTestBase {
JsonObject config = new JsonObject().put("foo", "bar");
Random rand = new Random();
boolean worker = rand.nextBoolean();
- boolean multiThreaded = rand.nextBoolean();
- String isolationGroup = TestUtils.randomAlphaString(100);
boolean ha = rand.nextBoolean();
List cp = Arrays.asList("foo", "bar");
List isol = Arrays.asList("com.foo.MyClass", "org.foo.*");
@@ -197,10 +186,7 @@ public class DeploymentTest extends VertxTestBase {
TimeUnit maxWorkerExecuteTimeUnit = TimeUnit.MILLISECONDS;
options.setConfig(config);
options.setWorker(worker);
- options.setIsolationGroup(isolationGroup);
options.setHa(ha);
- options.setExtraClasspath(cp);
- options.setIsolatedClasses(isol);
options.setWorkerPoolName(poolName);
options.setWorkerPoolSize(poolSize);
options.setMaxWorkerExecuteTime(maxWorkerExecuteTime);
@@ -208,11 +194,8 @@ public class DeploymentTest extends VertxTestBase {
JsonObject json = options.toJson();
DeploymentOptions copy = new DeploymentOptions(json);
assertEquals(worker, copy.isWorker());
- assertEquals(isolationGroup, copy.getIsolationGroup());
assertEquals("bar", copy.getConfig().getString("foo"));
assertEquals(ha, copy.isHa());
- assertEquals(cp, copy.getExtraClasspath());
- assertEquals(isol, copy.getIsolatedClasses());
assertEquals(poolName, copy.getWorkerPoolName());
assertEquals(poolSize, copy.getWorkerPoolSize());
assertEquals(maxWorkerExecuteTime, copy.getMaxWorkerExecuteTime());