diff --git a/src/it/projects/github322/invoker.properties b/src/it/projects/github322/invoker.properties
new file mode 100644
index 00000000..5f52c5a0
--- /dev/null
+++ b/src/it/projects/github322/invoker.properties
@@ -0,0 +1 @@
+invoker.goals = clean compile exec:java
diff --git a/src/it/projects/github322/pom.xml b/src/it/projects/github322/pom.xml
new file mode 100644
index 00000000..78201fbc
--- /dev/null
+++ b/src/it/projects/github322/pom.xml
@@ -0,0 +1,43 @@
+
+ 4.0.0
+
+
+ org.codehaus.mojo.exec.it
+ parent
+ 0.1
+
+
+ org.cb.maven.plugins.exec
+ github322
+ 0.1
+
+
+
+ xml-apis
+ xml-apis
+ 1.4.01
+
+
+
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ @pom.version@
+
+
+ test
+
+ java
+
+
+
+
+ org.codehaus.mojo.exec.it.github322.Main
+
+
+
+
+
+
diff --git a/src/it/projects/github322/src/main/java/org/codehaus/mojo/exec/it/github322/Main.java b/src/it/projects/github322/src/main/java/org/codehaus/mojo/exec/it/github322/Main.java
new file mode 100644
index 00000000..ffae7ac2
--- /dev/null
+++ b/src/it/projects/github322/src/main/java/org/codehaus/mojo/exec/it/github322/Main.java
@@ -0,0 +1,16 @@
+package org.codehaus.mojo.exec.it.github322;
+
+import javax.xml.transform.sax.SAXTransformerFactory;
+
+public class Main {
+ public static void main(final String... args) {
+ System.out.println(
+ "Main Result: <" +
+ (
+ SAXTransformerFactory.class.getProtectionDomain().getCodeSource() != null ?
+ SAXTransformerFactory.class.getProtectionDomain().getCodeSource().getLocation() :
+ null
+ ) +
+ ">");
+ }
+}
diff --git a/src/it/projects/github322/verify.groovy b/src/it/projects/github322/verify.groovy
new file mode 100644
index 00000000..5a2e621b
--- /dev/null
+++ b/src/it/projects/github322/verify.groovy
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+File log = new File(basedir, 'build.log')
+assert log.text.contains( 'Main Result: ')
diff --git a/src/main/java/org/codehaus/mojo/exec/ExecJavaMojo.java b/src/main/java/org/codehaus/mojo/exec/ExecJavaMojo.java
index 903c80c8..1b9e6013 100644
--- a/src/main/java/org/codehaus/mojo/exec/ExecJavaMojo.java
+++ b/src/main/java/org/codehaus/mojo/exec/ExecJavaMojo.java
@@ -194,6 +194,23 @@ public class ExecJavaMojo extends AbstractExecMojo {
@Parameter
private List classpathFilenameExclusions;
+ /**
+ * Additional packages to load from the jvm even if a classpath dependency matches.
+ *
+ * @since 3.5.0
+ */
+ @Parameter
+ private List forcedJvmPackages;
+
+ /**
+ * Additional packages to NOT load from the jvm even if it is in a flat classpath.
+ * Can enable to reproduce a webapp behavior for example where library is loaded over the JVM.
+ *
+ * @since 3.5.0
+ */
+ @Parameter
+ private List excludedJvmPackages;
+
/**
* Whether to try and prohibit the called Java program from terminating the JVM (and with it the whole Maven build)
* by calling {@link System#exit(int)}. When active, loaded classes will replace this call by a custom callback.
@@ -678,12 +695,13 @@ private URLClassLoader getClassLoader() throws MojoExecutionException {
this.addRelevantPluginDependenciesToClasspath(classpathURLs);
this.addRelevantProjectDependenciesToClasspath(classpathURLs);
this.addAdditionalClasspathElements(classpathURLs);
-
try {
final URLClassLoaderBuilder builder = URLClassLoaderBuilder.builder()
.setLogger(getLog())
.setPaths(classpathURLs)
- .setExclusions(classpathFilenameExclusions);
+ .setExclusions(classpathFilenameExclusions)
+ .setForcedJvmPackages(forcedJvmPackages)
+ .setExcludedJvmPackages(excludedJvmPackages);
if (blockSystemExit) {
builder.setTransformer(new BlockExitTransformer());
}
diff --git a/src/main/java/org/codehaus/mojo/exec/URLClassLoaderBuilder.java b/src/main/java/org/codehaus/mojo/exec/URLClassLoaderBuilder.java
index 2438695e..92cc55c2 100644
--- a/src/main/java/org/codehaus/mojo/exec/URLClassLoaderBuilder.java
+++ b/src/main/java/org/codehaus/mojo/exec/URLClassLoaderBuilder.java
@@ -42,12 +42,13 @@
import static java.util.Arrays.asList;
/**
- *
* @author Robert Scholte
* @since 3.0.0
*/
class URLClassLoaderBuilder {
private Log logger;
+ private List forcedJvmPackages;
+ private List excludedJvmPackages;
private Collection paths;
private Collection exclusions;
private ClassFileTransformer transformer;
@@ -58,6 +59,16 @@ static URLClassLoaderBuilder builder() {
return new URLClassLoaderBuilder();
}
+ URLClassLoaderBuilder setExcludedJvmPackages(List excludedJvmPackages) {
+ this.excludedJvmPackages = excludedJvmPackages;
+ return this;
+ }
+
+ URLClassLoaderBuilder setForcedJvmPackages(List forcedJvmPackages) {
+ this.forcedJvmPackages = forcedJvmPackages;
+ return this;
+ }
+
public URLClassLoaderBuilder setTransformer(final ClassFileTransformer transformer) {
this.transformer = transformer;
return this;
@@ -96,7 +107,7 @@ URLClassLoader build() throws IOException {
}
}
- return new ExecJavaClassLoader(urls.toArray(new URL[0]), transformer, logger);
+ return new ExecJavaClassLoader(urls.toArray(new URL[0]), transformer, forcedJvmPackages, excludedJvmPackages);
}
// child first strategy
@@ -110,14 +121,20 @@ private static class ExecJavaClassLoader extends URLClassLoader {
}
private final String jre;
- private final Log logger;
private final ClassFileTransformer transformer;
-
- public ExecJavaClassLoader(final URL[] urls, final ClassFileTransformer transformer, final Log logger) {
+ private final List forcedJvmPackages;
+ private final List excludedJvmPackages;
+
+ public ExecJavaClassLoader(
+ URL[] urls,
+ ClassFileTransformer transformer,
+ List forcedJvmPackages,
+ List excludedJvmPackages) {
super(urls);
this.jre = getJre();
- this.logger = logger;
this.transformer = transformer;
+ this.forcedJvmPackages = forcedJvmPackages;
+ this.excludedJvmPackages = excludedJvmPackages;
}
@Override
@@ -307,130 +324,101 @@ private boolean postLoad(boolean resolve, Class> clazz) {
return false;
}
- // not all jvm classes, for ex "javax" can be overriden so don't list it here
+ // not all jvm classes, for ex "javax" can be overridden so don't list it them all here (javax.resource for ex)
private boolean isDirectJvmClass(final String name) {
+ if (excludedJvmPackages != null && excludedJvmPackages.stream().anyMatch(name::startsWith)) {
+ return false;
+ }
if (name.startsWith("java.")) {
return true;
- }
- if (name.startsWith("sun.")) {
+ } else if (name.startsWith("javax.")) {
+ final String sub = name.substring("javax.".length());
+ if (sub.startsWith("xml.")) {
+ return true;
+ }
+ } else if (name.startsWith("sun.")) {
return true;
- }
- if (name.startsWith("jdk.")) {
+ } else if (name.startsWith("jdk.")) {
return true;
- }
- if (name.startsWith("oracle.")) {
+ } else if (name.startsWith("oracle.")) {
return true;
- }
- if (name.startsWith("javafx.")) {
+ } else if (name.startsWith("javafx.")) {
return true;
- }
- if (name.startsWith("netscape.")) {
+ } else if (name.startsWith("netscape.")) {
return true;
- }
- if (name.startsWith("org.")) {
+ } else if (name.startsWith("org.")) {
final String sub = name.substring("org.".length());
if (sub.startsWith("w3c.dom.")) {
return true;
- }
- if (sub.startsWith("omg.")) {
+ } else if (sub.startsWith("omg.")) {
return true;
- }
- if (sub.startsWith("xml.sax.")) {
+ } else if (sub.startsWith("xml.sax.")) {
return true;
- }
- if (sub.startsWith("ietf.jgss.")) {
+ } else if (sub.startsWith("ietf.jgss.")) {
return true;
- }
- if (sub.startsWith("jcp.xml.dsig.internal.")) {
+ } else if (sub.startsWith("jcp.xml.dsig.internal.")) {
return true;
}
- }
- if (name.startsWith("com.")) {
+ } else if (name.startsWith("com.")) {
final String sub = name.substring("com.".length());
if (sub.startsWith("oracle.")) {
return true;
- }
- if (sub.startsWith("sun.")) {
+ } else if (sub.startsWith("sun.")) {
final String subSun = sub.substring("sun.".length());
if (subSun.startsWith("accessibility.")) {
return true;
- }
- if (subSun.startsWith("activation.")) {
+ } else if (subSun.startsWith("activation.")) {
return true;
- }
- if (subSun.startsWith("awt.")) {
+ } else if (subSun.startsWith("awt.")) {
return true;
- }
- if (subSun.startsWith("beans.")) {
+ } else if (subSun.startsWith("beans.")) {
return true;
- }
- if (subSun.startsWith("corba.se.")) {
+ } else if (subSun.startsWith("corba.se.")) {
return true;
- }
- if (subSun.startsWith("demo.jvmti.")) {
+ } else if (subSun.startsWith("demo.jvmti.")) {
return true;
- }
- if (subSun.startsWith("image.codec.jpeg.")) {
+ } else if (subSun.startsWith("image.codec.jpeg.")) {
return true;
- }
- if (subSun.startsWith("imageio.")) {
+ } else if (subSun.startsWith("imageio.")) {
return true;
- }
- if (subSun.startsWith("istack.internal.")) {
+ } else if (subSun.startsWith("istack.internal.")) {
return true;
- }
- if (subSun.startsWith("java.")) {
+ } else if (subSun.startsWith("java.")) {
return true;
- }
- if (subSun.startsWith("java_cup.")) {
+ } else if (subSun.startsWith("java_cup.")) {
return true;
- }
- if (subSun.startsWith("jmx.")) {
+ } else if (subSun.startsWith("jmx.")) {
return true;
- }
- if (subSun.startsWith("jndi.")) {
+ } else if (subSun.startsWith("jndi.")) {
return true;
- }
- if (subSun.startsWith("management.")) {
+ } else if (subSun.startsWith("management.")) {
return true;
- }
- if (subSun.startsWith("media.sound.")) {
+ } else if (subSun.startsWith("media.sound.")) {
return true;
- }
- if (subSun.startsWith("naming.internal.")) {
+ } else if (subSun.startsWith("naming.internal.")) {
return true;
- }
- if (subSun.startsWith("net.")) {
+ } else if (subSun.startsWith("net.")) {
return true;
- }
- if (subSun.startsWith("nio.")) {
+ } else if (subSun.startsWith("nio.")) {
return true;
- }
- if (subSun.startsWith("org.")) {
+ } else if (subSun.startsWith("org.")) {
return true;
- }
- if (subSun.startsWith("rmi.rmid.")) {
+ } else if (subSun.startsWith("rmi.rmid.")) {
return true;
- }
- if (subSun.startsWith("rowset.")) {
+ } else if (subSun.startsWith("rowset.")) {
return true;
- }
- if (subSun.startsWith("security.")) {
+ } else if (subSun.startsWith("security.")) {
return true;
- }
- if (subSun.startsWith("swing.")) {
+ } else if (subSun.startsWith("swing.")) {
return true;
- }
- if (subSun.startsWith("tracing.")) {
+ } else if (subSun.startsWith("tracing.")) {
return true;
- }
- if (subSun.startsWith("xml.internal.")) {
+ } else if (subSun.startsWith("xml.internal.")) {
return true;
}
- return false;
}
}
- return false;
+ return forcedJvmPackages != null && forcedJvmPackages.stream().anyMatch(name::startsWith);
}
private class FilteringUrlEnum implements Enumeration {