diff --git a/plexus-java/pom.xml b/plexus-java/pom.xml
index 4f85f59..6607cb4 100644
--- a/plexus-java/pom.xml
+++ b/plexus-java/pom.xml
@@ -18,9 +18,9 @@
9.10.1
- com.thoughtworks.qdox
- qdox
- 2.2.0
+ com.github.javaparser
+ javaparser-core
+ 3.28.2
javax.inject
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 b484919..418ec9b 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
@@ -19,87 +19,88 @@
* under the License.
*/
-import java.io.File;
import java.io.IOException;
+import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
-import com.thoughtworks.qdox.JavaProjectBuilder;
-import com.thoughtworks.qdox.model.JavaClass;
-import com.thoughtworks.qdox.model.JavaModule;
-import com.thoughtworks.qdox.model.JavaModuleDescriptor;
+import com.github.javaparser.StaticJavaParser;
+import com.github.javaparser.ast.expr.Name;
+import com.github.javaparser.ast.modules.ModuleDeclaration;
+import com.github.javaparser.ast.modules.ModuleDirective;
+import com.github.javaparser.ast.modules.ModuleExportsDirective;
+import com.github.javaparser.ast.modules.ModuleProvidesDirective;
+import com.github.javaparser.ast.modules.ModuleRequiresDirective;
+import com.github.javaparser.ast.modules.ModuleUsesDirective;
/**
- * Extract information from module with QDox
+ * Extracts information from a source module descriptor.
*
* @author Robert Scholte
* @since 1.0.0
*/
class SourceModuleInfoParser {
- public org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor fromSourcePath(Path modulePath)
- throws IOException {
- File moduleDescriptor = modulePath.toFile();
+ public JavaModuleDescriptor fromSourcePath(Path modulePath) throws IOException {
+ JavaModuleDescriptor.Builder builder;
+ if (Files.exists(modulePath)) {
+ ModuleDeclaration descriptor = StaticJavaParser.parse(modulePath)
+ .getModule()
+ .orElseThrow(() -> new IOException("Module declaration not found in " + modulePath));
- org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.Builder builder;
- if (moduleDescriptor.exists()) {
- JavaModuleDescriptor descriptor = new JavaProjectBuilder()
- .addSourceFolder(moduleDescriptor.getParentFile())
- .getDescriptor();
+ builder = JavaModuleDescriptor.newModule(descriptor.getName().asString());
- 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);
- }
- if (requires.isTransitive()) {
- modifiers.add(
- org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.JavaRequires.JavaModifier
- .TRANSITIVE);
+ for (ModuleDirective directive : descriptor.getDirectives()) {
+ if (directive instanceof ModuleRequiresDirective) {
+ addRequires(builder, (ModuleRequiresDirective) directive);
+ } else if (directive instanceof ModuleExportsDirective) {
+ addExports(builder, (ModuleExportsDirective) directive);
+ } else if (directive instanceof ModuleUsesDirective) {
+ ModuleUsesDirective uses = (ModuleUsesDirective) directive;
+ builder.uses(uses.getName().asString());
+ } else if (directive instanceof ModuleProvidesDirective) {
+ ModuleProvidesDirective provides = (ModuleProvidesDirective) directive;
+ List providers = new ArrayList<>(provides.getWith().size());
+ for (Name provider : provides.getWith()) {
+ providers.add(provider.asString());
}
- builder.requires(modifiers, requires.getModule().getName());
- } else {
- builder.requires(requires.getModule().getName());
+ builder.provides(provides.getName().asString(), providers);
}
}
+ } else {
+ builder = JavaModuleDescriptor.newAutomaticModule(null);
+ }
- 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());
- }
- builder.exports(exports.getSource().getName(), targets);
- }
- }
+ return builder.build();
+ }
- for (JavaModuleDescriptor.JavaUses uses : descriptor.getUses()) {
- builder.uses(uses.getService().getName());
+ private static void addRequires(JavaModuleDescriptor.Builder builder, ModuleRequiresDirective requires) {
+ if (requires.isStatic() || requires.isTransitive()) {
+ Set modifiers = new LinkedHashSet<>(2);
+ if (requires.isStatic()) {
+ modifiers.add(JavaModuleDescriptor.JavaRequires.JavaModifier.STATIC);
}
-
- 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);
+ if (requires.isTransitive()) {
+ modifiers.add(JavaModuleDescriptor.JavaRequires.JavaModifier.TRANSITIVE);
}
+ builder.requires(modifiers, requires.getName().asString());
} else {
- builder = org.codehaus.plexus.languages.java.jpms.JavaModuleDescriptor.newAutomaticModule(null);
+ builder.requires(requires.getName().asString());
}
+ }
- return builder.build();
+ private static void addExports(JavaModuleDescriptor.Builder builder, ModuleExportsDirective exports) {
+ if (exports.getModuleNames().isEmpty()) {
+ builder.exports(exports.getName().asString());
+ } else {
+ Set targets = new LinkedHashSet<>();
+ for (Name module : exports.getModuleNames()) {
+ targets.add(module.asString());
+ }
+ builder.exports(exports.getName().asString(), targets);
+ }
}
}
diff --git a/plexus-java/src/main/java9/module-info.java b/plexus-java/src/main/java9/module-info.java
index c09093b..b9ce123 100644
--- a/plexus-java/src/main/java9/module-info.java
+++ b/plexus-java/src/main/java9/module-info.java
@@ -17,7 +17,7 @@
* under the License.
*/
module org.codehaus.plexus.languages.java {
- requires com.thoughtworks.qdox;
+ requires com.github.javaparser.core;
requires org.objectweb.asm;
exports org.codehaus.plexus.languages.java.jpms;
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 0859fd8..2ae3392 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
@@ -49,7 +49,7 @@ class LocationManagerIT {
private BinaryModuleInfoParser asmParser;
@Mock
- private SourceModuleInfoParser qdoxParser;
+ private SourceModuleInfoParser sourceParser;
private LocationManager locationManager;
@@ -57,7 +57,7 @@ class LocationManagerIT {
@BeforeEach
void onSetup() {
- locationManager = new LocationManager(qdoxParser) {
+ locationManager = new LocationManager(sourceParser) {
@Override
ModuleInfoParser getBinaryModuleInfoParser(Path jdkHome) {
return asmParser;
@@ -70,7 +70,7 @@ void manifestWithoutReflectRequires() 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);
+ when(sourceParser.fromSourcePath(any(Path.class))).thenReturn(descriptor);
ResolvePathsRequest request =
ResolvePathsRequest.ofPaths(Collections.singletonList(abc)).setMainModuleDescriptor(mockModuleInfoJava);
@@ -88,7 +88,7 @@ void emptyWithReflectRequires() 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);
+ when(sourceParser.fromSourcePath(any(Path.class))).thenReturn(descriptor);
ResolvePathsRequest request =
ResolvePathsRequest.ofPaths(Collections.singletonList(abc)).setMainModuleDescriptor(mockModuleInfoJava);
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 d758a0c..0fe8f29 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
@@ -38,7 +38,7 @@
class LocationManagerTest {
private BinaryModuleInfoParser asmParser;
- private SourceModuleInfoParser qdoxParser;
+ private SourceModuleInfoParser sourceParser;
private LocationManager locationManager;
@@ -47,8 +47,8 @@ class LocationManagerTest {
@BeforeEach
void onSetup() {
asmParser = mock(BinaryModuleInfoParser.class);
- qdoxParser = mock(SourceModuleInfoParser.class);
- locationManager = new LocationManager(qdoxParser) {
+ sourceParser = mock(SourceModuleInfoParser.class);
+ locationManager = new LocationManager(sourceParser) {
@Override
ModuleInfoParser getBinaryModuleInfoParser(Path jdkHome) {
return asmParser;
@@ -73,7 +73,7 @@ void withUnknownRequires() throws Exception {
.requires("java.base")
.requires("jdk.net")
.build();
- when(qdoxParser.fromSourcePath(any(Path.class))).thenReturn(descriptor);
+ when(sourceParser.fromSourcePath(any(Path.class))).thenReturn(descriptor);
ResolvePathsRequest request = ResolvePathsRequest.ofFiles(Collections.emptyList())
.setMainModuleDescriptor(mockModuleInfoJava.toFile());
@@ -92,7 +92,7 @@ void manifestWithReflectRequires() throws Exception {
JavaModuleDescriptor descriptor = JavaModuleDescriptor.newModule("base")
.requires("auto.by.manifest")
.build();
- when(qdoxParser.fromSourcePath(any(Path.class))).thenReturn(descriptor);
+ when(sourceParser.fromSourcePath(any(Path.class))).thenReturn(descriptor);
ResolvePathsRequest request =
ResolvePathsRequest.ofPaths(Collections.singletonList(abc)).setMainModuleDescriptor(mockModuleInfoJava);
@@ -112,7 +112,7 @@ void dirDescriptorWithReflectRequires() throws Exception {
JavaModuleDescriptor descriptor = JavaModuleDescriptor.newModule("base")
.requires("dir.descriptor")
.build();
- when(qdoxParser.fromSourcePath(any(Path.class))).thenReturn(descriptor);
+ when(sourceParser.fromSourcePath(any(Path.class))).thenReturn(descriptor);
ResolvePathsRequest request =
ResolvePathsRequest.ofPaths(Collections.singletonList(abc)).setMainModuleDescriptor(mockModuleInfoJava);
@@ -135,7 +135,7 @@ void jarWithAsmRequires() throws Exception {
JavaModuleDescriptor descriptor = JavaModuleDescriptor.newModule("base")
.requires("org.objectweb.asm")
.build();
- when(qdoxParser.fromSourcePath(any(Path.class))).thenReturn(descriptor);
+ when(sourceParser.fromSourcePath(any(Path.class))).thenReturn(descriptor);
ResolvePathsRequest request =
ResolvePathsRequest.ofPaths(Collections.singletonList(abc)).setMainModuleDescriptor(mockModuleInfoJava);
@@ -157,7 +157,7 @@ void identicalModuleNames() throws Exception {
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);
+ when(sourceParser.fromSourcePath(any(Path.class))).thenReturn(descriptor);
ResolvePathsRequest request =
ResolvePathsRequest.ofPaths(Arrays.asList(pj1, pj2)).setMainModuleDescriptor(mockModuleInfoJava);
@@ -187,7 +187,7 @@ void identicalAutomaticModuleNames() throws Exception {
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);
+ when(sourceParser.fromSourcePath(any(Path.class))).thenReturn(descriptor);
ResolvePathsRequest request =
ResolvePathsRequest.ofPaths(Arrays.asList(pj1, pj2)).setMainModuleDescriptor(mockModuleInfoJava);
@@ -217,7 +217,7 @@ void mainJarModuleAndTestJarAutomatic() throws Exception {
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);
+ when(sourceParser.fromSourcePath(any(Path.class))).thenReturn(descriptor);
ResolvePathsRequest request =
ResolvePathsRequest.ofPaths(Arrays.asList(pj1, pj2)).setMainModuleDescriptor(mockModuleInfoJava);
@@ -258,7 +258,7 @@ void additionalModules() 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);
+ when(sourceParser.fromSourcePath(any(Path.class))).thenReturn(descriptor);
ResolvePathsRequest request = ResolvePathsRequest.ofPaths(Collections.singletonList(p))
.setMainModuleDescriptor(mockModuleInfoJava)
.setAdditionalModules(Collections.singletonList("plexus.java"));
@@ -297,7 +297,7 @@ void noMatchingProviders() throws Exception {
ResolvePathsRequest request =
ResolvePathsRequest.ofPaths(def).setMainModuleDescriptor(abc).setIncludeAllProviders(true);
- when(qdoxParser.fromSourcePath(abc))
+ when(sourceParser.fromSourcePath(abc))
.thenReturn(JavaModuleDescriptor.newModule("abc").uses("device").build());
when(asmParser.getModuleDescriptor(def))
.thenReturn(JavaModuleDescriptor.newModule("def")
@@ -318,7 +318,7 @@ void mainModuleDescriptorWithProviders() throws Exception {
ResolvePathsRequest request =
ResolvePathsRequest.ofPaths(def).setMainModuleDescriptor(abc).setIncludeAllProviders(true);
- when(qdoxParser.fromSourcePath(abc))
+ when(sourceParser.fromSourcePath(abc))
.thenReturn(JavaModuleDescriptor.newModule("abc").uses("tool").build());
when(asmParser.getModuleDescriptor(def))
.thenReturn(JavaModuleDescriptor.newModule("def")
@@ -338,7 +338,7 @@ void mainModuleDescriptorWithProvidersDontIncludeProviders() throws Exception {
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))
+ when(sourceParser.fromSourcePath(abc))
.thenReturn(JavaModuleDescriptor.newModule("abc").uses("tool").build());
when(asmParser.getModuleDescriptor(def))
.thenReturn(JavaModuleDescriptor.newModule("def")
@@ -361,7 +361,7 @@ void transitiveProviders() throws Exception {
.setMainModuleDescriptor(abc)
.setIncludeAllProviders(true);
- when(qdoxParser.fromSourcePath(abc))
+ when(sourceParser.fromSourcePath(abc))
.thenReturn(
JavaModuleDescriptor.newModule("abc").requires("ghi").build());
when(asmParser.getModuleDescriptor(def))
@@ -386,7 +386,7 @@ void dontIncludeProviders() throws Exception {
ResolvePathsRequest request =
ResolvePathsRequest.ofPaths(def, ghi).setMainModuleDescriptor(abc);
- when(qdoxParser.fromSourcePath(abc))
+ when(sourceParser.fromSourcePath(abc))
.thenReturn(
JavaModuleDescriptor.newModule("abc").requires("ghi").build());
when(asmParser.getModuleDescriptor(def))
@@ -443,7 +443,7 @@ void reuseModuleDescriptor() throws Exception {
@Test
void parseModuleDescriptor() throws Exception {
Path descriptorPath = Paths.get("src/test/test-data/src.dir/module-info.java");
- when(qdoxParser.fromSourcePath(descriptorPath))
+ when(sourceParser.fromSourcePath(descriptorPath))
.thenReturn(JavaModuleDescriptor.newModule("a.b.c").build());
ResolvePathResult result = locationManager.parseModuleDescriptor(descriptorPath);
@@ -467,7 +467,7 @@ void transitiveStatic() throws Exception {
ResolvePathsRequest request =
ResolvePathsRequest.ofPaths(moduleB, moduleC).setMainModuleDescriptor(moduleA);
- when(qdoxParser.fromSourcePath(moduleA))
+ when(sourceParser.fromSourcePath(moduleA))
.thenReturn(JavaModuleDescriptor.newModule("moduleA")
.requires("moduleB")
.build());
@@ -495,7 +495,7 @@ void directStatic() throws Exception {
ResolvePathsRequest.ofPaths(moduleB, moduleC, moduleD).setMainModuleDescriptor(moduleA);
// .setIncludeStatic( true );
- when(qdoxParser.fromSourcePath(moduleA))
+ when(sourceParser.fromSourcePath(moduleA))
.thenReturn(JavaModuleDescriptor.newModule("moduleA")
.requires("moduleB")
.requires(Collections.singleton(JavaModifier.STATIC), "moduleD")
@@ -525,7 +525,7 @@ void duplicateModule() throws Exception {
ResolvePathsRequest request =
ResolvePathsRequest.ofPaths(moduleB, moduleC).setMainModuleDescriptor(moduleA);
- when(qdoxParser.fromSourcePath(moduleA))
+ when(sourceParser.fromSourcePath(moduleA))
.thenReturn(JavaModuleDescriptor.newModule("moduleA")
.requires("anonymous")
.build());
@@ -555,7 +555,7 @@ void staticTransitive() throws Exception {
ResolvePathsRequest request =
ResolvePathsRequest.ofPaths(moduleB, moduleC, moduleD).setMainModuleDescriptor(moduleA);
- when(qdoxParser.fromSourcePath(moduleA))
+ when(sourceParser.fromSourcePath(moduleA))
.thenReturn(JavaModuleDescriptor.newModule("moduleA")
.requires("moduleB")
.build());
@@ -588,7 +588,7 @@ void includeDeeperRequiresStatic() throws Exception {
ResolvePathsRequest request = ResolvePathsRequest.ofPaths(moduleA, moduleB, moduleC)
.setMainModuleDescriptor(moduleA)
.setIncludeStatic(true);
- when(qdoxParser.fromSourcePath(moduleA))
+ when(sourceParser.fromSourcePath(moduleA))
.thenReturn(JavaModuleDescriptor.newModule("moduleA")
.requires("moduleB")
.build());
@@ -615,7 +615,7 @@ void includeDeeperRequiresStaticTransitive() throws Exception {
ResolvePathsRequest request = ResolvePathsRequest.ofPaths(moduleA, moduleB, moduleC, moduleD)
.setMainModuleDescriptor(moduleA)
.setIncludeStatic(true);
- when(qdoxParser.fromSourcePath(moduleA))
+ when(sourceParser.fromSourcePath(moduleA))
.thenReturn(JavaModuleDescriptor.newModule("moduleA")
.requires("moduleB")
.build());
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 c29e921..3f7f694 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
@@ -85,4 +85,20 @@ void test() throws Exception {
assertArrayEquals(
new String[] {"com.example.foo.Impl"}, provides.providers().toArray(new String[0]));
}
+
+ @Test
+ void doesNotParseReferencedSources() throws Exception {
+ JavaModuleDescriptor moduleDescriptor =
+ parser.fromSourcePath(Paths.get("src/test/test-data/annotated-type-argument/module-info.java"));
+
+ assertEquals("annotated.type.argument", moduleDescriptor.name());
+ assertArrayEquals(
+ new String[] {"example.Service"}, moduleDescriptor.uses().toArray(new String[0]));
+
+ JavaProvides provides = moduleDescriptor.provides().iterator().next();
+ assertEquals("example.Service", provides.service());
+ assertArrayEquals(
+ new String[] {"example.ServiceImpl", "example.AlternativeServiceImpl"},
+ provides.providers().toArray(new String[0]));
+ }
}
diff --git a/plexus-java/src/test/test-data/annotated-type-argument/example/AlternativeServiceImpl.java b/plexus-java/src/test/test-data/annotated-type-argument/example/AlternativeServiceImpl.java
new file mode 100644
index 0000000..b03890e
--- /dev/null
+++ b/plexus-java/src/test/test-data/annotated-type-argument/example/AlternativeServiceImpl.java
@@ -0,0 +1,8 @@
+package example;
+
+import java.util.List;
+
+public class AlternativeServiceImpl implements Service