[SUREFIRE-1588] Surefire manifest jar classloading broken on latest Debian/Ubuntu Java8
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
index 1cce687..3a1a64a 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
@@ -2173,7 +2173,8 @@
getEffectiveForkCount(),
reuseForks,
platform,
- getConsoleLogger() );
+ getConsoleLogger(),
+ getReportsDirectory() );
}
else
{
@@ -2188,7 +2189,8 @@
getEffectiveForkCount(),
reuseForks,
platform,
- getConsoleLogger() );
+ getConsoleLogger(),
+ getReportsDirectory() );
}
}
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/AbstractClasspathForkConfiguration.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/AbstractClasspathForkConfiguration.java
index 6c57ebc..2d6412e 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/AbstractClasspathForkConfiguration.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/AbstractClasspathForkConfiguration.java
@@ -19,6 +19,7 @@
* under the License.
*/
+import org.apache.maven.plugin.surefire.booterclient.output.InPluginProcessDumpSingleton;
import org.apache.maven.plugin.surefire.log.api.ConsoleLogger;
import org.apache.maven.surefire.booter.Classpath;
@@ -35,6 +36,7 @@
abstract class AbstractClasspathForkConfiguration
extends DefaultForkConfiguration
{
+ private final File reportsDir;
@SuppressWarnings( "checkstyle:parameternumber" )
AbstractClasspathForkConfiguration( @Nonnull Classpath bootClasspath,
@@ -48,10 +50,12 @@
int forkCount,
boolean reuseForks,
@Nonnull Platform pluginPlatform,
- @Nonnull ConsoleLogger log )
+ @Nonnull ConsoleLogger log,
+ @Nonnull File reportsDir )
{
super( bootClasspath, tempDirectory, debugLine, workingDirectory, modelProperties, argLine,
environmentVariables, debug, forkCount, reuseForks, pluginPlatform, log );
+ this.reportsDir = reportsDir;
}
@Override
@@ -60,4 +64,10 @@
{
return jvmArgLine;
}
+
+ protected void logDump( Exception e, String msg )
+ {
+ InPluginProcessDumpSingleton.getSingleton()
+ .dumpException( e, msg, reportsDir );
+ }
}
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ClasspathForkConfiguration.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ClasspathForkConfiguration.java
index f87b473..bf97774 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ClasspathForkConfiguration.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ClasspathForkConfiguration.java
@@ -46,10 +46,10 @@
@Nonnull Properties modelProperties, @Nullable String argLine,
@Nonnull Map<String, String> environmentVariables, boolean debug, int forkCount,
boolean reuseForks, @Nonnull Platform pluginPlatform,
- @Nonnull ConsoleLogger log )
+ @Nonnull ConsoleLogger log, @Nonnull File reportsDir )
{
super( bootClasspath, tempDirectory, debugLine, workingDirectory, modelProperties, argLine,
- environmentVariables, debug, forkCount, reuseForks, pluginPlatform, log );
+ environmentVariables, debug, forkCount, reuseForks, pluginPlatform, log, reportsDir );
}
@Override
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/JarManifestForkConfiguration.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/JarManifestForkConfiguration.java
index 72ae7da..8014507 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/JarManifestForkConfiguration.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/JarManifestForkConfiguration.java
@@ -30,6 +30,9 @@
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.Path;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -53,10 +56,10 @@
@Nonnull Properties modelProperties, @Nullable String argLine,
@Nonnull Map<String, String> environmentVariables, boolean debug,
int forkCount, boolean reuseForks, @Nonnull Platform pluginPlatform,
- @Nonnull ConsoleLogger log )
+ @Nonnull ConsoleLogger log, @Nonnull File reportsDir )
{
super( bootClasspath, tempDirectory, debugLine, workingDirectory, modelProperties, argLine,
- environmentVariables, debug, forkCount, reuseForks, pluginPlatform, log );
+ environmentVariables, debug, forkCount, reuseForks, pluginPlatform, log, reportsDir );
}
@Override
@@ -95,6 +98,7 @@
{
file.deleteOnExit();
}
+ Path parent = file.getParentFile().toPath();
FileOutputStream fos = new FileOutputStream( file );
try ( JarOutputStream jos = new JarOutputStream( fos ) )
{
@@ -110,7 +114,7 @@
for ( Iterator<String> it = classPath.iterator(); it.hasNext(); )
{
File file1 = new File( it.next() );
- String uri = file1.toURI().toASCIIString();
+ String uri = toClasspathElementUri( parent, file1 );
cp.append( uri );
if ( file1.isDirectory() && !uri.endsWith( "/" ) )
{
@@ -135,4 +139,27 @@
return file;
}
}
+
+ private String toClasspathElementUri( Path parent, File classPathElement ) throws IOException
+ {
+ try
+ {
+ return new URI( null, parent.relativize( classPathElement.toPath() ).toString(), null )
+ .toASCIIString();
+ }
+ catch ( IllegalArgumentException e )
+ {
+ logDump( e, "Boot Manifest-JAR contains absolute paths in classpath " + classPathElement.getPath() );
+ return classPathElement.toURI()
+ .toASCIIString();
+ }
+ catch ( URISyntaxException e )
+ {
+ // This is really unexpected, so fail
+ throw new IOException( "Could not create a relative path "
+ + classPathElement
+ + " against "
+ + parent, e );
+ }
+ }
}
diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkConfigurationTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkConfigurationTest.java
index 0067a06..1858981 100644
--- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkConfigurationTest.java
+++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkConfigurationTest.java
@@ -39,6 +39,7 @@
import java.util.List;
import java.util.Properties;
+import static java.io.File.createTempFile;
import static java.util.Collections.singletonList;
import static org.apache.maven.surefire.booter.Classpath.emptyClasspath;
import static org.junit.Assert.assertEquals;
@@ -181,7 +182,7 @@
private File getTempClasspathFile()
throws IOException
{
- File cpElement = File.createTempFile( "ForkConfigurationTest.", ".file" );
+ File cpElement = createTempFile( "ForkConfigurationTest.", ".file" );
cpElement.deleteOnExit();
return cpElement;
}
@@ -204,12 +205,12 @@
throws IOException
{
Platform platform = new Platform().withJdkExecAttributesForTests( new JdkAttributes( jvm, false ) );
- File tmpDir = File.createTempFile( "target", "surefire" );
+ File tmpDir = createTempFile( "target", "surefire" );
assertTrue( tmpDir.delete() );
assertTrue( tmpDir.mkdirs() );
return new JarManifestForkConfiguration( emptyClasspath(), tmpDir, null,
cwd, new Properties(), argLine, Collections.<String, String>emptyMap(), false, 1, false,
- platform, new NullConsoleLogger() );
+ platform, new NullConsoleLogger(), createTempFile( "target", "surefire-reports" ) );
}
// based on http://stackoverflow.com/questions/2591083/getting-version-of-java-in-runtime