This is an automated email from the ASF dual-hosted git repository.
sjaranowski pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-dependency-analyzer.git
The following commit(s) were added to refs/heads/master by this push:
new 1779cf3 Introduced a DependencyClassesProvider service
1779cf3 is described below
commit 1779cf35c118e96d3b08463beeed52e37eb39614
Author: Slawomir Jaranowski <[email protected]>
AuthorDate: Sun Jan 11 17:00:18 2026 +0100
Introduced a DependencyClassesProvider service
The default detection of classes usage by bytecode in the project has been
moved to a new service.
This allows adding additional providers in the future, for example for
detecting classes from source files.
---
pom.xml | 26 ++++++++-
.../analyzer/DefaultProjectDependencyAnalyzer.java | 39 +++++---------
.../analyzer/DependencyClassesProvider.java | 39 ++++++++++++++
.../analyzer/MainDependencyClassesProvider.java | 24 +++++++++
.../analyzer/TestDependencyClassesProvider.java | 24 +++++++++
.../DefaultDependencyClassesProvider.java | 56 +++++++++++++++++++
.../DefaultMainDependencyClassesProvider.java | 46 ++++++++++++++++
.../DefaultTestDependencyClassesProvider.java | 46 ++++++++++++++++
.../DefaultMainDependencyClassesProviderTest.java | 62 ++++++++++++++++++++++
.../DefaultTestDependencyClassesProviderTest.java | 62 ++++++++++++++++++++++
10 files changed, 397 insertions(+), 27 deletions(-)
diff --git a/pom.xml b/pom.xml
index 205b90c..cf8b428 100644
--- a/pom.xml
+++ b/pom.xml
@@ -57,7 +57,6 @@
</distributionManagement>
<properties>
- <version.maven-plugin-tools>3.15.2</version.maven-plugin-tools>
<mavenVersion>3.9.12</mavenVersion>
<javaVersion>8</javaVersion>
<project.build.outputTimestamp>2025-04-14T16:19:51Z</project.build.outputTimestamp>
@@ -124,6 +123,30 @@
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <version>4.11.0</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-junit-jupiter</artifactId>
+ <version>4.11.0</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <version>1.7.36</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <!-- used in test runtime -->
+ <groupId>org.codehaus.plexus</groupId>
+ <artifactId>plexus-xml</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
@@ -155,7 +178,6 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-invoker-plugin</artifactId>
- <version>3.9.1</version>
<configuration>
<cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
<localRepositoryPath>target/local-repo</localRepositoryPath>
diff --git
a/src/main/java/org/apache/maven/shared/dependency/analyzer/DefaultProjectDependencyAnalyzer.java
b/src/main/java/org/apache/maven/shared/dependency/analyzer/DefaultProjectDependencyAnalyzer.java
index e5f02e4..b59bd41 100644
---
a/src/main/java/org/apache/maven/shared/dependency/analyzer/DefaultProjectDependencyAnalyzer.java
+++
b/src/main/java/org/apache/maven/shared/dependency/analyzer/DefaultProjectDependencyAnalyzer.java
@@ -32,6 +32,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.jar.JarEntry;
@@ -55,11 +56,11 @@ public class DefaultProjectDependencyAnalyzer implements
ProjectDependencyAnalyz
@Inject
private ClassAnalyzer classAnalyzer;
- /**
- * DependencyAnalyzer
- */
@Inject
- private DependencyAnalyzer dependencyAnalyzer;
+ private List<MainDependencyClassesProvider> mainDependencyClassesProviders;
+
+ @Inject
+ private List<TestDependencyClassesProvider> testDependencyClassesProviders;
/** {@inheritDoc} */
@Override
@@ -69,8 +70,15 @@ public class DefaultProjectDependencyAnalyzer implements
ProjectDependencyAnalyz
ClassesPatterns excludedClassesPatterns = new
ClassesPatterns(excludedClasses);
Map<Artifact, Set<String>> artifactClassMap =
buildArtifactClassMap(project, excludedClassesPatterns);
- Set<DependencyUsage> mainDependencyClasses =
buildMainDependencyClasses(project, excludedClassesPatterns);
- Set<DependencyUsage> testDependencyClasses =
buildTestDependencyClasses(project, excludedClassesPatterns);
+ Set<DependencyUsage> mainDependencyClasses = new HashSet<>();
+ for (MainDependencyClassesProvider provider :
mainDependencyClassesProviders) {
+
mainDependencyClasses.addAll(provider.getDependencyClasses(project,
excludedClassesPatterns));
+ }
+
+ Set<DependencyUsage> testDependencyClasses = new HashSet<>();
+ for (TestDependencyClassesProvider provider :
testDependencyClassesProviders) {
+
testDependencyClasses.addAll(provider.getDependencyClasses(project,
excludedClassesPatterns));
+ }
Set<DependencyUsage> dependencyClasses = new HashSet<>();
dependencyClasses.addAll(mainDependencyClasses);
@@ -207,25 +215,6 @@ public class DefaultProjectDependencyAnalyzer implements
ProjectDependencyAnalyz
return testOnlyDependencyClasses;
}
- private Set<DependencyUsage> buildMainDependencyClasses(MavenProject
project, ClassesPatterns excludedClasses)
- throws IOException {
- String outputDirectory = project.getBuild().getOutputDirectory();
- return buildDependencyClasses(outputDirectory, excludedClasses);
- }
-
- private Set<DependencyUsage> buildTestDependencyClasses(MavenProject
project, ClassesPatterns excludedClasses)
- throws IOException {
- String testOutputDirectory =
project.getBuild().getTestOutputDirectory();
- return buildDependencyClasses(testOutputDirectory, excludedClasses);
- }
-
- private Set<DependencyUsage> buildDependencyClasses(String path,
ClassesPatterns excludedClasses)
- throws IOException {
- URL url = new File(path).toURI().toURL();
-
- return dependencyAnalyzer.analyzeUsages(url, excludedClasses);
- }
-
private static Set<Artifact> buildDeclaredArtifacts(MavenProject project) {
Set<Artifact> declaredArtifacts = project.getDependencyArtifacts();
diff --git
a/src/main/java/org/apache/maven/shared/dependency/analyzer/DependencyClassesProvider.java
b/src/main/java/org/apache/maven/shared/dependency/analyzer/DependencyClassesProvider.java
new file mode 100644
index 0000000..01f7391
--- /dev/null
+++
b/src/main/java/org/apache/maven/shared/dependency/analyzer/DependencyClassesProvider.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.shared.dependency.analyzer;
+
+import java.io.IOException;
+import java.util.Set;
+
+import org.apache.maven.project.MavenProject;
+
+/**
+ * Base interface for services provided the dependency classes used by a
project.
+ */
+public interface DependencyClassesProvider {
+
+ /**
+ * Gets the dependency classes used by the given project, excluding those
that match the given patterns.
+ *
+ * @param project the Maven project
+ * @param excludedClasses patterns of classes to exclude
+ * @return the set of dependency usages
+ */
+ Set<DependencyUsage> getDependencyClasses(MavenProject project,
ClassesPatterns excludedClasses) throws IOException;
+}
diff --git
a/src/main/java/org/apache/maven/shared/dependency/analyzer/MainDependencyClassesProvider.java
b/src/main/java/org/apache/maven/shared/dependency/analyzer/MainDependencyClassesProvider.java
new file mode 100644
index 0000000..e9dbbb2
--- /dev/null
+++
b/src/main/java/org/apache/maven/shared/dependency/analyzer/MainDependencyClassesProvider.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.shared.dependency.analyzer;
+
+/**
+ * Service provides the main dependency classes used by a project.
+ */
+public interface MainDependencyClassesProvider extends
DependencyClassesProvider {}
diff --git
a/src/main/java/org/apache/maven/shared/dependency/analyzer/TestDependencyClassesProvider.java
b/src/main/java/org/apache/maven/shared/dependency/analyzer/TestDependencyClassesProvider.java
new file mode 100644
index 0000000..bdc53e1
--- /dev/null
+++
b/src/main/java/org/apache/maven/shared/dependency/analyzer/TestDependencyClassesProvider.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.shared.dependency.analyzer;
+
+/**
+ * Service provides the test dependency classes used by a project.
+ */
+public interface TestDependencyClassesProvider extends
DependencyClassesProvider {}
diff --git
a/src/main/java/org/apache/maven/shared/dependency/analyzer/dependencyclasses/DefaultDependencyClassesProvider.java
b/src/main/java/org/apache/maven/shared/dependency/analyzer/dependencyclasses/DefaultDependencyClassesProvider.java
new file mode 100644
index 0000000..c13832a
--- /dev/null
+++
b/src/main/java/org/apache/maven/shared/dependency/analyzer/dependencyclasses/DefaultDependencyClassesProvider.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.shared.dependency.analyzer.dependencyclasses;
+
+import javax.inject.Inject;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.Set;
+
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.shared.dependency.analyzer.ClassesPatterns;
+import org.apache.maven.shared.dependency.analyzer.DependencyAnalyzer;
+import org.apache.maven.shared.dependency.analyzer.DependencyClassesProvider;
+import org.apache.maven.shared.dependency.analyzer.DependencyUsage;
+
+abstract class DefaultDependencyClassesProvider implements
DependencyClassesProvider {
+
+ /**
+ * DependencyAnalyzer
+ */
+ private final DependencyAnalyzer dependencyAnalyzer;
+
+ @Inject
+ DefaultDependencyClassesProvider(DependencyAnalyzer dependencyAnalyzer) {
+ this.dependencyAnalyzer = dependencyAnalyzer;
+ }
+
+ @Override
+ public Set<DependencyUsage> getDependencyClasses(MavenProject project,
ClassesPatterns excludedClasses)
+ throws IOException {
+ String classesDirectory = getOutputClassesDirectory(project);
+ URL url = new File(classesDirectory).toURI().toURL();
+
+ return dependencyAnalyzer.analyzeUsages(url, excludedClasses);
+ }
+
+ protected abstract String getOutputClassesDirectory(MavenProject project);
+}
diff --git
a/src/main/java/org/apache/maven/shared/dependency/analyzer/dependencyclasses/DefaultMainDependencyClassesProvider.java
b/src/main/java/org/apache/maven/shared/dependency/analyzer/dependencyclasses/DefaultMainDependencyClassesProvider.java
new file mode 100644
index 0000000..205dc91
--- /dev/null
+++
b/src/main/java/org/apache/maven/shared/dependency/analyzer/dependencyclasses/DefaultMainDependencyClassesProvider.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.shared.dependency.analyzer.dependencyclasses;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.shared.dependency.analyzer.DependencyAnalyzer;
+import
org.apache.maven.shared.dependency.analyzer.MainDependencyClassesProvider;
+
+/**
+ * Default implementation of {@link MainDependencyClassesProvider}.
+ */
+@Named
+@Singleton
+class DefaultMainDependencyClassesProvider extends
DefaultDependencyClassesProvider
+ implements MainDependencyClassesProvider {
+
+ @Inject
+ DefaultMainDependencyClassesProvider(DependencyAnalyzer
dependencyAnalyzer) {
+ super(dependencyAnalyzer);
+ }
+
+ @Override
+ protected String getOutputClassesDirectory(MavenProject project) {
+ return project.getBuild().getOutputDirectory();
+ }
+}
diff --git
a/src/main/java/org/apache/maven/shared/dependency/analyzer/dependencyclasses/DefaultTestDependencyClassesProvider.java
b/src/main/java/org/apache/maven/shared/dependency/analyzer/dependencyclasses/DefaultTestDependencyClassesProvider.java
new file mode 100644
index 0000000..9a7d703
--- /dev/null
+++
b/src/main/java/org/apache/maven/shared/dependency/analyzer/dependencyclasses/DefaultTestDependencyClassesProvider.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.shared.dependency.analyzer.dependencyclasses;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.shared.dependency.analyzer.DependencyAnalyzer;
+import
org.apache.maven.shared.dependency.analyzer.TestDependencyClassesProvider;
+
+/**
+ * Default implementation of {@link TestDependencyClassesProvider}.
+ */
+@Named
+@Singleton
+class DefaultTestDependencyClassesProvider extends
DefaultDependencyClassesProvider
+ implements TestDependencyClassesProvider {
+
+ @Inject
+ DefaultTestDependencyClassesProvider(DependencyAnalyzer
dependencyAnalyzer) {
+ super(dependencyAnalyzer);
+ }
+
+ @Override
+ protected String getOutputClassesDirectory(MavenProject project) {
+ return project.getBuild().getTestOutputDirectory();
+ }
+}
diff --git
a/src/test/java/org/apache/maven/shared/dependency/analyzer/dependencyclasses/DefaultMainDependencyClassesProviderTest.java
b/src/test/java/org/apache/maven/shared/dependency/analyzer/dependencyclasses/DefaultMainDependencyClassesProviderTest.java
new file mode 100644
index 0000000..29ccafb
--- /dev/null
+++
b/src/test/java/org/apache/maven/shared/dependency/analyzer/dependencyclasses/DefaultMainDependencyClassesProviderTest.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.shared.dependency.analyzer.dependencyclasses;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Set;
+
+import org.apache.maven.model.Build;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.shared.dependency.analyzer.DependencyAnalyzer;
+import org.apache.maven.shared.dependency.analyzer.DependencyUsage;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(MockitoExtension.class)
+class DefaultMainDependencyClassesProviderTest {
+
+ @Mock
+ private DependencyAnalyzer analyzer;
+
+ @InjectMocks
+ private DefaultMainDependencyClassesProvider provider;
+
+ @Test
+ void mainOutputIsUsed() throws IOException {
+ MavenProject project = Mockito.mock(MavenProject.class);
+ Build build = Mockito.mock(Build.class);
+ when(project.getBuild()).thenReturn(build);
+ when(build.getOutputDirectory()).thenReturn("target/classes");
+
+ Set<DependencyUsage> dependencyUsages =
provider.getDependencyClasses(project, null);
+
+ assertThat(dependencyUsages).isNotNull();
+
+ verify(analyzer).analyzeUsages(new
File("target/classes").toURI().toURL(), null);
+ }
+}
diff --git
a/src/test/java/org/apache/maven/shared/dependency/analyzer/dependencyclasses/DefaultTestDependencyClassesProviderTest.java
b/src/test/java/org/apache/maven/shared/dependency/analyzer/dependencyclasses/DefaultTestDependencyClassesProviderTest.java
new file mode 100644
index 0000000..8a2f3d3
--- /dev/null
+++
b/src/test/java/org/apache/maven/shared/dependency/analyzer/dependencyclasses/DefaultTestDependencyClassesProviderTest.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.shared.dependency.analyzer.dependencyclasses;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Set;
+
+import org.apache.maven.model.Build;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.shared.dependency.analyzer.DependencyAnalyzer;
+import org.apache.maven.shared.dependency.analyzer.DependencyUsage;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@ExtendWith(MockitoExtension.class)
+class DefaultTestDependencyClassesProviderTest {
+
+ @Mock
+ private DependencyAnalyzer analyzer;
+
+ @InjectMocks
+ private DefaultTestDependencyClassesProvider provider;
+
+ @Test
+ void testOutputIsUsed() throws IOException {
+ MavenProject project = Mockito.mock(MavenProject.class);
+ Build build = Mockito.mock(Build.class);
+ when(project.getBuild()).thenReturn(build);
+ when(build.getTestOutputDirectory()).thenReturn("target/test-classes");
+
+ Set<DependencyUsage> dependencyUsages =
provider.getDependencyClasses(project, null);
+
+ assertThat(dependencyUsages).isNotNull();
+
+ verify(analyzer).analyzeUsages(new
File("target/test-classes").toURI().toURL(), null);
+ }
+}