You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by so...@apache.org on 2018/05/12 10:08:20 UTC
[maven-compiler-plugin] 01/01: Introduce white-box testing modules
This is an automated email from the ASF dual-hosted git repository.
sor pushed a commit to branch MCOMPILER-341
in repository https://gitbox.apache.org/repos/asf/maven-compiler-plugin.git
commit 570bf47017750fff4d44e370bcc5521bddcee58b
Author: Christian Stein <so...@gmail.com>
AuthorDate: Tue Apr 17 14:30:50 2018 +0200
Introduce white-box testing modules
Prior to this commit module descriptors `module-info.java` were not
compiled by the TestCompilerMojo. This commit introduces support for
test sources organized with module descriptors.
See motivation: https://twitter.com/rfscholte/status/927132319374331904
---
.../plugin/compiler/AbstractCompilerMojo.java | 5 +-
.../maven/plugin/compiler/TestCompilerMojo.java | 156 +++++++++++++++------
.../plugin/compiler/CompilerMojoTestCase.java | 27 ++++
.../unit/compiler-jpms-test/plugin-config.xml | 38 +++++
.../src/main/java/foo/TestJpms0.java | 31 ++++
.../src/main/java/module-info.java | 22 +++
.../src/test/java/foo/TestJpms0Test.java | 30 ++++
.../src/test/java/module-info.java | 22 +++
8 files changed, 288 insertions(+), 43 deletions(-)
diff --git a/src/main/java/org/apache/maven/plugin/compiler/AbstractCompilerMojo.java b/src/main/java/org/apache/maven/plugin/compiler/AbstractCompilerMojo.java
index 294ae23..31179d7 100644
--- a/src/main/java/org/apache/maven/plugin/compiler/AbstractCompilerMojo.java
+++ b/src/main/java/org/apache/maven/plugin/compiler/AbstractCompilerMojo.java
@@ -1005,7 +1005,10 @@ public abstract class AbstractCompilerMojo
if ( descriptor == null )
{
- getLog().warn( "Can't locate " + file );
+ if ( ! Files.isDirectory( Paths.get ( file ) ) )
+ {
+ getLog().warn( "Can't locate " + file );
+ }
}
else if ( !values[0].equals( descriptor.name() ) )
{
diff --git a/src/main/java/org/apache/maven/plugin/compiler/TestCompilerMojo.java b/src/main/java/org/apache/maven/plugin/compiler/TestCompilerMojo.java
index 78b0a0b..6fa080e 100644
--- a/src/main/java/org/apache/maven/plugin/compiler/TestCompilerMojo.java
+++ b/src/main/java/org/apache/maven/plugin/compiler/TestCompilerMojo.java
@@ -21,6 +21,8 @@ package org.apache.maven.plugin.compiler;
import java.io.File;
import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -207,22 +209,84 @@ public class TestCompilerMojo
protected void preparePaths( Set<File> sourceFiles )
{
File mainOutputDirectory = new File( getProject().getBuild().getOutputDirectory() );
-
- File mainModuleDescriptor = new File( mainOutputDirectory, "module-info.class" );
- boolean hasTestModuleDescriptor = false;
-
- // Go through the source files to respect includes/excludes
+ File mainModuleDescriptorClassFile = new File( mainOutputDirectory, "module-info.class" );
+ JavaModuleDescriptor mainModuleDescriptor = null;
+
+ File testModuleDescriptorJavaFile = new File( "module-info.java" );
+ JavaModuleDescriptor testModuleDescriptor = null;
+
+ // Go through the source files to respect includes/excludes
for ( File sourceFile : sourceFiles )
{
// @todo verify if it is the root of a sourcedirectory?
if ( "module-info.java".equals( sourceFile.getName() ) )
{
- hasTestModuleDescriptor = true;
+ testModuleDescriptorJavaFile = sourceFile;
break;
}
}
-
+
+ // Get additional information from the main module descriptor, if available
+ if ( mainModuleDescriptorClassFile.exists() )
+ {
+ ResolvePathsResult<String> result;
+
+ try
+ {
+ ResolvePathsRequest<String> request =
+ ResolvePathsRequest.withStrings( testPath )
+ .setMainModuleDescriptor( mainModuleDescriptorClassFile.getAbsolutePath() );
+
+ Toolchain toolchain = getToolchain();
+ if ( toolchain != null && toolchain instanceof DefaultJavaToolChain )
+ {
+ request.setJdkHome( ( (DefaultJavaToolChain) toolchain ).getJavaHome() );
+ }
+
+ result = locationManager.resolvePaths( request );
+ }
+ catch ( IOException e )
+ {
+ throw new RuntimeException( e );
+ }
+
+ mainModuleDescriptor = result.getMainModuleDescriptor();
+
+ pathElements = new LinkedHashMap<String, JavaModuleDescriptor>( result.getPathElements().size() );
+ pathElements.putAll( result.getPathElements() );
+
+ modulepathElements = result.getModulepathElements().keySet();
+ classpathElements = result.getClasspathElements();
+ }
+
+ // Get additional information from the test module descriptor, if available
+ if ( testModuleDescriptorJavaFile.exists() )
+ {
+ ResolvePathsResult<String> result;
+
+ try
+ {
+ ResolvePathsRequest<String> request =
+ ResolvePathsRequest.withStrings( testPath )
+ .setMainModuleDescriptor( testModuleDescriptorJavaFile.getAbsolutePath() );
+
+ Toolchain toolchain = getToolchain();
+ if ( toolchain != null && toolchain instanceof DefaultJavaToolChain )
+ {
+ request.setJdkHome( ( (DefaultJavaToolChain) toolchain ).getJavaHome() );
+ }
+
+ result = locationManager.resolvePaths( request );
+ }
+ catch ( IOException e )
+ {
+ throw new RuntimeException( e );
+ }
+
+ testModuleDescriptor = result.getMainModuleDescriptor();
+ }
+
if ( release != null )
{
if ( Integer.valueOf( release ) < 9 )
@@ -241,17 +305,54 @@ public class TestCompilerMojo
return;
}
- if ( hasTestModuleDescriptor )
+ if ( testModuleDescriptor != null )
{
modulepathElements = testPath;
classpathElements = Collections.emptyList();
- if ( mainModuleDescriptor.exists() )
+ if ( mainModuleDescriptor != null )
{
- // maybe some extra analysis required
+ if ( getLog().isDebugEnabled() )
+ {
+ getLog().debug( "Main and test module descriptors exist:" );
+ getLog().debug( " main module = " + mainModuleDescriptor.name() );
+ getLog().debug( " test module = " + testModuleDescriptor.name() );
+ }
+
+ if ( testModuleDescriptor.name().equals( mainModuleDescriptor.name() ) )
+ {
+ if ( compilerArgs == null )
+ {
+ compilerArgs = new ArrayList<String>();
+ }
+ compilerArgs.add( "--patch-module" );
+
+ StringBuilder patchModuleValue = new StringBuilder();
+ patchModuleValue.append( testModuleDescriptor.name() );
+ patchModuleValue.append( '=' );
+
+ for ( String root : getProject().getCompileSourceRoots() )
+ {
+ if ( Files.exists( Paths.get( root ) ) )
+ {
+ patchModuleValue.append( root ).append( PS );
+ }
+ }
+
+ compilerArgs.add( patchModuleValue.toString() );
+ }
+ else
+ {
+ getLog().debug( "Black-box testing - all is ready to compile" );
+ }
}
else
{
+ // No main binaries available? Means we're a test-only project.
+ if ( !mainOutputDirectory.exists() )
+ {
+ return;
+ }
// very odd
// Means that main sources must be compiled with -modulesource and -Xmodule:<moduleName>
// However, this has a huge impact since you can't simply use it as a classpathEntry
@@ -262,44 +363,15 @@ public class TestCompilerMojo
}
else
{
- if ( mainModuleDescriptor.exists() )
+ if ( mainModuleDescriptor != null )
{
- ResolvePathsResult<String> result;
-
- try
- {
- ResolvePathsRequest<String> request =
- ResolvePathsRequest.withStrings( testPath )
- .setMainModuleDescriptor( mainModuleDescriptor.getAbsolutePath() );
-
- Toolchain toolchain = getToolchain();
- if ( toolchain != null && toolchain instanceof DefaultJavaToolChain )
- {
- request.setJdkHome( ( (DefaultJavaToolChain) toolchain ).getJavaHome() );
- }
-
- result = locationManager.resolvePaths( request );
- }
- catch ( IOException e )
- {
- throw new RuntimeException( e );
- }
-
- JavaModuleDescriptor moduleDescriptor = result.getMainModuleDescriptor();
-
- pathElements = new LinkedHashMap<String, JavaModuleDescriptor>( result.getPathElements().size() );
- pathElements.putAll( result.getPathElements() );
-
- modulepathElements = result.getModulepathElements().keySet();
- classpathElements = result.getClasspathElements();
-
if ( compilerArgs == null )
{
compilerArgs = new ArrayList<String>();
}
compilerArgs.add( "--patch-module" );
- StringBuilder patchModuleValue = new StringBuilder( moduleDescriptor.name() )
+ StringBuilder patchModuleValue = new StringBuilder( mainModuleDescriptor.name() )
.append( '=' )
.append( mainOutputDirectory )
.append( PS );
@@ -311,7 +383,7 @@ public class TestCompilerMojo
compilerArgs.add( patchModuleValue.toString() );
compilerArgs.add( "--add-reads" );
- compilerArgs.add( moduleDescriptor.name() + "=ALL-UNNAMED" );
+ compilerArgs.add( mainModuleDescriptor.name() + "=ALL-UNNAMED" );
}
else
{
diff --git a/src/test/java/org/apache/maven/plugin/compiler/CompilerMojoTestCase.java b/src/test/java/org/apache/maven/plugin/compiler/CompilerMojoTestCase.java
index dfa5ec5..0d674ae 100644
--- a/src/test/java/org/apache/maven/plugin/compiler/CompilerMojoTestCase.java
+++ b/src/test/java/org/apache/maven/plugin/compiler/CompilerMojoTestCase.java
@@ -100,6 +100,31 @@ public class CompilerMojoTestCase
}
/**
+ * tests the ability of the plugin to compile a jpms project
+ *
+ * @throws Exception
+ */
+ public void testCompilerJpms()
+ throws Exception
+ {
+ CompilerMojo compileMojo = getCompilerMojo( "target/test-classes/unit/compiler-jpms-test/plugin-config.xml" );
+
+ compileMojo.execute();
+
+ assertTrue( new File( compileMojo.getOutputDirectory(), "module-info.class" ).exists() );
+ assertTrue( new File( compileMojo.getOutputDirectory(), "foo/TestJpms0.class" ).exists() );
+
+ TestCompilerMojo testCompileMojo =
+ getTestCompilerMojo( compileMojo, "target/test-classes/unit/compiler-jpms-test/plugin-config.xml" );
+
+ testCompileMojo.execute();
+
+ assertTrue( new File( testCompileMojo.getOutputDirectory(), "module-info.class" ).exists() );
+ assertTrue( new File( testCompileMojo.getOutputDirectory(), "foo/TestJpms0.class" ).exists() );
+ assertTrue( new File( testCompileMojo.getOutputDirectory(), "foo/TestJpms0Test.class" ).exists() );
+ }
+
+ /**
* tests the ability of the plugin to respond to empty source
*
* @throws Exception
@@ -419,6 +444,8 @@ public class CompilerMojoTestCase
setVariableValueToObject( mojo, "compileSourceRoots", Collections.singletonList( testSourceRoot ) );
MavenProject project = getMockMavenProject();
+ project.setFile( testPom );
+ project.addCompileSourceRoot("/src/main/java" );
project.setArtifacts( Collections.singleton( junitArtifact ) );
project.getBuild().setOutputDirectory( new File( buildDir, "classes" ).getAbsolutePath() );
setVariableValueToObject( mojo, "project", project );
diff --git a/src/test/resources/unit/compiler-jpms-test/plugin-config.xml b/src/test/resources/unit/compiler-jpms-test/plugin-config.xml
new file mode 100644
index 0000000..631ba01
--- /dev/null
+++ b/src/test/resources/unit/compiler-jpms-test/plugin-config.xml
@@ -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.
+ -->
+
+<project>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <compileSourceRoots>
+ <compileSourceRoot>${basedir}/target/test-classes/unit/compiler-jpms-test/src/main/java</compileSourceRoot>
+ </compileSourceRoots>
+ <compilerId>javac</compilerId>
+ <debug>true</debug>
+ <release>9</release>
+ <outputDirectory>${basedir}/target/test/unit/compiler-jpms-test/target/classes</outputDirectory>
+ <buildDirectory>${basedir}/target/test/unit/compiler-jpms-test/target</buildDirectory>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/src/test/resources/unit/compiler-jpms-test/src/main/java/foo/TestJpms0.java b/src/test/resources/unit/compiler-jpms-test/src/main/java/foo/TestJpms0.java
new file mode 100644
index 0000000..2f2110a
--- /dev/null
+++ b/src/test/resources/unit/compiler-jpms-test/src/main/java/foo/TestJpms0.java
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+package foo;
+
+public class TestJpms0
+{
+
+ public TestJpms0()
+ {
+
+ System.out.println( "Woo Hoo!" );
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/resources/unit/compiler-jpms-test/src/main/java/module-info.java b/src/test/resources/unit/compiler-jpms-test/src/main/java/module-info.java
new file mode 100644
index 0000000..763919e
--- /dev/null
+++ b/src/test/resources/unit/compiler-jpms-test/src/main/java/module-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+module foo {
+ // empty
+}
diff --git a/src/test/resources/unit/compiler-jpms-test/src/test/java/foo/TestJpms0Test.java b/src/test/resources/unit/compiler-jpms-test/src/test/java/foo/TestJpms0Test.java
new file mode 100644
index 0000000..6bb7c46
--- /dev/null
+++ b/src/test/resources/unit/compiler-jpms-test/src/test/java/foo/TestJpms0Test.java
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+package foo;
+
+import junit.framework.TestCase;
+
+public class TestJpms0Test
+ extends TestCase
+{
+ public void testJpms0Test()
+ {
+ TestJpms0 test = new TestJpms0();
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/unit/compiler-jpms-test/src/test/java/module-info.java b/src/test/resources/unit/compiler-jpms-test/src/test/java/module-info.java
new file mode 100644
index 0000000..74985f4
--- /dev/null
+++ b/src/test/resources/unit/compiler-jpms-test/src/test/java/module-info.java
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+open module foo {
+ requires junit;
+}
--
To stop receiving notification emails like this one, please contact
sor@apache.org.