Author: krosenvold Date: Wed Nov 23 20:27:35 2011 New Revision: 1205565 URL: http://svn.apache.org/viewvc?rev=1205565&view=rev Log: o Removed duplicated code path through classloader creation and parts of the fork logic
This was one of the last significant pieces of mess left in the code base, which was blocking any further additions like the one i promised stephenc Removed: maven/surefire/trunk/surefire-booter/src/main/java/org/apache/maven/surefire/booter/StarterCommon.java maven/surefire/trunk/surefire-booter/src/main/java/org/apache/maven/surefire/booter/SurefireStarter.java Modified: maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/InPluginVMSurefireStarter.java maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkStarter.java maven/surefire/trunk/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ClasspathConfiguration.java maven/surefire/trunk/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java maven/surefire/trunk/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderFactory.java maven/surefire/trunk/surefire-booter/src/main/java/org/apache/maven/surefire/booter/StartupConfiguration.java Modified: maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java?rev=1205565&r1=1205564&r2=1205565&view=diff ============================================================================== --- maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java (original) +++ maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java Wed Nov 23 20:27:35 2011 @@ -136,7 +136,7 @@ public abstract class AbstractSurefireMo handleSummary( summary ); } - private Artifact surefireArtifact; + private Artifact surefireBooterArtifact; private void createDependencyResolver() { @@ -632,16 +632,16 @@ public abstract class AbstractSurefireMo Artifact shadeFire = (Artifact) getPluginArtifactMap().get( "org.apache.maven.surefire:surefire-shadefire" ); - surefireArtifact = (Artifact) getPluginArtifactMap().get( "org.apache.maven.surefire:surefire-booter" ); - if ( surefireArtifact == null ) + surefireBooterArtifact = (Artifact) getPluginArtifactMap().get( "org.apache.maven.surefire:surefire-booter" ); + if ( surefireBooterArtifact == null ) { throw new RuntimeException( "Unable to locate surefire-booter in the list of plugin artifacts" ); } - surefireArtifact.isSnapshot(); // MNG-2961: before Maven 2.0.8, fixes getBaseVersion to be -SNAPSHOT if needed + surefireBooterArtifact.isSnapshot(); // MNG-2961: before Maven 2.0.8, fixes getBaseVersion to be -SNAPSHOT if needed final Classpath bootClasspathConfiguration = - getArtifactClasspath( shadeFire != null ? shadeFire : surefireArtifact ); + getArtifactClasspath( shadeFire != null ? shadeFire : surefireBooterArtifact ); ForkConfiguration fork = new ForkConfiguration( bootClasspathConfiguration, getForkMode(), tmpDir ); @@ -1228,7 +1228,7 @@ public abstract class AbstractSurefireMo { // add the JUnit provider as default - it doesn't require JUnit to be present, // since it supports POJO tests. - return dependencyResolver.getProviderClasspath( "surefire-junit3", surefireArtifact.getBaseVersion(), + return dependencyResolver.getProviderClasspath( "surefire-junit3", surefireBooterArtifact.getBaseVersion(), null ); } @@ -1265,7 +1265,7 @@ public abstract class AbstractSurefireMo public Classpath getProviderClasspath() throws ArtifactResolutionException, ArtifactNotFoundException { - return dependencyResolver.getProviderClasspath( "surefire-junit4", surefireArtifact.getBaseVersion(), + return dependencyResolver.getProviderClasspath( "surefire-junit4", surefireBooterArtifact.getBaseVersion(), null ); } @@ -1310,7 +1310,7 @@ public abstract class AbstractSurefireMo public Classpath getProviderClasspath() throws ArtifactResolutionException, ArtifactNotFoundException { - return dependencyResolver.getProviderClasspath( "surefire-junit47", surefireArtifact.getBaseVersion(), + return dependencyResolver.getProviderClasspath( "surefire-junit47", surefireBooterArtifact.getBaseVersion(), null ); } Modified: maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/InPluginVMSurefireStarter.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/InPluginVMSurefireStarter.java?rev=1205565&r1=1205564&r2=1205565&view=diff ============================================================================== --- maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/InPluginVMSurefireStarter.java (original) +++ maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/InPluginVMSurefireStarter.java Wed Nov 23 20:27:35 2011 @@ -20,7 +20,7 @@ package org.apache.maven.plugin.surefire */ import org.apache.maven.surefire.booter.ProviderConfiguration; -import org.apache.maven.surefire.booter.StarterCommon; +import org.apache.maven.surefire.booter.ProviderFactory; import org.apache.maven.surefire.booter.StartupConfiguration; import org.apache.maven.surefire.booter.StartupReportConfiguration; import org.apache.maven.surefire.booter.SurefireExecutionException; @@ -42,16 +42,19 @@ import org.apache.maven.surefire.suite.R public class InPluginVMSurefireStarter { + private final StartupConfiguration startupConfiguration; + private final StartupReportConfiguration startupReportConfiguration; - private final StarterCommon starterCommon; + private final ProviderConfiguration providerConfiguration; public InPluginVMSurefireStarter( StartupConfiguration startupConfiguration, ProviderConfiguration providerConfiguration, StartupReportConfiguration startupReportConfiguration ) { + this.startupConfiguration = startupConfiguration; this.startupReportConfiguration = startupReportConfiguration; - this.starterCommon = new StarterCommon( startupConfiguration, providerConfiguration ); + this.providerConfiguration = providerConfiguration; } public RunResult runSuitesInProcess() @@ -59,15 +62,18 @@ public class InPluginVMSurefireStarter { // The test classloader must be constructed first to avoid issues with commons-logging until we properly // separate the TestNG classloader - ClassLoader testsClassLoader = starterCommon.createInProcessTestClassLoader(); + startupConfiguration.writeSurefireTestClasspathProperty(); + ClassLoader testsClassLoader = startupConfiguration.getClasspathConfiguration().createTestClassLoader(); - ClassLoader surefireClassLoader = starterCommon.createSurefireInProcClassloader( testsClassLoader ); + ClassLoader surefireClassLoader = + startupConfiguration.getClasspathConfiguration().createInprocSurefireClassLoader( testsClassLoader ); CommonReflector surefireReflector = new CommonReflector( surefireClassLoader ); final Object factory = surefireReflector.createReportingReporterFactory( startupReportConfiguration ); - return starterCommon.invokeProvider( null, testsClassLoader, surefireClassLoader, factory, false ); + return ProviderFactory.invokeProvider( null, testsClassLoader, surefireClassLoader, factory, + providerConfiguration, false, startupConfiguration ); } } Modified: maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkStarter.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkStarter.java?rev=1205565&r1=1205564&r2=1205565&view=diff ============================================================================== --- maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkStarter.java (original) +++ maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkStarter.java Wed Nov 23 20:27:35 2011 @@ -160,10 +160,13 @@ public class ForkStarter } final Classpath bootClasspathConfiguration = forkConfiguration.getBootClasspath(); + final Classpath additionlClassPathUrls = startupConfiguration.useSystemClassLoader() ? startupConfiguration.getClasspathConfiguration().getTestClasspath() : null; + // Surefire-booter + all test classes if "useSystemClassloader" + // Surefire-booter if !useSystemClassLoader Classpath bootClasspath = Classpath.join( bootClasspathConfiguration, additionlClassPathUrls ); Commandline cli = forkConfiguration.createCommandLine( bootClasspath.getClassPath(), @@ -177,7 +180,7 @@ public class ForkStarter cli.createArg().setFile( systemProperties ); } - ThreadedStreamConsumer threadedStreamConsumer2 = new ThreadedStreamConsumer( forkClient ); + ThreadedStreamConsumer threadedStreamConsumer = new ThreadedStreamConsumer( forkClient ); if ( forkConfiguration.isDebug() ) { @@ -190,13 +193,13 @@ public class ForkStarter { final int timeout = forkedProcessTimeoutInSeconds > 0 ? forkedProcessTimeoutInSeconds : 0; final int result = - CommandLineUtils.executeCommandLine( cli, threadedStreamConsumer2, threadedStreamConsumer2, timeout ); + CommandLineUtils.executeCommandLine( cli, threadedStreamConsumer, threadedStreamConsumer, timeout ); if ( result != RunResult.SUCCESS ) { throw new SurefireBooterForkException( "Error occured in starting fork, check output in log" ); } - threadedStreamConsumer2.close(); + threadedStreamConsumer.close(); forkClient.close(); runResult = globalRunStatistics.getRunResult(); Modified: maven/surefire/trunk/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ClasspathConfiguration.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ClasspathConfiguration.java?rev=1205565&r1=1205564&r2=1205565&view=diff ============================================================================== --- maven/surefire/trunk/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ClasspathConfiguration.java (original) +++ maven/surefire/trunk/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ClasspathConfiguration.java Wed Nov 23 20:27:35 2011 @@ -22,7 +22,7 @@ package org.apache.maven.surefire.booter /** * Represents the classpaths for the BooterConfiguration. * <p/> - * + * * @author Jason van Zyl * @author Emmanuel Venisse * @author Kristian Rosenvold @@ -42,7 +42,9 @@ public class ClasspathConfiguration private final Classpath surefireClasspathUrls; - /** The surefire classpath to use when invoking in-process with the plugin */ + /** + * The surefire classpath to use when invoking in-process with the plugin + */ private final Classpath inprocClasspath; /** @@ -54,23 +56,19 @@ public class ClasspathConfiguration // todo: @deprecated because the IsolatedClassLoader is really isolated - no parent. private final boolean childDelegation; - private final JdkReflector jdkReflector = new JdkReflector(); - public ClasspathConfiguration( boolean enableAssertions, boolean childDelegation ) { - this( new Classpath(), new Classpath(),new Classpath(), enableAssertions, childDelegation ); + this( new Classpath(), new Classpath(), new Classpath(), enableAssertions, childDelegation ); } ClasspathConfiguration( PropertiesWrapper properties ) { - this( properties.getClasspath( CLASSPATH ), - properties.getClasspath( SUREFIRE_CLASSPATH ), - new Classpath( ), + this( properties.getClasspath( CLASSPATH ), properties.getClasspath( SUREFIRE_CLASSPATH ), new Classpath(), properties.getBooleanProperty( ENABLE_ASSERTIONS ), properties.getBooleanProperty( CHILD_DELEGATION ) ); } - public ClasspathConfiguration( Classpath testClasspath, Classpath surefireClassPathUrls, Classpath inprocClasspath, boolean enableAssertions, - boolean childDelegation ) + public ClasspathConfiguration( Classpath testClasspath, Classpath surefireClassPathUrls, Classpath inprocClasspath, + boolean enableAssertions, boolean childDelegation ) { this.enableAssertions = enableAssertions; this.childDelegation = childDelegation; @@ -87,14 +85,6 @@ public class ClasspathConfiguration properties.setProperty( CHILD_DELEGATION, String.valueOf( childDelegation ) ); } - public ClassLoader createTestClassLoaderConditionallySystem( boolean useSystemClassLoader ) - throws SurefireExecutionException - { - return useSystemClassLoader - ? ClassLoader.getSystemClassLoader() - : createTestClassLoader( this.childDelegation ); - } - public ClassLoader createTestClassLoader( boolean childDelegation ) throws SurefireExecutionException { @@ -112,6 +102,7 @@ public class ClasspathConfiguration { return surefireClasspathUrls.createClassLoader( parent, false, enableAssertions ); } + public ClassLoader createInprocSurefireClassLoader( ClassLoader parent ) throws SurefireExecutionException { @@ -123,4 +114,21 @@ public class ClasspathConfiguration return classpathUrls; } + public ClassLoader createForkingTestClassLoader( boolean manifestOnlyJarRequestedAndUsable ) + throws SurefireExecutionException + { + if ( manifestOnlyJarRequestedAndUsable ) + { + System.setProperty( "surefire.real.class.path", System.getProperty( "java.class.path" ) ); + getTestClasspath().writeToSystemProperty( "java.class.path" ); + // this.getClass.getClassLoader() is always loaded in system classloader if forking + // this.getClass().getClassLoader() is plugin classloder if in-process + // "this" must refer to a class within the booter module + return this.getClass().getClassLoader(); // SUREFIRE-459, trick the app under test into thinking its classpath was conventional; + } + else + { + return createTestClassLoader(); + } + } } Modified: maven/surefire/trunk/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java?rev=1205565&r1=1205564&r2=1205565&view=diff ============================================================================== --- maven/surefire/trunk/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java (original) +++ maven/surefire/trunk/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java Wed Nov 23 20:27:35 2011 @@ -22,6 +22,7 @@ package org.apache.maven.surefire.booter import java.io.File; import java.io.FileInputStream; import java.io.InputStream; +import java.io.PrintStream; import org.apache.maven.surefire.suite.RunResult; /** @@ -29,7 +30,6 @@ import org.apache.maven.surefire.suite.R * <p/> * Deals with deserialization of the booter wire-level protocol * <p/> - * Todo: Look at relationship between this class and BooterSerializer (BooterDeserializer?) * * @author Jason van Zyl * @author Emmanuel Venisse @@ -59,15 +59,19 @@ public class ForkedBooter File surefirePropertiesFile = new File( args[0] ); InputStream stream = surefirePropertiesFile.exists() ? new FileInputStream( surefirePropertiesFile ) : null; BooterDeserializer booterDeserializer = new BooterDeserializer( stream ); - ProviderConfiguration booterConfiguration = booterDeserializer.deserialize(); - final StartupConfiguration providerConfiguration = booterDeserializer.getProviderConfiguration(); + ProviderConfiguration providerConfiguration = booterDeserializer.deserialize(); + final StartupConfiguration startupConfiguration = booterDeserializer.getProviderConfiguration(); - SurefireStarter starter = new SurefireStarter( providerConfiguration, booterConfiguration ); + TypeEncodedValue forkedTestSet = providerConfiguration.getTestForFork(); - TypeEncodedValue forkedTestSet = booterConfiguration.getTestForFork(); - final RunResult result = forkedTestSet != null - ? starter.runSuitesInProcessWhenForked( forkedTestSet ) - : starter.runSuitesInProcessWhenForked(); + final ClasspathConfiguration classpathConfiguration = startupConfiguration.getClasspathConfiguration(); + final ClassLoader testClassLoader = classpathConfiguration.createForkingTestClassLoader( + startupConfiguration.isManifestOnlyJarRequestedAndUsable() ); + + startupConfiguration.writeSurefireTestClasspathProperty(); + + Object testSet = forkedTestSet != null ? forkedTestSet.getDecodedValue() : null; + runSuitesInProcess( testSet, testClassLoader, startupConfiguration, providerConfiguration ); // noinspection CallToSystemExit System.exit( 0 ); @@ -81,4 +85,28 @@ public class ForkedBooter System.exit( 1 ); } } + + public static RunResult runSuitesInProcess( Object testSet, ClassLoader testsClassLoader, + StartupConfiguration startupConfiguration, + ProviderConfiguration providerConfiguration ) + throws SurefireExecutionException + { + final ClasspathConfiguration classpathConfiguration = startupConfiguration.getClasspathConfiguration(); + ClassLoader surefireClassLoader = classpathConfiguration.createSurefireClassLoader( testsClassLoader ); + + SurefireReflector surefireReflector = new SurefireReflector( surefireClassLoader ); + + final Object factory = createForkingReporterFactory( surefireReflector, providerConfiguration ); + + return ProviderFactory.invokeProvider( testSet, testsClassLoader, surefireClassLoader, factory, + providerConfiguration, true, startupConfiguration ); + } + + private static Object createForkingReporterFactory( SurefireReflector surefireReflector, + ProviderConfiguration providerConfiguration ) + { + final Boolean trimStackTrace = providerConfiguration.getReporterConfiguration().isTrimStackTrace(); + final PrintStream originalSystemOut = providerConfiguration.getReporterConfiguration().getOriginalSystemOut(); + return surefireReflector.createForkingReporterFactory( trimStackTrace, originalSystemOut ); + } } Modified: maven/surefire/trunk/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderFactory.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderFactory.java?rev=1205565&r1=1205564&r2=1205565&view=diff ============================================================================== --- maven/surefire/trunk/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderFactory.java (original) +++ maven/surefire/trunk/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderFactory.java Wed Nov 23 20:27:35 2011 @@ -19,12 +19,14 @@ package org.apache.maven.surefire.booter * under the License. */ +import java.io.PrintStream; import java.lang.reflect.Method; import java.util.Iterator; import org.apache.maven.surefire.providerapi.SurefireProvider; import org.apache.maven.surefire.report.ReporterException; import org.apache.maven.surefire.suite.RunResult; import org.apache.maven.surefire.testset.TestSetFailedException; +import org.apache.maven.surefire.util.NestedRuntimeException; import org.apache.maven.surefire.util.ReflectionUtils; @@ -63,6 +65,43 @@ public class ProviderFactory this.reporterManagerFactory = reporterManagerFactory; } + public static RunResult invokeProvider( Object testSet, ClassLoader testsClassLoader, + ClassLoader surefireClassLoader, Object factory, + ProviderConfiguration providerConfiguration, boolean insideFork, + StartupConfiguration startupConfiguration1 ) + { + final PrintStream orgSystemOut = System.out; + final PrintStream orgSystemErr = System.err; + // Note that System.out/System.err are also read in the "ReporterConfiguration" instatiation + // in createProvider below. These are the same values as here. + + ProviderFactory providerFactory = + new ProviderFactory( startupConfiguration1, providerConfiguration, surefireClassLoader, testsClassLoader, + factory ); + final SurefireProvider provider = providerFactory.createProvider( insideFork ); + + try + { + return provider.invoke( testSet ); + } + catch ( TestSetFailedException e ) + { + throw new NestedRuntimeException( e ); + } + catch ( ReporterException e ) + { + throw new NestedRuntimeException( e ); + } + finally + { + if ( System.getSecurityManager() == null ) + { + System.setOut( orgSystemOut ); + System.setErr( orgSystemErr ); + } + } + } + public SurefireProvider createProvider( boolean isInsideFork ) { ClassLoader context = java.lang.Thread.currentThread().getContextClassLoader(); Modified: maven/surefire/trunk/surefire-booter/src/main/java/org/apache/maven/surefire/booter/StartupConfiguration.java URL: http://svn.apache.org/viewvc/maven/surefire/trunk/surefire-booter/src/main/java/org/apache/maven/surefire/booter/StartupConfiguration.java?rev=1205565&r1=1205564&r2=1205565&view=diff ============================================================================== --- maven/surefire/trunk/surefire-booter/src/main/java/org/apache/maven/surefire/booter/StartupConfiguration.java (original) +++ maven/surefire/trunk/surefire-booter/src/main/java/org/apache/maven/surefire/booter/StartupConfiguration.java Wed Nov 23 20:27:35 2011 @@ -36,9 +36,12 @@ public class StartupConfiguration private final boolean isInForkedVm; + private final static String SUREFIRE_TEST_CLASSPATH = "surefire.test.class.path"; + public StartupConfiguration( String providerClassName, ClasspathConfiguration classpathConfiguration, - ClassLoaderConfiguration classLoaderConfiguration, String forkMode, boolean inForkedVm ) + ClassLoaderConfiguration classLoaderConfiguration, String forkMode, + boolean inForkedVm ) { this.providerClassName = providerClassName; this.classpathConfiguration = classpathConfiguration; @@ -85,4 +88,11 @@ public class StartupConfiguration { return providerClassName.startsWith( "org.apache.maven.surefire.shadefire" ); } + + public void writeSurefireTestClasspathProperty() + { + ClasspathConfiguration classpathConfiguration = getClasspathConfiguration(); + classpathConfiguration.getTestClasspath().writeToSystemProperty( SUREFIRE_TEST_CLASSPATH ); + } + }