Repository: maven-surefire Updated Branches: refs/heads/SUREFIRE-1403 ecda11ea1 -> 395c68dc1 (forced update)
[SUREFIRE-1403] [Jigsaw] [Java 9] add "--add-modules ALL-SYSTEM" to forked CLI argument Project: http://git-wip-us.apache.org/repos/asf/maven-surefire/repo Commit: http://git-wip-us.apache.org/repos/asf/maven-surefire/commit/395c68dc Tree: http://git-wip-us.apache.org/repos/asf/maven-surefire/tree/395c68dc Diff: http://git-wip-us.apache.org/repos/asf/maven-surefire/diff/395c68dc Branch: refs/heads/SUREFIRE-1403 Commit: 395c68dc117f595c119094ce30605f9dd8dc019d Parents: 1a65d61 Author: Tibor17 <tibordig...@apache.org> Authored: Mon Aug 7 12:43:17 2017 +0200 Committer: Tibor17 <tibordig...@apache.org> Committed: Sat Aug 12 04:28:40 2017 +0200 ---------------------------------------------------------------------- maven-surefire-common/pom.xml | 2 +- .../plugin/surefire/AbstractSurefireMojo.java | 72 +++++++++-- .../maven/plugin/surefire/JdkAttributes.java | 48 +++++++ .../booterclient/ForkConfiguration.java | 72 +++++++---- .../surefire/report/StatelessXmlReporter.java | 4 +- ...erDeserializerProviderConfigurationTest.java | 2 +- ...terDeserializerStartupConfigurationTest.java | 2 +- .../booterclient/ForkConfigurationTest.java | 65 ++++++---- pom.xml | 2 +- surefire-api/pom.xml | 2 +- surefire-booter/pom.xml | 2 +- .../maven/surefire/booter/SystemUtils.java | 129 ++++++++++++++++++- .../maven/surefire/booter/SystemUtilsTest.java | 125 ++++++++++++++++++ surefire-booter/src/test/resources/jdk/bin/java | 0 .../src/test/resources/jdk/jre/bin/java | 0 .../src/test/resources/jdk8-IBM/release | 1 + .../src/test/resources/jdk8-oracle/release | 1 + .../src/test/resources/jdk9-oracle/release | 1 + surefire-integration-tests/pom.xml | 4 +- .../maven/surefire/its/AbstractJigsawIT.java | 102 +++++++++++++++ .../maven/surefire/its/Java9FullApiIT.java | 58 +++++++++ .../surefire/its/jiras/Surefire1265Java9IT.java | 17 ++- .../src/test/resources/java9-full-api/pom.xml | 60 +++++++++ .../java9-full-api/src/test/java/J9Test.java | 38 ++++++ 24 files changed, 731 insertions(+), 78 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/395c68dc/maven-surefire-common/pom.xml ---------------------------------------------------------------------- diff --git a/maven-surefire-common/pom.xml b/maven-surefire-common/pom.xml index ae050c7..121609b 100644 --- a/maven-surefire-common/pom.xml +++ b/maven-surefire-common/pom.xml @@ -160,7 +160,7 @@ <plugin> <artifactId>maven-surefire-plugin</artifactId> <configuration> - <jvm>${test.jre}/bin/java</jvm> + <jvm>${jdk.home}/bin/java</jvm> <redirectTestOutputToFile>true</redirectTestOutputToFile> <includes> <include>**/JUnit4SuiteTest.java</include> http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/395c68dc/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java ---------------------------------------------------------------------- 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 f2e5bfb..047f7a4 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 @@ -77,6 +77,7 @@ import org.apache.maven.surefire.testset.TestSetFailedException; import org.apache.maven.surefire.util.DefaultScanResult; import org.apache.maven.surefire.util.RunOrder; import org.apache.maven.surefire.util.SurefireReflectionException; +import org.apache.maven.toolchain.DefaultToolchain; import org.apache.maven.toolchain.Toolchain; import org.apache.maven.toolchain.ToolchainManager; @@ -100,13 +101,21 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import static java.lang.Thread.currentThread; +import static java.util.Collections.singletonMap; import static org.apache.commons.lang3.JavaVersion.JAVA_1_7; +import static org.apache.commons.lang3.JavaVersion.JAVA_9; +import static org.apache.commons.lang3.JavaVersion.JAVA_RECENT; import static org.apache.commons.lang3.SystemUtils.IS_OS_WINDOWS; import static org.apache.commons.lang3.SystemUtils.isJavaVersionAtLeast; import static org.apache.maven.shared.utils.StringUtils.capitalizeFirstLetter; import static org.apache.maven.shared.utils.StringUtils.isEmpty; import static org.apache.maven.shared.utils.StringUtils.isNotBlank; +import static org.apache.maven.shared.utils.StringUtils.isNotEmpty; import static org.apache.maven.shared.utils.StringUtils.split; +import static org.apache.maven.surefire.booter.SystemUtils.endsWithJavaPath; +import static org.apache.maven.surefire.booter.SystemUtils.isJava9AtLeast; +import static org.apache.maven.surefire.booter.SystemUtils.toJdkHomeFromJvmExec; +import static org.apache.maven.surefire.booter.SystemUtils.toJdkVersionFromReleaseFile; import static org.apache.maven.surefire.suite.RunResult.failure; import static org.apache.maven.surefire.suite.RunResult.noTestsRun; import static org.apache.maven.surefire.util.ReflectionUtils.invokeGetter; @@ -123,6 +132,10 @@ public abstract class AbstractSurefireMojo extends AbstractMojo implements SurefireExecutionParameters { + private static final Map<String, String> JAVA_9_MATCHER_OLD_NOTATION = singletonMap( "version", "[1.9,)" ); + + private static final Map<String, String> JAVA_9_MATCHER = singletonMap( "version", "[9,)" ); + private static final Platform PLATFORM = new Platform(); private static final File SYSTEM_TMP_DIR = new File( System.getProperty( "java.io.tmpdir" ) ); @@ -895,7 +908,7 @@ public abstract class AbstractSurefireMojo getConsoleLogger().info( "Toolchain in maven-" + getPluginName() + "-plugin: " + toolchain ); if ( jvmToUse != null ) { - getConsoleLogger().warning( "Toolchains are ignored, 'executable' parameter is set to " + jvmToUse ); + getConsoleLogger().warning( "Toolchains are ignored, 'jvm' parameter is set to " + jvmToUse ); } } @@ -1947,7 +1960,7 @@ public abstract class AbstractSurefireMojo startupReportConfiguration, consoleLogger ); } - protected ForkConfiguration getForkConfiguration() + private ForkConfiguration getForkConfiguration() throws MojoFailureException { File tmpDir = getSurefireTempDir(); @@ -2038,24 +2051,59 @@ public abstract class AbstractSurefireMojo return debugForkedProcess; } - private String getEffectiveJvm() + private JdkAttributes getEffectiveJvm() throws MojoFailureException { - String jvmToUse = getJvm(); - if ( toolchain != null && jvmToUse == null ) + if ( isNotEmpty( jvm ) ) { - jvmToUse = toolchain.findTool( "java" ); //NOI18N + File pathToJava = new File( jvm ).getAbsoluteFile(); + if ( !endsWithJavaPath( pathToJava.getPath() ) ) + { + throw new MojoFailureException( "Given path does not end with java executor \"" + + pathToJava.getPath() + "\"." ); + } + + if ( !( pathToJava.isFile() + || "java".equals( pathToJava.getName() ) && pathToJava.getParentFile().isDirectory() ) ) + { + throw new MojoFailureException( "Given path to java executor does not exist \"" + + pathToJava.getPath() + "\"." ); + } + + File jdkHome = toJdkHomeFromJvmExec( pathToJava.getPath() ); + Double version = jdkHome == null ? null : toJdkVersionFromReleaseFile( jdkHome ); + boolean javaVersion9 = version == null ? isJava9AtLeast( pathToJava.getPath() ) : isJava9AtLeast( version ); + return new JdkAttributes( pathToJava.getPath(), javaVersion9 ); } - if ( isEmpty( jvmToUse ) ) + if ( toolchain != null ) { - // use the same JVM as the one used to run Maven (the "java.home" one) - jvmToUse = System.getProperty( "java.home" ) + File.separator + "bin" + File.separator + "java"; - getConsoleLogger().debug( "Using JVM: " + jvmToUse ); + String jvmToUse = toolchain.findTool( "java" ); + if ( isNotEmpty( jvmToUse ) ) + { + boolean javaVersion9 = false; + + if ( toolchain instanceof DefaultToolchain ) + { + DefaultToolchain defaultToolchain = (DefaultToolchain) toolchain; + javaVersion9 = defaultToolchain.matchesRequirements( JAVA_9_MATCHER ) + || defaultToolchain.matchesRequirements( JAVA_9_MATCHER_OLD_NOTATION ); + } + + if ( !javaVersion9 ) + { + javaVersion9 = isJava9AtLeast( jvmToUse ); + } + + return new JdkAttributes( jvmToUse, javaVersion9 ); + } } - return jvmToUse; - } + // use the same JVM as the one used to run Maven (the "java.home" one) + String jvmToUse = System.getProperty( "java.home" ) + File.separator + "bin" + File.separator + "java"; + getConsoleLogger().debug( "Using JVM: " + jvmToUse + " with Java version " + JAVA_RECENT.toString() ); + return new JdkAttributes( jvmToUse, isJavaVersionAtLeast( JAVA_9 ) ); + } private Artifact getSurefireBooterArtifact() { http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/395c68dc/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/JdkAttributes.java ---------------------------------------------------------------------- diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/JdkAttributes.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/JdkAttributes.java new file mode 100644 index 0000000..65b1254 --- /dev/null +++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/JdkAttributes.java @@ -0,0 +1,48 @@ +package org.apache.maven.plugin.surefire; + +/* + * 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. + */ + +import static org.apache.maven.surefire.util.internal.ObjectUtils.requireNonNull; + +/** + * @author <a href="mailto:tibordig...@apache.org">Tibor Digana (tibor17)</a> + * @since 2.20.1 + */ +public final class JdkAttributes +{ + private final String jvmExecutable; + private final boolean java9AtLeast; + + public JdkAttributes( String jvmExecutable, boolean java9AtLeast ) + { + this.jvmExecutable = requireNonNull( jvmExecutable, "null path to java executable" ); + this.java9AtLeast = java9AtLeast; + } + + public String getJvmExecutable() + { + return jvmExecutable; + } + + public boolean isJava9AtLeast() + { + return java9AtLeast; + } +} http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/395c68dc/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkConfiguration.java ---------------------------------------------------------------------- diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkConfiguration.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkConfiguration.java index 1c7626e..b3b9251 100644 --- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkConfiguration.java +++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkConfiguration.java @@ -20,9 +20,9 @@ package org.apache.maven.plugin.surefire.booterclient; */ import org.apache.maven.plugin.surefire.AbstractSurefireMojo; +import org.apache.maven.plugin.surefire.JdkAttributes; import org.apache.maven.plugin.surefire.booterclient.lazytestprovider.OutputStreamFlushableCommandline; import org.apache.maven.plugin.surefire.util.Relocator; -import org.apache.maven.shared.utils.StringUtils; import org.apache.maven.surefire.booter.Classpath; import org.apache.maven.surefire.booter.ForkedBooter; import org.apache.maven.surefire.booter.StartupConfiguration; @@ -42,6 +42,7 @@ import java.util.jar.JarOutputStream; import java.util.jar.Manifest; import static org.apache.maven.plugin.surefire.SurefireHelper.escapeToPlatformPath; +import static org.apache.maven.shared.utils.StringUtils.join; /** * Configuration for forking tests. @@ -66,7 +67,7 @@ public class ForkConfiguration private final Classpath bootClasspathConfiguration; - private final String jvmExecutable; + private final JdkAttributes jdk; private final Properties modelProperties; @@ -86,14 +87,14 @@ public class ForkConfiguration @SuppressWarnings( "checkstyle:parameternumber" ) public ForkConfiguration( Classpath bootClasspathConfiguration, File tmpDir, String debugLine, - String jvmExecutable, File workingDirectory, Properties modelProperties, String argLine, + JdkAttributes jdk, File workingDirectory, Properties modelProperties, String argLine, Map<String, String> environmentVariables, boolean debugEnabled, int forkCount, boolean reuseForks, Platform pluginPlatform ) { this.bootClasspathConfiguration = bootClasspathConfiguration; this.tempDirectory = tmpDir; this.debugLine = debugLine; - this.jvmExecutable = jvmExecutable; + this.jdk = jdk; this.workingDirectory = workingDirectory; this.modelProperties = modelProperties; this.argLine = argLine; @@ -131,24 +132,25 @@ public class ForkConfiguration } /** - * @param classPath cla the classpath arguments - * @param startupConfiguration The startup configuration + * @param classPath cli the classpath arguments + * @param config The startup configuration * @param threadNumber the thread number, to be the replacement in the argLine @return A commandline * @return CommandLine able to flush entire command going to be sent to forked JVM * @throws org.apache.maven.surefire.booter.SurefireBooterForkException * when unable to perform the fork */ - public OutputStreamFlushableCommandline createCommandLine( List<String> classPath, - StartupConfiguration startupConfiguration, + public OutputStreamFlushableCommandline createCommandLine( List<String> classPath, StartupConfiguration config, int threadNumber ) - throws SurefireBooterForkException + throws SurefireBooterForkException { - return createCommandLine( classPath, - startupConfiguration.getClassLoaderConfiguration() - .isManifestOnlyJarRequestedAndUsable(), - startupConfiguration.isShadefire(), startupConfiguration.isProviderMainClass() - ? startupConfiguration.getActualClassName() - : ForkedBooter.class.getName(), threadNumber ); + boolean useJar = config.getClassLoaderConfiguration().isManifestOnlyJarRequestedAndUsable(); + + boolean shadefire = config.isShadefire(); + + String providerThatHasMainMethod = + config.isProviderMainClass() ? config.getActualClassName() : ForkedBooter.class.getName(); + + return createCommandLine( classPath, useJar, shadefire, providerThatHasMainMethod, threadNumber ); } OutputStreamFlushableCommandline createCommandLine( List<String> classPath, boolean useJar, boolean shadefire, @@ -157,13 +159,26 @@ public class ForkConfiguration { OutputStreamFlushableCommandline cli = new OutputStreamFlushableCommandline(); - cli.setExecutable( jvmExecutable ); + cli.setExecutable( jdk.getJvmExecutable() ); + + String jvmArgLine = + replaceThreadNumberPlaceholder( stripNewLines( replacePropertyExpressions() ), threadNumber ); + + if ( jdk.isJava9AtLeast() && !jvmArgLine.contains( "--add-modules" ) ) + { + if ( jvmArgLine.isEmpty() ) + { + jvmArgLine = "--add-modules ALL-SYSTEM"; + } + else + { + jvmArgLine = "--add-modules ALL-SYSTEM " + jvmArgLine; + } + } - if ( argLine != null ) + if ( !jvmArgLine.isEmpty() ) { - cli.createArg().setLine( - replaceThreadNumberPlaceholder( stripNewLines( replacePropertyExpressions( argLine ) ), - threadNumber ) ); + cli.createArg().setLine( jvmArgLine ); } for ( Map.Entry<String, String> entry : environmentVariables.entrySet() ) @@ -192,7 +207,7 @@ public class ForkConfiguration } else { - cli.addEnvironment( "CLASSPATH", StringUtils.join( classPath.iterator(), File.pathSeparator ) ); + cli.addEnvironment( "CLASSPATH", join( classPath.iterator(), File.pathSeparator ) ); final String forkedBooter = providerThatHasMainMethod != null ? providerThatHasMainMethod : ForkedBooter.class.getName(); @@ -235,11 +250,18 @@ public class ForkConfiguration * * This allows other plugins to modify or set properties with the changes getting picked up by surefire. */ - private String replacePropertyExpressions( String argLine ) + private String replacePropertyExpressions() { if ( argLine == null ) { - return null; + return ""; + } + + String resolvedArgLine = argLine.trim(); + + if ( resolvedArgLine.isEmpty() ) + { + return ""; } for ( final String key : modelProperties.stringPropertyNames() ) @@ -247,11 +269,11 @@ public class ForkConfiguration String field = "@{" + key + "}"; if ( argLine.contains( field ) ) { - argLine = argLine.replace( field, modelProperties.getProperty( key, "" ) ); + resolvedArgLine = resolvedArgLine.replace( field, modelProperties.getProperty( key, "" ) ); } } - return argLine; + return resolvedArgLine; } /** http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/395c68dc/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/StatelessXmlReporter.java ---------------------------------------------------------------------- diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/StatelessXmlReporter.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/StatelessXmlReporter.java index 60c6dfe..629778b 100644 --- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/StatelessXmlReporter.java +++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/report/StatelessXmlReporter.java @@ -19,7 +19,6 @@ package org.apache.maven.plugin.surefire.report; * under the License. */ -import org.apache.maven.shared.utils.io.IOUtil; import org.apache.maven.shared.utils.xml.PrettyPrintXMLWriter; import org.apache.maven.shared.utils.xml.XMLWriter; import org.apache.maven.surefire.report.ReportEntry; @@ -42,6 +41,7 @@ import java.util.Map; import java.util.Map.Entry; import java.util.StringTokenizer; +import static org.apache.commons.io.IOUtils.closeQuietly; import static org.apache.maven.plugin.surefire.report.DefaultReporterFactory.TestResultType; import static org.apache.maven.plugin.surefire.report.FileReporterUtils.stripIllegalFilenameChars; import static org.apache.maven.surefire.util.internal.StringUtils.UTF_8; @@ -239,7 +239,7 @@ public class StatelessXmlReporter } finally { - IOUtil.close( fw ); + closeQuietly( fw ); } } http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/395c68dc/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerProviderConfigurationTest.java ---------------------------------------------------------------------- diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerProviderConfigurationTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerProviderConfigurationTest.java index 5d970d8..26b8be7 100644 --- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerProviderConfigurationTest.java +++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerProviderConfigurationTest.java @@ -207,7 +207,7 @@ public class BooterDeserializerProviderConfigurationTest boolean readTestsFromInStream ) throws IOException { - final ForkConfiguration forkConfiguration = ForkConfigurationTest.getForkConfiguration( null, null ); + final ForkConfiguration forkConfiguration = ForkConfigurationTest.getForkConfiguration( (String) null ); PropertiesWrapper props = new PropertiesWrapper( new HashMap<String, String>() ); BooterSerializer booterSerializer = new BooterSerializer( forkConfiguration ); Object test; http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/395c68dc/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerStartupConfigurationTest.java ---------------------------------------------------------------------- diff --git a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerStartupConfigurationTest.java b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerStartupConfigurationTest.java index 0cb292c..035add0 100644 --- a/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerStartupConfigurationTest.java +++ b/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/BooterDeserializerStartupConfigurationTest.java @@ -119,7 +119,7 @@ public class BooterDeserializerStartupConfigurationTest private StartupConfiguration saveAndReload( StartupConfiguration startupConfiguration ) throws IOException { - final ForkConfiguration forkConfiguration = ForkConfigurationTest.getForkConfiguration( null, null ); + final ForkConfiguration forkConfiguration = ForkConfigurationTest.getForkConfiguration( (String) null ); PropertiesWrapper props = new PropertiesWrapper( new HashMap<String, String>() ); BooterSerializer booterSerializer = new BooterSerializer( forkConfiguration ); String aTest = "aTest"; http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/395c68dc/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/booterclient/ForkConfigurationTest.java ---------------------------------------------------------------------- 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 1e09d6f..b49e164 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 @@ -19,29 +19,32 @@ package org.apache.maven.plugin.surefire.booterclient; * under the License. */ -import java.io.File; -import java.io.IOException; -import java.util.Collections; -import java.util.Properties; - import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.SystemUtils; +import org.apache.maven.plugin.surefire.JdkAttributes; import org.apache.maven.shared.utils.StringUtils; import org.apache.maven.shared.utils.cli.Commandline; import org.apache.maven.surefire.booter.Classpath; import org.apache.maven.surefire.booter.SurefireBooterForkException; +import org.junit.Test; -import junit.framework.TestCase; +import java.io.File; +import java.io.IOException; +import java.util.Collections; +import java.util.Properties; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; public class ForkConfigurationTest - extends TestCase { - + @Test public void testCreateCommandLine_UseSystemClassLoaderForkOnce_ShouldConstructManifestOnlyJar() throws IOException, SurefireBooterForkException { - ForkConfiguration config = getForkConfiguration( null, "java" ); + ForkConfiguration config = getForkConfiguration( (String) null ); File cpElement = getTempClasspathFile(); Commandline cli = @@ -51,12 +54,13 @@ public class ForkConfigurationTest assertTrue( line.contains( "-jar" ) ); } + @Test public void testArglineWithNewline() throws IOException, SurefireBooterForkException { // SUREFIRE-657 File cpElement = getTempClasspathFile(); - ForkConfiguration forkConfiguration = getForkConfiguration( "abc\ndef", null ); + ForkConfiguration forkConfiguration = getForkConfiguration( "abc\ndef" ); final Commandline commandLine = forkConfiguration.createCommandLine( Collections.singletonList( cpElement.getAbsolutePath() ), false, false, @@ -64,18 +68,19 @@ public class ForkConfigurationTest assertTrue( commandLine.toString().contains( "abc def" ) ); } + @Test public void testCurrentWorkingDirectoryPropagationIncludingForkNumberExpansion() throws IOException, SurefireBooterForkException { // SUREFIRE-1136 File baseDir = new File( FileUtils.getTempDirectory(), "SUREFIRE-1136-" + RandomStringUtils.randomAlphabetic( 3 ) ); - baseDir.mkdirs(); + assertTrue( baseDir.mkdirs() ); baseDir.deleteOnExit(); File cwd = new File( baseDir, "fork_${surefire.forkNumber}" ); - ForkConfiguration config = getForkConfiguration( null, "java", cwd.getCanonicalFile() ); + ForkConfiguration config = getForkConfiguration( null, cwd.getCanonicalFile() ); Commandline commandLine = config.createCommandLine( Collections.<String>emptyList(), true, false, null, 1 ); File forkDirectory = new File( baseDir, "fork_1" ); @@ -84,20 +89,21 @@ public class ForkConfigurationTest commandLine.getShell().getWorkingDirectory().getCanonicalPath() ) ); } + @Test public void testExceptionWhenCurrentDirectoryIsNotRealDirectory() throws IOException, SurefireBooterForkException { // SUREFIRE-1136 File baseDir = new File( FileUtils.getTempDirectory(), "SUREFIRE-1136-" + RandomStringUtils.randomAlphabetic( 3 ) ); - baseDir.mkdirs(); + assertTrue( baseDir.mkdirs() ); baseDir.deleteOnExit(); File cwd = new File( baseDir, "cwd.txt" ); FileUtils.touch( cwd ); cwd.deleteOnExit(); - ForkConfiguration config = getForkConfiguration( null, "java", cwd.getCanonicalFile() ); + ForkConfiguration config = getForkConfiguration( null, cwd.getCanonicalFile() ); try { @@ -114,19 +120,20 @@ public class ForkConfigurationTest fail(); } + @Test public void testExceptionWhenCurrentDirectoryCannotBeCreated() throws IOException, SurefireBooterForkException { // SUREFIRE-1136 File baseDir = new File( FileUtils.getTempDirectory(), "SUREFIRE-1136-" + RandomStringUtils.randomAlphabetic( 3 ) ); - baseDir.mkdirs(); + assertTrue( baseDir.mkdirs() ); baseDir.deleteOnExit(); // NULL is invalid for JDK starting from 1.7.60 - https://github.com/openjdk-mirror/jdk/commit/e5389115f3634d25d101e2dcc71f120d4fd9f72f // ? character is invalid on Windows, seems to be imposable to create invalid directory using Java on Linux File cwd = new File( baseDir, "?\u0000InvalidDirectoryName" ); - ForkConfiguration config = getForkConfiguration( null, "java", cwd.getAbsoluteFile() ); + ForkConfiguration config = getForkConfiguration( null, cwd.getAbsoluteFile() ); try { @@ -152,17 +159,31 @@ public class ForkConfigurationTest return cpElement; } - public static ForkConfiguration getForkConfiguration( String argLine, String jvm ) + public static ForkConfiguration getForkConfiguration( File javaExec ) + throws IOException + { + return getForkConfiguration( null, javaExec.getAbsolutePath(), new File( "." ).getCanonicalFile() ); + } + + public static ForkConfiguration getForkConfiguration( String argLine ) throws IOException { - return getForkConfiguration( argLine, jvm, new File( "." ).getCanonicalFile() ); + File jvm = new File( new File( System.getProperty( "java.home" ), "bin" ), "java" ); + return getForkConfiguration( argLine, jvm.getAbsolutePath(), new File( "." ).getCanonicalFile() ); + } + + public static ForkConfiguration getForkConfiguration( String argLine, File cwd ) + throws IOException + { + File jvm = new File( new File( System.getProperty( "java.home" ), "bin" ), "java" ); + return getForkConfiguration( argLine, jvm.getAbsolutePath(), cwd ); } - public static ForkConfiguration getForkConfiguration( String argLine, String jvm, File cwd ) + private static ForkConfiguration getForkConfiguration( String argLine, String jvm, File cwd ) throws IOException { - return new ForkConfiguration( Classpath.emptyClasspath(), null, null, jvm, cwd, new Properties(), argLine, null, - false, 1, false, new Platform() ); + return new ForkConfiguration( Classpath.emptyClasspath(), null, null, new JdkAttributes( jvm, false ), + cwd, new Properties(), argLine, null, false, 1, false, new Platform() ); } // based on http://stackoverflow.com/questions/2591083/getting-version-of-java-in-runtime @@ -170,6 +191,6 @@ public class ForkConfigurationTest { String[] javaVersionElements = System.getProperty( "java.runtime.version" ).split( "\\.|_|-b" ); return Integer.valueOf( javaVersionElements[1] ) >= major - && Integer.valueOf( javaVersionElements[4] ) >= update; + && Integer.valueOf( javaVersionElements[3] ) >= update; } } http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/395c68dc/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index 6ba5602..2285482 100644 --- a/pom.xml +++ b/pom.xml @@ -97,7 +97,7 @@ <maven.surefire.scm.devConnection>scm:git:https://git-wip-us.apache.org/repos/asf/maven-surefire.git</maven.surefire.scm.devConnection> <maven.site.path>surefire-archives/surefire-LATEST</maven.site.path> <!-- Override with Jigsaw JRE 9 --> - <test.jre>${java.home}/..</test.jre> + <jdk.home>${java.home}/..</jdk.home> </properties> <dependencyManagement> http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/395c68dc/surefire-api/pom.xml ---------------------------------------------------------------------- diff --git a/surefire-api/pom.xml b/surefire-api/pom.xml index ec5c664..7b29c6d 100644 --- a/surefire-api/pom.xml +++ b/surefire-api/pom.xml @@ -52,7 +52,7 @@ <plugin> <artifactId>maven-surefire-plugin</artifactId> <configuration> - <jvm>${test.jre}/bin/java</jvm> + <jvm>${jdk.home}/bin/java</jvm> <redirectTestOutputToFile>true</redirectTestOutputToFile> <includes> <include>**/JUnit4SuiteTest.java</include> http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/395c68dc/surefire-booter/pom.xml ---------------------------------------------------------------------- diff --git a/surefire-booter/pom.xml b/surefire-booter/pom.xml index 8fdaf7e..9907424 100644 --- a/surefire-booter/pom.xml +++ b/surefire-booter/pom.xml @@ -85,7 +85,7 @@ </dependency> </dependencies> <configuration> - <jvm>${test.jre}/bin/java</jvm> + <jvm>${jdk.home}/bin/java</jvm> <redirectTestOutputToFile>true</redirectTestOutputToFile> <includes> <include>**/JUnit4SuiteTest.java</include> http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/395c68dc/surefire-booter/src/main/java/org/apache/maven/surefire/booter/SystemUtils.java ---------------------------------------------------------------------- diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/SystemUtils.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/SystemUtils.java index ccdb6e6..cf78fc3 100644 --- a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/SystemUtils.java +++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/SystemUtils.java @@ -22,19 +22,29 @@ package org.apache.maven.surefire.booter; import org.apache.maven.surefire.util.ReflectionUtils; import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; import java.lang.management.ManagementFactory; import java.lang.reflect.Method; +import java.util.Properties; +import java.util.StringTokenizer; import static java.lang.Thread.currentThread; +import static org.apache.commons.io.IOUtils.closeQuietly; import static org.apache.commons.lang3.JavaVersion.JAVA_9; import static org.apache.commons.lang3.JavaVersion.JAVA_RECENT; +import static org.apache.commons.lang3.StringUtils.isNumeric; import static org.apache.commons.lang3.SystemUtils.IS_OS_FREE_BSD; import static org.apache.commons.lang3.SystemUtils.IS_OS_LINUX; import static org.apache.commons.lang3.SystemUtils.IS_OS_NET_BSD; import static org.apache.commons.lang3.SystemUtils.IS_OS_OPEN_BSD; +import static org.apache.commons.lang3.SystemUtils.isJavaVersionAtLeast; import static org.apache.maven.surefire.util.ReflectionUtils.invokeMethodChain; import static org.apache.maven.surefire.util.ReflectionUtils.tryLoadClass; +import static org.apache.maven.surefire.util.internal.ObjectUtils.requireNonNull; /** * JDK 9 support. @@ -44,13 +54,130 @@ import static org.apache.maven.surefire.util.ReflectionUtils.tryLoadClass; */ public final class SystemUtils { + private static final double JIGSAW_JAVA_VERSION = 9.0d; + private static final int PROC_STATUS_PID_FIRST_CHARS = 20; - public SystemUtils() + private SystemUtils() { throw new IllegalStateException( "no instantiable constructor" ); } + /** + * @param jvmExecPath e.g. /jdk/bin/java, /jdk/jre/bin/java + * @return {@code true} if {@code jvmExecPath} is path to java binary executor + */ + public static boolean endsWithJavaPath( String jvmExecPath ) + { + File javaExec = new File( jvmExecPath ).getAbsoluteFile(); + File bin = javaExec.getParentFile(); + String exec = javaExec.getName(); + return exec.startsWith( "java" ) && bin != null && bin.getName().equals( "bin" ); + } + + /** + * If {@code jvmExecutable} is <tt>/jdk/bin/java</tt> or <tt>/jdk/jre/bin/java</tt> + * then the JDK home is returned <tt>/jdk</tt>. Null is returned if {@code jvmExecutable} is incorrect. + * + * @param jvmExecutable /jdk/bin/java* or /jdk/jre/bin/java* + * @return path to jdk directory; or <tt>null</tt> if wrong path or directory layout of JDK installation. + */ + public static File toJdkHomeFromJvmExec( String jvmExecutable ) + { + File bin = new File( jvmExecutable ).getAbsoluteFile().getParentFile(); + if ( "bin".equals( bin.getName() ) ) + { + File parent = bin.getParentFile(); + if ( "jre".equals( parent.getName() ) ) + { + File jdk = parent.getParentFile(); + return new File( jdk, "bin" ).isDirectory() ? jdk : null; + } + return parent; + } + return null; + } + + /** + * If {@code jreHome} is <tt>/jdk</tt> or <tt>/jdk/jre</tt> then the JDK home is returned <tt>/jdk</tt>. + * Null is returned if {@code jreHome} is incorrect. + * <br> + * JRE home directory {@code jreHome} is typically system property <tt>java.home</tt>. + * + * @param jreHome /jdk/jre + * @return path to JRE; or <tt>null</tt> if wrong path + */ + public static File toJdkHomeFromJre( String jreHome ) + { + File jre = new File( jreHome ).getAbsoluteFile(); + return "jre".equals( jre.getName() ) ? jre.getParentFile() : null; + } + + public static Double toJdkVersionFromReleaseFile( File jdkHome ) + { + File release = new File( requireNonNull( jdkHome ).getAbsoluteFile(), "release" ); + if ( !release.isFile() ) + { + return null; + } + InputStream is = null; + try + { + Properties properties = new Properties(); + is = new FileInputStream( release ); + properties.load( is ); + String javaVersion = properties.getProperty( "JAVA_VERSION" ).replace( "\"", "" ); + StringTokenizer versions = new StringTokenizer( javaVersion, "._" ); + + if ( versions.countTokens() == 1 ) + { + javaVersion = versions.nextToken(); + } + else if ( versions.countTokens() >= 2 ) + { + String majorVersion = versions.nextToken(); + String minorVersion = versions.nextToken(); + javaVersion = isNumeric( minorVersion ) ? majorVersion + "." + minorVersion : majorVersion; + } + else + { + return null; + } + + return Double.valueOf( javaVersion ); + } + catch ( IOException e ) + { + return null; + } + finally + { + closeQuietly( is ); + } + } + + public static boolean isJava9AtLeast( String jvmExecutablePath ) + { + File externalJavaHome = toJdkHomeFromJvmExec( jvmExecutablePath ); + File thisJavaHome = toJdkHomeFromJre( System.getProperty( "java.home" ) ); + if ( thisJavaHome.equals( externalJavaHome ) ) + { + return isBuiltInJava9AtLeast(); + } + Double releaseFileVersion = externalJavaHome == null ? null : toJdkVersionFromReleaseFile( externalJavaHome ); + return SystemUtils.isJava9AtLeast( releaseFileVersion ); + } + + static boolean isBuiltInJava9AtLeast() + { + return isJavaVersionAtLeast( JAVA_9 ); + } + + public static boolean isJava9AtLeast( Double version ) + { + return version != null && version >= JIGSAW_JAVA_VERSION; + } + public static ClassLoader platformClassLoader() { if ( JAVA_RECENT.atLeast( JAVA_9 ) ) http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/395c68dc/surefire-booter/src/test/java/org/apache/maven/surefire/booter/SystemUtilsTest.java ---------------------------------------------------------------------- diff --git a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/SystemUtilsTest.java b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/SystemUtilsTest.java index 12aff99..2b83946 100644 --- a/surefire-booter/src/test/java/org/apache/maven/surefire/booter/SystemUtilsTest.java +++ b/surefire-booter/src/test/java/org/apache/maven/surefire/booter/SystemUtilsTest.java @@ -21,8 +21,11 @@ package org.apache.maven.surefire.booter; import org.junit.Test; +import java.io.File; +import java.io.IOException; import java.lang.management.ManagementFactory; +import static java.io.File.separator; import static org.apache.commons.lang3.JavaVersion.JAVA_9; import static org.apache.commons.lang3.JavaVersion.JAVA_RECENT; import static org.apache.commons.lang3.SystemUtils.IS_OS_FREE_BSD; @@ -41,6 +44,128 @@ import static org.junit.Assume.assumeTrue; public class SystemUtilsTest { @Test + public void shouldParseProprietaryReleaseFile() throws IOException + { + String classes = new File( "." ).getCanonicalPath() + separator + "target" + separator + "test-classes"; + + File path = new File( classes, "jdk8-IBM" + separator + "bin" + separator + "java" ); + assertThat( SystemUtils.isJava9AtLeast( path.getAbsolutePath() ) ).isFalse(); + + path = new File( classes, "jdk8-oracle" + separator + "bin" + separator + "java" ); + assertThat( SystemUtils.isJava9AtLeast( path.getAbsolutePath() ) ).isFalse(); + + path = new File( classes, "jdk9-oracle" + separator + "bin" + separator + "java" ); + assertThat( SystemUtils.isJava9AtLeast( path.getAbsolutePath() ) ).isTrue(); + } + + @Test + public void shouldBeSameJdk9() throws IOException + { + testIsJava9AtLeast( new File( System.getProperty( "java.home" ) ).getParentFile() ); + } + + @Test + public void shouldBeDifferentJdk9() throws IOException + { + testIsJava9AtLeast( new File( System.getProperty( "java.home" ) ) ); + } + + @Test + public void incorrectJdkPath() throws IOException + { + File jre = new File( System.getProperty( "java.home" ) ); + File jdk = jre.getParentFile(); + File incorrect = jdk.getParentFile(); + assertThat( SystemUtils.isJava9AtLeast( incorrect.getAbsolutePath() ) ).isFalse(); + } + + private void testIsJava9AtLeast( File pathInJdk ) throws IOException + { + File path = new File( pathInJdk, "bin" + separator + "java" ); + + if ( JAVA_RECENT.atLeast( JAVA_9 ) ) + { + assertThat( SystemUtils.isJava9AtLeast( path.getAbsolutePath() ) ).isTrue(); + } + else + { + assertThat( SystemUtils.isJava9AtLeast( path.getAbsolutePath() ) ).isFalse(); + } + + /*verify( config, times( 0 ) ).toJdkVersionFromReleaseFile( any( File.class ) ); + verify( config, times( 1 ) ).isBuiltInJava9AtLeast();*/ + } + + @Test + public void shouldHaveJavaPath() + { + String javaPath = System.getProperty( "java.home" ) + separator + "bin" + separator + "java"; + assertThat( SystemUtils.endsWithJavaPath( javaPath ) ).isTrue(); + } + + @Test + public void shouldNotHaveJavaPath() + { + assertThat( SystemUtils.endsWithJavaPath( "/jdk" ) ).isFalse(); + } + + @Test + public void shouldNotExtractJdkHomeFromJavaExec() + { + File pathToJdk = SystemUtils.toJdkHomeFromJvmExec( "/jdk/binx/java" ); + assertThat( pathToJdk ).isNull(); + } + + @Test + public void shouldExtractJdkHomeFromJavaExec() + { + File pathToJdk = SystemUtils.toJdkHomeFromJvmExec( "/jdk/bin/java" ); + assertThat( pathToJdk ).isEqualTo( new File( "/jdk" ).getAbsoluteFile() ); + } + + @Test + public void shouldNotExtractJdkHomeFromJreExec() throws IOException + { + String classes = new File( "." ).getCanonicalPath() + separator + "target" + separator + "test-classes"; + File jdk = new File( classes, "jdk" ); + String pathToJreExec = jdk.getAbsolutePath() + separator + "jre" + separator + "binx" + separator + "java"; + File pathToJdk = SystemUtils.toJdkHomeFromJvmExec( pathToJreExec ); + assertThat( pathToJdk ).isNull(); + } + + @Test + public void shouldExtractJdkHomeFromJreExec() throws IOException + { + String classes = new File( "." ).getCanonicalPath() + separator + "target" + separator + "test-classes"; + File jdk = new File( classes, "jdk" ); + String pathToJreExec = jdk.getAbsolutePath() + separator + "jre" + separator + "bin" + separator + "java"; + File pathToJdk = SystemUtils.toJdkHomeFromJvmExec( pathToJreExec ); + assertThat( pathToJdk ).isEqualTo( jdk ); + } + + @Test + public void shouldExtractJdkHomeFromJre() + { + File pathToJdk = SystemUtils.toJdkHomeFromJre( "/jdk/jre" ); + assertThat( pathToJdk ).isEqualTo( new File( "/jdk" ).getAbsoluteFile() ); + } + + @Test + public void shouldNotExtractJdkHomeFromJre() + { + File pathToJdk = SystemUtils.toJdkHomeFromJre( "/jdk/jrex" ); + assertThat( pathToJdk ).isNull(); + } + + @Test + public void shouldBeJavaVersion() + { + assertThat( SystemUtils.isJava9AtLeast( (Double) null ) ).isFalse(); + assertThat( SystemUtils.isJava9AtLeast( 1.8d ) ).isFalse(); + assertThat( SystemUtils.isJava9AtLeast( 9.0d ) ).isTrue(); + } + + @Test public void shouldBePlatformClassLoader() { ClassLoader cl = SystemUtils.platformClassLoader(); http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/395c68dc/surefire-booter/src/test/resources/jdk/bin/java ---------------------------------------------------------------------- diff --git a/surefire-booter/src/test/resources/jdk/bin/java b/surefire-booter/src/test/resources/jdk/bin/java new file mode 100644 index 0000000..e69de29 http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/395c68dc/surefire-booter/src/test/resources/jdk/jre/bin/java ---------------------------------------------------------------------- diff --git a/surefire-booter/src/test/resources/jdk/jre/bin/java b/surefire-booter/src/test/resources/jdk/jre/bin/java new file mode 100644 index 0000000..e69de29 http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/395c68dc/surefire-booter/src/test/resources/jdk8-IBM/release ---------------------------------------------------------------------- diff --git a/surefire-booter/src/test/resources/jdk8-IBM/release b/surefire-booter/src/test/resources/jdk8-IBM/release new file mode 100644 index 0000000..f8baa30 --- /dev/null +++ b/surefire-booter/src/test/resources/jdk8-IBM/release @@ -0,0 +1 @@ +JAVA_VERSION="1.8.0" http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/395c68dc/surefire-booter/src/test/resources/jdk8-oracle/release ---------------------------------------------------------------------- diff --git a/surefire-booter/src/test/resources/jdk8-oracle/release b/surefire-booter/src/test/resources/jdk8-oracle/release new file mode 100644 index 0000000..567277b --- /dev/null +++ b/surefire-booter/src/test/resources/jdk8-oracle/release @@ -0,0 +1 @@ +JAVA_VERSION="1.8.0_141" http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/395c68dc/surefire-booter/src/test/resources/jdk9-oracle/release ---------------------------------------------------------------------- diff --git a/surefire-booter/src/test/resources/jdk9-oracle/release b/surefire-booter/src/test/resources/jdk9-oracle/release new file mode 100644 index 0000000..afcc747 --- /dev/null +++ b/surefire-booter/src/test/resources/jdk9-oracle/release @@ -0,0 +1 @@ +JAVA_VERSION="9" http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/395c68dc/surefire-integration-tests/pom.xml ---------------------------------------------------------------------- diff --git a/surefire-integration-tests/pom.xml b/surefire-integration-tests/pom.xml index d9142de..fee00c4 100644 --- a/surefire-integration-tests/pom.xml +++ b/surefire-integration-tests/pom.xml @@ -100,7 +100,8 @@ <forkMode>never</forkMode> <argLine>${argLine}</argLine> <includes> - <include>org/apache/**/*IT*.java</include> + <include>org/apache/**/Java9FullApiIT.java</include> + <include>org/apache/**/Surefire1265Java9IT.java</include> </includes> <!-- Pass current surefire version to the main suite so that it --> <!-- can forward to all integration test projects. SUREFIRE-513 --> @@ -115,6 +116,7 @@ <useInterpolatedSettings>${useInterpolatedSettings}</useInterpolatedSettings> <testBuildDirectory>${project.build.testOutputDirectory}</testBuildDirectory> <verifier.forkMode>${verifier.forkMode}</verifier.forkMode> + <jdk.home>${jdk.home}</jdk.home> </systemPropertyVariables> <redirectTestOutputToFile>false</redirectTestOutputToFile> </configuration> http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/395c68dc/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/AbstractJigsawIT.java ---------------------------------------------------------------------- diff --git a/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/AbstractJigsawIT.java b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/AbstractJigsawIT.java new file mode 100644 index 0000000..5d95a8d --- /dev/null +++ b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/AbstractJigsawIT.java @@ -0,0 +1,102 @@ +package org.apache.maven.surefire.its; + +/* + * 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. + */ + +import org.apache.maven.surefire.its.fixture.SurefireJUnit4IntegrationTestCase; +import org.apache.maven.surefire.its.fixture.SurefireLauncher; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; +import java.util.StringTokenizer; + +import static org.apache.commons.lang3.JavaVersion.JAVA_9; +import static org.apache.commons.lang3.JavaVersion.JAVA_RECENT; +import static org.junit.Assert.fail; +import static org.junit.Assume.assumeTrue; + +/** + * Abstract test class for Jigsaw tests. + * + * @author <a href="mailto:tibordig...@apache.org">Tibor Digana (tibor17)</a> + * @since 2.20.1 + */ +public abstract class AbstractJigsawIT + extends SurefireJUnit4IntegrationTestCase +{ + private static final String JDK_HOME_KEY = "jdk.home"; + private static final String JDK_HOME = System.getProperty( JDK_HOME_KEY ); + private static final double JIGSAW_JAVA_VERSION = 9.0d; + + protected abstract String getProjectDirectoryName(); + + protected SurefireLauncher assumeJigsaw() throws IOException + { + assumeTrue( "There's no JDK 9 provided.", + JAVA_RECENT.atLeast( JAVA_9 ) || JDK_HOME != null && isExtJava9AtLeast() ); + // fail( JDK_HOME_KEY + " was provided with value " + JDK_HOME + " but it is not Jigsaw Java 9." ); + + SurefireLauncher launcher = unpack( getProjectDirectoryName() ); + + if ( JDK_HOME != null ) + { + launcher.setLauncherJavaHome( JDK_HOME ); + } + + return launcher; + } + + private static boolean isExtJava9AtLeast() throws IOException + { + File release = new File( JDK_HOME, "release" ); + + if ( !release.isFile() ) + { + fail( JDK_HOME_KEY + " was provided with value " + JDK_HOME + " but file does not exist " + + JDK_HOME + File.separator + "release" + ); + } + + Properties properties = new Properties(); + try ( InputStream is = new FileInputStream( release ) ) + { + properties.load( is ); + } + String javaVersion = properties.getProperty( "JAVA_VERSION" ).replace( "\"", "" ); + StringTokenizer versions = new StringTokenizer( javaVersion, "._" ); + + if ( versions.countTokens() == 1 ) + { + javaVersion = versions.nextToken(); + } + else if ( versions.countTokens() >= 2 ) + { + javaVersion = versions.nextToken() + "." + versions.nextToken(); + } + else + { + fail( "unexpected java version format" ); + } + + return Double.valueOf( javaVersion ) >= JIGSAW_JAVA_VERSION; + } +} http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/395c68dc/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/Java9FullApiIT.java ---------------------------------------------------------------------- diff --git a/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/Java9FullApiIT.java b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/Java9FullApiIT.java new file mode 100644 index 0000000..9ebd2f3 --- /dev/null +++ b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/Java9FullApiIT.java @@ -0,0 +1,58 @@ +package org.apache.maven.surefire.its; + +/* + * 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. + */ + +import org.apache.maven.surefire.its.fixture.OutputValidator; +import org.junit.Test; + +import java.io.IOException; + +/** + * Running Surefire on the top of JDK 9 and should be able to load + * classes of multiple different Jigsaw modules without error. + * + * @author <a href="mailto:tibordig...@apache.org">Tibor Digana (tibor17)</a> + * @since 2.20.1 + */ +public class Java9FullApiIT + extends AbstractJigsawIT +{ + + @Test + public void shouldLoadMultipleJavaModules() throws IOException + { + OutputValidator validator = assumeJigsaw() + .setForkJvm() + .executeTest() + .verifyErrorFree( 2 ); + + validator.verifyTextInLog( "loaded class java.sql.SQLException" ) + .verifyTextInLog( "loaded class javax.xml.ws.Holder" ) + .verifyTextInLog( "loaded class javax.xml.bind.JAXBException" ) + .verifyTextInLog( "loaded class org.omg.CORBA.BAD_INV_ORDER" ) + .verifyTextInLog( "java.specification.version=9" ); + } + + @Override + protected String getProjectDirectoryName() + { + return "java9-full-api"; + } +} http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/395c68dc/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1265Java9IT.java ---------------------------------------------------------------------- diff --git a/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1265Java9IT.java b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1265Java9IT.java index 9e06e8e..2e92805 100644 --- a/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1265Java9IT.java +++ b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1265Java9IT.java @@ -19,11 +19,10 @@ package org.apache.maven.surefire.its.jiras; * under the License. */ -import org.apache.maven.surefire.its.fixture.SurefireJUnit4IntegrationTestCase; -import org.apache.maven.surefire.its.fixture.SurefireLauncher; +import org.apache.maven.surefire.its.AbstractJigsawIT; import org.junit.Test; -import static org.junit.Assume.assumeTrue; +import java.io.IOException; @SuppressWarnings( { "javadoc", "checkstyle:javadoctype" } ) /** @@ -40,19 +39,19 @@ import static org.junit.Assume.assumeTrue; * @since 2.20.1 */ public class Surefire1265Java9IT - extends SurefireJUnit4IntegrationTestCase + extends AbstractJigsawIT { @Test - public void shouldRunInPluginJava9() + public void shouldRunInPluginJava9() throws IOException { - assumeTrue( System.getProperty( "java.specification.version" ).compareTo( "1.8" ) > 0 ); - unpack() + assumeJigsaw() .executeTest() .verifyErrorFree( 2 ); } - private SurefireLauncher unpack() + @Override + protected String getProjectDirectoryName() { - return unpack( "/surefire-1265" ); + return "/surefire-1265"; } } http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/395c68dc/surefire-integration-tests/src/test/resources/java9-full-api/pom.xml ---------------------------------------------------------------------- diff --git a/surefire-integration-tests/src/test/resources/java9-full-api/pom.xml b/surefire-integration-tests/src/test/resources/java9-full-api/pom.xml new file mode 100644 index 0000000..099900c --- /dev/null +++ b/surefire-integration-tests/src/test/resources/java9-full-api/pom.xml @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + ~ 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. + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.maven.surefire</groupId> + <artifactId>it-parent</artifactId> + <version>1.0</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <artifactId>java9-full-api</artifactId> + + <properties> + <maven.compiler.source>1.6</maven.compiler.source> + <maven.compiler.target>1.6</maven.compiler.target> + </properties> + + <build> + <plugins> + <plugin> + <artifactId>maven-surefire-plugin</artifactId> + <configuration> + <forkMode>once</forkMode> + </configuration> + </plugin> + </plugins> + </build> + + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.12</version> + <scope>test</scope> + </dependency> + </dependencies> + +</project> http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/395c68dc/surefire-integration-tests/src/test/resources/java9-full-api/src/test/java/J9Test.java ---------------------------------------------------------------------- diff --git a/surefire-integration-tests/src/test/resources/java9-full-api/src/test/java/J9Test.java b/surefire-integration-tests/src/test/resources/java9-full-api/src/test/java/J9Test.java new file mode 100644 index 0000000..0ee3115 --- /dev/null +++ b/surefire-integration-tests/src/test/resources/java9-full-api/src/test/java/J9Test.java @@ -0,0 +1,38 @@ +/* + * 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. + */ + +import org.junit.Test; + +public class J9Test +{ + @Test + public void testMiscellaneousAPI() throws java.sql.SQLException + { + System.out.println( "loaded class " + java.sql.SQLException.class.getName() ); + System.out.println( "loaded class " + javax.xml.ws.Holder.class.getName() ); + System.out.println( "loaded class " + javax.xml.bind.JAXBException.class.getName() ); + System.out.println( "loaded class " + org.omg.CORBA.BAD_INV_ORDER.class.getName() ); + System.out.println( "java.specification.version=" + System.getProperty( "java.specification.version" ) ); + } + + @Test + public void test_corba_mod() throws org.omg.CORBA.BAD_INV_ORDER + { + } +}