Benjamin, Thanks, and those comments are right. In fact, I started with
reflection untill I came up with the idea to try to initialize and destroy
Servlets and Filters.In the end I'd prefer to use the servlet-api as specified
by the project, but for now I'm fine with the current implementation.
-RobertFrom: [email protected]
To: [email protected]
Date: Sat, 5 Nov 2011 10:36:41 -0500
Subject: [mojo-scm] [15040]
trunk/sandbox/warcustoms-maven-plugin/class-loading.patch: o Added patch
demoing solutions to class loading issues
[15040] trunk/sandbox/warcustoms-maven-plugin/class-loading.patch: o Added
patch demoing solutions to class loading issues
Revision 15040
Author bentmann
Date 2011-11-05 10:36:41 -0500 (Sat, 05 Nov 2011)
Log Message
o Added patch demoing solutions to class loading issues
Added Paths
trunk/sandbox/warcustoms-maven-plugin/class-loading.patch
Diff
Added: trunk/sandbox/warcustoms-maven-plugin/class-loading.patch (0 => 15040)
--- trunk/sandbox/warcustoms-maven-plugin/class-loading.patch
(rev 0)
+++ trunk/sandbox/warcustoms-maven-plugin/class-loading.patch 2011-11-05
15:36:41 UTC (rev 15040)
@@ -0,0 +1,157 @@
+Index: src/main/java/org/codehaus/mojo/warcustoms/VerifyMojo.java
+===================================================================
+--- src/main/java/org/codehaus/mojo/warcustoms/VerifyMojo.java (revision 15037)
++++ src/main/java/org/codehaus/mojo/warcustoms/VerifyMojo.java (working copy)
+@@ -20,6 +20,8 @@
+ import java.io.FileInputStream;
+ import java.io.IOException;
+ import java.net.MalformedURLException;
++import java.net.URL;
++import java.net.URLClassLoader;
+ import java.util.ArrayList;
+ import java.util.HashMap;
+ import java.util.List;
+@@ -149,65 +151,51 @@
+
+ WebAppType webApp = parseWebXml();
+
++ ClassLoader pluginLoader = getClass().getClassLoader();
++
++ ClassWorld classWorld = new ClassWorld( "mojo", null );
++
++ ClassRealm projectRealm = null;
+ try
+ {
+- ClassLoader parent = this.getClass().getClassLoader();
+- ClassWorld classWorld = new ClassWorld( "mojo", parent );
+-
+- ClassRealm projectRealm = null;
+- try
+- {
+- projectRealm = classWorld.newRealm( "project" );
+- }
+- catch ( DuplicateRealmException e )
+- {
+- }
+-
+- try
+- {
+- List<String> compileClasspathElements =
project.getCompileClasspathElements();
+- for( String compileSourccompileClasspathElement :
compileClasspathElements )
+- {
+- File compileSourceDirectory = new File(
compileSourccompileClasspathElement );
+- if ( compileSourceDirectory.isDirectory() )
+- {
+- getLog().debug( "Add to projectRealm: " +
compileSourceDirectory.toURI().toURL().toString() );
+- projectRealm.addURL(
compileSourceDirectory.toURI().toURL() );
+- }
+- }
+- }
+- catch ( DependencyResolutionRequiredException e )
+- {
+- // TODO Auto-generated catch block
+- e.printStackTrace();
+- }
++ projectRealm = classWorld.newRealm( "project" );
++ }
++ catch ( DuplicateRealmException e )
++ {
++ }
+
+- List<Artifact> testArtifacts = project.getTestArtifacts();
+- for ( Artifact artifact : testArtifacts )
+- {
+- // we need compile, runtime and provided, not test
+- if ( !Artifact.SCOPE_TEST.equals( artifact.getScope() ) &&
artifact.getFile().exists() )
+- {
+- getLog().debug( "Add to projectRealm: " +
artifact.getFile().toURI().toURL().toString() );
+- projectRealm.addURL( artifact.getFile().toURI().toURL() );
+- }
+- }
++ URL[] urls = getWebAppClassLoaderUrls();
+
+- try
+- {
+- Thread.currentThread().setContextClassLoader( projectRealm );
+- verify( webApp );
+- }
+- finally
+- {
+- // Set back the old classloader
+- Thread.currentThread().setContextClassLoader( parent );
+- }
++ for ( URL url : urls )
++ {
++ projectRealm.addURL( url );
+ }
+- catch ( MalformedURLException e )
++ projectRealm.importFrom( pluginLoader, "javax.servlet" );
++
++ /*
++ * The current plugin design requires to share javax.servlet classes
between the plugin and the project. This
++ * can either be accomplished using a traditional class loader where
the plugin loader is the parent or using a
++ * ClassRealm with a specific import. Obviously, a specific import of
the shared classes provides better
++ * isolation between webapp and plugin. Ideally, the plugin would not
require any class sharing and use
++ * reflection to access the webapp classes/objects. In this case, an
ordinary URLClassLoader( urls ) instance
++ * would safely do.
++ */
++ // plain java ...
++ ClassLoader webLoader = new URLClassLoader( urls, pluginLoader );
++ // ... or classworlds
++ webLoader = projectRealm;
++
++ ClassLoader oldTccl = Thread.currentThread().getContextClassLoader();
++ try
+ {
+- throw new MojoExecutionException( e.getMessage(), e );
++ Thread.currentThread().setContextClassLoader( webLoader );
++ verify( webApp );
+ }
++ finally
++ {
++ // Set back the old classloader
++ Thread.currentThread().setContextClassLoader( oldTccl );
++ }
+ }
+
+ private WebAppType parseWebXml()
+@@ -574,4 +562,37 @@
+ }
+ elementIndex.put( clazz, index++ );
+ }
+-}
+\ No newline at end of file
++
++ @SuppressWarnings( "unchecked" )
++ private URL[] getWebAppClassLoaderUrls()
++ {
++ List<File> files = new ArrayList<File>();
++ files.add( new File( project.getBuild().getOutputDirectory() ) );
++ for ( Artifact artifact : (List<Artifact>) project.getTestArtifacts()
)
++ {
++ if ( !Artifact.SCOPE_TEST.equals( artifact.getScope() ) )
++ {
++ files.add( artifact.getFile() );
++ }
++ }
++
++ List<URL> urls = new ArrayList<URL>();
++ for ( File file : files )
++ {
++ if ( file != null && file.exists() )
++ {
++ try
++ {
++ urls.add( file.toURI().toURL() );
++ }
++ catch ( MalformedURLException e )
++ {
++ throw new IllegalStateException( e );
++ }
++ }
++ }
++
++ return urls.toArray( new URL[urls.size()] );
++ }
++
++}
To unsubscribe from this list please visit:
http://xircles.codehaus.org/manage_email