Skip to content

Commit 1bab77f

Browse files
committed
#322, enable to control the exec:java interaction with JVM classloader more finely
1 parent 716a232 commit 1bab77f

File tree

7 files changed

+148
-19
lines changed

7 files changed

+148
-19
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
invoker.goals = clean compile exec:java

src/it/projects/github322/pom.xml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<project>
2+
<modelVersion>4.0.0</modelVersion>
3+
4+
<parent>
5+
<groupId>org.codehaus.mojo.exec.it</groupId>
6+
<artifactId>parent</artifactId>
7+
<version>0.1</version>
8+
</parent>
9+
10+
<groupId>org.cb.maven.plugins.exec</groupId>
11+
<artifactId>github322</artifactId>
12+
<version>0.1</version>
13+
14+
<dependencies>
15+
<dependency>
16+
<groupId>xml-apis</groupId>
17+
<artifactId>xml-apis</artifactId>
18+
<version>1.4.01</version>
19+
</dependency>
20+
</dependencies>
21+
22+
<build>
23+
<plugins>
24+
<plugin>
25+
<groupId>org.codehaus.mojo</groupId>
26+
<artifactId>exec-maven-plugin</artifactId>
27+
<version>@pom.version@</version>
28+
<executions>
29+
<execution>
30+
<phase>test</phase>
31+
<goals>
32+
<goal>java</goal>
33+
</goals>
34+
</execution>
35+
</executions>
36+
<configuration>
37+
<mainClass>org.codehaus.mojo.exec.it.github322.Main</mainClass>
38+
</configuration>
39+
</plugin>
40+
</plugins>
41+
</build>
42+
43+
</project>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package org.codehaus.mojo.exec.it.github322;
2+
3+
import javax.xml.transform.sax.SAXTransformerFactory;
4+
5+
public class Main {
6+
public static void main(final String... args) {
7+
System.out.println(
8+
"Main Result: <" +
9+
(
10+
SAXTransformerFactory.class.getProtectionDomain().getCodeSource() != null ?
11+
SAXTransformerFactory.class.getProtectionDomain().getCodeSource().getLocation() :
12+
null
13+
) +
14+
">");
15+
}
16+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
new IntegrationBase().checkExistenceAndContentOfAFile(new File( basedir, "build.log" ), [ "Main Result: <null>" ])
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
invoker.goals = clean verify
22

33
invoker.debug = true
4-
invoker.buildResult = failure
4+
invoker.buildResult = success

src/main/java/org/codehaus/mojo/exec/ExecJavaMojo.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,23 @@ public class ExecJavaMojo
203203
@Parameter
204204
private List<String> classpathFilenameExclusions;
205205

206+
/**
207+
* Additional packages to load from the jvm even if a classpath dependency matches.
208+
*
209+
* @since 3.1.1
210+
*/
211+
@Parameter
212+
private List<String> forcedJvmPackages;
213+
214+
/**
215+
* Additional packages to NOT load from the jvm even if it is in a flat classpath.
216+
* Can enable to reproduce a webapp behavior for example where library is loaded over the JVM.
217+
*
218+
* @since 3.1.1
219+
*/
220+
@Parameter
221+
private List<String> excludedJvmPackages;
222+
206223
/**
207224
* Execute goal.
208225
*
@@ -573,6 +590,8 @@ private URLClassLoader getClassLoader()
573590
.setLogger( getLog() )
574591
.setPaths( classpathURLs )
575592
.setExclusions( classpathFilenameExclusions )
593+
.setForcedJvmPackages( forcedJvmPackages )
594+
.setExcludedJvmPackages( excludedJvmPackages )
576595
.build();
577596
}
578597
catch ( NullPointerException | IOException e )

src/main/java/org/codehaus/mojo/exec/URLClassLoaderBuilder.java

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
*/
4545
class URLClassLoaderBuilder
4646
{
47+
private List<String> forcedJvmPackages;
48+
private List<String> excludedJvmPackages;
4749
private Log logger;
4850
private Collection<Path> paths;
4951
private Collection<String> exclusions;
@@ -57,6 +59,18 @@ static URLClassLoaderBuilder builder()
5759
return new URLClassLoaderBuilder();
5860
}
5961

62+
URLClassLoaderBuilder setExcludedJvmPackages(List<String> excludedJvmPackages )
63+
{
64+
this.excludedJvmPackages = excludedJvmPackages;
65+
return this;
66+
}
67+
68+
URLClassLoaderBuilder setForcedJvmPackages(List<String> forcedJvmPackages )
69+
{
70+
this.forcedJvmPackages = forcedJvmPackages;
71+
return this;
72+
}
73+
6074
URLClassLoaderBuilder setLogger(Log logger )
6175
{
6276
this.logger = logger;
@@ -99,7 +113,7 @@ URLClassLoader build() throws IOException
99113
}
100114
}
101115

102-
return new ExecJavaClassLoader( urls.toArray( new URL[0] ) );
116+
return new ExecJavaClassLoader( urls.toArray( new URL[0] ), forcedJvmPackages, excludedJvmPackages );
103117
}
104118

105119
// child first strategy
@@ -118,11 +132,15 @@ private static class ExecJavaClassLoader extends URLClassLoader
118132
}
119133

120134
private final String jre;
135+
private final List<String> forcedJvmPackages;
136+
private final List<String> excludedJvmPackages;
121137

122-
public ExecJavaClassLoader(URL[] urls )
138+
public ExecJavaClassLoader(URL[] urls, List<String> forcedJvmPackages, List<String> excludedJvmPackages )
123139
{
124140
super(urls);
125-
jre = getJre();
141+
this.jre = getJre();
142+
this.forcedJvmPackages = forcedJvmPackages;
143+
this.excludedJvmPackages = excludedJvmPackages;
126144
}
127145

128146
@Override
@@ -334,64 +352,77 @@ private boolean postLoad( boolean resolve, Class<?> clazz )
334352
return false;
335353
}
336354

337-
// not all jvm classes, for ex "javax" can be overriden so don't list it here
355+
// not all jvm classes, for ex "javax" can be overridden so don't list it them all here (javax.resource for ex)
338356
private boolean isDirectJvmClass(final String name) {
357+
if (excludedJvmPackages != null && excludedJvmPackages.stream().anyMatch( name::startsWith ))
358+
{
359+
return false;
360+
}
361+
339362
if (name.startsWith( "java." ) )
340363
{
341364
return true;
342365
}
343-
if ( name.startsWith( "sun." ) )
366+
else if (name.startsWith( "javax." ) )
367+
{
368+
final String sub = name.substring( "javax.".length() );
369+
if ( sub.startsWith( "xml." ) )
370+
{
371+
return true;
372+
}
373+
}
374+
else if ( name.startsWith( "sun." ) )
344375
{
345376
return true;
346377
}
347-
if ( name.startsWith( "jdk." ) )
378+
else if ( name.startsWith( "jdk." ) )
348379
{
349380
return true;
350381
}
351-
if ( name.startsWith( "oracle." ) )
382+
else if ( name.startsWith( "oracle." ) )
352383
{
353384
return true;
354385
}
355-
if ( name.startsWith( "javafx." ) )
386+
else if ( name.startsWith( "javafx." ) )
356387
{
357388
return true;
358389
}
359-
if ( name.startsWith( "netscape." ) )
390+
else if ( name.startsWith( "netscape." ) )
360391
{
361392
return true;
362393
}
363-
if ( name.startsWith( "org." ) )
394+
else if ( name.startsWith( "org." ) )
364395
{
365396
final String sub = name.substring( "org.".length() );
366397
if ( sub.startsWith( "w3c.dom." ) )
367398
{
368399
return true;
369400
}
370-
if ( sub.startsWith( "omg." ) )
401+
else if ( sub.startsWith( "omg." ) )
371402
{
372403
return true;
373404
}
374-
if ( sub.startsWith( "xml.sax." ) )
405+
else if ( sub.startsWith( "xml.sax." ) )
375406
{
376407
return true;
377408
}
378-
if ( sub.startsWith( "ietf.jgss." ) )
409+
else if ( sub.startsWith( "ietf.jgss." ) )
379410
{
380411
return true;
381412
}
382-
if ( sub.startsWith( "jcp.xml.dsig.internal." ) )
413+
else if ( sub.startsWith( "jcp.xml.dsig.internal." ) )
383414
{
384415
return true;
385416
}
386417
}
387-
if ( name.startsWith( "com." ) )
418+
else if ( name.startsWith( "com." ) )
388419
{
389420
final String sub = name.substring( "com.".length() );
390421
if ( sub.startsWith( "oracle." ) )
391422
{
392423
return true;
393424
}
394-
if ( sub.startsWith( "sun." ) )
425+
else if ( sub.startsWith( "sun." ) )
395426
{
396427
final String subSun = sub.substring( "sun.".length() );
397428
if ( subSun.startsWith( "accessibility." ) )
@@ -494,10 +525,9 @@ private boolean isDirectJvmClass(final String name) {
494525
{
495526
return true;
496527
}
497-
return false;
498528
}
499529
}
500-
return false;
530+
return forcedJvmPackages != null && forcedJvmPackages.stream().anyMatch( name::startsWith );
501531
}
502532

503533
private class FilteringUrlEnum implements Enumeration<URL>

0 commit comments

Comments
 (0)