diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 0000000..0b002f3 --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,2 @@ +# Parent 13 reformat +a3d830e666214d555be5717a6e3576e957319a60 diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index 8e43192..faf344f 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -21,23 +21,11 @@ on: [push, pull_request] jobs: build: + name: Build it + uses: codehaus-plexus/.github/.github/workflows/maven.yml@master - strategy: - matrix: - os: [ubuntu-latest,windows-latest, macOS-latest] - java: [8, 11, 17] - jdk: [temurin, zulu, adopt-openj9] - fail-fast: false - - runs-on: ${{ matrix.os }} - - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-java@v2 - with: - distribution: ${{ matrix.jdk }} - java-version: ${{ matrix.java }} - cache: 'maven' - - - name: Build with Maven - run: mvn install javadoc:javadoc site -e -B -V -Pno-tests-if-not-on-osx +# deploy: +# name: Deploy +# needs: build +# uses: codehaus-plexus/.github/.github/workflows/maven-deploy.yml@master +# secrets: inherit diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml index 8c0dc6f..4c09c8a 100644 --- a/.github/workflows/release-drafter.yml +++ b/.github/workflows/release-drafter.yml @@ -7,6 +7,6 @@ jobs: update_release_draft: runs-on: ubuntu-latest steps: - - uses: release-drafter/release-drafter@v5.17.6 + - uses: release-drafter/release-drafter@v6 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/README.md b/README.md index 87b6925..d299f8d 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,14 @@ # Plexus Language + ![Build Status](https://github.com/codehaus-plexus/plexus-languages/workflows/GitHub%20CI/badge.svg) -![GitHub Workflow Status](https://img.shields.io/github/workflow/status/codehaus-plexus/plexus-languages/GitHub%20CI) +![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/codehaus-plexus/plexus-languages/maven.yml?branch=master) +[![Reproducible Builds](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/jvm-repo-rebuild/reproducible-central/master/content/org/codehaus/plexus/plexus-languages/badge.json)](https://github.com/jvm-repo-rebuild/reproducible-central/blob/master/content/org/codehaus/plexus/plexus-languages/README.md) Plexus Languages: - * [![Maven Central](https://img.shields.io/maven-central/v/org.codehaus.plexus/plexus-languages.svg?label=Maven%20Central)](https://search.maven.org/artifact/org.codehaus.plexus/plexus-languages) +* [![Maven Central](https://img.shields.io/maven-central/v/org.codehaus.plexus/plexus-languages.svg?label=Maven%20Central)](https://search.maven.org/artifact/org.codehaus.plexus/plexus-languages) Plexus Java: - * [![Maven Central](https://img.shields.io/maven-central/v/org.codehaus.plexus/plexus-java.svg?label=Maven%20Central)](https://search.maven.org/artifact/org.codehaus.plexus/plexus-java) +* [![Maven Central](https://img.shields.io/maven-central/v/org.codehaus.plexus/plexus-java.svg?label=Maven%20Central)](https://search.maven.org/artifact/org.codehaus.plexus/plexus-java) + diff --git a/plexus-java/pom.xml b/plexus-java/pom.xml index 96ab3b6..c1a9931 100644 --- a/plexus-java/pom.xml +++ b/plexus-java/pom.xml @@ -5,74 +5,22 @@ org.codehaus.plexus plexus-languages - 1.1.1 + 1.5.1-SNAPSHOT plexus-java Plexus Languages :: Java - - 1.8 - 1.8 - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.22.2 - - - - - - org.eclipse.sisu - sisu-maven-plugin - 0.3.5 - - - index-project - - main-index - - - - - - - org.apache.maven.plugins - maven-failsafe-plugin - 2.22.2 - - - - integration-test - verify - - - - - - **/*Test.java - **/*IT.java - - - - - - org.ow2.asm asm - 9.2 + 9.8 com.thoughtworks.qdox qdox - 2.0.1 + 2.2.0 javax.inject @@ -80,39 +28,58 @@ 1 true - - org.hamcrest - hamcrest - 2.2 - test + org.junit.jupiter + junit-jupiter-api + test - org.hamcrest - hamcrest-library - 2.2 - test + org.junit.jupiter + junit-jupiter-params + test - junit - junit - 4.13.2 + org.mockito + mockito-core + 4.11.0 test org.mockito - mockito-core - 4.3.1 + mockito-junit-jupiter + 4.11.0 test - com.google.inject - guice - 5.1.0 + org.assertj + assertj-core + 3.27.3 test + + + + org.eclipse.sisu + sisu-maven-plugin + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + + integration-test + verify + + + + + + + jdk9 diff --git a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/AbstractBinaryModuleInfoParser.java b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/AbstractBinaryModuleInfoParser.java index 3b58137..0abd925 100644 --- a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/AbstractBinaryModuleInfoParser.java +++ b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/AbstractBinaryModuleInfoParser.java @@ -29,54 +29,41 @@ import org.codehaus.plexus.languages.java.version.JavaVersion; -abstract class AbstractBinaryModuleInfoParser implements ModuleInfoParser -{ +abstract class AbstractBinaryModuleInfoParser implements ModuleInfoParser { @Override - public JavaModuleDescriptor getModuleDescriptor( Path modulePath ) - throws IOException - { - return getModuleDescriptor( modulePath, JavaVersion.JAVA_SPECIFICATION_VERSION ); + public JavaModuleDescriptor getModuleDescriptor(Path modulePath) throws IOException { + return getModuleDescriptor(modulePath, JavaVersion.JAVA_SPECIFICATION_VERSION); } - + @Override - public JavaModuleDescriptor getModuleDescriptor( Path modulePath, JavaVersion jdkVersion ) - throws IOException - { + public JavaModuleDescriptor getModuleDescriptor(Path modulePath, JavaVersion jdkVersion) throws IOException { JavaModuleDescriptor descriptor; - if ( Files.isDirectory( modulePath ) ) - { - try ( InputStream in = Files.newInputStream( modulePath.resolve( "module-info.class" ) ) ) - { - descriptor = parse( in ); + if (Files.isDirectory(modulePath)) { + try (InputStream in = Files.newInputStream(modulePath.resolve("module-info.class"))) { + descriptor = parse(in); } - } - else - { - try ( JarFile jarFile = new JarFile( modulePath.toFile() ) ) - { + } else { + try (JarFile jarFile = new JarFile(modulePath.toFile())) { JarEntry moduleInfo; - if ( modulePath.toString().toLowerCase().endsWith( ".jmod" ) ) - { - moduleInfo = jarFile.getJarEntry( "classes/module-info.class" ); - } - else - { - moduleInfo = jarFile.getJarEntry( "module-info.class" ); + if (modulePath.toString().toLowerCase().endsWith(".jmod")) { + moduleInfo = jarFile.getJarEntry("classes/module-info.class"); + } else { + moduleInfo = jarFile.getJarEntry("module-info.class"); - if ( moduleInfo == null ) - { - Manifest manifest = jarFile.getManifest(); + if (moduleInfo == null) { + Manifest manifest = jarFile.getManifest(); - if ( manifest != null && "true".equalsIgnoreCase( manifest.getMainAttributes().getValue( "Multi-Release" ) ) ) - { - int javaVersion = Integer.valueOf( jdkVersion.asMajor().getValue( 1 ) ); - - for ( int version = javaVersion; version >= 9; version-- ) - { + if (manifest != null + && "true" + .equalsIgnoreCase( + manifest.getMainAttributes().getValue("Multi-Release"))) { + int javaVersion = + Integer.parseInt(jdkVersion.asMajor().getValue(1)); + + for (int version = javaVersion; version >= 9; version--) { String resource = "META-INF/versions/" + version + "/module-info.class"; - JarEntry entry = jarFile.getJarEntry( resource ); - if ( entry != null ) - { + JarEntry entry = jarFile.getJarEntry(resource); + if (entry != null) { moduleInfo = entry; break; } @@ -85,12 +72,9 @@ public JavaModuleDescriptor getModuleDescriptor( Path modulePath, JavaVersion jd } } - if ( moduleInfo != null ) - { - descriptor = parse( jarFile.getInputStream( moduleInfo ) ); - } - else - { + if (moduleInfo != null) { + descriptor = parse(jarFile.getInputStream(moduleInfo)); + } else { descriptor = null; } } @@ -98,5 +82,5 @@ public JavaModuleDescriptor getModuleDescriptor( Path modulePath, JavaVersion jd return descriptor; } - abstract JavaModuleDescriptor parse( InputStream in ) throws IOException; + abstract JavaModuleDescriptor parse(InputStream in) throws IOException; } diff --git a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/AsmModuleInfoParser.java b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/AsmModuleInfoParser.java index 8587549..c35ebcb 100644 --- a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/AsmModuleInfoParser.java +++ b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/AsmModuleInfoParser.java @@ -35,89 +35,73 @@ /** * Extract information from module with ASM - * - * + * + * * @author Robert Scholte * @since 1.0.0 */ -class AsmModuleInfoParser extends AbstractBinaryModuleInfoParser -{ +class AsmModuleInfoParser extends AbstractBinaryModuleInfoParser { @Override - JavaModuleDescriptor parse( InputStream in ) - throws IOException - { + JavaModuleDescriptor parse(InputStream in) throws IOException { final JavaModuleDescriptorWrapper wrapper = new JavaModuleDescriptorWrapper(); - ClassReader reader = new ClassReader( in ); - reader.accept( new ClassVisitor( Opcodes.ASM9 ) - { - @Override - public ModuleVisitor visitModule( String name, int arg1, String arg2 ) - { - wrapper.builder = JavaModuleDescriptor.newModule( name ); - - return new ModuleVisitor( Opcodes.ASM9 ) - { + ClassReader reader = new ClassReader(in); + reader.accept( + new ClassVisitor(Opcodes.ASM9) { @Override - public void visitRequire( String module, int access, String version ) - { - if ( ( access & ( Opcodes.ACC_STATIC_PHASE | Opcodes.ACC_TRANSITIVE ) ) != 0 ) - { - Set modifiers = new LinkedHashSet<>(); - if ( ( access & Opcodes.ACC_STATIC_PHASE ) != 0 ) - { - modifiers.add( JavaModuleDescriptor.JavaRequires.JavaModifier.STATIC ); + public ModuleVisitor visitModule(String name, int arg1, String arg2) { + wrapper.builder = JavaModuleDescriptor.newModule(name); + + return new ModuleVisitor(Opcodes.ASM9) { + @Override + public void visitRequire(String module, int access, String version) { + if ((access & (Opcodes.ACC_STATIC_PHASE | Opcodes.ACC_TRANSITIVE)) != 0) { + Set modifiers = + new LinkedHashSet<>(); + if ((access & Opcodes.ACC_STATIC_PHASE) != 0) { + modifiers.add(JavaModuleDescriptor.JavaRequires.JavaModifier.STATIC); + } + if ((access & Opcodes.ACC_TRANSITIVE) != 0) { + modifiers.add(JavaModuleDescriptor.JavaRequires.JavaModifier.TRANSITIVE); + } + + wrapper.builder.requires(modifiers, module); + } else { + wrapper.builder.requires(module); + } } - if ( ( access & Opcodes.ACC_TRANSITIVE ) != 0 ) - { - modifiers.add( JavaModuleDescriptor.JavaRequires.JavaModifier.TRANSITIVE ); + + @Override + public void visitExport(String pn, int ms, String... targets) { + if (targets == null || targets.length == 0) { + wrapper.builder.exports(pn.replace('/', '.')); + } else { + wrapper.builder.exports( + pn.replace('/', '.'), new HashSet<>(Arrays.asList(targets))); + } } - wrapper.builder.requires( modifiers, module ); - } - else - { - wrapper.builder.requires( module ); - } - } + @Override + public void visitUse(String service) { + wrapper.builder.uses(service.replace('/', '.')); + } - @Override - public void visitExport( String pn, int ms, String... targets ) - { - if ( targets == null || targets.length == 0 ) - { - wrapper.builder.exports( pn.replace( '/', '.' ) ); - } - else - { - wrapper.builder.exports( pn.replace( '/', '.' ), new HashSet<>( Arrays.asList( targets ) ) ); - } - } - - @Override - public void visitUse( String service ) - { - wrapper.builder.uses( service.replace( '/', '.' ) ); - } - - @Override - public void visitProvide( String service, String... providers ) - { - List renamedProvides = new ArrayList<>( providers.length ); - for ( String provider : providers ) - { - renamedProvides.add( provider.replace( '/', '.' ) ); - } - wrapper.builder.provides( service.replace( '/', '.' ), renamedProvides ); + @Override + public void visitProvide(String service, String... providers) { + List renamedProvides = new ArrayList<>(providers.length); + for (String provider : providers) { + renamedProvides.add(provider.replace('/', '.')); + } + wrapper.builder.provides(service.replace('/', '.'), renamedProvides); + } + }; } - }; - } - }, 0 ); + }, + 0); return wrapper.builder.build(); } - private static class JavaModuleDescriptorWrapper - { + private static class JavaModuleDescriptorWrapper { private JavaModuleDescriptor.Builder builder; } } diff --git a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/BinaryModuleInfoParser.java b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/BinaryModuleInfoParser.java index dc9b1c8..e6e67c5 100644 --- a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/BinaryModuleInfoParser.java +++ b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/BinaryModuleInfoParser.java @@ -18,7 +18,4 @@ * specific language governing permissions and limitations * under the License. */ -class BinaryModuleInfoParser extends AsmModuleInfoParser -{ - -} +class BinaryModuleInfoParser extends AsmModuleInfoParser {} diff --git a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/CmdModuleNameExtractor.java b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/CmdModuleNameExtractor.java index d08ffee..4d2ff96 100644 --- a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/CmdModuleNameExtractor.java +++ b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/CmdModuleNameExtractor.java @@ -23,26 +23,23 @@ /** * This is just a placeholder class - * + * * @author Robert Scholte * @since 1.0.0 */ -public class CmdModuleNameExtractor -{ - public static void main( String[] args ) - { - System.err.println( "Use at least Java 9 to execute this class" ); - - System.exit( -1 ); +public class CmdModuleNameExtractor { + public static void main(String[] args) { + System.err.println("Use at least Java 9 to execute this class"); + + System.exit(-1); } /** - * + * * @param modulePath * @return */ - public static String getModuleName( Path modulePath ) - { + public static String getModuleName(Path modulePath) { throw new UnsupportedOperationException(); } } diff --git a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/JavaModuleDescriptor.java b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/JavaModuleDescriptor.java index 37ac927..84d001b 100644 --- a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/JavaModuleDescriptor.java +++ b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/JavaModuleDescriptor.java @@ -27,103 +27,85 @@ /** * Simple representation of a ModuleDescriptor containing info required by this plugin. - * It will provide only methods matching Java 9 ModuleDescriptor, so once Java 9 is required, we can easily switch - * + * It will provide only methods matching Java 9 ModuleDescriptor, so once Java 9 is required, we can easily switch + * * @author Robert Scholte * @since 1.0.0 * */ -public class JavaModuleDescriptor -{ +public class JavaModuleDescriptor { private String name; - + private boolean automatic; private Set requires = new LinkedHashSet<>(); - + private Set exports = new LinkedHashSet<>(); - + private Set uses = new LinkedHashSet<>(); - + private Set provides = new LinkedHashSet<>(); - - public String name() - { + + public String name() { return name; } - public boolean isAutomatic() - { + public boolean isAutomatic() { return automatic; } - - public Set requires() - { - return Collections.unmodifiableSet( requires ); + + public Set requires() { + return Collections.unmodifiableSet(requires); } - public Set exports() - { - return Collections.unmodifiableSet( exports ); + public Set exports() { + return Collections.unmodifiableSet(exports); } - - public Set provides() - { - return Collections.unmodifiableSet( provides ); + + public Set provides() { + return Collections.unmodifiableSet(provides); } - - public Set uses() - { - return Collections.unmodifiableSet( uses ); + + public Set uses() { + return Collections.unmodifiableSet(uses); } - - public static JavaModuleDescriptor.Builder newModule( String name ) - { - return new Builder( name ).setAutomatic( false ); + + public static JavaModuleDescriptor.Builder newModule(String name) { + return new Builder(name).setAutomatic(false); + } + + public static Builder newAutomaticModule(String name) { + return new Builder(name).setAutomatic(true); } - - public static Builder newAutomaticModule( String name ) - { - return new Builder( name ).setAutomatic( true ); - } @Override - public int hashCode() - { - return Objects.hash( name, automatic, requires, exports ); + public int hashCode() { + return Objects.hash(name, automatic, requires, exports); } - + @Override - public boolean equals( Object obj ) - { - if ( this == obj ) - { + public boolean equals(Object obj) { + if (this == obj) { return true; } - if ( obj == null ) - { + if (obj == null) { return false; } - if ( getClass() != obj.getClass() ) - { + if (getClass() != obj.getClass()) { return false; } JavaModuleDescriptor other = (JavaModuleDescriptor) obj; - if ( automatic != other.automatic ) - { + if (automatic != other.automatic) { return false; } - if ( !Objects.equals( name, other.name ) ) - { + if (!Objects.equals(name, other.name)) { return false; } - if ( !Objects.equals( requires, other.requires ) ) - { + if (!Objects.equals(requires, other.requires)) { return false; } - if ( !Objects.equals( exports, other.exports ) ) - { + if (!Objects.equals(exports, other.exports)) { return false; } return true; @@ -131,191 +113,168 @@ public boolean equals( Object obj ) @Override public String toString() { - return "JavaModuleDescriptor{" + - "name='" + name + '\'' + - ", automatic=" + automatic + - ", requires=" + requires + - ", exports=" + exports + - ", uses=" + uses + - ", provides=" + provides + - '}'; + return "JavaModuleDescriptor{" + "name='" + + name + '\'' + ", automatic=" + + automatic + ", requires=" + + requires + ", exports=" + + exports + ", uses=" + + uses + ", provides=" + + provides + '}'; } /** * A JavaModuleDescriptor Builder - * + * * @author Robert Scholte * @since 1.0.0 */ - public static final class Builder - { + public static final class Builder { private JavaModuleDescriptor jModule; - - private Builder( String name ) - { + + private Builder(String name) { jModule = new JavaModuleDescriptor(); jModule.name = name; } - - private Builder setAutomatic( boolean isAutomatic ) - { + + private Builder setAutomatic(boolean isAutomatic) { jModule.automatic = isAutomatic; return this; } /** * Adds a dependence on a module with the given (and possibly empty) set of modifiers. - * + * * @param modifiers The set of modifiers * @param name The module name * @return This builder */ - public Builder requires( Set modifiers, String name ) - { - jModule.requires.add( new JavaRequires( modifiers, name ) ); + public Builder requires(Set modifiers, String name) { + jModule.requires.add(new JavaRequires(modifiers, name)); return this; } /** * Adds a dependence on a module with an empty set of modifiers. - * + * * @param name The module name * @return This builder */ - public Builder requires( String name ) - { - jModule.requires.add( new JavaRequires( name ) ); + public Builder requires(String name) { + jModule.requires.add(new JavaRequires(name)); return this; } /** * Adds an exported package. The package is exported to all modules. - * + * * @param source The package name * @return This builder */ - public Builder exports( String source ) - { - jModule.exports.add( new JavaExports( source ) ); + public Builder exports(String source) { + jModule.exports.add(new JavaExports(source)); return this; } /** * Adds an exported package. The package is exported to a set of target modules. - * + * * @param source The package name * @param targets The set of target modules names * @return This builder */ - public Builder exports( String source, Set targets ) - { - jModule.exports.add( new JavaExports( source, targets ) ); + public Builder exports(String source, Set targets) { + jModule.exports.add(new JavaExports(source, targets)); return this; } - + /** * Adds a service dependence. - * + * * @param service The service type * @return This Builder */ - public Builder uses( String service ) - { - jModule.uses.add( service ); + public Builder uses(String service) { + jModule.uses.add(service); return this; } - - public Builder provides( String service, List providers ) - { - jModule.provides.add( new JavaProvides( service, providers ) ); + + public Builder provides(String service, List providers) { + jModule.provides.add(new JavaProvides(service, providers)); return this; } /** * Builds and returns a ModuleDescriptor from its components. - * + * * @return The module descriptor */ - public JavaModuleDescriptor build() - { + public JavaModuleDescriptor build() { return jModule; } } - + /** * Represents ModuleDescriptor.Requires - * + * * @author Robert Scholte * @since 1.0.0 */ - public static class JavaRequires - { + public static class JavaRequires { private final Set modifiers; - + private final String name; - private JavaRequires( Set modifiers, String name ) - { + private JavaRequires(Set modifiers, String name) { this.modifiers = modifiers; this.name = name; } - private JavaRequires( String name ) - { + private JavaRequires(String name) { this.modifiers = Collections.emptySet(); this.name = name; } - public Set modifiers() - { + public Set modifiers() { return modifiers; } - - public String name() - { + + public String name() { return name; } - + /** * Represents ModuleDescriptor.Requires.Modifier - * + * * @author Robert Scholte * @since 1.0.0 */ - public enum JavaModifier - { - STATIC, TRANSITIVE + public enum JavaModifier { + STATIC, + TRANSITIVE } @Override - public int hashCode() - { - return Objects.hash( modifiers, name ); + public int hashCode() { + return Objects.hash(modifiers, name); } @Override - public boolean equals( Object obj ) - { - if ( this == obj ) - { + public boolean equals(Object obj) { + if (this == obj) { return true; } - if ( obj == null ) - { + if (obj == null) { return false; } - if ( getClass() != obj.getClass() ) - { + if (getClass() != obj.getClass()) { return false; } JavaRequires other = (JavaRequires) obj; - if ( !Objects.equals( modifiers, other.modifiers ) ) - { + if (!Objects.equals(modifiers, other.modifiers)) { return false; } - if ( !Objects.equals( name, other.name ) ) - { + if (!Objects.equals(name, other.name)) { return false; } return true; @@ -323,158 +282,126 @@ public boolean equals( Object obj ) @Override public String toString() { - return "JavaRequires{" + - "modifiers=" + modifiers + - ", name='" + name + '\'' + - '}'; + return "JavaRequires{" + "modifiers=" + modifiers + ", name='" + name + '\'' + '}'; } } - + /** * Represents ModuleDescriptor.Exports - * + * * @author Robert Scholte * @since 1.0.0 */ - public static class JavaExports - { + public static class JavaExports { private final String source; - + private final Set targets; - - private JavaExports( String source ) - { + + private JavaExports(String source) { this.source = source; this.targets = null; } - - public JavaExports( String source, Set targets ) - { + + public JavaExports(String source, Set targets) { this.source = source; this.targets = targets; } - public String source() - { + public String source() { return source; } - - public Set targets() - { + + public Set targets() { return targets; } @Override - public int hashCode() - { - return Objects.hash( source, targets ); + public int hashCode() { + return Objects.hash(source, targets); } @Override - public boolean equals( Object obj ) - { - if ( this == obj ) - { + public boolean equals(Object obj) { + if (this == obj) { return true; } - if ( obj == null ) - { + if (obj == null) { return false; } - if ( getClass() != obj.getClass() ) - { + if (getClass() != obj.getClass()) { return false; } - + JavaExports other = (JavaExports) obj; - if ( !Objects.equals( source, other.source ) ) - { - return false; + if (!Objects.equals(source, other.source)) { + return false; } - if ( !Objects.equals( targets, other.targets ) ) - { - return false; + if (!Objects.equals(targets, other.targets)) { + return false; } return true; } @Override public String toString() { - return "JavaExports{" + - "source='" + source + '\'' + - ", targets=" + targets + - '}'; + return "JavaExports{" + "source='" + source + '\'' + ", targets=" + targets + '}'; } } - + /** * Represents ModuleDescriptor.Provides - * + * * @author Robert Scholte * @since 1.0.0 */ - public static class JavaProvides - { + public static class JavaProvides { private final String service; - + private final List providers; - private JavaProvides( String service, List providers ) - { + private JavaProvides(String service, List providers) { this.service = service; this.providers = providers; } - public String service() - { + public String service() { return service; } - - public List providers() - { + + public List providers() { return providers; } - + @Override - public int hashCode() - { - return Objects.hash( service, providers ); + public int hashCode() { + return Objects.hash(service, providers); } - + @Override - public boolean equals( Object obj ) - { - if ( this == obj ) - { + public boolean equals(Object obj) { + if (this == obj) { return true; } - if ( obj == null ) - { + if (obj == null) { return false; } - if ( getClass() != obj.getClass() ) - { + if (getClass() != obj.getClass()) { return false; } - + JavaProvides other = (JavaProvides) obj; - if ( !Objects.equals( service, other.service ) ) - { - return false; + if (!Objects.equals(service, other.service)) { + return false; } - if ( !Objects.equals( providers, other.providers ) ) - { - return false; + if (!Objects.equals(providers, other.providers)) { + return false; } return true; } @Override public String toString() { - return "JavaProvides{" + - "service='" + service + '\'' + - ", providers=" + providers + - '}'; + return "JavaProvides{" + "service='" + service + '\'' + ", providers=" + providers + '}'; } } } diff --git a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/LocationManager.java b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/LocationManager.java index 2a01618..2c866cf 100644 --- a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/LocationManager.java +++ b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/LocationManager.java @@ -1,7 +1,5 @@ package org.codehaus.plexus.languages.java.jpms; -import java.io.File; - /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -21,6 +19,10 @@ * under the License. */ +import javax.inject.Named; +import javax.inject.Singleton; + +import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -33,33 +35,27 @@ import java.util.Map.Entry; import java.util.Set; -import javax.inject.Named; -import javax.inject.Singleton; - import org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaProvides; /** * Maps artifacts to modules and analyzes the type of required modules - * + * * @author Robert Scholte * @since 1.0.0 */ @Named @Singleton -public class LocationManager -{ +public class LocationManager { private SourceModuleInfoParser sourceParser; private ManifestModuleNameExtractor manifestModuleNameExtractor; - - public LocationManager() - { + + public LocationManager() { this.sourceParser = new SourceModuleInfoParser(); this.manifestModuleNameExtractor = new ManifestModuleNameExtractor(); } - - LocationManager( SourceModuleInfoParser sourceParser ) - { + + LocationManager(SourceModuleInfoParser sourceParser) { this.sourceParser = sourceParser; this.manifestModuleNameExtractor = new ManifestModuleNameExtractor(); } @@ -69,230 +65,209 @@ public LocationManager() * @return the parsed module descriptor * @throws IOException when descriptorPath could not be read */ - public ResolvePathResult parseModuleDescriptor( Path descriptorPath ) throws IOException - { + public ResolvePathResult parseModuleDescriptor(Path descriptorPath) throws IOException { JavaModuleDescriptor moduleDescriptor; - if ( descriptorPath.endsWith( "module-info.java" ) ) - { - moduleDescriptor = sourceParser.fromSourcePath( descriptorPath ); + if (descriptorPath.endsWith("module-info.java")) { + moduleDescriptor = sourceParser.fromSourcePath(descriptorPath); + } else { + throw new IOException("Invalid path to module descriptor: " + descriptorPath); } - else - { - throw new IOException( "Invalid path to module descriptor: " + descriptorPath ); - } - return new ResolvePathResult().setModuleDescriptor( moduleDescriptor) - .setModuleNameSource( ModuleNameSource.MODULEDESCRIPTOR ); + return new ResolvePathResult() + .setModuleDescriptor(moduleDescriptor) + .setModuleNameSource(ModuleNameSource.MODULEDESCRIPTOR); } - + /** * @param descriptorPath never {@code null} * @return the parsed module descriptor * @throws IOException when descriptorPath could not be read */ - public ResolvePathResult parseModuleDescriptor( File descriptorPath ) throws IOException - { - return parseModuleDescriptor( descriptorPath.toPath() ); + public ResolvePathResult parseModuleDescriptor(File descriptorPath) throws IOException { + return parseModuleDescriptor(descriptorPath.toPath()); } - + /** * @param descriptorPath never {@code null} * @return the parsed module descriptor * @throws IOException when descriptorPath could not be read */ - public ResolvePathResult parseModuleDescriptor( String descriptorPath ) throws IOException - { - return parseModuleDescriptor( Paths.get( descriptorPath ) ); + public ResolvePathResult parseModuleDescriptor(String descriptorPath) throws IOException { + return parseModuleDescriptor(Paths.get(descriptorPath)); } - + /** * Resolve a single jar - * + * * @param request the request * @return the {@link ResolvePathResult}, containing the name and optional module descriptor * @throws IOException if any occurs */ - public ResolvePathResult resolvePath( final ResolvePathRequest request ) throws IOException - { - ModuleNameExtractor filenameExtractor = new ModuleNameExtractor() - { - MainClassModuleNameExtractor extractor = new MainClassModuleNameExtractor( request.getJdkHome() ); - + public ResolvePathResult resolvePath(final ResolvePathRequest request) throws IOException { + ModuleNameExtractor filenameExtractor = new ModuleNameExtractor() { + MainClassModuleNameExtractor extractor = new MainClassModuleNameExtractor(request.getJdkHome()); + @Override - public String extract( Path file ) - throws IOException - { - if ( request.getJdkHome() != null ) - { - return extractor.extract( Collections.singletonMap( file, file ) ).get( file ); - } - else - { - return CmdModuleNameExtractor.getModuleName( file ); + public String extract(Path file) throws IOException { + if (request.getJdkHome() != null) { + return extractor + .extract(Collections.singletonMap(file, file)) + .get(file); + } else { + return CmdModuleNameExtractor.getModuleName(file); } } }; - - return resolvePath( request.toPath( request.getPathElement() ), filenameExtractor, getBinaryModuleInfoParser( request.getJdkHome() ) ); + + return resolvePath( + request.toPath(request.getPathElement()), + filenameExtractor, + getBinaryModuleInfoParser(request.getJdkHome())); } - + /** * Decide for every {@code request.getPathElements()} if it belongs to the modulePath or classPath, based on the * {@code request.getMainModuleDescriptor()}. - * + * * @param request the paths to resolve * @return the result of the resolution * @throws IOException if a critical IOException occurs */ - public ResolvePathsResult resolvePaths( final ResolvePathsRequest request ) - throws IOException - { + public ResolvePathsResult resolvePaths(final ResolvePathsRequest request) throws IOException { final ResolvePathsResult result = request.createResult(); - - Map pathElements = new LinkedHashMap<>( request.getPathElements().size() ); - final ModuleInfoParser binaryParser = getBinaryModuleInfoParser( request.getJdkHome() ); + Map pathElements = + new LinkedHashMap<>(request.getPathElements().size()); - JavaModuleDescriptor mainModuleDescriptor = getMainModuleDescriptor( request, binaryParser ); + final ModuleInfoParser binaryParser = getBinaryModuleInfoParser(request.getJdkHome()); - result.setMainModuleDescriptor( mainModuleDescriptor ); + JavaModuleDescriptor mainModuleDescriptor = getMainModuleDescriptor(request, binaryParser); + + result.setMainModuleDescriptor(mainModuleDescriptor); // key = service, value = names of modules that provide this service Map> availableProviders = new HashMap<>(); - if( mainModuleDescriptor != null && request.isIncludeAllProviders() ) - { - collectProviders( mainModuleDescriptor, availableProviders ); + if (mainModuleDescriptor != null && request.isIncludeAllProviders()) { + collectProviders(mainModuleDescriptor, availableProviders); } Map availableNamedModules = new HashMap<>(); - + Map moduleNameSources = new HashMap<>(); - + final Map filenameAutoModules = new HashMap<>(); - + // collect all modules from path - for ( final T t : request.getPathElements() ) - { + for (final T t : request.getPathElements()) { JavaModuleDescriptor moduleDescriptor; ModuleNameSource source; - - ModuleNameExtractor nameExtractor = new ModuleNameExtractor() - { - @Override - public String extract( Path path ) - throws IOException - { - if ( request.getJdkHome() != null ) - { - filenameAutoModules.put( t, path ); - } - else - { - return CmdModuleNameExtractor.getModuleName( path ); - } - return null; + + ModuleNameExtractor nameExtractor = path -> { + if (request.getJdkHome() != null) { + filenameAutoModules.put(t, path); + } else { + return CmdModuleNameExtractor.getModuleName(path); } + return null; }; - - try - { - ResolvePathResult resolvedPath = resolvePath( request.toPath( t ), nameExtractor, binaryParser ); - + + try { + ResolvePathResult resolvedPath = resolvePath(request.toPath(t), nameExtractor, binaryParser); + moduleDescriptor = resolvedPath.getModuleDescriptor(); source = resolvedPath.getModuleNameSource(); - } - catch ( Exception e ) - { - result.getPathExceptions().put( t, e ); + } catch (Exception e) { + result.getPathExceptions().put(t, e); - pathElements.put( t, null ); + pathElements.put(t, null); continue; } - - // Consider strategies how to handle duplicate modules by name - // For now, just ignore it - if ( moduleDescriptor != null && moduleNameSources.putIfAbsent( moduleDescriptor.name(), source ) == null ) - { - availableNamedModules.put( moduleDescriptor.name(), moduleDescriptor ); - - if ( request.isIncludeAllProviders() ) - { - collectProviders( moduleDescriptor, availableProviders ); + + // in case of identical module names, first one wins + if (moduleDescriptor != null && moduleNameSources.putIfAbsent(moduleDescriptor.name(), source) == null) { + availableNamedModules.put(moduleDescriptor.name(), moduleDescriptor); + + if (request.isIncludeAllProviders()) { + collectProviders(moduleDescriptor, availableProviders); } } - - pathElements.put( t, moduleDescriptor ); - + + pathElements.put(t, moduleDescriptor); } - result.setPathElements( pathElements ); - - if ( !filenameAutoModules.isEmpty() ) - { - MainClassModuleNameExtractor extractor = new MainClassModuleNameExtractor( request.getJdkHome() ); - - Map automodules = extractor.extract( filenameAutoModules ); - - for ( Map.Entry entry : automodules.entrySet() ) - { + result.setPathElements(pathElements); + + if (!filenameAutoModules.isEmpty()) { + MainClassModuleNameExtractor extractor = new MainClassModuleNameExtractor(request.getJdkHome()); + + Map automodules = extractor.extract(filenameAutoModules); + + for (Map.Entry entry : automodules.entrySet()) { String moduleName = entry.getValue(); - - if ( moduleName != null ) - { - JavaModuleDescriptor moduleDescriptor = JavaModuleDescriptor.newAutomaticModule( moduleName ).build(); - - moduleNameSources.put( moduleDescriptor.name(), ModuleNameSource.FILENAME ); - - availableNamedModules.put( moduleDescriptor.name(), moduleDescriptor ); - - pathElements.put( entry.getKey(), moduleDescriptor ); + + if (moduleName != null) { + JavaModuleDescriptor moduleDescriptor = + JavaModuleDescriptor.newAutomaticModule(moduleName).build(); + + moduleNameSources.put(moduleDescriptor.name(), ModuleNameSource.FILENAME); + + availableNamedModules.put(moduleDescriptor.name(), moduleDescriptor); + + pathElements.put(entry.getKey(), moduleDescriptor); } } } - + Set requiredNamedModules = new HashSet<>(); - if ( mainModuleDescriptor != null ) - { - requiredNamedModules.add( mainModuleDescriptor.name() ); - - selectRequires( mainModuleDescriptor, - Collections.unmodifiableMap( availableNamedModules ), - Collections.unmodifiableMap( availableProviders ), - requiredNamedModules, - true, - true, - request.isIncludeStatic()); + if (mainModuleDescriptor != null) { + requiredNamedModules.add(mainModuleDescriptor.name()); + + selectRequires( + mainModuleDescriptor, + Collections.unmodifiableMap(availableNamedModules), + Collections.unmodifiableMap(availableProviders), + requiredNamedModules, + true, + true, + request.isIncludeStatic()); } - - for ( String additionalModule : request.getAdditionalModules() ) - { - selectModule( additionalModule, - Collections.unmodifiableMap( availableNamedModules ), - Collections.unmodifiableMap( availableProviders ), - requiredNamedModules, - true, - true, - request.isIncludeStatic()); + + for (String additionalModule : request.getAdditionalModules()) { + selectModule( + additionalModule, + Collections.unmodifiableMap(availableNamedModules), + Collections.unmodifiableMap(availableProviders), + requiredNamedModules, + true, + true, + request.isIncludeStatic()); } - // in case of identical module names, first one wins - Set collectedModules = new HashSet<>( requiredNamedModules.size() ); - - for ( Entry entry : pathElements.entrySet() ) - { - if ( entry.getValue() != null && requiredNamedModules.contains( entry.getValue().name() ) ) - { - if ( collectedModules.add( entry.getValue().name() ) ) - { - result.getModulepathElements().put( entry.getKey(), - moduleNameSources.get( entry.getValue().name() ) ); + Set collectedModules = new HashSet<>(requiredNamedModules.size()); + + for (Entry entry : pathElements.entrySet()) { + if (entry.getValue() != null + && requiredNamedModules.contains(entry.getValue().name())) { + // Consider strategies how to handle duplicate modules by name + // For now only add first on modulePath, just ignore others, + // This has effectively the same result as putting it on the modulePath, but might better help + // analyzing issues. + if (collectedModules.add(entry.getValue().name())) { + result.getModulepathElements() + .put( + entry.getKey(), + moduleNameSources.get(entry.getValue().name())); + } else { + result.getPathExceptions() + .put( + entry.getKey(), + new IllegalStateException( + "Module '" + entry.getValue().name() + "' is already on the module path!")); } - } - else - { - result.getClasspathElements().add( entry.getKey() ); + } else { + result.getClasspathElements().add(entry.getKey()); } } @@ -302,170 +277,157 @@ public String extract( Path path ) /** * If the jdkHome is specified, its version it considered higher than the runtime java version. * In that case ASM must be used to read the module descriptor - * + * * @param jdkHome * @return */ - ModuleInfoParser getBinaryModuleInfoParser( final Path jdkHome ) - { + ModuleInfoParser getBinaryModuleInfoParser(final Path jdkHome) { final ModuleInfoParser binaryParser; - if ( jdkHome == null ) - { + if (jdkHome == null) { binaryParser = new BinaryModuleInfoParser(); - } - else - { + } else { binaryParser = new AsmModuleInfoParser(); } return binaryParser; } - private JavaModuleDescriptor getMainModuleDescriptor( final ResolvePathsRequest request, ModuleInfoParser binaryParser ) - throws IOException - { + private JavaModuleDescriptor getMainModuleDescriptor( + final ResolvePathsRequest request, ModuleInfoParser binaryParser) throws IOException { JavaModuleDescriptor mainModuleDescriptor; - + Path descriptorPath = request.getMainModuleDescriptor(); - - if ( descriptorPath != null ) - { - if ( descriptorPath.endsWith( "module-info.java" ) ) - { - mainModuleDescriptor = sourceParser.fromSourcePath( descriptorPath ); - } - else if ( descriptorPath.endsWith( "module-info.class" ) ) - { - mainModuleDescriptor = binaryParser.getModuleDescriptor( descriptorPath.getParent() ); - } - else - { - throw new IOException( "Invalid path to module descriptor: " + descriptorPath ); + + if (descriptorPath != null) { + if (descriptorPath.endsWith("module-info.java")) { + mainModuleDescriptor = sourceParser.fromSourcePath(descriptorPath); + } else if (descriptorPath.endsWith("module-info.class")) { + mainModuleDescriptor = binaryParser.getModuleDescriptor(descriptorPath.getParent()); + } else { + throw new IOException("Invalid path to module descriptor: " + descriptorPath); } - } - else - { + } else { mainModuleDescriptor = request.getModuleDescriptor(); } return mainModuleDescriptor; } - private ResolvePathResult resolvePath( Path path, ModuleNameExtractor fileModulenameExtractor, ModuleInfoParser binaryParser ) throws IOException - { + private ResolvePathResult resolvePath( + Path path, ModuleNameExtractor fileModulenameExtractor, ModuleInfoParser binaryParser) throws IOException { ResolvePathResult result = new ResolvePathResult(); JavaModuleDescriptor moduleDescriptor = null; - + // either jar or outputDirectory - if ( Files.isRegularFile( path ) && !path.getFileName().toString().endsWith( ".jar" ) ) - { - throw new IllegalArgumentException( "'" + path.toString() + "' not allowed on the path, only outputDirectories and jars are accepted" ); - } - - if ( Files.isRegularFile( path ) || Files.exists( path.resolve( "module-info.class" ) ) ) - { - moduleDescriptor = binaryParser.getModuleDescriptor( path ); + if (Files.isRegularFile(path) && !path.getFileName().toString().endsWith(".jar")) { + throw new IllegalArgumentException( + "'" + path + "' not allowed on the path, only outputDirectories and jars are accepted"); } - if ( moduleDescriptor != null ) - { - result.setModuleNameSource( ModuleNameSource.MODULEDESCRIPTOR ); + if (Files.isRegularFile(path) || Files.exists(path.resolve("module-info.class"))) { + moduleDescriptor = binaryParser.getModuleDescriptor(path); } - else - { - String moduleName = manifestModuleNameExtractor.extract( path ); - if ( moduleName != null ) - { - result.setModuleNameSource( ModuleNameSource.MANIFEST ); - } - else - { - moduleName = fileModulenameExtractor.extract( path ); - - if ( moduleName != null ) - { - result.setModuleNameSource( ModuleNameSource.FILENAME ); + if (moduleDescriptor != null) { + result.setModuleNameSource(ModuleNameSource.MODULEDESCRIPTOR); + } else { + String moduleName = manifestModuleNameExtractor.extract(path); + + if (moduleName != null) { + result.setModuleNameSource(ModuleNameSource.MANIFEST); + } else { + moduleName = fileModulenameExtractor.extract(path); + + if (moduleName != null) { + result.setModuleNameSource(ModuleNameSource.FILENAME); } } - if ( moduleName != null ) - { - moduleDescriptor = JavaModuleDescriptor.newAutomaticModule( moduleName ).build(); + if (moduleName != null) { + moduleDescriptor = + JavaModuleDescriptor.newAutomaticModule(moduleName).build(); } } - result.setModuleDescriptor( moduleDescriptor ); + result.setModuleDescriptor(moduleDescriptor); return result; } - - private void selectRequires( JavaModuleDescriptor module, - Map availableModules, - Map> availableProviders, - Set namedModules, - boolean isRootModule, - boolean includeAsTransitive, - boolean includeStatic) - { - for ( JavaModuleDescriptor.JavaRequires requires : module.requires() ) - { + + private void selectRequires( + JavaModuleDescriptor module, + Map availableModules, + Map> availableProviders, + Set namedModules, + boolean isRootModule, + boolean includeAsTransitive, + boolean includeStatic) { + for (JavaModuleDescriptor.JavaRequires requires : module.requires()) { // includeTransitive is one level deeper compared to includeStatic - if ( isRootModule - || includeStatic - || includeAsTransitive - || !requires.modifiers().contains( JavaModuleDescriptor.JavaRequires.JavaModifier.STATIC ) - || requires.modifiers().contains( JavaModuleDescriptor.JavaRequires.JavaModifier.TRANSITIVE ) ) - { - selectModule( requires.name(), availableModules, availableProviders, - namedModules, false, includeStatic, includeStatic ); + if (isRootModule + || includeStatic + || includeAsTransitive + || !requires.modifiers().contains(JavaModuleDescriptor.JavaRequires.JavaModifier.STATIC) + || requires.modifiers().contains(JavaModuleDescriptor.JavaRequires.JavaModifier.TRANSITIVE)) { + selectModule( + requires.name(), + availableModules, + availableProviders, + namedModules, + false, + includeStatic, + includeStatic); } } - - for ( String uses : module.uses() ) - { - if ( availableProviders.containsKey( uses ) ) - { - for ( String providerModule : availableProviders.get( uses ) ) - { - JavaModuleDescriptor requiredModule = availableModules.get( providerModule ); - - if ( requiredModule != null && namedModules.add( providerModule ) ) - { - selectRequires( requiredModule, availableModules, availableProviders, - namedModules, false, includeAsTransitive, includeStatic ); + + for (String uses : module.uses()) { + if (availableProviders.containsKey(uses)) { + for (String providerModule : availableProviders.get(uses)) { + JavaModuleDescriptor requiredModule = availableModules.get(providerModule); + + if (requiredModule != null && namedModules.add(providerModule)) { + selectRequires( + requiredModule, + availableModules, + availableProviders, + namedModules, + false, + includeAsTransitive, + includeStatic); } } } - } + } } - private void selectModule( String module, Map availableModules, Map> availableProviders, - Set namedModules, boolean isRootModule, boolean includeTransitive, boolean includeStatic ) - { - JavaModuleDescriptor requiredModule = availableModules.get( module ); - - if ( requiredModule != null && namedModules.add( module ) ) - { - selectRequires( requiredModule, availableModules, availableProviders, - namedModules, false, includeTransitive, includeStatic ); + private void selectModule( + String module, + Map availableModules, + Map> availableProviders, + Set namedModules, + boolean isRootModule, + boolean includeTransitive, + boolean includeStatic) { + JavaModuleDescriptor requiredModule = availableModules.get(module); + + if (requiredModule != null && namedModules.add(module)) { + selectRequires( + requiredModule, + availableModules, + availableProviders, + namedModules, + false, + includeTransitive, + includeStatic); } } - - private void collectProviders( JavaModuleDescriptor moduleDescriptor, Map> availableProviders ) - { - for ( JavaProvides provides : moduleDescriptor.provides() ) - { - // module-info.class uses FQN, i.e. $-separator for subclasses - final String serviceClassName = provides.service().replace( '$', '.' ); - - Set providingModules = availableProviders.get( serviceClassName ); - - if ( providingModules == null ) - { - providingModules = new HashSet<>(); - - availableProviders.put( serviceClassName, providingModules ); - } - providingModules.add( moduleDescriptor.name() ); + + private void collectProviders(JavaModuleDescriptor moduleDescriptor, Map> availableProviders) { + for (JavaProvides provides : moduleDescriptor.provides()) { + // module-info.class uses FQN, i.e. $-separator for subclasses + final String serviceClassName = provides.service().replace('$', '.'); + + Set providingModules = availableProviders.computeIfAbsent(serviceClassName, k -> new HashSet<>()); + + providingModules.add(moduleDescriptor.name()); } } } diff --git a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/MainClassModuleNameExtractor.java b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/MainClassModuleNameExtractor.java index 1357c03..1b0d4d0 100644 --- a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/MainClassModuleNameExtractor.java +++ b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/MainClassModuleNameExtractor.java @@ -35,102 +35,87 @@ /** * Extract the module name by calling the main method with an external JVM - * + * * @author Robert Scholte * @since 1.0.0 */ -public class MainClassModuleNameExtractor -{ +public class MainClassModuleNameExtractor { private final Path jdkHome; - public MainClassModuleNameExtractor( Path jdkHome ) - { + public MainClassModuleNameExtractor(Path jdkHome) { this.jdkHome = jdkHome; } - public Map extract( Map files ) - throws IOException - { - Path workDir = Files.createTempDirectory( "plexus-java_jpms-" ); - - String classResourcePath = CmdModuleNameExtractor.class.getName().replace( '.', '/' ) + ".class"; + public Map extract(Map files) throws IOException { + Path workDir = Files.createTempDirectory("plexus-java_jpms-"); + + String classResourcePath = CmdModuleNameExtractor.class.getName().replace('.', '/') + ".class"; try (InputStream is = - MainClassModuleNameExtractor.class.getResourceAsStream( "/META-INF/versions/9/" + classResourcePath )) - { - if ( is==null ) - { + MainClassModuleNameExtractor.class.getResourceAsStream("/META-INF/versions/9/" + classResourcePath)) { + if (is == null) { return Collections.emptyMap(); } - Path target = workDir.resolve( classResourcePath ); + Path target = workDir.resolve(classResourcePath); - Files.createDirectories( target.getParent() ); + Files.createDirectories(target.getParent()); - Files.copy( is, target ); + Files.copy(is, target); } - try (BufferedWriter argsWriter = Files.newBufferedWriter( workDir.resolve( "args" ), Charset.defaultCharset() )) - { - argsWriter.append( "--class-path" ); + try (BufferedWriter argsWriter = Files.newBufferedWriter(workDir.resolve("args"), Charset.defaultCharset())) { + argsWriter.append("--class-path"); argsWriter.newLine(); - argsWriter.append( "." ); + argsWriter.append("."); argsWriter.newLine(); - argsWriter.append( CmdModuleNameExtractor.class.getName() ); + argsWriter.append(CmdModuleNameExtractor.class.getName()); argsWriter.newLine(); - for ( Path p : files.values() ) - { + for (Path p : files.values()) { // make sure the path is surrounded with quotes in case there is space - argsWriter.append( '"' ); + argsWriter.append('"'); // make sure to escape Windows paths - argsWriter.append( p.toAbsolutePath().toString().replace( "\\", "\\\\" ) ); - argsWriter.append( '"' ); + argsWriter.append(p.toAbsolutePath().toString().replace("\\", "\\\\")); + argsWriter.append('"'); argsWriter.newLine(); } } - ProcessBuilder builder = new ProcessBuilder( jdkHome.resolve( "bin/java" ).toAbsolutePath().toString(), - "@args" ).directory( workDir.toFile() ); + ProcessBuilder builder = new ProcessBuilder( + jdkHome.resolve("bin/java").toAbsolutePath().toString(), "@args") + .directory(workDir.toFile()); Process p = builder.start(); Properties output = new Properties(); - try (InputStream is = p.getInputStream()) - { - output.load( is ); + try (InputStream is = p.getInputStream()) { + output.load(is); } - Map moduleNames = new HashMap<>( files.size() ); - for ( Map.Entry entry : files.entrySet() ) - { - moduleNames.put( entry.getKey(), output.getProperty( entry.getValue().toAbsolutePath().toString(), null ) ); + Map moduleNames = new HashMap<>(files.size()); + for (Map.Entry entry : files.entrySet()) { + moduleNames.put( + entry.getKey(), + output.getProperty(entry.getValue().toAbsolutePath().toString(), null)); } - try - { - Files.walkFileTree( workDir, new SimpleFileVisitor() - { + try { + Files.walkFileTree(workDir, new SimpleFileVisitor() { @Override - public FileVisitResult visitFile( Path file, BasicFileAttributes attrs ) - throws IOException - { - Files.delete( file ); + public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { + Files.delete(file); return FileVisitResult.CONTINUE; } @Override - public FileVisitResult postVisitDirectory( Path dir, IOException exc ) - throws IOException - { - Files.delete( dir ); + public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { + Files.delete(dir); return FileVisitResult.CONTINUE; } - } ); - } - catch ( IOException e ) - { + }); + } catch (IOException e) { // noop, we did our best to clean it up } diff --git a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ManifestModuleNameExtractor.java b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ManifestModuleNameExtractor.java index 16d0984..4c1fc90 100644 --- a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ManifestModuleNameExtractor.java +++ b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ManifestModuleNameExtractor.java @@ -19,61 +19,45 @@ * under the License. */ -import java.io.File; -import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.file.Files; import java.nio.file.Path; import java.util.jar.JarFile; import java.util.jar.Manifest; /** * Extracts the name of the module by reading the Automatic-Module-Name attribute of the manifest file - * + * * @author Robert Scholte * @since 1.0.0 */ -class ManifestModuleNameExtractor implements ModuleNameExtractor -{ +class ManifestModuleNameExtractor implements ModuleNameExtractor { @Override - public String extract( Path file ) - throws IOException - { - Manifest manifest = extractManifest( file.toFile() ); - + public String extract(Path file) throws IOException { + Manifest manifest = extractManifest(file); + String automaticModuleName; - if ( manifest != null ) - { - automaticModuleName = manifest.getMainAttributes().getValue( "Automatic-Module-Name" ); - } - else - { + if (manifest != null) { + automaticModuleName = manifest.getMainAttributes().getValue("Automatic-Module-Name"); + } else { automaticModuleName = null; } return automaticModuleName; } - - private Manifest extractManifest( File file ) - throws IOException - { + + private Manifest extractManifest(Path file) throws IOException { Manifest manifest; - if ( file.isFile() ) - { - try ( JarFile jarFile = new JarFile( file ) ) - { + if (Files.isRegularFile(file)) { + try (JarFile jarFile = new JarFile(file.toFile())) { manifest = jarFile.getManifest(); } - } - else if ( new File( file, "META-INF/MANIFEST.MF" ).exists() ) - { - try ( InputStream is = new FileInputStream( new File( file, "META-INF/MANIFEST.MF" ) ) ) - { - manifest = new Manifest( is ); + } else if (Files.exists(file.resolve("META-INF/MANIFEST.MF"))) { + try (InputStream is = Files.newInputStream(file.resolve("META-INF/MANIFEST.MF"))) { + manifest = new Manifest(is); } - } - else - { + } else { manifest = null; } diff --git a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ModuleInfoParser.java b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ModuleInfoParser.java index f0ed02e..5967ac8 100644 --- a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ModuleInfoParser.java +++ b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ModuleInfoParser.java @@ -26,29 +26,27 @@ /** * Extract information from the module-info file - * + * * @author Robert Scholte * @since 1.0.0 */ -interface ModuleInfoParser -{ +interface ModuleInfoParser { /** * Extracts the name from the module-info file - * + * * @param modulePath the path to the {@code module-info.class} * @return the module descriptor * @throws IOException when the file could not be parsed */ - JavaModuleDescriptor getModuleDescriptor( Path modulePath ) throws IOException; - + JavaModuleDescriptor getModuleDescriptor(Path modulePath) throws IOException; + /** * Extracts the name from the module-info file - * + * * @param modulePath the path to the {@code module-info.class} * @param javaVersion the java version in case of a multirelease jar * @return the module descriptor * @throws IOException when the file could not be parsed */ - JavaModuleDescriptor getModuleDescriptor( Path modulePath, JavaVersion javaVersion ) - throws IOException; -} \ No newline at end of file + JavaModuleDescriptor getModuleDescriptor(Path modulePath, JavaVersion javaVersion) throws IOException; +} diff --git a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ModuleNameExtractor.java b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ModuleNameExtractor.java index 541f8c3..dc3327e 100644 --- a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ModuleNameExtractor.java +++ b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ModuleNameExtractor.java @@ -22,7 +22,6 @@ import java.io.IOException; import java.nio.file.Path; -interface ModuleNameExtractor -{ - String extract( Path path ) throws IOException; +interface ModuleNameExtractor { + String extract(Path path) throws IOException; } diff --git a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ModuleNameSource.java b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ModuleNameSource.java index 0112299..c674b40 100644 --- a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ModuleNameSource.java +++ b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ModuleNameSource.java @@ -19,7 +19,8 @@ * under the License. */ -public enum ModuleNameSource -{ - FILENAME, MANIFEST, MODULEDESCRIPTOR +public enum ModuleNameSource { + FILENAME, + MANIFEST, + MODULEDESCRIPTOR } diff --git a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ResolvePathRequest.java b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ResolvePathRequest.java index 5e0674a..afd321f 100644 --- a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ResolvePathRequest.java +++ b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ResolvePathRequest.java @@ -24,83 +24,68 @@ import java.nio.file.Paths; /** - * + * * @author Robert Scholte * @since 1.0.0 */ -public abstract class ResolvePathRequest -{ +public abstract class ResolvePathRequest { private Path jdkHome; - + private T path; - - private ResolvePathRequest() - { - } - - public static ResolvePathRequest ofFile( File file ) - { - ResolvePathRequest request = new ResolvePathRequest() - { + + private ResolvePathRequest() {} + + public static ResolvePathRequest ofFile(File file) { + ResolvePathRequest request = new ResolvePathRequest() { @Override - protected Path toPath( File f ) - { + protected Path toPath(File f) { return f.toPath(); } }; request.path = file; return request; } - - public static ResolvePathRequest ofPath( Path path ) - { - ResolvePathRequest request = new ResolvePathRequest() - { + + public static ResolvePathRequest ofPath(Path path) { + ResolvePathRequest request = new ResolvePathRequest() { @Override - protected Path toPath( Path p ) - { + protected Path toPath(Path p) { return p; } }; request.path = path; return request; } - - public static ResolvePathRequest ofString( String string ) - { - ResolvePathRequest request = new ResolvePathRequest() - { + + public static ResolvePathRequest ofString(String string) { + ResolvePathRequest request = new ResolvePathRequest() { @Override - protected Path toPath( String s ) - { - return Paths.get( s ); + protected Path toPath(String s) { + return Paths.get(s); } }; request.path = string; return request; } - protected abstract Path toPath( T t ); - - public T getPathElement() - { + protected abstract Path toPath(T t); + + public T getPathElement() { return path; } - + /** * In case the JRE is Java 8 or before, this jdkHome is used to extract the module name. - * + * * @param jdkHome * @return this request */ - public ResolvePathRequest setJdkHome( T jdkHome ) - { - this.jdkHome = toPath( jdkHome ); + public ResolvePathRequest setJdkHome(T jdkHome) { + this.jdkHome = toPath(jdkHome); return this; } - public Path getJdkHome() - { + public Path getJdkHome() { return jdkHome; } } diff --git a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ResolvePathResult.java b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ResolvePathResult.java index 5651337..b312f9e 100644 --- a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ResolvePathResult.java +++ b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ResolvePathResult.java @@ -21,39 +21,32 @@ /** * Holds the results of the location manager - * + * * @author Robert Scholte * @since 1.0.0 */ -public class ResolvePathResult -{ +public class ResolvePathResult { private JavaModuleDescriptor moduleDescriptor; - + private ModuleNameSource moduleNameSource; - - ResolvePathResult() - { - } - ResolvePathResult setModuleDescriptor( JavaModuleDescriptor moduleDescriptor ) - { + ResolvePathResult() {} + + ResolvePathResult setModuleDescriptor(JavaModuleDescriptor moduleDescriptor) { this.moduleDescriptor = moduleDescriptor; return this; } - - public JavaModuleDescriptor getModuleDescriptor() - { + + public JavaModuleDescriptor getModuleDescriptor() { return moduleDescriptor; } - - ResolvePathResult setModuleNameSource( ModuleNameSource moduleNameSource ) - { + + ResolvePathResult setModuleNameSource(ModuleNameSource moduleNameSource) { this.moduleNameSource = moduleNameSource; return this; } - - public ModuleNameSource getModuleNameSource() - { + + public ModuleNameSource getModuleNameSource() { return moduleNameSource; } } diff --git a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ResolvePathsRequest.java b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ResolvePathsRequest.java index 66ad59f..60b9f78 100644 --- a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ResolvePathsRequest.java +++ b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ResolvePathsRequest.java @@ -28,12 +28,11 @@ /** * Contains all information required to analyze the project - * + * * @author Robert Scholte * @since 1.0.0 */ -public abstract class ResolvePathsRequest -{ +public abstract class ResolvePathsRequest { private Path jdkHome; private Path mainModuleDescriptor; @@ -41,38 +40,31 @@ public abstract class ResolvePathsRequest private Collection pathElements; private Collection additionalModules; - + private boolean includeAllProviders; private JavaModuleDescriptor resolvedMainModuleDescriptor; private boolean includeStatic; - private ResolvePathsRequest() - { - } + private ResolvePathsRequest() {} /** * @deprecated use {@link #ofFiles(Collection)} instead */ @Deprecated - public static ResolvePathsRequest withFiles( Collection files ) - { - return ofFiles( files ); + public static ResolvePathsRequest withFiles(Collection files) { + return ofFiles(files); } - - public static ResolvePathsRequest ofFiles( File... files ) - { - return ofFiles( Arrays.asList( files ) ); + + public static ResolvePathsRequest ofFiles(File... files) { + return ofFiles(Arrays.asList(files)); } - - public static ResolvePathsRequest ofFiles( Collection files ) - { - ResolvePathsRequest request = new ResolvePathsRequest() - { + + public static ResolvePathsRequest ofFiles(Collection files) { + ResolvePathsRequest request = new ResolvePathsRequest() { @Override - protected Path toPath( File t ) - { + protected Path toPath(File t) { return t.toPath(); } }; @@ -85,22 +77,18 @@ protected Path toPath( File t ) * @deprecated use {@link #ofPaths(Collection)} instead */ @Deprecated - public static ResolvePathsRequest withPaths( Collection paths ) - { - return ofPaths( paths ); + public static ResolvePathsRequest withPaths(Collection paths) { + return ofPaths(paths); } - - public static ResolvePathsRequest ofPaths( Path... paths ) - { - return ofPaths( Arrays.asList( paths ) ); + + public static ResolvePathsRequest ofPaths(Path... paths) { + return ofPaths(Arrays.asList(paths)); } - - public static ResolvePathsRequest ofPaths( Collection paths ) - { + + public static ResolvePathsRequest ofPaths(Collection paths) { ResolvePathsRequest request = new ResolvePathsRequest() { @Override - protected Path toPath( Path t ) - { + protected Path toPath(Path t) { return t; } }; @@ -112,126 +100,110 @@ protected Path toPath( Path t ) * @deprecated use {@link #ofStrings(Collection)} instead */ @Deprecated - public static ResolvePathsRequest withStrings( Collection strings ) - { - return ofStrings( strings ); + public static ResolvePathsRequest withStrings(Collection strings) { + return ofStrings(strings); } - - public static ResolvePathsRequest ofStrings( String... strings ) - { - return ofStrings( Arrays.asList( strings ) ); + + public static ResolvePathsRequest ofStrings(String... strings) { + return ofStrings(Arrays.asList(strings)); } - - public static ResolvePathsRequest ofStrings( Collection strings ) - { + + public static ResolvePathsRequest ofStrings(Collection strings) { ResolvePathsRequest request = new ResolvePathsRequest() { @Override - protected Path toPath( String t ) - { - return Paths.get( t ); + protected Path toPath(String t) { + return Paths.get(t); } }; request.pathElements = strings; return request; } - protected abstract Path toPath( T t ); + protected abstract Path toPath(T t); final ResolvePathsResult createResult() { return new ResolvePathsResult<>(); } - public Path getMainModuleDescriptor() - { + public Path getMainModuleDescriptor() { return mainModuleDescriptor; } - public JavaModuleDescriptor getModuleDescriptor() - { + public JavaModuleDescriptor getModuleDescriptor() { return resolvedMainModuleDescriptor; } - + /** - * Must be either {@code module-info.java} or {@code module-info.class} - * + * Must be either {@code module-info.java} or {@code module-info.class} + * * @param mainModuleDescriptor * @return this request */ - public ResolvePathsRequest setMainModuleDescriptor( T mainModuleDescriptor ) - { - this.mainModuleDescriptor = toPath( mainModuleDescriptor ); + public ResolvePathsRequest setMainModuleDescriptor(T mainModuleDescriptor) { + this.mainModuleDescriptor = toPath(mainModuleDescriptor); return this; } /*** * Provide a resolved module descriptor - * + * * @param mainModuleDescriptor * @return this request */ - public ResolvePathsRequest setModuleDescriptor( JavaModuleDescriptor mainModuleDescriptor ) - { + public ResolvePathsRequest setModuleDescriptor(JavaModuleDescriptor mainModuleDescriptor) { this.resolvedMainModuleDescriptor = mainModuleDescriptor; return this; } - public Collection getPathElements() - { + public Collection getPathElements() { return pathElements; } /** * In case the JRE is Java 8 or before, this jdkHome is used to extract the module name. - * + * * @param jdkHome * @return this request */ - public ResolvePathsRequest setJdkHome( T jdkHome ) - { - this.jdkHome = toPath( jdkHome ); + public ResolvePathsRequest setJdkHome(T jdkHome) { + this.jdkHome = toPath(jdkHome); return this; } - public Path getJdkHome() - { + public Path getJdkHome() { return jdkHome; } /** * The module names that are usually passed with {@code --add-modules} - * + * * @param additionalModules * @return this request */ - public ResolvePathsRequest setAdditionalModules( Collection additionalModules ) - { + public ResolvePathsRequest setAdditionalModules(Collection additionalModules) { this.additionalModules = additionalModules; return this; } - public Collection getAdditionalModules() - { - if ( additionalModules == null ) - { + public Collection getAdditionalModules() { + if (additionalModules == null) { additionalModules = Collections.emptyList(); } return additionalModules; } - + /** * Will also include all modules that contain providers for used services, should only be used at runtime (not during compile nor test) - * + * * @param includeAllProviders * @return this request */ - public ResolvePathsRequest setIncludeAllProviders( boolean includeAllProviders ) - { + public ResolvePathsRequest setIncludeAllProviders(boolean includeAllProviders) { this.includeAllProviders = includeAllProviders; return this; } - - public boolean isIncludeAllProviders() - { + + public boolean isIncludeAllProviders() { return includeAllProviders; } @@ -240,8 +212,7 @@ public boolean isIncludeAllProviders() * @return true if the result will include all static dependencies * @since 1.0.5 */ - public boolean isIncludeStatic() - { + public boolean isIncludeStatic() { return includeStatic; } @@ -251,8 +222,7 @@ public boolean isIncludeStatic() * @return this request * @since 1.0.5 */ - public ResolvePathsRequest setIncludeStatic( boolean includeStatic ) - { + public ResolvePathsRequest setIncludeStatic(boolean includeStatic) { this.includeStatic = includeStatic; return this; } diff --git a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ResolvePathsResult.java b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ResolvePathsResult.java index a5fc834..753c4be 100644 --- a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ResolvePathsResult.java +++ b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/ResolvePathsResult.java @@ -27,110 +27,98 @@ /** * Holds the results of the project analyzer - * + * * @author Robert Scholte * @since 1.0.0 */ -public class ResolvePathsResult -{ +public class ResolvePathsResult { private JavaModuleDescriptor mainModuleDescriptor; - + /** * Ordered map, respects the classpath order */ private Map pathElements; - + private Map modulepathElements = new LinkedHashMap<>(); - + private Collection classpathElements = new ArrayList<>(); - + private Map pathExceptions = new HashMap<>(); - void setMainModuleDescriptor( JavaModuleDescriptor mainModuleDescriptor ) - { + void setMainModuleDescriptor(JavaModuleDescriptor mainModuleDescriptor) { this.mainModuleDescriptor = mainModuleDescriptor; } /** - * The resolved main module descriptor - * - * @return the resolved descriptor + * The resolved main module descriptor + * + * @return the resolved descriptor * @see ResolvePathsRequest#setMainModuleDescriptor(Object) */ - public JavaModuleDescriptor getMainModuleDescriptor() - { + public JavaModuleDescriptor getMainModuleDescriptor() { return mainModuleDescriptor; } - void setPathElements( Map pathElements ) - { + void setPathElements(Map pathElements) { this.pathElements = pathElements; } - + /** * Ordered map, respects the classpath order */ - public Map getPathElements() - { + public Map getPathElements() { return pathElements; } - - void setClasspathElements( Collection classpathElements ) - { + + void setClasspathElements(Collection classpathElements) { this.classpathElements = classpathElements; } - + /** * All T that belong to the classpath based on the module descriptor - * + * * @return the classpath elements, never {@code null} * @see #getPathElements() */ - public Collection getClasspathElements() - { + public Collection getClasspathElements() { return classpathElements; } - - void setModulepathElements( Map modulepathElements ) - { + + void setModulepathElements(Map modulepathElements) { this.modulepathElements = modulepathElements; } - + /** * All T that belong to the modulepath, based on the module descriptor. - * For every T the source for the module name is added. - * - * @return all modulepath elements, never {@code null} + * For every T the source for the module name is added. + * + * @return all modulepath elements, never {@code null} * @see #getPathElements() */ - public Map getModulepathElements() - { + public Map getModulepathElements() { return modulepathElements; } - void setPathExceptions( Map pathExceptions ) - { + void setPathExceptions(Map pathExceptions) { this.pathExceptions = pathExceptions; } /** * Map containing exceptions for every T which modulename resolution failed - * + * * @return the exceptions for every T, never {@code null} */ - public Map getPathExceptions() - { + public Map getPathExceptions() { return pathExceptions; } @Override public String toString() { - return "ResolvePathsResult{" + System.lineSeparator() + - "mainModuleDescriptor=" + mainModuleDescriptor + System.lineSeparator() + - ", pathElements=" + pathElements + System.lineSeparator() + - ", modulepathElements=" + modulepathElements + System.lineSeparator() + - ", classpathElements=" + classpathElements + System.lineSeparator() + - ", pathExceptions=" + pathExceptions + System.lineSeparator() + - '}'; + return "ResolvePathsResult{" + System.lineSeparator() + "mainModuleDescriptor=" + + mainModuleDescriptor + System.lineSeparator() + ", pathElements=" + + pathElements + System.lineSeparator() + ", modulepathElements=" + + modulepathElements + System.lineSeparator() + ", classpathElements=" + + classpathElements + System.lineSeparator() + ", pathExceptions=" + + pathExceptions + System.lineSeparator() + '}'; } } diff --git a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/SourceModuleInfoParser.java b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/SourceModuleInfoParser.java index 40258f7..b484919 100644 --- a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/SourceModuleInfoParser.java +++ b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/SourceModuleInfoParser.java @@ -34,86 +34,72 @@ /** * Extract information from module with QDox - * + * * @author Robert Scholte * @since 1.0.0 */ -class SourceModuleInfoParser -{ +class SourceModuleInfoParser { - public org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor fromSourcePath( Path modulePath ) - throws IOException - { + public org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor fromSourcePath(Path modulePath) + throws IOException { File moduleDescriptor = modulePath.toFile(); org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.Builder builder; - if ( moduleDescriptor.exists() ) - { - JavaModuleDescriptor descriptor = new JavaProjectBuilder().addSourceFolder( moduleDescriptor.getParentFile() ).getDescriptor(); + if (moduleDescriptor.exists()) { + JavaModuleDescriptor descriptor = new JavaProjectBuilder() + .addSourceFolder(moduleDescriptor.getParentFile()) + .getDescriptor(); + + builder = org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.newModule(descriptor.getName()); - builder = org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.newModule( descriptor.getName() ); - - for ( JavaModuleDescriptor.JavaRequires requires : descriptor.getRequires() ) - { - if ( requires.isStatic() || requires.isTransitive() ) - { - Set modifiers = - new LinkedHashSet<>( 2 ); - if ( requires.isStatic() ) - { - modifiers.add( org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaRequires.JavaModifier.STATIC ); + for (JavaModuleDescriptor.JavaRequires requires : descriptor.getRequires()) { + if (requires.isStatic() || requires.isTransitive()) { + Set + modifiers = new LinkedHashSet<>(2); + if (requires.isStatic()) { + modifiers.add( + org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaRequires.JavaModifier + .STATIC); } - if ( requires.isTransitive() ) - { - modifiers.add( org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaRequires.JavaModifier.TRANSITIVE ); + if (requires.isTransitive()) { + modifiers.add( + org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaRequires.JavaModifier + .TRANSITIVE); } - builder.requires( modifiers , requires.getModule().getName() ); - } - else - { - builder.requires( requires.getModule().getName() ); + builder.requires(modifiers, requires.getModule().getName()); + } else { + builder.requires(requires.getModule().getName()); } } - - for ( JavaModuleDescriptor.JavaExports exports : descriptor.getExports() ) - { - if ( exports.getTargets().isEmpty() ) - { - builder.exports( exports.getSource().getName() ); - } - else - { + + for (JavaModuleDescriptor.JavaExports exports : descriptor.getExports()) { + if (exports.getTargets().isEmpty()) { + builder.exports(exports.getSource().getName()); + } else { Set targets = new LinkedHashSet<>(); - for ( JavaModule module : exports.getTargets() ) - { - targets.add( module.getName() ); + for (JavaModule module : exports.getTargets()) { + targets.add(module.getName()); } - builder.exports( exports.getSource().getName(), targets ); + builder.exports(exports.getSource().getName(), targets); } } - - for ( JavaModuleDescriptor.JavaUses uses : descriptor.getUses() ) - { - builder.uses( uses.getService().getName() ); + + for (JavaModuleDescriptor.JavaUses uses : descriptor.getUses()) { + builder.uses(uses.getService().getName()); } - - for ( JavaModuleDescriptor.JavaProvides provides : descriptor.getProvides() ) - { - List providers = new ArrayList<>( provides.getProviders().size() ); - for ( JavaClass provider : provides.getProviders() ) - { - providers.add( provider.getName() ); + + for (JavaModuleDescriptor.JavaProvides provides : descriptor.getProvides()) { + List providers = new ArrayList<>(provides.getProviders().size()); + for (JavaClass provider : provides.getProviders()) { + providers.add(provider.getName()); } - - builder.provides( provides.getService().getName(), providers ); + + builder.provides(provides.getService().getName(), providers); } - } - else - { - builder = org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.newAutomaticModule( null ); + } else { + builder = org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.newAutomaticModule(null); } return builder.build(); } - } diff --git a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/package-info.java b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/package-info.java index accd0eb..eb2ed35 100644 --- a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/package-info.java +++ b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/jpms/package-info.java @@ -17,4 +17,4 @@ * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. - */ \ No newline at end of file + */ diff --git a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/version/JavaClassfileVersion.java b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/version/JavaClassfileVersion.java new file mode 100644 index 0000000..d380a01 --- /dev/null +++ b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/version/JavaClassfileVersion.java @@ -0,0 +1,152 @@ +package org.codehaus.plexus.languages.java.version; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Path; + +/* + * 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. + */ + +/** + * Reads the bytecode of a Java class to detect the major, minor and Java + * version that was compiled. + * + * @author Jorge Solórzano + */ +public final class JavaClassfileVersion { + + private final int major; + private final int minor; + + JavaClassfileVersion(int major, int minor) { + if (major < 45) { + throw new IllegalArgumentException("Java class major version must be 45 or above."); + } + this.major = major; + this.minor = minor; + } + + /** + * Reads the bytecode of a Java class file and returns the + * {@link JavaClassfileVersion}. + * + * @param bytes {@code byte[]} of the Java class file + * @return the {@link JavaClassfileVersion} of the byte array + */ + public static JavaClassfileVersion of(byte[] bytes) { + return JavaClassfileVersionParser.of(bytes); + } + + /** + * Reads the bytecode of a Java class file and returns the + * {@link JavaClassfileVersion}. + * + * @param path {@link Path} of the Java class file + * @return the {@link JavaClassfileVersion} of the path java class + */ + public static JavaClassfileVersion of(Path path) { + try (InputStream is = Files.newInputStream(path)) { + byte[] bytes = new byte[8]; + int total = 0; + while (total < 8) { + int l = is.read(bytes, total, 8 - total); + if (l > 0) { + total += l; + } + if (l == -1) { + break; + } + } + return of(bytes); + } catch (IOException ex) { + throw new UncheckedIOException(ex); + } + } + + /** + * JavaVersion of the class file version detected. + * + * @return JavaVersion based on the major version of the class file. + */ + public JavaVersion javaVersion() { + int javaVer = major - 44; + String javaVersion = javaVer < 9 ? "1." + javaVer : Integer.toString(javaVer); + + return JavaVersion.parse(javaVersion); + } + + /** + * Returns the major version of the parsed classfile. + * + * @return the major classfile version + */ + public int majorVersion() { + return major; + } + + /** + * Returns the minor version of the parsed classfile. + * + * @return the minor classfile version + */ + public int minorVersion() { + return minor; + } + + /** + * Returns if the classfile use preview features. + * + * @return {@code true} if the classfile use preview features. + */ + public boolean isPreview() { + return minor == 65535; + } + + /** + * Returns a String representation of the Java class file version, e.g. + * {@code 65.0 (Java 21)}. + * + * @return String representation of the Java class file version + */ + @Override + public String toString() { + return major + "." + minor + " (Java " + javaVersion() + ")"; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + major; + result = prime * result + minor; + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (!(obj instanceof JavaClassfileVersion)) return false; + JavaClassfileVersion other = (JavaClassfileVersion) obj; + if (major != other.major) return false; + if (minor != other.minor) return false; + return true; + } +} diff --git a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/version/JavaClassfileVersionParser.java b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/version/JavaClassfileVersionParser.java new file mode 100644 index 0000000..a994180 --- /dev/null +++ b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/version/JavaClassfileVersionParser.java @@ -0,0 +1,55 @@ +package org.codehaus.plexus.languages.java.version; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.io.UncheckedIOException; + +/* + * 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. + */ + +/** + * This class is intented to be package-private and consumed by + * {@link JavaClassfileVersion}. + * + * @author Jorge Solórzano + */ +final class JavaClassfileVersionParser { + + private JavaClassfileVersionParser() {} + + /** + * Reads the bytecode of a Java class file and returns the {@link JavaClassfileVersion}. + * + * @param in {@code byte[]} of the Java class file + * @return the {@link JavaClassfileVersion} of the input stream + */ + public static JavaClassfileVersion of(byte[] bytes) { + try (final DataInputStream data = new DataInputStream(new ByteArrayInputStream(bytes))) { + if (0xCAFEBABE != data.readInt()) { + throw new IOException("Invalid java class file header"); + } + int minor = data.readUnsignedShort(); + int major = data.readUnsignedShort(); + return new JavaClassfileVersion(major, minor); + } catch (IOException ex) { + throw new UncheckedIOException(ex); + } + } +} diff --git a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/version/JavaVersion.java b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/version/JavaVersion.java index f39d840..245527e 100644 --- a/plexus-java/src/main/java/org/codehaus/plexus/languages/java/version/JavaVersion.java +++ b/plexus-java/src/main/java/org/codehaus/plexus/languages/java/version/JavaVersion.java @@ -27,191 +27,164 @@ /** * @author Robert Scholte * @since 1.0.0 - * + * * @see Java SE Naming and Versions * @see JEP 223: New Version-String Scheme * @see JEP 322: Time-Based Release Versioning */ -public class JavaVersion implements Comparable -{ +public class JavaVersion implements Comparable { /** * Represents the System property {@code java.specification.version} */ - public static final JavaVersion JAVA_SPECIFICATION_VERSION = parse( System.getProperty( "java.specification.version" ) ); + public static final JavaVersion JAVA_SPECIFICATION_VERSION = + parse(System.getProperty("java.specification.version")); /** * Represents the System property {@code java.version} */ - public static final JavaVersion JAVA_VERSION = parse( System.getProperty( "java.version" ) ); - - private static final Pattern startingDigits = Pattern.compile( "(\\d+)(.*)" ); - + public static final JavaVersion JAVA_VERSION = parse(System.getProperty("java.version")); + + private static final Pattern startingDigits = Pattern.compile("(\\d+)(.*)"); + private final String rawVersion; - - private final boolean isMajor; - private JavaVersion( String rawVersion, boolean isMajor ) - { + private final boolean isMajor; + + private JavaVersion(String rawVersion, boolean isMajor) { this.rawVersion = rawVersion; this.isMajor = isMajor; } /** * Lazy parse the version-scheme. - * Actual parsing is done when calling {@link #compareTo(JavaVersion)} - * + * Actual parsing is done when calling {@link #compareTo(JavaVersion)} + * * @param s the version string, never {@code null} - * @return the version wrapped in a JavadocVersion + * @return the version wrapped in a JavaVersion */ - public static JavaVersion parse( String s ) - { - return new JavaVersion( s, !s.startsWith( "1." ) ); + public static JavaVersion parse(String s) { + return new JavaVersion(s, !s.startsWith("1.")); } @Override - public int compareTo( JavaVersion other ) - { - String[] thisSegments = this.rawVersion.split( "\\." ); - String[] otherSegments = other.rawVersion.split( "\\." ); - - int minSegments = Math.min( thisSegments.length, otherSegments.length ); - - for ( int index = 0; index < minSegments; index++ ) - { - Matcher thisMatcher = startingDigits.matcher( thisSegments[index] ); - + public int compareTo(JavaVersion other) { + String[] thisSegments = this.rawVersion.split("\\."); + String[] otherSegments = other.rawVersion.split("\\."); + + int minSegments = Math.min(thisSegments.length, otherSegments.length); + + for (int index = 0; index < minSegments; index++) { + Matcher thisMatcher = startingDigits.matcher(thisSegments[index]); + int thisValue; - - if( thisMatcher.find() ) - { - thisValue = Integer.parseInt( thisMatcher.group( 1 ) ); - } - else - { + + if (thisMatcher.find()) { + thisValue = Integer.parseInt(thisMatcher.group(1)); + } else { thisValue = -1; } - - Matcher otherMatcher = startingDigits.matcher( otherSegments[index] ); - + + Matcher otherMatcher = startingDigits.matcher(otherSegments[index]); + int otherValue; - - if( otherMatcher.find() ) - { - otherValue = Integer.parseInt( otherMatcher.group( 1 ) ); - } - else - { + + if (otherMatcher.find()) { + otherValue = Integer.parseInt(otherMatcher.group(1)); + } else { otherValue = -1; } - - int compareValue = Integer.compare( thisValue, otherValue ); - - if ( compareValue != 0 ) - { + + int compareValue = Integer.compare(thisValue, otherValue); + + if (compareValue != 0) { return compareValue; } - compareValue = suffixRate( thisMatcher.group( 2 ) ) - suffixRate( otherMatcher.group( 2 ) ); - if ( compareValue != 0 ) - { + compareValue = suffixRate(thisMatcher.group(2)) - suffixRate(otherMatcher.group(2)); + if (compareValue != 0) { return compareValue; } - + // works for now, but needs improvement - compareValue = thisMatcher.group( 2 ).compareTo( otherMatcher.group( 2 ) ); - - if ( compareValue != 0 ) - { + compareValue = thisMatcher.group(2).compareTo(otherMatcher.group(2)); + + if (compareValue != 0) { return compareValue; } } - - return ( thisSegments.length - otherSegments.length ); + + return (thisSegments.length - otherSegments.length); } - - private int suffixRate( String suffix ) { - if ( "-ea".equals( suffix ) ) - { + + private int suffixRate(String suffix) { + if ("-ea".equals(suffix)) { return -100; - } - else if ( "".equals( suffix ) ) - { + } else if ("".equals(suffix)) { return 0; - } - else - { + } else { return 10; } } /** * Verify if this version is before some other version - * + * * @param other the version to compare with * @return {@code true} is this is less than {@code other}, otherwise {@code false} */ - public boolean isBefore( JavaVersion other ) - { - return this.compareTo( other ) < 0; + public boolean isBefore(JavaVersion other) { + return this.compareTo(other) < 0; } /** * Verify if this version is before some other version - * + * * @param other the version to compare with * @return {@code true} is this is less than {@code other}, otherwise {@code false} */ - public boolean isBefore( String other ) - { - return this.compareTo( parse( other ) ) < 0; + public boolean isBefore(String other) { + return this.compareTo(parse(other)) < 0; } /** * Verify if this version is at least some other version - * + * * @param other the version to compare with * @return {@code true} is this is greater than or equal to {@code other}, otherwise {@code false} */ - public boolean isAtLeast( JavaVersion other ) - { - return this.compareTo( other ) >= 0; + public boolean isAtLeast(JavaVersion other) { + return this.compareTo(other) >= 0; } /** * Verify if this version is at least some other version - * + * * @param other the version to compare with * @return {@code true} is this is greater than or equal to {@code other}, otherwise {@code false} */ - public boolean isAtLeast( String other ) - { - return this.compareTo( parse( other ) ) >= 0; + public boolean isAtLeast(String other) { + return this.compareTo(parse(other)) >= 0; } - + /** * If original version starts with {@code "1."}, then remove this part from the version - * + * * @return a new JavaVersion if version has to be changed, otherwise return itself */ - public JavaVersion asMajor() - { - if ( !isMajor ) - { - return new JavaVersion( rawVersion.substring( 2 ), true ); - } - else - { + public JavaVersion asMajor() { + if (!isMajor) { + return new JavaVersion(rawVersion.substring(2), true); + } else { return this; } } - + /** * Returns the original version - * + * * @return the raw version */ - public String getValue() - { + public String getValue() { return rawVersion; } @@ -219,90 +192,72 @@ public String getValue() * Returns a value respecting the nuber of groups.
* If the original has more groups, the end of that value will be removed.
* If the original has less groups, the value will be extended this ".0".
- * + * *
-     *   JavaVersion.parse( "1" ).getValue( 1 )   is "1" 
-     *   JavaVersion.parse( "1" ).getValue( 2 )   is "1.0" 
-     *   JavaVersion.parse( "2.1" ).getValue( 1 ) is "2" 
-     *   JavaVersion.parse( "2.1" ).getValue( 2 ) is "2.1" 
+     *   JavaVersion.parse( "1" ).getValue( 1 )   is "1"
+     *   JavaVersion.parse( "1" ).getValue( 2 )   is "1.0"
+     *   JavaVersion.parse( "2.1" ).getValue( 1 ) is "2"
+     *   JavaVersion.parse( "2.1" ).getValue( 2 ) is "2.1"
      * 
- * + * * @param groups number of groups to return * @return the version respecting the number of groups */ - public String getValue( int groups ) - { + public String getValue(int groups) { StringBuilder value = new StringBuilder(); - StringTokenizer tokenizer = new StringTokenizer( rawVersion, "." ); - - value.append( tokenizer.nextToken() ); - for ( int group = 1 ; group < groups ; group++ ) - { - value.append( '.' ); - if( tokenizer.hasMoreTokens() ) - { - value.append( tokenizer.nextToken() ); - } - else - { - value.append( "0" ); + StringTokenizer tokenizer = new StringTokenizer(rawVersion, "."); + + value.append(tokenizer.nextToken()); + for (int group = 1; group < groups; group++) { + value.append('.'); + if (tokenizer.hasMoreTokens()) { + value.append(tokenizer.nextToken()); + } else { + value.append("0"); } } return value.toString(); } @Override - public String toString() - { + public String toString() { return rawVersion; } @Override - public int hashCode() - { - return Objects.hashCode( rawVersion ); + public int hashCode() { + return Objects.hashCode(rawVersion); } @Override - public boolean equals( Object obj ) - { - if ( this == obj ) - { + public boolean equals(Object obj) { + if (this == obj) { return true; } - if ( obj == null ) - { + if (obj == null) { return false; } - if ( getClass() != obj.getClass() ) - { + if (getClass() != obj.getClass()) { return false; } - + JavaVersion other = (JavaVersion) obj; - if ( isMajor != other.isMajor ) - { + if (isMajor != other.isMajor) { final String thisOneDotVersion; final String otherOneDotVersion; - if ( isMajor ) - { + if (isMajor) { thisOneDotVersion = "1." + rawVersion; otherOneDotVersion = other.rawVersion; - } - else - { + } else { thisOneDotVersion = rawVersion; otherOneDotVersion = "1." + other.rawVersion; } - - if ( !Objects.equals( thisOneDotVersion, otherOneDotVersion ) ) - { - return false; - } - } - else if ( !Objects.equals( rawVersion, other.rawVersion ) ) - { + + if (!Objects.equals(thisOneDotVersion, otherOneDotVersion)) { return false; + } + } else if (!Objects.equals(rawVersion, other.rawVersion)) { + return false; } return true; } diff --git a/plexus-java/src/main/java9/module-info.java b/plexus-java/src/main/java9/module-info.java index 9b83831..c09093b 100644 --- a/plexus-java/src/main/java9/module-info.java +++ b/plexus-java/src/main/java9/module-info.java @@ -16,13 +16,13 @@ * specific language governing permissions and limitations * under the License. */ -module org.codehaus.plexus.languages.java -{ +module org.codehaus.plexus.languages.java { requires com.thoughtworks.qdox; requires org.objectweb.asm; - + exports org.codehaus.plexus.languages.java.jpms; exports org.codehaus.plexus.languages.java.version; - - provides org.codehaus.plexus.languages.java.jpms.LocationManager with org.codehaus.plexus.languages.java.jpms.LocationManager; -} \ No newline at end of file + + provides org.codehaus.plexus.languages.java.jpms.LocationManager with + org.codehaus.plexus.languages.java.jpms.LocationManager; +} diff --git a/plexus-java/src/main/java9/org/codehaus/plexus/languages/java/jpms/BinaryModuleInfoParser.java b/plexus-java/src/main/java9/org/codehaus/plexus/languages/java/jpms/BinaryModuleInfoParser.java index 6bab93e..a2f3af1 100644 --- a/plexus-java/src/main/java9/org/codehaus/plexus/languages/java/jpms/BinaryModuleInfoParser.java +++ b/plexus-java/src/main/java9/org/codehaus/plexus/languages/java/jpms/BinaryModuleInfoParser.java @@ -21,68 +21,55 @@ import java.io.IOException; import java.io.InputStream; - import java.lang.module.ModuleDescriptor; -import java.util.Collections; import java.util.LinkedHashSet; import java.util.Set; import org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.Builder; -class BinaryModuleInfoParser extends AbstractBinaryModuleInfoParser -{ +class BinaryModuleInfoParser extends AbstractBinaryModuleInfoParser { @Override - JavaModuleDescriptor parse( InputStream in ) throws IOException - { - ModuleDescriptor descriptor = ModuleDescriptor.read( in ); - - Builder builder = JavaModuleDescriptor.newModule( descriptor.name() ); - - for ( ModuleDescriptor.Requires requires : descriptor.requires() ) - { - if ( requires.modifiers().contains( ModuleDescriptor.Requires.Modifier.STATIC ) - || requires.modifiers().contains( ModuleDescriptor.Requires.Modifier.TRANSITIVE ) ) - { + JavaModuleDescriptor parse(InputStream in) throws IOException { + ModuleDescriptor descriptor = ModuleDescriptor.read(in); + + Builder builder = JavaModuleDescriptor.newModule(descriptor.name()); + + for (ModuleDescriptor.Requires requires : descriptor.requires()) { + if (requires.modifiers().contains(ModuleDescriptor.Requires.Modifier.STATIC) + || requires.modifiers().contains(ModuleDescriptor.Requires.Modifier.TRANSITIVE)) { Set modifiers = new LinkedHashSet<>(); - if ( requires.modifiers().contains( ModuleDescriptor.Requires.Modifier.STATIC ) ) - { - modifiers.add( org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaRequires.JavaModifier.STATIC ); + if (requires.modifiers().contains(ModuleDescriptor.Requires.Modifier.STATIC)) { + modifiers.add( + org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaRequires.JavaModifier + .STATIC); } - if ( requires.modifiers().contains( ModuleDescriptor.Requires.Modifier.TRANSITIVE ) ) - { - modifiers.add( org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaRequires.JavaModifier.TRANSITIVE ); + if (requires.modifiers().contains(ModuleDescriptor.Requires.Modifier.TRANSITIVE)) { + modifiers.add( + org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaRequires.JavaModifier + .TRANSITIVE); } - builder.requires( modifiers, requires.name() ); - } - else - { - builder.requires( requires.name() ); + builder.requires(modifiers, requires.name()); + } else { + builder.requires(requires.name()); } } - - for ( ModuleDescriptor.Exports exports : descriptor.exports() ) - { - if ( exports.targets().isEmpty() ) - { - builder.exports( exports.source() ); - } - else - { - builder.exports( exports.source(), exports.targets() ); + + for (ModuleDescriptor.Exports exports : descriptor.exports()) { + if (exports.targets().isEmpty()) { + builder.exports(exports.source()); + } else { + builder.exports(exports.source(), exports.targets()); } } - - for ( String uses : descriptor.uses() ) - { - builder.uses( uses ); + + for (String uses : descriptor.uses()) { + builder.uses(uses); } - - for ( ModuleDescriptor.Provides provides : descriptor.provides() ) - { - builder.provides( provides.service(), provides.providers() ); + + for (ModuleDescriptor.Provides provides : descriptor.provides()) { + builder.provides(provides.service(), provides.providers()); } - - + return builder.build(); } } diff --git a/plexus-java/src/main/java9/org/codehaus/plexus/languages/java/jpms/CmdModuleNameExtractor.java b/plexus-java/src/main/java9/org/codehaus/plexus/languages/java/jpms/CmdModuleNameExtractor.java index 2c7a090..5f684a4 100644 --- a/plexus-java/src/main/java9/org/codehaus/plexus/languages/java/jpms/CmdModuleNameExtractor.java +++ b/plexus-java/src/main/java9/org/codehaus/plexus/languages/java/jpms/CmdModuleNameExtractor.java @@ -41,54 +41,43 @@ *

* The result is a properties-file written ot the StdOut, having the jar path as key and the module name as value.
* Any exception is written to the StdErr. - *

- * + *

+ * * @author Robert Scholte * @since 1.0.0 */ -public class CmdModuleNameExtractor -{ - public static void main( String[] args ) - { +public class CmdModuleNameExtractor { + public static void main(String[] args) { Properties properties = new Properties(); - for ( String path : args ) - { - try - { - String moduleName = getModuleName( Paths.get( path ) ); - if ( moduleName != null ) - { - properties.setProperty( path, moduleName ); + for (String path : args) { + try { + String moduleName = getModuleName(Paths.get(path)); + if (moduleName != null) { + properties.setProperty(path, moduleName); } - } - catch ( Exception e ) - { - System.err.append( e.getMessage() ); + } catch (Exception e) { + System.err.append(e.getMessage()); } } - try - { - properties.store( System.out, "" ); - } - catch ( IOException e ) - { - System.exit( 1 ); + try { + properties.store(System.out, ""); + } catch (IOException e) { + System.exit(1); } } /** * Get the name of the module, using Java 9 code without reflection - * + * * @param modulePath the module path * @return the module name * @throws FindException If an error occurs finding the module */ - public static String getModuleName( Path modulePath ) throws FindException - { - Set moduleReferences = ModuleFinder.of( modulePath ).findAll(); - + public static String getModuleName(Path modulePath) throws FindException { + Set moduleReferences = ModuleFinder.of(modulePath).findAll(); + Optional modRef = moduleReferences.stream().findFirst(); return modRef.isPresent() ? modRef.get().descriptor().name() : null; diff --git a/plexus-java/src/site/markdown/locationmanager.md b/plexus-java/src/site/markdown/locationmanager.md index 61be07a..1e03c94 100644 --- a/plexus-java/src/site/markdown/locationmanager.md +++ b/plexus-java/src/site/markdown/locationmanager.md @@ -1,12 +1,12 @@ The plexus-java library is created to have a solution for common activities, so this business logic doesn't have to be maintained at multiple places. The first provided feature was the `LocationManager` to analyze module desciptors and to decide which jars should end up on the modulepath and which on the classpath. The name was based on the [javax.tools.JavaFileManager.Location]. (https://docs.oracle.com/javase/10/docs/api/javax/tools/JavaFileManager.Location.html) -The library requires Java 8 to run, but contains optimized code for Java 9. By requiring Java 8 it was much easier to embed this library in several other projects. +The library requires Java 8 to run, but contains optimized code for Java 9. By requiring Java 8 it was much easier to embed this library in several other projects. This jar is a multi release jar (aka MRJAR), because it contains 2 implementations for the `BinaryModuleInfoParser`. If the Java runtime is 9 or above, the `java.lang.module.ModuleDescriptor` is used to read the `module-info.class`. If the runtime is Java 8, then ASM is used to read the module descriptor. When extracting the the automatic module name based the of the file, it is a little bit more complex. The result must be precise, so the only way to solve this is by calling Java 9 code, either from the runtime or by calling Java 9 explicitly when provided via `ResolvePathsRequest.setJdkHome`. -## Request +# Request The `LocationManager.resolvePaths()` only has one argument, `ResolvePathsRequest`. If there is more data required, the request will be extended so the method signature of `resolvePaths` will stay the same. @@ -18,28 +18,28 @@ There are 3 ways to create a `ResolvePathsRequest`: - `ResolvePathsRequest.ofStrings(Collection)` -As argument you pass all the archives and/or outputDirectories specified to build the project. +As argument you pass all the archives and/or outputDirectories specified to build the project. Additional methods are: - `setAdditionalModules`, in case the consumer wants to use `--add-modules` -- `setIncludeAllProviders`, in general would only be used at runtime, not during compile or test. In case `uses` is used, all modules with matching `provides` are added as well. +- `setIncludeAllProviders`, in general would only be used at runtime, not during compile or test. In case `uses` is used, all modules with matching `provides` are added as well. - `setJdkHome`, should point to Java 9 or above in case the runtime of this library is Java 8 - `setMainModuleDescriptor`, which can either be a `module-info.java` or `module-info.class` -## Phase 1: Collect +# Phase 1: Collect If there's a `mainModuleDescriptor`, extract a `JavaModuleDescriptor` of it. This might cause a `IOException` to be thrown. All pathElements of `ResolvePathsRequest.ofT` are transformed to Path instances. For every element the name will be resolved in the following order: 1. Module descriptor: verify if the jar or the directory contains `module-info.class`. If so, the its descriptor is transformed to a `JavaModuleDescriptor`, where its ModuleNameSource is marked as `ModuleNameSource.MODULEDESCRIPTOR` - -2. Manifest: verify if the jar or directory has a `META-INF/MANIFEST.MF` and if it contains the `Automatic-Module-Name` attribute. If so, an automatic `JavaModuleDescriptor` is created, where its ModuleNameSource is marked as `ModuleNameSource.MANIFEST`. - + +2. Manifest: verify if the jar or directory has a `META-INF/MANIFEST.MF` and if it contains the `Automatic-Module-Name` attribute. If so, an automatic `JavaModuleDescriptor` is created, where its ModuleNameSource is marked as `ModuleNameSource.MANIFEST`. + 3. Filename: try to extract the module name based on the filename. If the filename could be transformed to a module name (which is not always the case), an automatic `JavaModuleDescriptor` is created, where its ModuleNameSource is marked as `ModuleNameSource.FILENAME`. When there's an `IOException` with one of the pathElements, the exception is stored in the `ResolvePathsResult.pathExceptions` so the consumer can handle them separately. @@ -48,15 +48,16 @@ The result are a couple of Maps: * module name to `ModuleNameSource` -* module name to `JavaModuleDescriptor` +* module name to `JavaModuleDescriptor` -## Phase 2: Resolve +# Phase 2: Resolve If there's a `mainModuleDescriptor`, collect all its direct and indirect requirements. This contains recursive code and ensures that required modules are only evaluated once. All these pathElements must be placed on the modulepath, all other pathElements will be marked for the classPath. -## Result +# Result + All results will be stored in a `ResolvePathsResult`. - `getClasspathElements()`, ordered collection of all pathElements that don't belong to the modulepath @@ -68,3 +69,4 @@ All results will be stored in a `ResolvePathsResult`. - `getPathElements()`, ordered map of the pathElements with their module descriptor - `getPathExceptions()`, map of pathElements containing only the elements that faced an exception. + diff --git a/plexus-java/src/site/markdown/usage.md b/plexus-java/src/site/markdown/usage.md index 0912d30..1e8891d 100644 --- a/plexus-java/src/site/markdown/usage.md +++ b/plexus-java/src/site/markdown/usage.md @@ -1,5 +1,4 @@ - -## LocationManager.resolvePaths +# LocationManager.resolvePaths In order to use this class you must setup a `ResolvePathsRequest`, which requires a list of all the jars and output directories and the main module descriptor. @@ -7,34 +6,34 @@ You start by using `ResolvePathsRequest.ofXXX`, where XXX is either Files, Paths The `ResolvePathRequest` also contains: - * mainModuleDescriptor: the path or file of the main module descriptor, can either be `mdouel-info.java` or `module-info.class` - - * additionalModules: the modules that will be addedusing `-add-modules` - - * jdkHome: in case you need to use a different JDK to extract the name from the modules. Can be interesting if the runtime is still Java 7. +* mainModuleDescriptor: the path or file of the main module descriptor, can either be `module-info.java` or `module-info.class` + +* additionalModules: the modules that will be addedusing `-add-modules` + +* jdkHome: in case you need to use a different JDK to extract the name from the modules. Can be interesting if the runtime is still Java 7. The `ResolvePathsResult` contains: - * mainModuleDescriptor: the module descriptor of the passed descriptor file. - - * pathElements: as a map in the same order as provided by the request. Every entry has a matching moduledescriptor when available. - - * classpathElements: all the pathElements which should end up on the classpath. - - * modulepathElements: all the pathElements which should end up on the modulepath. Per entry you get the source of the modulename which is either the moduledescriptor, the manifestfile of the filename. This information can be used to warn users in case they use automatic modules, which module names are not reliable yet. - - * pathExceptions: pathElements with their exception while trying to resolve it. Only pathElements with an exception are listed. - -## JavaVersion +* mainModuleDescriptor: the module descriptor of the passed descriptor file. + +* pathElements: as a map in the same order as provided by the request. Every entry has a matching moduledescriptor when available. + +* classpathElements: all the pathElements which should end up on the classpath. + +* modulepathElements: all the pathElements which should end up on the modulepath. Per entry you get the source of the modulename which is either the moduledescriptor, the manifestfile of the filename. This information can be used to warn users in case they use automatic modules, which module names are not reliable yet. + +* pathExceptions: pathElements with their exception while trying to resolve it. Only pathElements with an exception are listed. + +# JavaVersion This is a String based, lazy-parsing implementation of a Java Version which can be used to compare versions. It's goal is to support to support the following patterns: - * [Java SE Naming and Versions](http://www.oracle.com/technetwork/java/javase/namechange-140185.html) - * [JEP 223: New Version-String Scheme](http://openjdk.java.net/jeps/223) - * [JEP 322: Time-Based Release Versioning](http://openjdk.java.net/jeps/322) +* [JEP 223: New Version-String Scheme](https://openjdk.java.net/jeps/223) +* [JEP 322: Time-Based Release Versioning](https://openjdk.java.net/jeps/322) Additional features: - * `JavaVersion.JAVA_SPECIFICATION_VERSION` represents `System.getProperty( "java.specification.version" )` - - * `JavaVersion.JAVA_VERSION` represents `System.getProperty( "java.version" )` \ No newline at end of file +* `JavaVersion.JAVA_SPECIFICATION_VERSION` represents `System.getProperty( "java.specification.version" )` + +* `JavaVersion.JAVA_VERSION` represents `System.getProperty( "java.version" )` + diff --git a/plexus-java/src/site/site.xml b/plexus-java/src/site/site.xml index c5b6dd7..b8b7da8 100644 --- a/plexus-java/src/site/site.xml +++ b/plexus-java/src/site/site.xml @@ -19,19 +19,18 @@ specific language governing permissions and limitations under the License. --> - + + - - \ No newline at end of file + diff --git a/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/AbstractFilenameModuleNameExtractorTest.java b/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/AbstractFilenameModuleNameExtractorTest.java index 96e0307..356cb11 100644 --- a/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/AbstractFilenameModuleNameExtractorTest.java +++ b/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/AbstractFilenameModuleNameExtractorTest.java @@ -19,52 +19,39 @@ * under the License. */ -import static org.hamcrest.CoreMatchers.not; -import static org.hamcrest.CoreMatchers.startsWith; -import static org.junit.Assert.assertEquals; -import static org.junit.Assume.assumeThat; - import java.nio.file.Paths; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; -public abstract class AbstractFilenameModuleNameExtractorTest -{ +public abstract class AbstractFilenameModuleNameExtractorTest { protected abstract ModuleNameExtractor getExtractor(); - @BeforeClass - public static void assume() - { - assumeThat( "Requires at least Java 9", System.getProperty( "java.version" ), not( startsWith( "1." ) ) ); - } - @Test - public void testJarWithoutManifest() throws Exception - { - String name = getExtractor().extract( Paths.get( "src/test/resources/jar.empty/plexus-java-1.0.0-SNAPSHOT.jar" ) ); - assertEquals( "plexus.java", name ); + void testJarWithoutManifest() throws Exception { + String name = getExtractor().extract(Paths.get("src/test/test-data/jar.empty/plexus-java-1.0.0-SNAPSHOT.jar")); + assertEquals("plexus.java", name); } @Test - public void testJarWithManifest() throws Exception - { - String name = getExtractor().extract( Paths.get( "src/test/resources/jar.manifest.with/plexus-java-1.0.0-SNAPSHOT.jar" ) ); - assertEquals( "org.codehaus.plexus.languages.java", name ); + void testJarWithManifest() throws Exception { + String name = getExtractor() + .extract(Paths.get("src/test/test-data/jar.manifest.with/plexus-java-1.0.0-SNAPSHOT.jar")); + assertEquals("org.codehaus.plexus.languages.java", name); } - + @Test - public void testJarUnsupported() throws Exception - { - String name = getExtractor().extract( Paths.get( "src/test/resources/jar.unsupported/jdom-1.0.jar" ) ); - assertEquals( null, name ); + void testJarUnsupported() throws Exception { + String name = getExtractor().extract(Paths.get("src/test/test-data/jar.unsupported/jdom-1.0.jar")); + assertNull(name); } @Test - public void testJarWithSpacesInPath() throws Exception - { - String name = getExtractor().extract( Paths.get( "src/test/resources/jar with spaces in path/plexus-java-1.0.0-SNAPSHOT.jar" ) ); - assertEquals( "org.codehaus.plexus.languages.java", name ); + void testJarWithSpacesInPath() throws Exception { + String name = getExtractor() + .extract(Paths.get("src/test/test-data/jar with spaces in path/plexus-java-1.0.0-SNAPSHOT.jar")); + assertEquals("org.codehaus.plexus.languages.java", name); } - } diff --git a/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/BinaryModuleInfoParserTest.java b/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/BinaryModuleInfoParserTest.java index 963b508..c688b0b 100644 --- a/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/BinaryModuleInfoParserTest.java +++ b/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/BinaryModuleInfoParserTest.java @@ -1,6 +1,5 @@ package org.codehaus.plexus.languages.java.jpms; - /* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -20,13 +19,6 @@ * under the License. */ -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.is; - import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; @@ -41,164 +33,180 @@ import org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaProvides; import org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaRequires; import org.codehaus.plexus.languages.java.version.JavaVersion; -import org.junit.Test; +import org.junit.jupiter.api.Test; -public class BinaryModuleInfoParserTest -{ - private BinaryModuleInfoParser parser = new BinaryModuleInfoParser(); +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class BinaryModuleInfoParserTest { + private final BinaryModuleInfoParser parser = new BinaryModuleInfoParser(); @Test - public void testJarDescriptor() throws Exception - { - JavaModuleDescriptor descriptor = parser.getModuleDescriptor( Paths.get( "src/test/resources/jar.descriptor/asm-6.0_BETA.jar" ) ); - - assertNotNull( descriptor); - assertEquals( "org.objectweb.asm", descriptor.name() ); - assertEquals( false, descriptor.isAutomatic() ); - - assertEquals( 1, descriptor.requires().size() ); - assertEquals( "java.base", descriptor.requires().iterator().next().name() ); - - Set expectedExports = JavaModuleDescriptor.newAutomaticModule( "_" ) - .exports( "org.objectweb.asm" ) - .exports( "org.objectweb.asm.signature" ) + void testJarDescriptor() throws Exception { + JavaModuleDescriptor descriptor = + parser.getModuleDescriptor(Paths.get("src/test/test-data/jar.descriptor/asm-6.0_BETA.jar")); + + assertNotNull(descriptor); + assertThat(descriptor.name()).isEqualTo("org.objectweb.asm"); + assertFalse(descriptor.isAutomatic()); + + assertThat(descriptor.requires()).hasSize(1); + assertEquals("java.base", descriptor.requires().iterator().next().name()); + + Set expectedExports = JavaModuleDescriptor.newAutomaticModule("_") + .exports("org.objectweb.asm") + .exports("org.objectweb.asm.signature") .build() .exports(); - assertEquals( expectedExports, descriptor.exports() ); + assertEquals(expectedExports, descriptor.exports()); } @Test - public void testMultiReleaseJarDescriptor() throws Exception - { - JavaModuleDescriptor descriptor = parser.getModuleDescriptor( Paths.get( "src/test/resources/jar.mr.descriptor/jloadr-1.0-SNAPSHOT.jar" ), JavaVersion.parse( "17" ) ); - - assertNotNull( descriptor); - assertEquals( "de.adito.jloadr", descriptor.name() ); - assertEquals( false, descriptor.isAutomatic() ); + void testMultiReleaseJarDescriptor() throws Exception { + JavaModuleDescriptor descriptor = parser.getModuleDescriptor( + Paths.get("src/test/test-data/jar.mr.descriptor/jloadr-1.0-SNAPSHOT.jar"), JavaVersion.parse("17")); + + assertNotNull(descriptor); + assertEquals("de.adito.jloadr", descriptor.name()); + assertFalse(descriptor.isAutomatic()); } @Test - public void testIncompleteMultiReleaseJarDescriptor() throws Exception - { + void testIncompleteMultiReleaseJarDescriptor() throws Exception { // this jar is missing the Multi-Release: true entry in the Manifest - JavaModuleDescriptor descriptor = parser.getModuleDescriptor( Paths.get( "src/test/resources/jar.mr.incomplete.descriptor/jloadr-1.0-SNAPSHOT.jar" ) ); - - assertNull( descriptor); + JavaModuleDescriptor descriptor = parser.getModuleDescriptor( + Paths.get("src/test/test-data/jar.mr.incomplete.descriptor/jloadr-1.0-SNAPSHOT.jar")); + + assertNull(descriptor); } @Test - public void testClassicJar() throws Exception - { - JavaModuleDescriptor descriptor = parser.getModuleDescriptor( Paths.get( "src/test/resources/jar.empty/plexus-java-1.0.0-SNAPSHOT.jar" ) ); - - assertNull( descriptor); + void testClassicJar() throws Exception { + JavaModuleDescriptor descriptor = + parser.getModuleDescriptor(Paths.get("src/test/test-data/jar.empty/plexus-java-1.0.0-SNAPSHOT.jar")); + + assertNull(descriptor); } - + @Test - public void testOutputDirectoryDescriptor() - throws Exception - { + void testOutputDirectoryDescriptor() throws Exception { JavaModuleDescriptor descriptor = - parser.getModuleDescriptor( Paths.get( "src/test/resources/dir.descriptor/out" ) ); + parser.getModuleDescriptor(Paths.get("src/test/test-data/dir.descriptor/out")); - assertNotNull( descriptor ); - assertEquals( "org.codehaus.plexus.languages.java.demo", descriptor.name() ); - assertEquals( false, descriptor.isAutomatic() ); + assertNotNull(descriptor); + assertEquals("org.codehaus.plexus.languages.java.demo", descriptor.name()); + assertFalse(descriptor.isAutomatic()); - assertEquals( 3, descriptor.requires().size() ); + assertThat(descriptor.requires()).hasSize(3); - Set expectedRequires = JavaModuleDescriptor.newAutomaticModule( "_" ) - .requires( "java.base" ) - .requires( "java.xml" ) - .requires( Collections.singleton( JavaRequires.JavaModifier.STATIC ), "com.google.common" ) - .build() - .requires(); + Set expectedRequires = JavaModuleDescriptor.newAutomaticModule("_") + .requires("java.base") + .requires("java.xml") + .requires(Collections.singleton(JavaRequires.JavaModifier.STATIC), "com.google.common") + .build() + .requires(); - assertEquals( expectedRequires, descriptor.requires() ); + assertEquals(expectedRequires, descriptor.requires()); } - @Test( expected = NoSuchFileException.class ) - public void testClassicOutputDirectory() throws Exception - { - parser.getModuleDescriptor( Paths.get( "src/test/resources/dir.empty/out" ) ); + @Test + void testClassicOutputDirectory() { + assertThrows( + NoSuchFileException.class, + () -> parser.getModuleDescriptor(Paths.get("src/test/test-data/dir.empty/out"))); } @Test - public void testJModDescriptor() throws Exception - { - JavaModuleDescriptor descriptor = parser.getModuleDescriptor( Paths.get( "src/test/resources/jmod.descriptor/first-jmod-1.0-SNAPSHOT.jmod" ) ); - - assertNotNull( descriptor); - assertEquals( "com.corporate.project", descriptor.name() ); - assertEquals( false, descriptor.isAutomatic() ); - - assertEquals( 1, descriptor.requires().size() ); - assertEquals( "java.base", descriptor.requires().iterator().next().name() ); - - assertEquals ( 1, descriptor.exports().size() ); - assertEquals ( "com.corporate.project", descriptor.exports().iterator().next().source() ); + void testJModDescriptor() throws Exception { + JavaModuleDescriptor descriptor = parser.getModuleDescriptor( + Paths.get("src/test/test-data/jmod.descriptor/first-jmod-1.0-SNAPSHOT.jmod")); + + assertNotNull(descriptor); + assertEquals("com.corporate.project", descriptor.name()); + assertFalse(descriptor.isAutomatic()); + + assertEquals(1, descriptor.requires().size()); + assertEquals("java.base", descriptor.requires().iterator().next().name()); + + assertEquals(1, descriptor.exports().size()); + assertEquals( + "com.corporate.project", descriptor.exports().iterator().next().source()); } - - @Test( expected = IOException.class ) - public void testInvalidFile() throws Exception - { - parser.getModuleDescriptor( Paths.get( "src/test/resources/nonjar/pom.xml" ) ); + + @Test + void testInvalidFile() { + assertThrows( + IOException.class, () -> parser.getModuleDescriptor(Paths.get("src/test/test-data/nonjar/pom.xml"))); } - + @Test - public void testUses() throws Exception - { - try ( InputStream is = Files.newInputStream( Paths.get( "src/test/resources/dir.descriptor.uses/out/module-info.class" ) ) ) - { - JavaModuleDescriptor descriptor = parser.parse( is ); - - assertNotNull( descriptor); - assertEquals( new HashSet<>( Arrays.asList( "org.apache.logging.log4j.spi.Provider", - "org.apache.logging.log4j.util.PropertySource", - "org.apache.logging.log4j.message.ThreadDumpMessage$ThreadInfoFactory" ) ), - descriptor.uses() ); + void testUses() throws Exception { + try (InputStream is = + Files.newInputStream(Paths.get("src/test/test-data/dir.descriptor.uses/out/module-info.class"))) { + JavaModuleDescriptor descriptor = parser.parse(is); + + assertNotNull(descriptor); + assertEquals( + new HashSet<>(Arrays.asList( + "org.apache.logging.log4j.spi.Provider", + "org.apache.logging.log4j.util.PropertySource", + "org.apache.logging.log4j.message.ThreadDumpMessage$ThreadInfoFactory")), + descriptor.uses()); } } - + @Test - public void testProvides() throws Exception - { - JavaModuleDescriptor descriptor = parser.getModuleDescriptor( Paths.get( "src/test/resources/jar.service/threeten-extra-1.4.jar" ) ); - - assertNotNull( descriptor ); - assertEquals( 1, descriptor.provides().size() ); - - JavaProvides provides = descriptor.provides().iterator().next(); - assertEquals( "java.time.chrono.Chronology", provides.service() ); - assertArrayEquals( new String[] { "org.threeten.extra.chrono.BritishCutoverChronology", - "org.threeten.extra.chrono.CopticChronology", "org.threeten.extra.chrono.DiscordianChronology", - "org.threeten.extra.chrono.EthiopicChronology", "org.threeten.extra.chrono.InternationalFixedChronology", - "org.threeten.extra.chrono.JulianChronology", "org.threeten.extra.chrono.PaxChronology", - "org.threeten.extra.chrono.Symmetry010Chronology", "org.threeten.extra.chrono.Symmetry454Chronology" }, - provides.providers().toArray( new String[0] ) ); + void testProvides() throws Exception { + JavaModuleDescriptor descriptor = + parser.getModuleDescriptor(Paths.get("src/test/test-data/jar.service/threeten-extra-1.4.jar")); + + assertNotNull(descriptor); + assertEquals(1, descriptor.provides().size()); + JavaProvides provides = descriptor.provides().iterator().next(); + assertEquals("java.time.chrono.Chronology", provides.service()); + assertArrayEquals( + new String[] { + "org.threeten.extra.chrono.BritishCutoverChronology", + "org.threeten.extra.chrono.CopticChronology", + "org.threeten.extra.chrono.DiscordianChronology", + "org.threeten.extra.chrono.EthiopicChronology", + "org.threeten.extra.chrono.InternationalFixedChronology", + "org.threeten.extra.chrono.JulianChronology", + "org.threeten.extra.chrono.PaxChronology", + "org.threeten.extra.chrono.Symmetry010Chronology", + "org.threeten.extra.chrono.Symmetry454Chronology" + }, + provides.providers().toArray(new String[0])); } @Test - public void testRequires() throws Exception - { - try ( InputStream is = Files.newInputStream( Paths.get( "src/test/resources/dir.descriptor.requires/out/module-info.class" ) ) ) - { - JavaModuleDescriptor descriptor = parser.parse( is ); - - assertNotNull( descriptor); - assertThat( descriptor.requires().size(), is( 5 ) ); - - Set expectedRequires = JavaModuleDescriptor.newAutomaticModule( "_" ) - .requires( "java.base" ) - .requires( "mod_r" ) - .requires( Collections.singleton( JavaRequires.JavaModifier.STATIC ), "mod_r_s" ) - .requires( Collections.singleton( JavaRequires.JavaModifier.TRANSITIVE ), "mod_r_t" ) - .requires( new HashSet( Arrays.asList( JavaRequires.JavaModifier.STATIC, JavaRequires.JavaModifier.TRANSITIVE ) ), "mod_r_s_t" ) - .build() - .requires(); - - assertEquals( expectedRequires, descriptor.requires() ); + void testRequires() throws Exception { + try (InputStream is = + Files.newInputStream(Paths.get("src/test/test-data/dir.descriptor.requires/out/module-info.class"))) { + JavaModuleDescriptor descriptor = parser.parse(is); + + assertNotNull(descriptor); + assertThat(descriptor.requires()).hasSize(5); + + Set expectedRequires = JavaModuleDescriptor.newAutomaticModule("_") + .requires("java.base") + .requires("mod_r") + .requires(Collections.singleton(JavaRequires.JavaModifier.STATIC), "mod_r_s") + .requires(Collections.singleton(JavaRequires.JavaModifier.TRANSITIVE), "mod_r_t") + .requires( + new HashSet<>(Arrays.asList( + JavaRequires.JavaModifier.STATIC, JavaRequires.JavaModifier.TRANSITIVE)), + "mod_r_s_t") + .build() + .requires(); + + assertEquals(expectedRequires, descriptor.requires()); } } } diff --git a/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/CmdModuleNameExtractorTest.java b/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/CmdModuleNameExtractorTest.java index dd1248f..8430cbf 100644 --- a/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/CmdModuleNameExtractorTest.java +++ b/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/CmdModuleNameExtractorTest.java @@ -19,22 +19,20 @@ * under the License. */ -import static org.junit.Assert.assertEquals; - import java.nio.file.Path; -import org.junit.Test; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; -public class CmdModuleNameExtractorTest -{ +class CmdModuleNameExtractorTest { @Test - public void testMethodCount() throws Exception - { + void testMethodCount() throws Exception { // ensure that both implementations are in sync - assertEquals( 2, CmdModuleNameExtractor.class.getDeclaredMethods().length ); - + assertThat(CmdModuleNameExtractor.class.getDeclaredMethods()).hasSize(2); + // if these don't exist, a NoSuchMethodException is thrown - CmdModuleNameExtractor.class.getDeclaredMethod( "main", String[].class ); - CmdModuleNameExtractor.class.getDeclaredMethod( "getModuleName", Path.class ); + CmdModuleNameExtractor.class.getDeclaredMethod("main", String[].class); + CmdModuleNameExtractor.class.getDeclaredMethod("getModuleName", Path.class); } } diff --git a/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/LocationManagerIT.java b/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/LocationManagerIT.java index c79a29f..a33c7ce 100644 --- a/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/LocationManagerIT.java +++ b/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/LocationManagerIT.java @@ -19,34 +19,32 @@ * under the License. */ -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.not; -import static org.hamcrest.CoreMatchers.startsWith; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.Assume.assumeThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.when; - import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Arrays; import java.util.Collections; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.DisabledOnJre; +import org.junit.jupiter.api.condition.JRE; +import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; /** - * NOTE Eclipse users must disable the Build automatically option, - * otherwise it'll continually rebuild the project, causing compilations or tests to fail. - * + * NOTE Eclipse users must disable the Build automatically option, + * otherwise it'll continually rebuild the project, causing compilations or tests to fail. + * * @author Robert Scholte */ -@RunWith( org.mockito.junit.MockitoJUnitRunner.class ) -public class LocationManagerIT -{ +@DisabledOnJre(value = JRE.JAVA_8, disabledReason = "Requires Java 9+ Module System") +@ExtendWith(MockitoExtension.class) +class LocationManagerIT { @Mock private BinaryModuleInfoParser asmParser; @@ -54,84 +52,74 @@ public class LocationManagerIT private SourceModuleInfoParser qdoxParser; private LocationManager locationManager; - - final Path mockModuleInfoJava = Paths.get( "src/test/resources/mock/module-info.java"); - - @BeforeClass - public static void assume() - { - assumeThat( "Requires at least Java 9", System.getProperty( "java.version" ), not( startsWith( "1." ) ) ); - } - - @Before - public void onSetup() - { - locationManager = new LocationManager( qdoxParser ) - { + + final Path mockModuleInfoJava = Paths.get("src/test/test-data/mock/module-info.java"); + + @BeforeEach + void onSetup() { + locationManager = new LocationManager(qdoxParser) { @Override - ModuleInfoParser getBinaryModuleInfoParser( Path jdkHome ) - { + ModuleInfoParser getBinaryModuleInfoParser(Path jdkHome) { return asmParser; } }; } - + @Test - public void testManifestWithoutReflectRequires() throws Exception - { - Path abc = Paths.get( "src/test/resources/manifest.without/out" ); - JavaModuleDescriptor descriptor = JavaModuleDescriptor.newModule( "base" ).requires( "any" ).build(); - when( qdoxParser.fromSourcePath( any( Path.class ) ) ).thenReturn( descriptor ); - ResolvePathsRequest request = ResolvePathsRequest.ofPaths( Collections.singletonList( abc ) ).setMainModuleDescriptor( mockModuleInfoJava ); - - ResolvePathsResult result = locationManager.resolvePaths( request ); - - assertThat( result.getPathExceptions().size(), is( 0 ) ); - assertThat( result.getMainModuleDescriptor(), is( descriptor) ); - assertThat( result.getPathElements().size(), is( 1 ) ); - assertThat( result.getModulepathElements().size(), is( 0 ) ); - assertThat( result.getClasspathElements().size(), is( 1 ) ); + void testManifestWithoutReflectRequires() throws Exception { + Path abc = Paths.get("src/test/test-data/manifest.without/out"); + JavaModuleDescriptor descriptor = + JavaModuleDescriptor.newModule("base").requires("any").build(); + when(qdoxParser.fromSourcePath(any(Path.class))).thenReturn(descriptor); + ResolvePathsRequest request = + ResolvePathsRequest.ofPaths(Collections.singletonList(abc)).setMainModuleDescriptor(mockModuleInfoJava); + + ResolvePathsResult result = locationManager.resolvePaths(request); + + assertThat(result.getPathExceptions()).isEmpty(); + assertThat(result.getMainModuleDescriptor()).isEqualTo(descriptor); + assertThat(result.getPathElements()).hasSize(1); + assertThat(result.getModulepathElements()).isEmpty(); + assertThat(result.getClasspathElements()).hasSize(1); } - + @Test - public void testEmptyWithReflectRequires() throws Exception - { - Path abc = Paths.get( "src/test/resources/empty/out" ); - JavaModuleDescriptor descriptor = JavaModuleDescriptor.newModule( "base" ).requires( "a.b.c" ).build(); - when( qdoxParser.fromSourcePath( any( Path.class ) ) ).thenReturn( descriptor ); - ResolvePathsRequest request = ResolvePathsRequest.ofPaths( Collections.singletonList( abc ) ).setMainModuleDescriptor( mockModuleInfoJava ); - - ResolvePathsResult result = locationManager.resolvePaths( request ); - - assertThat( result.getPathExceptions().size(), is( 0 ) ); - assertThat( result.getMainModuleDescriptor(), is( descriptor) ); - assertThat( result.getPathElements().size(), is( 1 ) ); - assertThat( result.getModulepathElements().size(), is( 0 ) ); - assertThat( result.getClasspathElements().size(), is( 1 ) ); + void testEmptyWithReflectRequires() throws Exception { + Path abc = Paths.get("src/test/test-data/empty/out"); + JavaModuleDescriptor descriptor = + JavaModuleDescriptor.newModule("base").requires("a.b.c").build(); + when(qdoxParser.fromSourcePath(any(Path.class))).thenReturn(descriptor); + ResolvePathsRequest request = + ResolvePathsRequest.ofPaths(Collections.singletonList(abc)).setMainModuleDescriptor(mockModuleInfoJava); + + ResolvePathsResult result = locationManager.resolvePaths(request); + + assertThat(result.getPathExceptions()).hasSize(0); + assertThat(result.getMainModuleDescriptor()).isEqualTo(descriptor); + assertThat(result.getPathElements()).hasSize(1); + assertThat(result.getModulepathElements()).hasSize(0); + assertThat(result.getClasspathElements()).hasSize(1); } - - @Test( expected = RuntimeException.class ) - public void testResolvePathWithException() throws Exception - { - assumeThat( "Requires at least Java 9", System.getProperty( "java.version" ), not( startsWith( "1." ) ) ); - - Path p = Paths.get( "src/test/resources/jar.empty.invalid.name/101-1.0.0-SNAPSHOT.jar" ); - ResolvePathRequest request = ResolvePathRequest.ofPath( p ); - - locationManager.resolvePath( request ); + + @Test + void testResolvePathWithException() { + assertThrows(RuntimeException.class, () -> { + Path p = Paths.get("src/test/test-data/jar.empty.invalid.name/101-1.0.0-SNAPSHOT.jar"); + ResolvePathRequest request = ResolvePathRequest.ofPath(p); + + locationManager.resolvePath(request); + }); } - + @Test - public void testClassicJarNameStartsWithNumber() throws Exception - { - assumeThat( "Requires at least Java 9", System.getProperty( "java.version" ), not( startsWith( "1." ) ) ); - - Path p = Paths.get( "src/test/resources/jar.empty.invalid.name/101-1.0.0-SNAPSHOT.jar" ); - ResolvePathsRequest request = ResolvePathsRequest.ofPaths( Arrays.asList( p ) ).setMainModuleDescriptor( mockModuleInfoJava ); - - ResolvePathsResult result = locationManager.resolvePaths( request ); - - assertThat( result.getPathExceptions().size(), is( 1 ) ); - assertThat( result.getClasspathElements().size(), is(1) ); + void testClassicJarNameStartsWithNumber() throws Exception { + Path p = Paths.get("src/test/test-data/jar.empty.invalid.name/101-1.0.0-SNAPSHOT.jar"); + ResolvePathsRequest request = + ResolvePathsRequest.ofPaths(Collections.singletonList(p)).setMainModuleDescriptor(mockModuleInfoJava); + + ResolvePathsResult result = locationManager.resolvePaths(request); + + assertThat(result.getPathExceptions()).hasSize(1); + assertThat(result.getClasspathElements()).hasSize(1); } } diff --git a/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/LocationManagerTest.java b/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/LocationManagerTest.java index 35a6f4e..2b8cb04 100644 --- a/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/LocationManagerTest.java +++ b/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/LocationManagerTest.java @@ -19,12 +19,6 @@ * under the License. */ -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.nullValue; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.when; - import java.io.File; import java.nio.file.Path; import java.nio.file.Paths; @@ -33,516 +27,611 @@ import java.util.HashSet; import org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaRequires.JavaModifier; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; -@RunWith( org.mockito.junit.MockitoJUnitRunner.class ) -public class LocationManagerTest -{ - @Mock +class LocationManagerTest { private BinaryModuleInfoParser asmParser; - @Mock private SourceModuleInfoParser qdoxParser; private LocationManager locationManager; - - final Path mockModuleInfoJava = Paths.get( "src/test/resources/mock/module-info.java"); - - @Before - public void onSetup() - { - locationManager = new LocationManager( qdoxParser ) - { + + final Path mockModuleInfoJava = Paths.get("src/test/test-data/mock/module-info.java"); + + @BeforeEach + void onSetup() { + asmParser = mock(BinaryModuleInfoParser.class); + qdoxParser = mock(SourceModuleInfoParser.class); + locationManager = new LocationManager(qdoxParser) { @Override - ModuleInfoParser getBinaryModuleInfoParser( Path jdkHome ) - { + ModuleInfoParser getBinaryModuleInfoParser(Path jdkHome) { return asmParser; } }; } @Test - public void testNoPaths() throws Exception - { - ResolvePathsResult result = locationManager.resolvePaths( ResolvePathsRequest.ofFiles( Collections.emptyList() ) ); - assertThat( result.getMainModuleDescriptor(), nullValue( JavaModuleDescriptor.class) ); - assertThat( result.getPathElements().size(), is( 0 ) ); - assertThat( result.getModulepathElements().size(), is( 0 ) ); - assertThat( result.getClasspathElements().size(), is( 0 ) ); - assertThat( result.getPathExceptions().size(), is( 0 ) ); + void testNoPaths() throws Exception { + ResolvePathsResult result = + locationManager.resolvePaths(ResolvePathsRequest.ofFiles(Collections.emptyList())); + assertThat(result.getMainModuleDescriptor()).isNull(); + assertThat(result.getPathElements()).isEmpty(); + assertThat(result.getModulepathElements()).isEmpty(); + assertThat(result.getClasspathElements()).isEmpty(); + assertThat(result.getPathExceptions()).isEmpty(); } @Test - public void testWithUnknownRequires() throws Exception - { - JavaModuleDescriptor descriptor = JavaModuleDescriptor.newModule( "base" ).requires( "java.base" ).requires( "jdk.net" ).build(); - when( qdoxParser.fromSourcePath( any( Path.class ) ) ).thenReturn( descriptor ); - ResolvePathsRequest request = ResolvePathsRequest.ofFiles( Collections.emptyList() ).setMainModuleDescriptor( mockModuleInfoJava.toFile() ); - - ResolvePathsResult result = locationManager.resolvePaths( request ); - - assertThat( result.getMainModuleDescriptor(), is( descriptor) ); - assertThat( result.getPathElements().size(), is( 0 ) ); - assertThat( result.getModulepathElements().size(), is( 0 ) ); - assertThat( result.getClasspathElements().size(), is( 0 ) ); - assertThat( result.getPathExceptions().size(), is( 0 ) ); + void testWithUnknownRequires() throws Exception { + JavaModuleDescriptor descriptor = JavaModuleDescriptor.newModule("base") + .requires("java.base") + .requires("jdk.net") + .build(); + when(qdoxParser.fromSourcePath(any(Path.class))).thenReturn(descriptor); + ResolvePathsRequest request = ResolvePathsRequest.ofFiles(Collections.emptyList()) + .setMainModuleDescriptor(mockModuleInfoJava.toFile()); + + ResolvePathsResult result = locationManager.resolvePaths(request); + + assertThat(result.getMainModuleDescriptor()).isEqualTo(descriptor); + assertThat(result.getPathElements()).isEmpty(); + assertThat(result.getModulepathElements()).isEmpty(); + assertThat(result.getClasspathElements()).isEmpty(); + assertThat(result.getPathExceptions()).isEmpty(); } - + @Test - public void testManifestWithReflectRequires() throws Exception - { - Path abc = Paths.get( "src/test/resources/dir.manifest.with/out" ); - JavaModuleDescriptor descriptor = JavaModuleDescriptor.newModule( "base" ).requires( "auto.by.manifest" ).build(); - when( qdoxParser.fromSourcePath( any( Path.class ) ) ).thenReturn( descriptor ); - ResolvePathsRequest request = ResolvePathsRequest.ofPaths( Collections.singletonList( abc ) ).setMainModuleDescriptor( mockModuleInfoJava ); - - ResolvePathsResult result = locationManager.resolvePaths( request ); - - assertThat( result.getMainModuleDescriptor(), is( descriptor) ); - assertThat( result.getPathElements().size(), is( 1 ) ); - assertThat( result.getModulepathElements().size(), is( 1 ) ); - assertThat( result.getModulepathElements().get( abc), is( ModuleNameSource.MANIFEST ) ); - assertThat( result.getClasspathElements().size(), is( 0 ) ); - assertThat( result.getPathExceptions().size(), is( 0 ) ); + void testManifestWithReflectRequires() throws Exception { + Path abc = Paths.get("src/test/test-data/dir.manifest.with/out"); + JavaModuleDescriptor descriptor = JavaModuleDescriptor.newModule("base") + .requires("auto.by.manifest") + .build(); + when(qdoxParser.fromSourcePath(any(Path.class))).thenReturn(descriptor); + ResolvePathsRequest request = + ResolvePathsRequest.ofPaths(Collections.singletonList(abc)).setMainModuleDescriptor(mockModuleInfoJava); + + ResolvePathsResult result = locationManager.resolvePaths(request); + + assertThat(result.getMainModuleDescriptor()).isEqualTo(descriptor); + assertThat(result.getPathElements()).hasSize(1); + assertThat(result.getModulepathElements()).hasSize(1); + assertThat(result.getModulepathElements().get(abc)).isEqualTo(ModuleNameSource.MANIFEST); + assertThat(result.getClasspathElements()).isEmpty(); + assertThat(result.getPathExceptions()).isEmpty(); } - + @Test - public void testDirDescriptorWithReflectRequires() throws Exception - { - Path abc = Paths.get( "src/test/resources/dir.descriptor/out" ); - JavaModuleDescriptor descriptor = JavaModuleDescriptor.newModule( "base" ).requires( "dir.descriptor" ).build(); - when( qdoxParser.fromSourcePath( any( Path.class ) ) ).thenReturn( descriptor ); - ResolvePathsRequest request = ResolvePathsRequest.ofPaths( Collections.singletonList( abc ) ).setMainModuleDescriptor( mockModuleInfoJava ); - - when( asmParser.getModuleDescriptor( abc ) ).thenReturn( JavaModuleDescriptor.newModule( "dir.descriptor" ).build() ); - - ResolvePathsResult result = locationManager.resolvePaths( request ); - - assertThat( result.getMainModuleDescriptor(), is( descriptor) ); - assertThat( result.getPathElements().size(), is( 1 ) ); - assertThat( result.getModulepathElements().size(), is( 1 ) ); - assertThat( result.getModulepathElements().get( abc), is( ModuleNameSource.MODULEDESCRIPTOR ) ); - assertThat( result.getClasspathElements().size(), is( 0 ) ); - assertThat( result.getPathExceptions().size(), is( 0 ) ); + void testDirDescriptorWithReflectRequires() throws Exception { + Path abc = Paths.get("src/test/test-data/dir.descriptor/out"); + JavaModuleDescriptor descriptor = JavaModuleDescriptor.newModule("base") + .requires("dir.descriptor") + .build(); + when(qdoxParser.fromSourcePath(any(Path.class))).thenReturn(descriptor); + ResolvePathsRequest request = + ResolvePathsRequest.ofPaths(Collections.singletonList(abc)).setMainModuleDescriptor(mockModuleInfoJava); + + when(asmParser.getModuleDescriptor(abc)) + .thenReturn(JavaModuleDescriptor.newModule("dir.descriptor").build()); + + ResolvePathsResult result = locationManager.resolvePaths(request); + + assertThat(result.getMainModuleDescriptor()).isEqualTo(descriptor); + assertThat(result.getPathElements()).hasSize(1); + assertThat(result.getModulepathElements()).hasSize(1); + assertThat(result.getModulepathElements().get(abc)).isEqualTo(ModuleNameSource.MODULEDESCRIPTOR); + assertThat(result.getClasspathElements()).isEmpty(); + assertThat(result.getPathExceptions()).isEmpty(); } @Test - public void testJarWithAsmRequires() throws Exception - { - Path abc = Paths.get( "src/test/resources/jar.descriptor/asm-6.0_BETA.jar" ); - JavaModuleDescriptor descriptor = JavaModuleDescriptor.newModule( "base" ).requires( "org.objectweb.asm" ).build(); - when( qdoxParser.fromSourcePath( any( Path.class ) ) ).thenReturn( descriptor ); - ResolvePathsRequest request = ResolvePathsRequest.ofPaths( Collections.singletonList( abc ) ).setMainModuleDescriptor( mockModuleInfoJava ); - - when( asmParser.getModuleDescriptor( abc ) ).thenReturn( JavaModuleDescriptor.newModule( "org.objectweb.asm" ).build() ); - - ResolvePathsResult result = locationManager.resolvePaths( request ); - - assertThat( result.getMainModuleDescriptor(), is( descriptor) ); - assertThat( result.getPathElements().size(), is( 1 ) ); - assertThat( result.getModulepathElements().size(), is( 1 ) ); - assertThat( result.getModulepathElements().get( abc), is( ModuleNameSource.MODULEDESCRIPTOR ) ); - assertThat( result.getClasspathElements().size(), is( 0 ) ); - assertThat( result.getPathExceptions().size(), is( 0 ) ); + void testJarWithAsmRequires() throws Exception { + Path abc = Paths.get("src/test/test-data/jar.descriptor/asm-6.0_BETA.jar"); + JavaModuleDescriptor descriptor = JavaModuleDescriptor.newModule("base") + .requires("org.objectweb.asm") + .build(); + when(qdoxParser.fromSourcePath(any(Path.class))).thenReturn(descriptor); + ResolvePathsRequest request = + ResolvePathsRequest.ofPaths(Collections.singletonList(abc)).setMainModuleDescriptor(mockModuleInfoJava); + + when(asmParser.getModuleDescriptor(abc)) + .thenReturn(JavaModuleDescriptor.newModule("org.objectweb.asm").build()); + + ResolvePathsResult result = locationManager.resolvePaths(request); + assertThat(result.getMainModuleDescriptor()).isEqualTo(descriptor); + assertThat(result.getPathElements()).hasSize(1); + assertThat(result.getModulepathElements()).hasSize(1); + assertThat(result.getModulepathElements().get(abc)).isEqualTo(ModuleNameSource.MODULEDESCRIPTOR); + assertThat(result.getClasspathElements()).isEmpty(); + assertThat(result.getPathExceptions()).isEmpty(); } - + @Test - public void testIdenticalModuleNames() throws Exception - { - Path pj1 = Paths.get( "src/test/resources/jar.empty/plexus-java-1.0.0-SNAPSHOT.jar" ); - Path pj2 = Paths.get( "src/test/resources/jar.empty.2/plexus-java-2.0.0-SNAPSHOT.jar" ); - JavaModuleDescriptor descriptor = JavaModuleDescriptor.newModule( "base" ).requires( "plexus.java" ).build(); - when( qdoxParser.fromSourcePath( any( Path.class ) ) ).thenReturn( descriptor ); - ResolvePathsRequest request = ResolvePathsRequest.ofPaths( Arrays.asList( pj1, pj2 ) ).setMainModuleDescriptor( mockModuleInfoJava ); - - when( asmParser.getModuleDescriptor( pj1 ) ).thenReturn( JavaModuleDescriptor.newAutomaticModule( "plexus.java" ).build() ); - when( asmParser.getModuleDescriptor( pj2 ) ).thenReturn( JavaModuleDescriptor.newAutomaticModule( "plexus.java" ).build() ); - - ResolvePathsResult result = locationManager.resolvePaths( request ); - - assertThat( result.getMainModuleDescriptor(), is( descriptor) ); - assertThat( result.getPathElements().size(), is( 2 ) ); - assertThat( result.getModulepathElements().size(), is( 1 ) ); - assertThat( result.getModulepathElements().containsKey( pj1 ), is( true ) ); - assertThat( result.getModulepathElements().containsKey( pj2 ), is( false ) ); - assertThat( result.getClasspathElements().size(), is( 0 ) ); - assertThat( result.getPathExceptions().size(), is( 0 ) ); + void testIdenticalModuleNames() throws Exception { + Path pj1 = Paths.get("src/test/test-data/jar.empty/plexus-java-1.0.0-SNAPSHOT.jar"); + Path pj2 = Paths.get("src/test/test-data/jar.empty.2/plexus-java-2.0.0-SNAPSHOT.jar"); + JavaModuleDescriptor descriptor = + JavaModuleDescriptor.newModule("base").requires("plexus.java").build(); + when(qdoxParser.fromSourcePath(any(Path.class))).thenReturn(descriptor); + ResolvePathsRequest request = + ResolvePathsRequest.ofPaths(Arrays.asList(pj1, pj2)).setMainModuleDescriptor(mockModuleInfoJava); + + when(asmParser.getModuleDescriptor(pj1)) + .thenReturn(JavaModuleDescriptor.newModule("plexus.java").build()); + when(asmParser.getModuleDescriptor(pj2)) + .thenReturn(JavaModuleDescriptor.newModule("plexus.java").build()); + + ResolvePathsResult result = locationManager.resolvePaths(request); + + assertThat(result.getMainModuleDescriptor()).isEqualTo(descriptor); + assertThat(result.getPathElements()).hasSize(2); + assertThat(result.getModulepathElements()).hasSize(1); + assertThat(result.getModulepathElements()).containsKey(pj1); + assertThat(result.getModulepathElements()).doesNotContainKey(pj2); + assertThat(result.getClasspathElements()).isEmpty(); + // duplicate is flagged as an error + assertThat(result.getPathExceptions()).containsOnlyKeys(pj2); + assertThat(result.getPathExceptions().get(pj2)) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining("Module 'plexus.java' is already on the module path!"); } @Test - public void testNonJar() throws Exception - { - Path p = Paths.get( "src/test/resources/nonjar/pom.xml" ); - - ResolvePathsRequest request = ResolvePathsRequest.ofPaths( Collections.singletonList( p ) ).setMainModuleDescriptor( mockModuleInfoJava ); - - ResolvePathsResult result = locationManager.resolvePaths( request ); - - assertThat( result.getPathExceptions().size(), is( 1 ) ); + public void testIdenticalAutomaticModuleNames() throws Exception { + Path pj1 = Paths.get("src/test/test-data/jar.empty/plexus-java-1.0.0-SNAPSHOT.jar"); + Path pj2 = Paths.get("src/test/test-data/jar.empty.2/plexus-java-2.0.0-SNAPSHOT.jar"); + JavaModuleDescriptor descriptor = + JavaModuleDescriptor.newModule("base").requires("plexus.java").build(); + when(qdoxParser.fromSourcePath(any(Path.class))).thenReturn(descriptor); + ResolvePathsRequest request = + ResolvePathsRequest.ofPaths(Arrays.asList(pj1, pj2)).setMainModuleDescriptor(mockModuleInfoJava); + + when(asmParser.getModuleDescriptor(pj1)) + .thenReturn( + JavaModuleDescriptor.newAutomaticModule("plexus.java").build()); + when(asmParser.getModuleDescriptor(pj2)) + .thenReturn( + JavaModuleDescriptor.newAutomaticModule("plexus.java").build()); + + ResolvePathsResult result = locationManager.resolvePaths(request); + assertThat(result.getMainModuleDescriptor()).isEqualTo(descriptor); + assertThat(result.getPathElements()).hasSize(2); + assertThat(result.getModulepathElements()).containsOnlyKeys(pj1); + assertThat(result.getModulepathElements()).doesNotContainKey(pj2); + assertThat(result.getClasspathElements()).isEmpty(); + // duplicate is flagged as an error + assertThat(result.getPathExceptions()).containsOnlyKeys(pj2); + assertThat(result.getPathExceptions().get(pj2)) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining("Module 'plexus.java' is already on the module path!"); } - + @Test - public void testAdditionalModules() throws Exception - { - Path p = Paths.get( "src/test/resources/mock/jar0.jar" ); - - JavaModuleDescriptor descriptor = JavaModuleDescriptor.newModule( "base" ).build(); - when( qdoxParser.fromSourcePath( any( Path.class ) ) ).thenReturn( descriptor ); + public void testMainJarModuleAndTestJarAutomatic() throws Exception { + Path pj1 = Paths.get("src/test/test-data/jar.tests/plexus-java-1.0.0-SNAPSHOT.jar"); + Path pj2 = Paths.get("src/test/test-data/jar.tests/plexus-java-1.0.0-SNAPSHOT-tests.jar"); + JavaModuleDescriptor descriptor = + JavaModuleDescriptor.newModule("base").requires("plexus.java").build(); + when(qdoxParser.fromSourcePath(any(Path.class))).thenReturn(descriptor); ResolvePathsRequest request = - ResolvePathsRequest.ofPaths( Collections.singletonList( p ) ) - .setMainModuleDescriptor( mockModuleInfoJava ) - .setAdditionalModules( Collections.singletonList( "plexus.java" ) ); + ResolvePathsRequest.ofPaths(Arrays.asList(pj1, pj2)).setMainModuleDescriptor(mockModuleInfoJava); + + when(asmParser.getModuleDescriptor(pj1)) + .thenReturn(JavaModuleDescriptor.newModule("plexus.java").build()); + when(asmParser.getModuleDescriptor(pj2)).thenReturn(null); + + ResolvePathsResult result = locationManager.resolvePaths(request); + + assertThat(result.getMainModuleDescriptor()).isEqualTo(descriptor); + assertThat(result.getPathElements()).hasSize(2); + assertThat(result.getModulepathElements()).hasSize(1); + assertThat(result.getModulepathElements()).containsKey(pj1); + assertThat(result.getModulepathElements()).doesNotContainKey(pj2); + assertThat(result.getClasspathElements()).isEmpty(); + + // duplicate is flagged as an error + assertThat(result.getPathExceptions()).containsOnlyKeys(pj2); + assertThat(result.getPathExceptions().get(pj2)) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining("Module 'plexus.java' is already on the module path!"); + } - when( asmParser.getModuleDescriptor( p ) ).thenReturn( JavaModuleDescriptor.newAutomaticModule( "plexus.java" ).build() ); + @Test + void testNonJar() throws Exception { + Path p = Paths.get("src/test/test-data/nonjar/pom.xml"); - ResolvePathsResult result = locationManager.resolvePaths( request ); + ResolvePathsRequest request = + ResolvePathsRequest.ofPaths(Collections.singletonList(p)).setMainModuleDescriptor(mockModuleInfoJava); + + ResolvePathsResult result = locationManager.resolvePaths(request); - assertThat( result.getMainModuleDescriptor(), is( descriptor) ); - assertThat( result.getPathElements().size(), is( 1 ) ); - assertThat( result.getModulepathElements().size(), is( 1 ) ); - assertThat( result.getClasspathElements().size(), is( 0 ) ); - assertThat( result.getPathExceptions().size(), is( 0 ) ); + assertThat(result.getPathExceptions()).hasSize(1); } - + @Test - public void testResolvePath() throws Exception - { - Path abc = Paths.get( "src/test/resources/mock/jar0.jar" ); - ResolvePathRequest request = ResolvePathRequest.ofPath( abc ); - - when( asmParser.getModuleDescriptor( abc ) ).thenReturn( JavaModuleDescriptor.newModule( "org.objectweb.asm" ).build() ); - - ResolvePathResult result = locationManager.resolvePath( request ); - - assertThat( result.getModuleDescriptor(), is( JavaModuleDescriptor.newModule( "org.objectweb.asm" ).build() ) ); - assertThat( result.getModuleNameSource(), is( ModuleNameSource.MODULEDESCRIPTOR ) ); + void testAdditionalModules() throws Exception { + Path p = Paths.get("src/test/test-data/mock/jar0.jar"); + + JavaModuleDescriptor descriptor = JavaModuleDescriptor.newModule("base").build(); + when(qdoxParser.fromSourcePath(any(Path.class))).thenReturn(descriptor); + ResolvePathsRequest request = ResolvePathsRequest.ofPaths(Collections.singletonList(p)) + .setMainModuleDescriptor(mockModuleInfoJava) + .setAdditionalModules(Collections.singletonList("plexus.java")); + + when(asmParser.getModuleDescriptor(p)) + .thenReturn( + JavaModuleDescriptor.newAutomaticModule("plexus.java").build()); + + ResolvePathsResult result = locationManager.resolvePaths(request); + assertThat(result.getMainModuleDescriptor()).isEqualTo(descriptor); + assertThat(result.getPathElements()).hasSize(1); + assertThat(result.getModulepathElements()).hasSize(1); + assertThat(result.getClasspathElements()).isEmpty(); + assertThat(result.getPathExceptions()).isEmpty(); } @Test - public void testNoMatchingProviders() throws Exception - { - Path abc = Paths.get( "src/test/resources/mock/module-info.java" ); // some file called module-info.java - Path def = Paths.get( "src/test/resources/mock/jar0.jar" ); // any existing file - ResolvePathsRequest request = ResolvePathsRequest.ofPaths( def ).setMainModuleDescriptor( abc ).setIncludeAllProviders( true ); - - when( qdoxParser.fromSourcePath( abc ) ).thenReturn( JavaModuleDescriptor.newModule( "abc" ).uses( "device" ).build() ); - when( asmParser.getModuleDescriptor( def ) ).thenReturn( JavaModuleDescriptor.newModule( "def" ).provides( "tool", Arrays.asList( "java", "javac" ) ).build() ); - - ResolvePathsResult result = locationManager.resolvePaths( request ); - assertThat( result.getPathElements().size(), is( 1 ) ); - assertThat( result.getModulepathElements().size(), is( 0 ) ); - assertThat( result.getClasspathElements().size(), is( 1 ) ); - assertThat( result.getPathExceptions().size(), is( 0 ) ); + void testResolvePath() throws Exception { + Path abc = Paths.get("src/test/test-data/mock/jar0.jar"); + ResolvePathRequest request = ResolvePathRequest.ofPath(abc); + + when(asmParser.getModuleDescriptor(abc)) + .thenReturn(JavaModuleDescriptor.newModule("org.objectweb.asm").build()); + + ResolvePathResult result = locationManager.resolvePath(request); + + assertThat(result.getModuleDescriptor()) + .isEqualTo(JavaModuleDescriptor.newModule("org.objectweb.asm").build()); + assertThat(result.getModuleNameSource()).isEqualTo(ModuleNameSource.MODULEDESCRIPTOR); } - @Test - public void testMainModuleDescriptorWithProviders() throws Exception - { - Path abc = Paths.get( "src/test/resources/mock/module-info.java" ); // some file called module-info.java - Path def = Paths.get( "src/test/resources/mock/jar0.jar" ); // any existing file - ResolvePathsRequest request = ResolvePathsRequest.ofPaths( def ).setMainModuleDescriptor( abc ).setIncludeAllProviders( true ); - - when( qdoxParser.fromSourcePath( abc ) ).thenReturn( JavaModuleDescriptor.newModule( "abc" ).uses( "tool" ).build() ); - when( asmParser.getModuleDescriptor( def ) ).thenReturn( JavaModuleDescriptor.newModule( "def" ).provides( "tool", Arrays.asList( "java", "javac" ) ).build() ); - - ResolvePathsResult result = locationManager.resolvePaths( request ); - assertThat( result.getPathElements().size(), is( 1 ) ); - assertThat( result.getModulepathElements().size(), is( 1 ) ); - assertThat( result.getClasspathElements().size(), is( 0 ) ); - assertThat( result.getPathExceptions().size(), is( 0 ) ); + void testNoMatchingProviders() throws Exception { + Path abc = Paths.get("src/test/test-data/mock/module-info.java"); // some file called module-info.java + Path def = Paths.get("src/test/test-data/mock/jar0.jar"); // any existing file + ResolvePathsRequest request = + ResolvePathsRequest.ofPaths(def).setMainModuleDescriptor(abc).setIncludeAllProviders(true); + + when(qdoxParser.fromSourcePath(abc)) + .thenReturn(JavaModuleDescriptor.newModule("abc").uses("device").build()); + when(asmParser.getModuleDescriptor(def)) + .thenReturn(JavaModuleDescriptor.newModule("def") + .provides("tool", Arrays.asList("java", "javac")) + .build()); + + ResolvePathsResult result = locationManager.resolvePaths(request); + assertThat(result.getPathElements()).hasSize(1); + assertThat(result.getModulepathElements()).isEmpty(); + assertThat(result.getClasspathElements()).hasSize(1); + assertThat(result.getPathExceptions()).isEmpty(); } @Test - public void testMainModuleDescriptorWithProvidersDontIncludeProviders() throws Exception - { - Path abc = Paths.get( "src/test/resources/mock/module-info.java" ); // some file called module-info.java - Path def = Paths.get( "src/test/resources/mock/jar0.jar" ); // any existing file - ResolvePathsRequest request = ResolvePathsRequest.ofPaths( def ).setMainModuleDescriptor( abc ); - - when( qdoxParser.fromSourcePath( abc ) ).thenReturn( JavaModuleDescriptor.newModule( "abc" ).uses( "tool" ).build() ); - when( asmParser.getModuleDescriptor( def ) ).thenReturn( JavaModuleDescriptor.newModule( "def" ).provides( "tool", Arrays.asList( "java", "javac" ) ).build() ); - - ResolvePathsResult result = locationManager.resolvePaths( request ); - assertThat( result.getPathElements().size(), is( 1 ) ); - assertThat( result.getModulepathElements().size(), is( 0 ) ); - assertThat( result.getClasspathElements().size(), is( 1 ) ); - assertThat( result.getPathExceptions().size(), is( 0 ) ); + void testMainModuleDescriptorWithProviders() throws Exception { + Path abc = Paths.get("src/test/test-data/mock/module-info.java"); // some file called module-info.java + Path def = Paths.get("src/test/test-data/mock/jar0.jar"); // any existing file + ResolvePathsRequest request = + ResolvePathsRequest.ofPaths(def).setMainModuleDescriptor(abc).setIncludeAllProviders(true); + + when(qdoxParser.fromSourcePath(abc)) + .thenReturn(JavaModuleDescriptor.newModule("abc").uses("tool").build()); + when(asmParser.getModuleDescriptor(def)) + .thenReturn(JavaModuleDescriptor.newModule("def") + .provides("tool", Arrays.asList("java", "javac")) + .build()); + + ResolvePathsResult result = locationManager.resolvePaths(request); + assertThat(result.getPathElements()).hasSize(1); + assertThat(result.getModulepathElements()).hasSize(1); + assertThat(result.getClasspathElements()).isEmpty(); + assertThat(result.getPathExceptions()).isEmpty(); } @Test - public void testTransitiveProviders() throws Exception - { - Path abc = Paths.get( "src/test/resources/mock/module-info.java" ); // some file called module-info.java - Path def = Paths.get( "src/test/resources/mock/jar0.jar" ); // any existing file - Path ghi = Paths.get( "src/test/resources/mock/jar1.jar" ); // any existing file - ResolvePathsRequest request = ResolvePathsRequest.ofPaths( def, ghi ).setMainModuleDescriptor( abc ).setIncludeAllProviders( true ); - - when( qdoxParser.fromSourcePath( abc ) ).thenReturn( JavaModuleDescriptor.newModule( "abc" ).requires( "ghi" ).build() ); - when( asmParser.getModuleDescriptor( def ) ).thenReturn( JavaModuleDescriptor.newModule( "def" ).provides( "tool", Arrays.asList( "java", "javac" ) ).build() ); - when( asmParser.getModuleDescriptor( ghi ) ).thenReturn( JavaModuleDescriptor.newModule( "ghi" ).uses( "tool" ).build() ); - - - ResolvePathsResult result = locationManager.resolvePaths( request ); - assertThat( result.getPathElements().size(), is( 2 ) ); - assertThat( result.getModulepathElements().size(), is( 2 ) ); - assertThat( result.getClasspathElements().size(), is( 0 ) ); - assertThat( result.getPathExceptions().size(), is( 0 ) ); + void testMainModuleDescriptorWithProvidersDontIncludeProviders() throws Exception { + Path abc = Paths.get("src/test/test-data/mock/module-info.java"); // some file called module-info.java + Path def = Paths.get("src/test/test-data/mock/jar0.jar"); // any existing file + ResolvePathsRequest request = ResolvePathsRequest.ofPaths(def).setMainModuleDescriptor(abc); + + when(qdoxParser.fromSourcePath(abc)) + .thenReturn(JavaModuleDescriptor.newModule("abc").uses("tool").build()); + when(asmParser.getModuleDescriptor(def)) + .thenReturn(JavaModuleDescriptor.newModule("def") + .provides("tool", Arrays.asList("java", "javac")) + .build()); + + ResolvePathsResult result = locationManager.resolvePaths(request); + assertThat(result.getPathElements()).hasSize(1); + assertThat(result.getModulepathElements()).isEmpty(); + assertThat(result.getClasspathElements()).hasSize(1); + assertThat(result.getPathExceptions()).isEmpty(); } - + @Test - public void testDontIncludeProviders() throws Exception - { - Path abc = Paths.get( "src/test/resources/mock/module-info.java" ); // some file called module-info.java - Path def = Paths.get( "src/test/resources/mock/jar0.jar" ); // any existing file - Path ghi = Paths.get( "src/test/resources/mock/jar1.jar" ); // any existing file - ResolvePathsRequest request = ResolvePathsRequest.ofPaths( def, ghi ).setMainModuleDescriptor( abc ); - - when( qdoxParser.fromSourcePath( abc ) ).thenReturn( JavaModuleDescriptor.newModule( "abc" ).requires( "ghi" ).build() ); - when( asmParser.getModuleDescriptor( def ) ).thenReturn( JavaModuleDescriptor.newModule( "def" ).provides( "tool", Arrays.asList( "java", "javac" ) ).build() ); - when( asmParser.getModuleDescriptor( ghi ) ).thenReturn( JavaModuleDescriptor.newModule( "ghi" ).uses( "tool" ).build() ); - - - ResolvePathsResult result = locationManager.resolvePaths( request ); - assertThat( result.getPathElements().size(), is( 2 ) ); - assertThat( result.getModulepathElements().size(), is( 1 ) ); - assertThat( result.getClasspathElements().size(), is( 1 ) ); - assertThat( result.getPathExceptions().size(), is( 0 ) ); + void testTransitiveProviders() throws Exception { + Path abc = Paths.get("src/test/test-data/mock/module-info.java"); // some file called module-info.java + Path def = Paths.get("src/test/test-data/mock/jar0.jar"); // any existing file + Path ghi = Paths.get("src/test/test-data/mock/jar1.jar"); // any existing file + ResolvePathsRequest request = ResolvePathsRequest.ofPaths(def, ghi) + .setMainModuleDescriptor(abc) + .setIncludeAllProviders(true); + + when(qdoxParser.fromSourcePath(abc)) + .thenReturn( + JavaModuleDescriptor.newModule("abc").requires("ghi").build()); + when(asmParser.getModuleDescriptor(def)) + .thenReturn(JavaModuleDescriptor.newModule("def") + .provides("tool", Arrays.asList("java", "javac")) + .build()); + when(asmParser.getModuleDescriptor(ghi)) + .thenReturn(JavaModuleDescriptor.newModule("ghi").uses("tool").build()); + + ResolvePathsResult result = locationManager.resolvePaths(request); + assertThat(result.getPathElements()).hasSize(2); + assertThat(result.getModulepathElements()).hasSize(2); + assertThat(result.getClasspathElements()).isEmpty(); + assertThat(result.getPathExceptions()).isEmpty(); } - + @Test - public void testAllowAdditionalModulesWithoutMainDescriptor() throws Exception - { - Path def = Paths.get( "src/test/resources/mock/jar0.jar" ); // any existing file - Path ghi = Paths.get( "src/test/resources/mock/jar1.jar" ); // any existing file - ResolvePathsRequest request = ResolvePathsRequest.ofPaths( def, ghi ).setAdditionalModules( Collections.singleton( "def" ) ); - - when( asmParser.getModuleDescriptor( def ) ).thenReturn( JavaModuleDescriptor.newModule( "def" ).build() ); - when( asmParser.getModuleDescriptor( ghi ) ).thenReturn( JavaModuleDescriptor.newModule( "ghi" ).build() ); - - ResolvePathsResult result = locationManager.resolvePaths( request ); - - assertThat( result.getPathElements().size(), is( 2 ) ); - assertThat( result.getModulepathElements().size(), is( 1 ) ); - assertThat( result.getClasspathElements().size(), is( 1 ) ); - assertThat( result.getPathExceptions().size(), is( 0 ) ); + void testDontIncludeProviders() throws Exception { + Path abc = Paths.get("src/test/test-data/mock/module-info.java"); // some file called module-info.java + Path def = Paths.get("src/test/test-data/mock/jar0.jar"); // any existing file + Path ghi = Paths.get("src/test/test-data/mock/jar1.jar"); // any existing file + ResolvePathsRequest request = + ResolvePathsRequest.ofPaths(def, ghi).setMainModuleDescriptor(abc); + + when(qdoxParser.fromSourcePath(abc)) + .thenReturn( + JavaModuleDescriptor.newModule("abc").requires("ghi").build()); + when(asmParser.getModuleDescriptor(def)) + .thenReturn(JavaModuleDescriptor.newModule("def") + .provides("tool", Arrays.asList("java", "javac")) + .build()); + when(asmParser.getModuleDescriptor(ghi)) + .thenReturn(JavaModuleDescriptor.newModule("ghi").uses("tool").build()); + + ResolvePathsResult result = locationManager.resolvePaths(request); + assertThat(result.getPathElements()).hasSize(2); + assertThat(result.getModulepathElements()).hasSize(1); + assertThat(result.getClasspathElements()).hasSize(1); + assertThat(result.getPathExceptions()).isEmpty(); } - + @Test - public void testReuseModuleDescriptor() throws Exception - { - Path def = Paths.get( "src/test/resources/mock/jar0.jar" ); - - ResolvePathRequest request1 = ResolvePathRequest.ofPath( def ); - when( asmParser.getModuleDescriptor( def ) ).thenReturn( JavaModuleDescriptor.newModule( "def" ).build() ); - - ResolvePathResult result1 = locationManager.resolvePath( request1 ); - - ResolvePathsRequest request2 = ResolvePathsRequest.ofPaths( def ); - request2.setModuleDescriptor( result1.getModuleDescriptor() ); - - ResolvePathsResult result2 = locationManager.resolvePaths( request2 ); - - assertThat( result1.getModuleDescriptor(), is( result2.getMainModuleDescriptor() ) ); + void testAllowAdditionalModulesWithoutMainDescriptor() throws Exception { + Path def = Paths.get("src/test/test-data/mock/jar0.jar"); // any existing file + Path ghi = Paths.get("src/test/test-data/mock/jar1.jar"); // any existing file + ResolvePathsRequest request = + ResolvePathsRequest.ofPaths(def, ghi).setAdditionalModules(Collections.singleton("def")); + + when(asmParser.getModuleDescriptor(def)) + .thenReturn(JavaModuleDescriptor.newModule("def").build()); + when(asmParser.getModuleDescriptor(ghi)) + .thenReturn(JavaModuleDescriptor.newModule("ghi").build()); + + ResolvePathsResult result = locationManager.resolvePaths(request); + assertThat(result.getPathElements()).hasSize(2); + assertThat(result.getModulepathElements()).hasSize(1); + assertThat(result.getClasspathElements()).hasSize(1); + assertThat(result.getPathExceptions()).isEmpty(); } - + @Test - public void testParseModuleDescriptor() throws Exception - { - Path descriptorPath = Paths.get( "src/test/resources/src.dir/module-info.java" ); - when( qdoxParser.fromSourcePath( descriptorPath ) ).thenReturn( JavaModuleDescriptor.newModule( "a.b.c" ).build() ); - - ResolvePathResult result = locationManager.parseModuleDescriptor( descriptorPath ); - assertThat( result.getModuleNameSource(), is( ModuleNameSource.MODULEDESCRIPTOR ) ); - assertThat( result.getModuleDescriptor().name(), is( "a.b.c" ) ); - - locationManager.parseModuleDescriptor( descriptorPath.toFile() ); - assertThat( result.getModuleNameSource(), is( ModuleNameSource.MODULEDESCRIPTOR ) ); - assertThat( result.getModuleDescriptor().name(), is( "a.b.c" ) ); - - locationManager.parseModuleDescriptor( descriptorPath.toString() ); - assertThat( result.getModuleNameSource(), is( ModuleNameSource.MODULEDESCRIPTOR ) ); - assertThat( result.getModuleDescriptor().name(), is( "a.b.c" ) ); + void testReuseModuleDescriptor() throws Exception { + Path def = Paths.get("src/test/test-data/mock/jar0.jar"); + + ResolvePathRequest request1 = ResolvePathRequest.ofPath(def); + when(asmParser.getModuleDescriptor(def)) + .thenReturn(JavaModuleDescriptor.newModule("def").build()); + + ResolvePathResult result1 = locationManager.resolvePath(request1); + + ResolvePathsRequest request2 = ResolvePathsRequest.ofPaths(def); + request2.setModuleDescriptor(result1.getModuleDescriptor()); + + ResolvePathsResult result2 = locationManager.resolvePaths(request2); + + assertThat(result1.getModuleDescriptor()).isEqualTo(result2.getMainModuleDescriptor()); } - + @Test - public void testTransitiveStatic() throws Exception - { - Path moduleA = Paths.get( "src/test/resources/mock/module-info.java" ); // some file called module-info.java - Path moduleB = Paths.get( "src/test/resources/mock/jar0.jar" ); // any existing file - Path moduleC = Paths.get( "src/test/resources/mock/jar1.jar" ); // any existing file - ResolvePathsRequest request = ResolvePathsRequest.ofPaths( moduleB, moduleC ).setMainModuleDescriptor( moduleA ); - - when( qdoxParser.fromSourcePath( moduleA ) ).thenReturn( JavaModuleDescriptor.newModule( "moduleA" ) - .requires( "moduleB" ).build() ); - when( asmParser.getModuleDescriptor( moduleB ) ).thenReturn( JavaModuleDescriptor.newModule( "moduleB" ) - .requires( Collections.singleton( JavaModifier.STATIC ), "moduleC" ).build() ); - when( asmParser.getModuleDescriptor( moduleC ) ).thenReturn( JavaModuleDescriptor.newModule( "moduleC" ).build() ); - - - ResolvePathsResult result = locationManager.resolvePaths( request ); - assertThat( result.getPathElements().size(), is( 2 ) ); - assertThat( result.getModulepathElements().size(), is( 1 ) ); - assertThat( result.getClasspathElements().size(), is( 1 ) ); - assertThat( result.getPathExceptions().size(), is( 0 ) ); + void testParseModuleDescriptor() throws Exception { + Path descriptorPath = Paths.get("src/test/test-data/src.dir/module-info.java"); + when(qdoxParser.fromSourcePath(descriptorPath)) + .thenReturn(JavaModuleDescriptor.newModule("a.b.c").build()); + + ResolvePathResult result = locationManager.parseModuleDescriptor(descriptorPath); + assertThat(result.getModuleNameSource()).isEqualTo(ModuleNameSource.MODULEDESCRIPTOR); + assertThat(result.getModuleDescriptor().name()).isEqualTo("a.b.c"); + + locationManager.parseModuleDescriptor(descriptorPath.toFile()); + assertThat(result.getModuleNameSource()).isEqualTo(ModuleNameSource.MODULEDESCRIPTOR); + assertThat(result.getModuleDescriptor().name()).isEqualTo("a.b.c"); + + locationManager.parseModuleDescriptor(descriptorPath.toString()); + assertThat(result.getModuleNameSource()).isEqualTo(ModuleNameSource.MODULEDESCRIPTOR); + assertThat(result.getModuleDescriptor().name()).isEqualTo("a.b.c"); } @Test - public void testDirectStatic() throws Exception - { - Path moduleA = Paths.get( "src/test/resources/mock/module-info.java" ); // some file called module-info.java - Path moduleB = Paths.get( "src/test/resources/mock/jar0.jar" ); // any existing file - Path moduleC = Paths.get( "src/test/resources/mock/jar1.jar" ); // any existing file - Path moduleD = Paths.get( "src/test/resources/mock/jar2.jar" ); // any existing file - ResolvePathsRequest request = ResolvePathsRequest.ofPaths( moduleB, moduleC, moduleD ) - .setMainModuleDescriptor( moduleA ); - //.setIncludeStatic( true ); - - when( qdoxParser.fromSourcePath( moduleA ) ).thenReturn( JavaModuleDescriptor.newModule( "moduleA" ) - .requires( "moduleB" ) - .requires( Collections.singleton( JavaModifier.STATIC ), "moduleD") - .build() ); - when( asmParser.getModuleDescriptor( moduleB ) ).thenReturn( JavaModuleDescriptor.newModule( "moduleB" ) - .requires( Collections.singleton( JavaModifier.STATIC ), "moduleC" ) - .build() ); - when( asmParser.getModuleDescriptor( moduleC ) ).thenReturn( JavaModuleDescriptor.newModule( "moduleC" ).build() ); - when( asmParser.getModuleDescriptor( moduleD ) ).thenReturn( JavaModuleDescriptor.newModule( "moduleD" ).build() ); - - - ResolvePathsResult result = locationManager.resolvePaths( request ); - assertThat( result.getPathElements().size(), is( 3 ) ); - assertThat( "content: " + result.getModulepathElements(), result.getModulepathElements().size(), is( 2 ) ); - assertThat( result.getModulepathElements().containsKey( moduleB ), is( true ) ); - assertThat( result.getModulepathElements().containsKey( moduleD ), is( true ) ); - assertThat( result.getClasspathElements().size(), is( 1 ) ); - assertThat( result.getClasspathElements().contains( moduleC ), is( true ) ); - assertThat( result.getPathExceptions().size(), is( 0 ) ); + void testTransitiveStatic() throws Exception { + Path moduleA = Paths.get("src/test/test-data/mock/module-info.java"); // some file called module-info.java + Path moduleB = Paths.get("src/test/test-data/mock/jar0.jar"); // any existing file + Path moduleC = Paths.get("src/test/test-data/mock/jar1.jar"); // any existing file + ResolvePathsRequest request = + ResolvePathsRequest.ofPaths(moduleB, moduleC).setMainModuleDescriptor(moduleA); + + when(qdoxParser.fromSourcePath(moduleA)) + .thenReturn(JavaModuleDescriptor.newModule("moduleA") + .requires("moduleB") + .build()); + when(asmParser.getModuleDescriptor(moduleB)) + .thenReturn(JavaModuleDescriptor.newModule("moduleB") + .requires(Collections.singleton(JavaModifier.STATIC), "moduleC") + .build()); + when(asmParser.getModuleDescriptor(moduleC)) + .thenReturn(JavaModuleDescriptor.newModule("moduleC").build()); + + ResolvePathsResult result = locationManager.resolvePaths(request); + assertThat(result.getPathElements()).hasSize(2); + assertThat(result.getModulepathElements()).hasSize(1); + assertThat(result.getClasspathElements()).hasSize(1); + assertThat(result.getPathExceptions()).isEmpty(); } - + @Test - public void testDuplicateModule() throws Exception - { - Path moduleA = Paths.get( "src/test/resources/mock/module-info.java" ); // some file called module-info.java - Path moduleB = Paths.get( "src/test/resources/mock/jar0.jar" ); // any existing file - Path moduleC = Paths.get( "src/test/resources/mock/jar1.jar" ); // any existing file - - ResolvePathsRequest request = ResolvePathsRequest.ofPaths( moduleB, moduleC ).setMainModuleDescriptor( moduleA ); - - when( qdoxParser.fromSourcePath( moduleA ) ).thenReturn( JavaModuleDescriptor.newModule( "moduleA" ) - .requires( "anonymous" ) - .build() ); - when( asmParser.getModuleDescriptor( moduleB ) ).thenReturn( JavaModuleDescriptor.newModule( "anonymous" ) - .build() ); - when( asmParser.getModuleDescriptor( moduleC ) ).thenReturn( JavaModuleDescriptor.newModule( "anonymous" ) - .build() ); - - ResolvePathsResult result = locationManager.resolvePaths( request ); - assertThat( result.getPathElements().size(), is( 2 ) ); - assertThat( result.getModulepathElements().size(), is( 1 ) ); - assertThat( result.getModulepathElements().containsKey( moduleB ), is( true ) ); - // with current default the duplicate will be ignored - assertThat( result.getClasspathElements().size(), is( 0 ) ); - assertThat( result.getPathExceptions().size(), is( 0 ) ); + void testDirectStatic() throws Exception { + Path moduleA = Paths.get("src/test/test-data/mock/module-info.java"); // some file called module-info.java + Path moduleB = Paths.get("src/test/test-data/mock/jar0.jar"); // any existing file + Path moduleC = Paths.get("src/test/test-data/mock/jar1.jar"); // any existing file + Path moduleD = Paths.get("src/test/test-data/mock/jar2.jar"); // any existing file + ResolvePathsRequest request = + ResolvePathsRequest.ofPaths(moduleB, moduleC, moduleD).setMainModuleDescriptor(moduleA); + // .setIncludeStatic( true ); + + when(qdoxParser.fromSourcePath(moduleA)) + .thenReturn(JavaModuleDescriptor.newModule("moduleA") + .requires("moduleB") + .requires(Collections.singleton(JavaModifier.STATIC), "moduleD") + .build()); + when(asmParser.getModuleDescriptor(moduleB)) + .thenReturn(JavaModuleDescriptor.newModule("moduleB") + .requires(Collections.singleton(JavaModifier.STATIC), "moduleC") + .build()); + when(asmParser.getModuleDescriptor(moduleC)) + .thenReturn(JavaModuleDescriptor.newModule("moduleC").build()); + when(asmParser.getModuleDescriptor(moduleD)) + .thenReturn(JavaModuleDescriptor.newModule("moduleD").build()); + + ResolvePathsResult result = locationManager.resolvePaths(request); + assertThat(result.getPathElements()).hasSize(3); + assertThat(result.getModulepathElements()).containsOnlyKeys(moduleB, moduleD); + assertThat(result.getClasspathElements()).containsOnly(moduleC); + assertThat(result.getPathExceptions()).isEmpty(); } - + @Test - public void testStaticTransitive() throws Exception - { - Path moduleA = Paths.get( "src/test/resources/mock/module-info.java" ); // some file called module-info.java - Path moduleB = Paths.get( "src/test/resources/mock/jar0.jar" ); // any existing file - Path moduleC = Paths.get( "src/test/resources/mock/jar1.jar" ); // any existing file - Path moduleD = Paths.get( "src/test/resources/mock/jar2.jar" ); // any existing file - ResolvePathsRequest request = ResolvePathsRequest.ofPaths( moduleB, moduleC, moduleD ).setMainModuleDescriptor( moduleA ); - - when( qdoxParser.fromSourcePath( moduleA ) ).thenReturn( JavaModuleDescriptor.newModule( "moduleA" ) - .requires( "moduleB" ) - .build() ); - when( asmParser.getModuleDescriptor( moduleB ) ).thenReturn( JavaModuleDescriptor.newModule( "moduleB" ) - .requires( new HashSet<>( Arrays.asList( JavaModifier.STATIC,JavaModifier.TRANSITIVE ) ), "moduleC" ) - .build() ); - when( asmParser.getModuleDescriptor( moduleC ) ).thenReturn( JavaModuleDescriptor.newModule( "moduleC" ) - .requires( new HashSet<>( Arrays.asList( JavaModifier.STATIC ) ), "moduleD" ) - .build() ); - when( asmParser.getModuleDescriptor( moduleD ) ).thenReturn( JavaModuleDescriptor.newModule( "moduleD" ).build() ); - - - ResolvePathsResult result = locationManager.resolvePaths( request ); - assertThat( result.getPathElements().size(), is( 3 ) ); - assertThat( "modulepathelements:" + result.getModulepathElements(), - result.getModulepathElements().size(), is( 2 ) ); - assertThat( result.getModulepathElements().containsKey( moduleB ), is( true ) ); - assertThat( result.getModulepathElements().containsKey( moduleC ), is( true ) ); - assertThat( result.getClasspathElements().size(), is( 1 ) ); - assertThat( result.getClasspathElements().contains( moduleD ), is( true ) ); - assertThat( result.getPathExceptions().size(), is( 0 ) ); + void testDuplicateModule() throws Exception { + Path moduleA = Paths.get("src/test/test-data/mock/module-info.java"); // some file called module-info.java + Path moduleB = Paths.get("src/test/test-data/mock/jar0.jar"); // any existing file + Path moduleC = Paths.get("src/test/test-data/mock/jar1.jar"); // any existing file + + ResolvePathsRequest request = + ResolvePathsRequest.ofPaths(moduleB, moduleC).setMainModuleDescriptor(moduleA); + + when(qdoxParser.fromSourcePath(moduleA)) + .thenReturn(JavaModuleDescriptor.newModule("moduleA") + .requires("anonymous") + .build()); + when(asmParser.getModuleDescriptor(moduleB)) + .thenReturn(JavaModuleDescriptor.newModule("anonymous").build()); + when(asmParser.getModuleDescriptor(moduleC)) + .thenReturn(JavaModuleDescriptor.newModule("anonymous").build()); + + ResolvePathsResult result = locationManager.resolvePaths(request); + assertThat(result.getPathElements()).hasSize(2); + assertThat(result.getModulepathElements()).containsOnlyKeys(moduleB); + assertThat(result.getClasspathElements()).isEmpty(); + assertThat(result.getPathExceptions()).hasSize(1); + // duplicate (module B / module C) is flagged as an error + assertThat(result.getPathExceptions()).containsOnlyKeys(moduleC); + assertThat(result.getPathExceptions().get(moduleC)) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining("Module 'anonymous' is already on the module path!"); } @Test + void testStaticTransitive() throws Exception { + Path moduleA = Paths.get("src/test/test-data/mock/module-info.java"); // some file called module-info.java + Path moduleB = Paths.get("src/test/test-data/mock/jar0.jar"); // any existing file + Path moduleC = Paths.get("src/test/test-data/mock/jar1.jar"); // any existing file + Path moduleD = Paths.get("src/test/test-data/mock/jar2.jar"); // any existing file + ResolvePathsRequest request = + ResolvePathsRequest.ofPaths(moduleB, moduleC, moduleD).setMainModuleDescriptor(moduleA); + + when(qdoxParser.fromSourcePath(moduleA)) + .thenReturn(JavaModuleDescriptor.newModule("moduleA") + .requires("moduleB") + .build()); + when(asmParser.getModuleDescriptor(moduleB)) + .thenReturn(JavaModuleDescriptor.newModule("moduleB") + .requires(new HashSet<>(Arrays.asList(JavaModifier.STATIC, JavaModifier.TRANSITIVE)), "moduleC") + .build()); + when(asmParser.getModuleDescriptor(moduleC)) + .thenReturn(JavaModuleDescriptor.newModule("moduleC") + .requires(new HashSet<>(Collections.singletonList(JavaModifier.STATIC)), "moduleD") + .build()); + when(asmParser.getModuleDescriptor(moduleD)) + .thenReturn(JavaModuleDescriptor.newModule("moduleD").build()); + + ResolvePathsResult result = locationManager.resolvePaths(request); + assertThat(result.getPathElements()).hasSize(3); + assertThat(result.getModulepathElements()).containsOnlyKeys(moduleB, moduleC); + assertThat(result.getClasspathElements()).containsOnly(moduleD); + assertThat(result.getPathExceptions()).isEmpty(); + } + /** - * test case for https://issues.apache.org/jira/browse/MCOMPILER-481 + * test case for MCOMPILER-481 */ - public void includeDeeperRequiresStatic() throws Exception - { - Path moduleA = Paths.get( "src/test/resources/mock/module-info.java" ); // some file called module-info.java - Path moduleB = Paths.get( "src/test/resources/mock/jar0.jar" ); // any existing file - Path moduleC = Paths.get( "src/test/resources/mock/jar1.jar" ); // any existing file - ResolvePathsRequest request = ResolvePathsRequest.ofPaths( moduleA, moduleB, moduleC ) - .setMainModuleDescriptor( moduleA ) - .setIncludeStatic( true ); - when( qdoxParser.fromSourcePath( moduleA ) ).thenReturn( JavaModuleDescriptor.newModule( "moduleA" ) - .requires( "moduleB") - .build() ); - when( asmParser.getModuleDescriptor( moduleB ) ).thenReturn( JavaModuleDescriptor.newModule( "moduleB" ) - .requires( Collections.singleton( JavaModifier.STATIC ), "moduleC" ) - .build() ); - when( asmParser.getModuleDescriptor( moduleC ) ).thenReturn( JavaModuleDescriptor.newModule( "moduleC" ).build() ); - - ResolvePathsResult result = locationManager.resolvePaths( request ); - assertThat( "modulepathelements:" + result.getModulepathElements(), - result.getModulepathElements().size(), is( 2 ) ); - assertThat( result.getModulepathElements().containsKey( moduleB ), is( true ) ); - assertThat( result.getModulepathElements().containsKey( moduleC ), is( true ) ); - + @Test + void includeDeeperRequiresStatic() throws Exception { + Path moduleA = Paths.get("src/test/test-data/mock/module-info.java"); // some file called module-info.java + Path moduleB = Paths.get("src/test/test-data/mock/jar0.jar"); // any existing file + Path moduleC = Paths.get("src/test/test-data/mock/jar1.jar"); // any existing file + ResolvePathsRequest request = ResolvePathsRequest.ofPaths(moduleA, moduleB, moduleC) + .setMainModuleDescriptor(moduleA) + .setIncludeStatic(true); + when(qdoxParser.fromSourcePath(moduleA)) + .thenReturn(JavaModuleDescriptor.newModule("moduleA") + .requires("moduleB") + .build()); + when(asmParser.getModuleDescriptor(moduleB)) + .thenReturn(JavaModuleDescriptor.newModule("moduleB") + .requires(Collections.singleton(JavaModifier.STATIC), "moduleC") + .build()); + when(asmParser.getModuleDescriptor(moduleC)) + .thenReturn(JavaModuleDescriptor.newModule("moduleC").build()); + + ResolvePathsResult result = locationManager.resolvePaths(request); + assertThat(result.getModulepathElements()).containsOnlyKeys(moduleB, moduleC); } - @Test /** - * test case for https://issues.apache.org/jira/browse/MCOMPILER-482 + * test case for MCOMPILER-482 */ - public void includeDeeperRequiresStaticTransitive() throws Exception - { - Path moduleA = Paths.get( "src/test/resources/mock/module-info.java" ); // some file called module-info.java core - Path moduleB = Paths.get( "src/test/resources/mock/jar0.jar" ); // any existing file - Path moduleC = Paths.get( "src/test/resources/mock/jar1.jar" ); // any existing file - Path moduleD = Paths.get( "src/test/resources/mock/jar2.jar" ); // any existing file - ResolvePathsRequest request = ResolvePathsRequest.ofPaths( moduleA, moduleB, moduleC, moduleD ) - .setMainModuleDescriptor( moduleA ) - .setIncludeStatic( true ); - when( qdoxParser.fromSourcePath( moduleA ) ).thenReturn( JavaModuleDescriptor.newModule( "moduleA" ) - .requires( "moduleB") - .build() ); - when( asmParser.getModuleDescriptor( moduleB ) ).thenReturn( JavaModuleDescriptor.newModule( "moduleB" ) - .requires( "moduleC" ) - .requires( new HashSet<>( Arrays.asList( JavaModifier.STATIC,JavaModifier.TRANSITIVE ) ), "moduleD" ) - .build() ); - when( asmParser.getModuleDescriptor( moduleC ) ).thenReturn( JavaModuleDescriptor.newModule( "moduleC" ) - .requires( new HashSet<>( Arrays.asList( JavaModifier.STATIC,JavaModifier.TRANSITIVE ) ), "moduleD" ) - .build() ); - when( asmParser.getModuleDescriptor( moduleD ) ).thenReturn( JavaModuleDescriptor.newModule( "moduleD" ) - .build() ); - - ResolvePathsResult result = locationManager.resolvePaths( request ); - assertThat( "modulepathelements:" + result.getModulepathElements(), - result.getModulepathElements().size(), is( 3 ) ); - assertThat( result.getModulepathElements().containsKey( moduleB ), is( true ) ); - assertThat( result.getModulepathElements().containsKey( moduleC ), is( true ) ); - assertThat( result.getModulepathElements().containsKey( moduleD ), is( true ) ); - + @Test + void includeDeeperRequiresStaticTransitive() throws Exception { + Path moduleA = Paths.get("src/test/test-data/mock/module-info.java"); // some file called module-info.java core + Path moduleB = Paths.get("src/test/test-data/mock/jar0.jar"); // any existing file + Path moduleC = Paths.get("src/test/test-data/mock/jar1.jar"); // any existing file + Path moduleD = Paths.get("src/test/test-data/mock/jar2.jar"); // any existing file + ResolvePathsRequest request = ResolvePathsRequest.ofPaths(moduleA, moduleB, moduleC, moduleD) + .setMainModuleDescriptor(moduleA) + .setIncludeStatic(true); + when(qdoxParser.fromSourcePath(moduleA)) + .thenReturn(JavaModuleDescriptor.newModule("moduleA") + .requires("moduleB") + .build()); + when(asmParser.getModuleDescriptor(moduleB)) + .thenReturn(JavaModuleDescriptor.newModule("moduleB") + .requires("moduleC") + .requires(new HashSet<>(Arrays.asList(JavaModifier.STATIC, JavaModifier.TRANSITIVE)), "moduleD") + .build()); + when(asmParser.getModuleDescriptor(moduleC)) + .thenReturn(JavaModuleDescriptor.newModule("moduleC") + .requires(new HashSet<>(Arrays.asList(JavaModifier.STATIC, JavaModifier.TRANSITIVE)), "moduleD") + .build()); + when(asmParser.getModuleDescriptor(moduleD)) + .thenReturn(JavaModuleDescriptor.newModule("moduleD").build()); + + ResolvePathsResult result = locationManager.resolvePaths(request); + assertThat(result.getModulepathElements()).containsOnlyKeys(moduleB, moduleC, moduleD); } - - } diff --git a/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/MainClassModuleNameExtractorTest.java b/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/MainClassModuleNameExtractorTest.java index 4a8acd9..f3d3662 100644 --- a/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/MainClassModuleNameExtractorTest.java +++ b/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/MainClassModuleNameExtractorTest.java @@ -24,20 +24,20 @@ import java.nio.file.Paths; import java.util.Collections; -public class MainClassModuleNameExtractorTest extends AbstractFilenameModuleNameExtractorTest -{ +import org.junit.jupiter.api.condition.DisabledOnJre; +import org.junit.jupiter.api.condition.JRE; + +@DisabledOnJre(value = JRE.JAVA_8, disabledReason = "Requires Java 9+ Module System") +public class MainClassModuleNameExtractorTest extends AbstractFilenameModuleNameExtractorTest { @Override - protected ModuleNameExtractor getExtractor() - { - return new ModuleNameExtractor() - { - MainClassModuleNameExtractor extractor = new MainClassModuleNameExtractor( Paths.get( System.getProperty( "java.home" ) ) ); - + protected ModuleNameExtractor getExtractor() { + return new ModuleNameExtractor() { + final MainClassModuleNameExtractor extractor = + new MainClassModuleNameExtractor(Paths.get(System.getProperty("java.home"))); + @Override - public String extract( Path file ) - throws IOException - { - return extractor.extract( Collections.singletonMap( file, file ) ).get( file ); + public String extract(Path file) throws IOException { + return extractor.extract(Collections.singletonMap(file, file)).get(file); } }; } diff --git a/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/ManifestModuleNameExtractorTest.java b/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/ManifestModuleNameExtractorTest.java index f221e62..e264a47 100644 --- a/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/ManifestModuleNameExtractorTest.java +++ b/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/ManifestModuleNameExtractorTest.java @@ -18,44 +18,40 @@ * specific language governing permissions and limitations * under the License. */ -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; - import java.nio.file.Paths; -import org.junit.Test; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; -public class ManifestModuleNameExtractorTest -{ +class ManifestModuleNameExtractorTest { private ManifestModuleNameExtractor extractor = new ManifestModuleNameExtractor(); @Test - public void testNoManifestInJar() throws Exception - { - assertNull( extractor.extract( Paths.get( "src/test/resources/jar.name/plexus-java-1.0.0-SNAPSHOT.jar" ) ) ); + void testNoManifestInJar() throws Exception { + assertNull(extractor.extract(Paths.get("src/test/test-data/jar.name/plexus-java-1.0.0-SNAPSHOT.jar"))); } @Test - public void testManifestInJar() throws Exception - { - assertEquals( "org.codehaus.plexus.languages.java", extractor.extract( Paths.get( "src/test/resources/jar.manifest.with/plexus-java-1.0.0-SNAPSHOT.jar" ) ) ); + void testManifestInJar() throws Exception { + assertEquals( + "org.codehaus.plexus.languages.java", + extractor.extract(Paths.get("src/test/test-data/jar.manifest.with/plexus-java-1.0.0-SNAPSHOT.jar"))); } @Test - public void testNoManifestInDir() throws Exception - { - assertNull( extractor.extract( Paths.get( "src/test/resources/empty/out" ) ) ); + void testNoManifestInDir() throws Exception { + assertNull(extractor.extract(Paths.get("src/test/test-data/empty/out"))); } @Test - public void testEmptyManifestInDir() throws Exception - { - assertNull( extractor.extract( Paths.get( "src/test/resources/manifest.without/out" ) ) ); + void testEmptyManifestInDir() throws Exception { + assertNull(extractor.extract(Paths.get("src/test/test-data/manifest.without/out"))); } @Test - public void testManifestInDir() throws Exception - { - assertEquals( "auto.by.manifest", extractor.extract( Paths.get( "src/test/resources/dir.manifest.with/out" ) ) ); + void testManifestInDir() throws Exception { + assertEquals("auto.by.manifest", extractor.extract(Paths.get("src/test/test-data/dir.manifest.with/out"))); } } diff --git a/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/SourceModuleInfoParserTest.java b/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/SourceModuleInfoParserTest.java index 9c4b883..c29e921 100644 --- a/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/SourceModuleInfoParserTest.java +++ b/plexus-java/src/test/java/org/codehaus/plexus/languages/java/jpms/SourceModuleInfoParserTest.java @@ -19,11 +19,6 @@ * under the License. */ -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - import java.nio.file.Paths; import java.util.Arrays; import java.util.HashSet; @@ -33,57 +28,61 @@ import org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaExports; import org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaProvides; import org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaRequires; -import org.junit.Test; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; -public class SourceModuleInfoParserTest -{ - private SourceModuleInfoParser parser = new SourceModuleInfoParser(); +class SourceModuleInfoParserTest { + private final SourceModuleInfoParser parser = new SourceModuleInfoParser(); @Test - public void test() throws Exception - { - JavaModuleDescriptor moduleDescriptor = parser.fromSourcePath( Paths.get( "src/test/resources/src.dir/module-info.java" ) ); - assertEquals( "a.b.c", moduleDescriptor.name() ); - + void test() throws Exception { + JavaModuleDescriptor moduleDescriptor = + parser.fromSourcePath(Paths.get("src/test/test-data/src.dir/module-info.java")); + assertEquals("a.b.c", moduleDescriptor.name()); + Iterator requiresIter = moduleDescriptor.requires().iterator(); - + JavaRequires requires = requiresIter.next(); - assertEquals( "d.e", requires.name() ); - assertFalse( requires.modifiers().contains( JavaRequires.JavaModifier.STATIC ) ); - assertFalse( requires.modifiers().contains( JavaRequires.JavaModifier.TRANSITIVE ) ); + assertEquals("d.e", requires.name()); + assertFalse(requires.modifiers().contains(JavaRequires.JavaModifier.STATIC)); + assertFalse(requires.modifiers().contains(JavaRequires.JavaModifier.TRANSITIVE)); requires = requiresIter.next(); - assertEquals( "s.d.e", requires.name() ); - assertTrue( requires.modifiers().contains( JavaRequires.JavaModifier.STATIC ) ); - assertFalse( requires.modifiers().contains( JavaRequires.JavaModifier.TRANSITIVE ) ); + assertEquals("s.d.e", requires.name()); + assertTrue(requires.modifiers().contains(JavaRequires.JavaModifier.STATIC)); + assertFalse(requires.modifiers().contains(JavaRequires.JavaModifier.TRANSITIVE)); requires = requiresIter.next(); - assertEquals( "t.d.e", requires.name() ); - assertFalse( requires.modifiers().contains( JavaRequires.JavaModifier.STATIC ) ); - assertTrue( requires.modifiers().contains( JavaRequires.JavaModifier.TRANSITIVE ) ); - + assertEquals("t.d.e", requires.name()); + assertFalse(requires.modifiers().contains(JavaRequires.JavaModifier.STATIC)); + assertTrue(requires.modifiers().contains(JavaRequires.JavaModifier.TRANSITIVE)); + requires = requiresIter.next(); - assertEquals( "s.t.d.e", requires.name() ); - assertTrue( requires.modifiers().contains( JavaRequires.JavaModifier.STATIC ) ); - assertTrue( requires.modifiers().contains( JavaRequires.JavaModifier.TRANSITIVE ) ); - + assertEquals("s.t.d.e", requires.name()); + assertTrue(requires.modifiers().contains(JavaRequires.JavaModifier.STATIC)); + assertTrue(requires.modifiers().contains(JavaRequires.JavaModifier.TRANSITIVE)); + Iterator exportsIter = moduleDescriptor.exports().iterator(); - - JavaExports exports = exportsIter.next(); - assertEquals( "f.g", exports.source() ); - - exports = exportsIter.next(); - assertEquals( "f.g.h", exports.source() ); - assertEquals( new HashSet<>( Arrays.asList( "i.j", "k.l.m" ) ), exports.targets() ); - + + JavaExports exports = exportsIter.next(); + assertEquals("f.g", exports.source()); + + exports = exportsIter.next(); + assertEquals("f.g.h", exports.source()); + assertEquals(new HashSet<>(Arrays.asList("i.j", "k.l.m")), exports.targets()); + Set uses = moduleDescriptor.uses(); - assertArrayEquals( new String[] { "com.example.foo.spi.Intf" } , uses.toArray( new String[0] ) ); - + assertArrayEquals(new String[] {"com.example.foo.spi.Intf"}, uses.toArray(new String[0])); + Iterator providesIter = moduleDescriptor.provides().iterator(); JavaProvides provides = providesIter.next(); - - assertEquals( "com.example.foo.spi.Intf", provides.service() ); - assertArrayEquals( new String[] { "com.example.foo.Impl" }, provides.providers().toArray( new String[0] ) ); - } + assertEquals("com.example.foo.spi.Intf", provides.service()); + assertArrayEquals( + new String[] {"com.example.foo.Impl"}, provides.providers().toArray(new String[0])); + } } diff --git a/plexus-java/src/test/java/org/codehaus/plexus/languages/java/version/JavaClassVersionTest.java b/plexus-java/src/test/java/org/codehaus/plexus/languages/java/version/JavaClassVersionTest.java new file mode 100644 index 0000000..c29b50a --- /dev/null +++ b/plexus-java/src/test/java/org/codehaus/plexus/languages/java/version/JavaClassVersionTest.java @@ -0,0 +1,79 @@ +package org.codehaus.plexus.languages.java.version; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class JavaClassVersionTest { + + @ParameterizedTest + @MethodSource("provideClassFiles") + void testFilesClassVersions(Path filePath) { + String fileName = filePath.getFileName().toString(); + int javaVersion = Integer.parseInt(fileName.substring(fileName.indexOf("-") + 1, fileName.length() - 6)); + JavaClassfileVersion classVersion = JavaClassfileVersion.of(filePath); + assertEquals(javaVersion + 44, classVersion.majorVersion()); + assertEquals(0, classVersion.minorVersion()); + assertEquals(JavaVersion.parse("" + javaVersion), classVersion.javaVersion()); + } + + static Stream provideClassFiles() { + List paths; + try (DirectoryStream directoryStream = + Files.newDirectoryStream(Paths.get("src/test/test-data/classfile.version/"), "*-[0-9]?.class")) { + paths = StreamSupport.stream(directoryStream.spliterator(), false) + .filter(Files::isRegularFile) + .collect(Collectors.toList()); + } catch (IOException ex) { + throw new UncheckedIOException(ex); + } + return paths.stream(); + } + + @Test + void testJavaClassPreview() { + Path previewFile = Paths.get("src/test/test-data/classfile.version/helloworld-preview.class"); + JavaClassfileVersion previewClass = JavaClassfileVersion.of(previewFile); + assertTrue(previewClass.isPreview()); + assertEquals(20 + 44, previewClass.majorVersion()); + assertEquals(JavaVersion.parse("20"), previewClass.javaVersion()); + } + + @Test + void testJavaClassVersionMajor45orAbove() { + assertThrows( + IllegalArgumentException.class, + () -> new JavaClassfileVersion(44, 0), + "Java class major version must be 45 or above."); + } + + @Test + void equalsContract() { + JavaClassfileVersion javaClassVersion = new JavaClassfileVersion(65, 0); + JavaClassfileVersion previewFeature = new JavaClassfileVersion(65, 65535); + assertNotEquals(javaClassVersion, previewFeature); + assertNotEquals(javaClassVersion.hashCode(), previewFeature.hashCode()); + + JavaClassfileVersion javaClassVersionOther = new JavaClassfileVersion(65, 0); + assertEquals(javaClassVersion, javaClassVersionOther); + assertEquals(javaClassVersion.hashCode(), javaClassVersionOther.hashCode()); + assertEquals(javaClassVersion.javaVersion(), javaClassVersionOther.javaVersion()); + assertEquals(javaClassVersion.javaVersion(), previewFeature.javaVersion()); + } +} diff --git a/plexus-java/src/test/java/org/codehaus/plexus/languages/java/version/JavaVersionTest.java b/plexus-java/src/test/java/org/codehaus/plexus/languages/java/version/JavaVersionTest.java index 8474349..39b4381 100644 --- a/plexus-java/src/test/java/org/codehaus/plexus/languages/java/version/JavaVersionTest.java +++ b/plexus-java/src/test/java/org/codehaus/plexus/languages/java/version/JavaVersionTest.java @@ -19,143 +19,151 @@ * under the License. */ -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; +import org.junit.jupiter.api.Test; -import org.junit.Test; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; /* * Parsing is lazy, only triggered when comparing */ -public class JavaVersionTest -{ +class JavaVersionTest { @Test - public void testParse() - throws Exception - { - assertTrue( JavaVersion.parse( "1.4" ).compareTo( JavaVersion.parse( "1.4.2" ) ) < 0 ); - assertTrue( JavaVersion.parse( "1.4" ).compareTo( JavaVersion.parse( "1.5" ) ) < 0 ); - assertTrue( JavaVersion.parse( "1.8" ).compareTo( JavaVersion.parse( "9" ) ) < 0 ); - - assertTrue( JavaVersion.parse( "1.4" ).compareTo( JavaVersion.parse( "1.4" ) ) == 0 ); - assertTrue( JavaVersion.parse( "1.4.2" ).compareTo( JavaVersion.parse( "1.4.2" ) ) == 0 ); - assertTrue( JavaVersion.parse( "9" ).compareTo( JavaVersion.parse( "9" ) ) == 0 ); - - assertTrue( JavaVersion.parse( "1.4.2" ).compareTo( JavaVersion.parse( "1.4" ) ) > 0 ); - assertTrue( JavaVersion.parse( "1.5" ).compareTo( JavaVersion.parse( "1.4" ) ) > 0 ); - assertTrue( JavaVersion.parse( "9" ).compareTo( JavaVersion.parse( "1.8" ) ) > 0 ); + void testParse() { + assertThat(JavaVersion.parse("1.4").compareTo(JavaVersion.parse("1.4.2"))) + .isNegative(); + assertThat(JavaVersion.parse("1.4").compareTo(JavaVersion.parse("1.5"))).isNegative(); + assertThat(JavaVersion.parse("1.8").compareTo(JavaVersion.parse("9"))).isNegative(); + + assertThat(JavaVersion.parse("1.4").compareTo(JavaVersion.parse("1.4"))).isZero(); + assertThat(JavaVersion.parse("1.4.2").compareTo(JavaVersion.parse("1.4.2"))) + .isZero(); + assertThat(JavaVersion.parse("9").compareTo(JavaVersion.parse("9"))).isZero(); + + assertThat(JavaVersion.parse("1.4.2").compareTo(JavaVersion.parse("1.4"))) + .isPositive(); + assertThat(JavaVersion.parse("1.5").compareTo(JavaVersion.parse("1.4"))).isPositive(); + assertThat(JavaVersion.parse("9").compareTo(JavaVersion.parse("1.8"))).isPositive(); } - + @Test - public void testVersionNamingExamples() - { - // All GA (FCS) versions are ordered based on the standard dot-notation. For example: 1.3.0 < 1.3.0_01 < 1.3.1 < 1.3.1_01. + void testVersionNamingExamples() { + // All GA (FCS) versions are ordered based on the standard dot-notation. For example: 1.3.0 < 1.3.0_01 < 1.3.1 < + // 1.3.1_01. // Source: http://www.oracle.com/technetwork/java/javase/versioning-naming-139433.html - - assertTrue( JavaVersion.parse( "1.3.0" ).compareTo( JavaVersion.parse( "1.3.0_01" ) ) < 0 ); - assertTrue( JavaVersion.parse( "1.3.0_01" ).compareTo( JavaVersion.parse( "1.3.1" ) ) < 0 ); - assertTrue( JavaVersion.parse( "1.3.1" ).compareTo( JavaVersion.parse( "1.3.1_01" ) ) < 0 ); - - assertTrue( JavaVersion.parse( "1.3.0" ).compareTo( JavaVersion.parse( "1.3.0-b24" ) ) < 0 ); + + assertThat(JavaVersion.parse("1.3.0").compareTo(JavaVersion.parse("1.3.0_01"))) + .isNegative(); + assertThat(JavaVersion.parse("1.3.0_01").compareTo(JavaVersion.parse("1.3.1"))) + .isNegative(); + assertThat(JavaVersion.parse("1.3.1").compareTo(JavaVersion.parse("1.3.1_01"))) + .isNegative(); + + assertThat(JavaVersion.parse("1.3.0").compareTo(JavaVersion.parse("1.3.0-b24"))) + .isNegative(); } @Test - public void testJEP223Short() { + void testJEP223Short() { // http://openjdk.java.net/jeps/223 - assertTrue( JavaVersion.parse( "9-ea" ).compareTo( JavaVersion.parse( "9" ) ) < 0 ); - assertTrue( JavaVersion.parse( "9" ).compareTo( JavaVersion.parse( "9.0.1" ) ) < 0 ); - assertTrue( JavaVersion.parse( "9.0.1" ).compareTo( JavaVersion.parse( "9.0.2" ) ) < 0 ); - assertTrue( JavaVersion.parse( "9.0.2" ).compareTo( JavaVersion.parse( "9.1.2" ) ) < 0 ); - assertTrue( JavaVersion.parse( "9.1.2" ).compareTo( JavaVersion.parse( "9.1.3" ) ) < 0 ); - assertTrue( JavaVersion.parse( "9.1.3" ).compareTo( JavaVersion.parse( "9.1.4" ) ) < 0 ); - assertTrue( JavaVersion.parse( "9.1.4" ).compareTo( JavaVersion.parse( "9.2.4" ) ) < 0 ); + assertThat(JavaVersion.parse("9-ea").compareTo(JavaVersion.parse("9"))).isNegative(); + assertThat(JavaVersion.parse("9").compareTo(JavaVersion.parse("9.0.1"))).isNegative(); + assertThat(JavaVersion.parse("9.0.1").compareTo(JavaVersion.parse("9.0.2"))) + .isNegative(); + assertThat(JavaVersion.parse("9.0.2").compareTo(JavaVersion.parse("9.1.2"))) + .isNegative(); + assertThat(JavaVersion.parse("9.1.2").compareTo(JavaVersion.parse("9.1.3"))) + .isNegative(); + assertThat(JavaVersion.parse("9.1.3").compareTo(JavaVersion.parse("9.1.4"))) + .isNegative(); + assertThat(JavaVersion.parse("9.1.4").compareTo(JavaVersion.parse("9.2.4"))) + .isNegative(); } - + @Test - public void testIsAtLeastString() { - JavaVersion base = JavaVersion.parse( "7" ); - assertTrue( base.isAtLeast( "7" ) ); - assertFalse( base.isAtLeast( "8" ) ); + void testIsAtLeastString() { + JavaVersion base = JavaVersion.parse("7"); + assertTrue(base.isAtLeast("7")); + assertFalse(base.isAtLeast("8")); } @Test - public void testIsAtLeastVersion() { + void testIsAtLeastVersion() { // e.g. can I use the module-path, which is supported since java 9 - JavaVersion j9 = JavaVersion.parse( "9" ); - assertFalse( JavaVersion.parse( "8" ).isAtLeast( j9 ) ); - assertTrue( JavaVersion.parse( "9" ).isAtLeast( j9 ) ); + JavaVersion j9 = JavaVersion.parse("9"); + assertFalse(JavaVersion.parse("8").isAtLeast(j9)); + assertTrue(JavaVersion.parse("9").isAtLeast(j9)); } @Test - public void testIsBeforeString() { - JavaVersion base = JavaVersion.parse( "7" ); - assertFalse( base.isBefore( "7" ) ); - assertTrue( base.isBefore( "8" ) ); + void testIsBeforeString() { + JavaVersion base = JavaVersion.parse("7"); + assertFalse(base.isBefore("7")); + assertTrue(base.isBefore("8")); } @Test - public void testIsBeforeStringVersion() { + void testIsBeforeStringVersion() { // e.g. can I use -XX:MaxPermSize, which has been removed in Java 9 - JavaVersion j9 = JavaVersion.parse( "9" ); - assertTrue( JavaVersion.parse( "8" ).isBefore( j9 ) ); - assertFalse( JavaVersion.parse( "9" ).isBefore( j9 ) ); + JavaVersion j9 = JavaVersion.parse("9"); + assertTrue(JavaVersion.parse("8").isBefore(j9)); + assertFalse(JavaVersion.parse("9").isBefore(j9)); } @Test - public void testEquals() { - JavaVersion seven = JavaVersion.parse( "7" ); - JavaVersion other = JavaVersion.parse( "7" ); - - assertEquals( seven, seven ); - assertEquals( seven, other ); - assertNotEquals( seven, null ); - assertNotEquals( seven, new Object() ); - assertNotEquals( seven, JavaVersion.parse( "8" ) ); + void testEquals() { + JavaVersion seven = JavaVersion.parse("7"); + JavaVersion other = JavaVersion.parse("7"); + + assertThat(seven).isEqualTo(seven); + assertEquals(seven, other); + assertNotEquals(null, seven); + assertNotEquals(seven, new Object()); + assertNotEquals(seven, JavaVersion.parse("8")); } @Test - public void testHascode() { - JavaVersion seven = JavaVersion.parse( "7" ); - JavaVersion other = JavaVersion.parse( "7" ); - - assertEquals( seven.hashCode(), other.hashCode() ); + void testHascode() { + JavaVersion seven = JavaVersion.parse("7"); + JavaVersion other = JavaVersion.parse("7"); + + assertEquals(seven.hashCode(), other.hashCode()); } @Test - public void testToString() { - assertEquals( "7", JavaVersion.parse( "7" ).toString() ); - - assertEquals( "Raw version should not be parsed", "!@#$%^&*()", JavaVersion.parse( "!@#$%^&*()" ).toString() ); + void testToString() { + assertEquals("7", JavaVersion.parse("7").toString()); + + assertEquals("!@#$%^&*()", JavaVersion.parse("!@#$%^&*()").toString(), "Raw version should not be parsed"); } - + @Test - public void testAsMajor() { - assertEquals( JavaVersion.parse( "2" ), JavaVersion.parse( "1.2" ).asMajor() ); - assertEquals( JavaVersion.parse( "5.0" ), JavaVersion.parse( "5.0" ).asMajor() ); + void testAsMajor() { + assertEquals(JavaVersion.parse("2"), JavaVersion.parse("1.2").asMajor()); + assertEquals(JavaVersion.parse("5.0"), JavaVersion.parse("5.0").asMajor()); // only shift one time - assertEquals( JavaVersion.parse( "1.1.2" ).asMajor().asMajor().toString(), "1.2" ); + assertEquals("1.2", JavaVersion.parse("1.1.2").asMajor().asMajor().toString()); } - + @Test - public void testAsMajorEquals() { - JavaVersion version = JavaVersion.parse( "1.2" ); - assertEquals( version, version.asMajor() ); + void testAsMajorEquals() { + JavaVersion version = JavaVersion.parse("1.2"); + assertEquals(version, version.asMajor()); } - + @Test - public void testValueWithGroups() { - assertThat( JavaVersion.parse( "1" ).getValue( 1 ), is( "1" ) ); - assertThat( JavaVersion.parse( "1" ).getValue( 2 ), is( "1.0" ) ); - assertThat( JavaVersion.parse( "1" ).getValue( 3 ), is( "1.0.0" ) ); - assertThat( JavaVersion.parse( "2.1" ).getValue( 1 ), is( "2" ) ); - assertThat( JavaVersion.parse( "2.1" ).getValue( 2 ), is( "2.1" ) ); - assertThat( JavaVersion.parse( "2.1" ).getValue( 3 ), is( "2.1.0" ) ); - assertThat( JavaVersion.parse( "3.2.1" ).getValue( 1 ), is( "3" ) ); - assertThat( JavaVersion.parse( "3.2.1" ).getValue( 2 ), is( "3.2" ) ); - assertThat( JavaVersion.parse( "3.2.1" ).getValue( 3 ), is( "3.2.1" ) ); + void testValueWithGroups() { + assertThat(JavaVersion.parse("1").getValue(1)).isEqualTo("1"); + assertThat(JavaVersion.parse("1").getValue(2)).isEqualTo("1.0"); + assertThat(JavaVersion.parse("1").getValue(3)).isEqualTo("1.0.0"); + assertThat(JavaVersion.parse("2.1").getValue(1)).isEqualTo("2"); + assertThat(JavaVersion.parse("2.1").getValue(2)).isEqualTo("2.1"); + assertThat(JavaVersion.parse("2.1").getValue(3)).isEqualTo("2.1.0"); + assertThat(JavaVersion.parse("3.2.1").getValue(1)).isEqualTo("3"); + assertThat(JavaVersion.parse("3.2.1").getValue(2)).isEqualTo("3.2"); + assertThat(JavaVersion.parse("3.2.1").getValue(3)).isEqualTo("3.2.1"); } } diff --git a/plexus-java/src/test/test-data/classfile.version/helloworld-10.class b/plexus-java/src/test/test-data/classfile.version/helloworld-10.class new file mode 100644 index 0000000..9251951 Binary files /dev/null and b/plexus-java/src/test/test-data/classfile.version/helloworld-10.class differ diff --git a/plexus-java/src/test/test-data/classfile.version/helloworld-11.class b/plexus-java/src/test/test-data/classfile.version/helloworld-11.class new file mode 100644 index 0000000..e7b2672 Binary files /dev/null and b/plexus-java/src/test/test-data/classfile.version/helloworld-11.class differ diff --git a/plexus-java/src/test/test-data/classfile.version/helloworld-12.class b/plexus-java/src/test/test-data/classfile.version/helloworld-12.class new file mode 100644 index 0000000..5cd0678 Binary files /dev/null and b/plexus-java/src/test/test-data/classfile.version/helloworld-12.class differ diff --git a/plexus-java/src/test/test-data/classfile.version/helloworld-13.class b/plexus-java/src/test/test-data/classfile.version/helloworld-13.class new file mode 100644 index 0000000..e95b0b4 Binary files /dev/null and b/plexus-java/src/test/test-data/classfile.version/helloworld-13.class differ diff --git a/plexus-java/src/test/test-data/classfile.version/helloworld-14.class b/plexus-java/src/test/test-data/classfile.version/helloworld-14.class new file mode 100644 index 0000000..c0d0662 Binary files /dev/null and b/plexus-java/src/test/test-data/classfile.version/helloworld-14.class differ diff --git a/plexus-java/src/test/test-data/classfile.version/helloworld-15.class b/plexus-java/src/test/test-data/classfile.version/helloworld-15.class new file mode 100644 index 0000000..1b62db6 Binary files /dev/null and b/plexus-java/src/test/test-data/classfile.version/helloworld-15.class differ diff --git a/plexus-java/src/test/test-data/classfile.version/helloworld-16.class b/plexus-java/src/test/test-data/classfile.version/helloworld-16.class new file mode 100644 index 0000000..bade14e Binary files /dev/null and b/plexus-java/src/test/test-data/classfile.version/helloworld-16.class differ diff --git a/plexus-java/src/test/test-data/classfile.version/helloworld-17.class b/plexus-java/src/test/test-data/classfile.version/helloworld-17.class new file mode 100644 index 0000000..461c9cd Binary files /dev/null and b/plexus-java/src/test/test-data/classfile.version/helloworld-17.class differ diff --git a/plexus-java/src/test/test-data/classfile.version/helloworld-18.class b/plexus-java/src/test/test-data/classfile.version/helloworld-18.class new file mode 100644 index 0000000..5ae0ca1 Binary files /dev/null and b/plexus-java/src/test/test-data/classfile.version/helloworld-18.class differ diff --git a/plexus-java/src/test/test-data/classfile.version/helloworld-19.class b/plexus-java/src/test/test-data/classfile.version/helloworld-19.class new file mode 100644 index 0000000..bd24b66 Binary files /dev/null and b/plexus-java/src/test/test-data/classfile.version/helloworld-19.class differ diff --git a/plexus-java/src/test/test-data/classfile.version/helloworld-20.class b/plexus-java/src/test/test-data/classfile.version/helloworld-20.class new file mode 100644 index 0000000..99f757e Binary files /dev/null and b/plexus-java/src/test/test-data/classfile.version/helloworld-20.class differ diff --git a/plexus-java/src/test/test-data/classfile.version/helloworld-21.class b/plexus-java/src/test/test-data/classfile.version/helloworld-21.class new file mode 100644 index 0000000..e57d1b9 Binary files /dev/null and b/plexus-java/src/test/test-data/classfile.version/helloworld-21.class differ diff --git a/plexus-java/src/test/test-data/classfile.version/helloworld-22.class b/plexus-java/src/test/test-data/classfile.version/helloworld-22.class new file mode 100644 index 0000000..ff268d8 Binary files /dev/null and b/plexus-java/src/test/test-data/classfile.version/helloworld-22.class differ diff --git a/plexus-java/src/test/test-data/classfile.version/helloworld-23.class b/plexus-java/src/test/test-data/classfile.version/helloworld-23.class new file mode 100644 index 0000000..08eff34 Binary files /dev/null and b/plexus-java/src/test/test-data/classfile.version/helloworld-23.class differ diff --git a/plexus-java/src/test/test-data/classfile.version/helloworld-24.class b/plexus-java/src/test/test-data/classfile.version/helloworld-24.class new file mode 100644 index 0000000..7191293 Binary files /dev/null and b/plexus-java/src/test/test-data/classfile.version/helloworld-24.class differ diff --git a/plexus-java/src/test/test-data/classfile.version/helloworld-8.class b/plexus-java/src/test/test-data/classfile.version/helloworld-8.class new file mode 100644 index 0000000..c1ad791 Binary files /dev/null and b/plexus-java/src/test/test-data/classfile.version/helloworld-8.class differ diff --git a/plexus-java/src/test/test-data/classfile.version/helloworld-9.class b/plexus-java/src/test/test-data/classfile.version/helloworld-9.class new file mode 100644 index 0000000..06772b5 Binary files /dev/null and b/plexus-java/src/test/test-data/classfile.version/helloworld-9.class differ diff --git a/plexus-java/src/test/test-data/classfile.version/helloworld-preview.class b/plexus-java/src/test/test-data/classfile.version/helloworld-preview.class new file mode 100644 index 0000000..7b77d72 Binary files /dev/null and b/plexus-java/src/test/test-data/classfile.version/helloworld-preview.class differ diff --git a/plexus-java/src/test/resources/dir.descriptor.requires/out/module-info.class b/plexus-java/src/test/test-data/dir.descriptor.requires/out/module-info.class similarity index 100% rename from plexus-java/src/test/resources/dir.descriptor.requires/out/module-info.class rename to plexus-java/src/test/test-data/dir.descriptor.requires/out/module-info.class diff --git a/plexus-java/src/test/resources/dir.descriptor.uses/out/module-info.class b/plexus-java/src/test/test-data/dir.descriptor.uses/out/module-info.class similarity index 100% rename from plexus-java/src/test/resources/dir.descriptor.uses/out/module-info.class rename to plexus-java/src/test/test-data/dir.descriptor.uses/out/module-info.class diff --git a/plexus-java/src/test/resources/dir.descriptor/out/module-info.class b/plexus-java/src/test/test-data/dir.descriptor/out/module-info.class similarity index 100% rename from plexus-java/src/test/resources/dir.descriptor/out/module-info.class rename to plexus-java/src/test/test-data/dir.descriptor/out/module-info.class diff --git a/plexus-java/src/test/resources/dir.empty/out/README.txt b/plexus-java/src/test/test-data/dir.empty/out/README.txt similarity index 100% rename from plexus-java/src/test/resources/dir.empty/out/README.txt rename to plexus-java/src/test/test-data/dir.empty/out/README.txt diff --git a/plexus-java/src/test/resources/dir.manifest.with/out/META-INF/MANIFEST.MF b/plexus-java/src/test/test-data/dir.manifest.with/out/META-INF/MANIFEST.MF similarity index 100% rename from plexus-java/src/test/resources/dir.manifest.with/out/META-INF/MANIFEST.MF rename to plexus-java/src/test/test-data/dir.manifest.with/out/META-INF/MANIFEST.MF diff --git a/plexus-java/src/test/resources/dir.manifest.without/out/META-INF/MANIFEST.MF b/plexus-java/src/test/test-data/dir.manifest.without/out/META-INF/MANIFEST.MF similarity index 100% rename from plexus-java/src/test/resources/dir.manifest.without/out/META-INF/MANIFEST.MF rename to plexus-java/src/test/test-data/dir.manifest.without/out/META-INF/MANIFEST.MF diff --git a/plexus-java/src/test/resources/jar with spaces in path/plexus-java-1.0.0-SNAPSHOT.jar b/plexus-java/src/test/test-data/jar with spaces in path/plexus-java-1.0.0-SNAPSHOT.jar similarity index 100% rename from plexus-java/src/test/resources/jar with spaces in path/plexus-java-1.0.0-SNAPSHOT.jar rename to plexus-java/src/test/test-data/jar with spaces in path/plexus-java-1.0.0-SNAPSHOT.jar diff --git a/plexus-java/src/test/resources/jar.descriptor/asm-6.0_BETA.jar b/plexus-java/src/test/test-data/jar.descriptor/asm-6.0_BETA.jar similarity index 100% rename from plexus-java/src/test/resources/jar.descriptor/asm-6.0_BETA.jar rename to plexus-java/src/test/test-data/jar.descriptor/asm-6.0_BETA.jar diff --git a/plexus-java/src/test/resources/jar.empty.2/plexus-java-2.0.0-SNAPSHOT.jar b/plexus-java/src/test/test-data/jar.empty.2/plexus-java-2.0.0-SNAPSHOT.jar similarity index 100% rename from plexus-java/src/test/resources/jar.empty.2/plexus-java-2.0.0-SNAPSHOT.jar rename to plexus-java/src/test/test-data/jar.empty.2/plexus-java-2.0.0-SNAPSHOT.jar diff --git a/plexus-java/src/test/resources/jar.empty.invalid.name/101-1.0.0-SNAPSHOT.jar b/plexus-java/src/test/test-data/jar.empty.invalid.name/101-1.0.0-SNAPSHOT.jar similarity index 100% rename from plexus-java/src/test/resources/jar.empty.invalid.name/101-1.0.0-SNAPSHOT.jar rename to plexus-java/src/test/test-data/jar.empty.invalid.name/101-1.0.0-SNAPSHOT.jar diff --git a/plexus-java/src/test/resources/jar.empty/plexus-java-1.0.0-SNAPSHOT.jar b/plexus-java/src/test/test-data/jar.empty/plexus-java-1.0.0-SNAPSHOT.jar similarity index 100% rename from plexus-java/src/test/resources/jar.empty/plexus-java-1.0.0-SNAPSHOT.jar rename to plexus-java/src/test/test-data/jar.empty/plexus-java-1.0.0-SNAPSHOT.jar diff --git a/plexus-java/src/test/resources/jar.manifest.with/plexus-java-1.0.0-SNAPSHOT.jar b/plexus-java/src/test/test-data/jar.manifest.with/plexus-java-1.0.0-SNAPSHOT.jar similarity index 100% rename from plexus-java/src/test/resources/jar.manifest.with/plexus-java-1.0.0-SNAPSHOT.jar rename to plexus-java/src/test/test-data/jar.manifest.with/plexus-java-1.0.0-SNAPSHOT.jar diff --git a/plexus-java/src/test/resources/jar.mr.descriptor/jloadr-1.0-SNAPSHOT.jar b/plexus-java/src/test/test-data/jar.mr.descriptor/jloadr-1.0-SNAPSHOT.jar similarity index 100% rename from plexus-java/src/test/resources/jar.mr.descriptor/jloadr-1.0-SNAPSHOT.jar rename to plexus-java/src/test/test-data/jar.mr.descriptor/jloadr-1.0-SNAPSHOT.jar diff --git a/plexus-java/src/test/resources/jar.mr.incomplete.descriptor/jloadr-1.0-SNAPSHOT.jar b/plexus-java/src/test/test-data/jar.mr.incomplete.descriptor/jloadr-1.0-SNAPSHOT.jar similarity index 100% rename from plexus-java/src/test/resources/jar.mr.incomplete.descriptor/jloadr-1.0-SNAPSHOT.jar rename to plexus-java/src/test/test-data/jar.mr.incomplete.descriptor/jloadr-1.0-SNAPSHOT.jar diff --git a/plexus-java/src/test/resources/jar.service/threeten-extra-1.4.jar b/plexus-java/src/test/test-data/jar.service/threeten-extra-1.4.jar similarity index 100% rename from plexus-java/src/test/resources/jar.service/threeten-extra-1.4.jar rename to plexus-java/src/test/test-data/jar.service/threeten-extra-1.4.jar diff --git a/plexus-java/src/test/test-data/jar.tests/plexus-java-1.0.0-SNAPSHOT-tests.jar b/plexus-java/src/test/test-data/jar.tests/plexus-java-1.0.0-SNAPSHOT-tests.jar new file mode 100644 index 0000000..a6afd0f Binary files /dev/null and b/plexus-java/src/test/test-data/jar.tests/plexus-java-1.0.0-SNAPSHOT-tests.jar differ diff --git a/plexus-java/src/test/test-data/jar.tests/plexus-java-1.0.0-SNAPSHOT.jar b/plexus-java/src/test/test-data/jar.tests/plexus-java-1.0.0-SNAPSHOT.jar new file mode 100644 index 0000000..413ae96 Binary files /dev/null and b/plexus-java/src/test/test-data/jar.tests/plexus-java-1.0.0-SNAPSHOT.jar differ diff --git a/plexus-java/src/test/resources/jar.unsupported/jdom-1.0.jar b/plexus-java/src/test/test-data/jar.unsupported/jdom-1.0.jar similarity index 100% rename from plexus-java/src/test/resources/jar.unsupported/jdom-1.0.jar rename to plexus-java/src/test/test-data/jar.unsupported/jdom-1.0.jar diff --git a/plexus-java/src/test/resources/jmod.descriptor/first-jmod-1.0-SNAPSHOT.jmod b/plexus-java/src/test/test-data/jmod.descriptor/first-jmod-1.0-SNAPSHOT.jmod similarity index 100% rename from plexus-java/src/test/resources/jmod.descriptor/first-jmod-1.0-SNAPSHOT.jmod rename to plexus-java/src/test/test-data/jmod.descriptor/first-jmod-1.0-SNAPSHOT.jmod diff --git a/plexus-java/src/test/resources/mock/jar0.jar b/plexus-java/src/test/test-data/mock/jar0.jar similarity index 100% rename from plexus-java/src/test/resources/mock/jar0.jar rename to plexus-java/src/test/test-data/mock/jar0.jar diff --git a/plexus-java/src/test/resources/mock/jar1.jar b/plexus-java/src/test/test-data/mock/jar1.jar similarity index 100% rename from plexus-java/src/test/resources/mock/jar1.jar rename to plexus-java/src/test/test-data/mock/jar1.jar diff --git a/plexus-java/src/test/resources/mock/jar2.jar b/plexus-java/src/test/test-data/mock/jar2.jar similarity index 100% rename from plexus-java/src/test/resources/mock/jar2.jar rename to plexus-java/src/test/test-data/mock/jar2.jar diff --git a/plexus-java/src/test/resources/mock/module-info.class b/plexus-java/src/test/test-data/mock/module-info.class similarity index 100% rename from plexus-java/src/test/resources/mock/module-info.class rename to plexus-java/src/test/test-data/mock/module-info.class diff --git a/plexus-java/src/test/resources/mock/module-info.java b/plexus-java/src/test/test-data/mock/module-info.java similarity index 100% rename from plexus-java/src/test/resources/mock/module-info.java rename to plexus-java/src/test/test-data/mock/module-info.java diff --git a/plexus-java/src/test/resources/nonjar/pom.xml b/plexus-java/src/test/test-data/nonjar/pom.xml similarity index 100% rename from plexus-java/src/test/resources/nonjar/pom.xml rename to plexus-java/src/test/test-data/nonjar/pom.xml diff --git a/plexus-java/src/test/resources/src.dir/module-info.java b/plexus-java/src/test/test-data/src.dir/module-info.java similarity index 100% rename from plexus-java/src/test/resources/src.dir/module-info.java rename to plexus-java/src/test/test-data/src.dir/module-info.java diff --git a/pom.xml b/pom.xml index 12a6922..cf7264e 100644 --- a/pom.xml +++ b/pom.xml @@ -5,32 +5,34 @@ org.codehaus.plexus plexus - 8 + 22 plexus-languages - 1.1.1 + 1.5.1-SNAPSHOT pom Plexus Languages - - Plexus Languages maintains shared language features. - + Plexus Languages maintains shared language features. plexus-java - scm:git:git@github.com:codehaus-plexus/plexus-languages.git - scm:git:git@github.com:codehaus-plexus/plexus-languages.git + scm:git:https://github.com/codehaus-plexus/plexus-languages.git + scm:git:https://github.com/codehaus-plexus/plexus-languages.git + HEAD https://github.com/codehaus-plexus/plexus-languages/tree/plexus-languages - plexus-languages-1.1.1 github - http://github.com/codehaus-plexus/plexus-languages/issues + https://github.com/codehaus-plexus/plexus-languages/issues + + GitHub + https://github.com/codehaus-plexus/plexus-languages/actions + github:gh-pages @@ -39,32 +41,13 @@ - scm:git:git@github.com:codehaus-plexus/plexus-languages.git - UTF-8 - 8 - 2022-01-31T22:27:20Z + scm:git:https://github.com/codehaus-plexus/plexus-languages.git + 2025-04-05T09:30:44Z - - org.apache.maven.plugins - maven-checkstyle-plugin - 3.1.2 - - - org.apache.maven.shared - maven-shared-resources - 4 - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.9.0 - org.apache.maven.plugins maven-release-plugin @@ -73,13 +56,18 @@ - org.apache.maven.plugins - maven-javadoc-plugin - - 3.3.1 + com.diffplug.spotless + spotless-maven-plugin + ${spotless-maven-plugin.version} + + + + src/main/java/**/*.java + src/main/java9/**/*.java + src/test/java/**/*.java + + + @@ -93,16 +81,9 @@ - + - - org.codehaus.mojo - cobertura-maven-plugin - - - - org.apache.maven.plugins maven-pmd-plugin @@ -121,7 +102,6 @@ org.apache.maven.plugins maven-enforcer-plugin - 3.0.0 enforce-java @@ -133,7 +113,7 @@ 9 - + diff --git a/src/site/site.xml b/src/site/site.xml deleted file mode 100644 index b178bd4..0000000 --- a/src/site/site.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - org.apache.maven.skins - maven-fluido-skin - 1.7 - - \ No newline at end of file