analyze.
+ * + * @param url the JAR file or directory to analyze + * @return a {@link java.util.Set} object + * @throws java.io.IOException if any + */ + SetConstructor for CollectorClassFileVisitor.
*/ public CollectorClassFileVisitor() { + this(new ClassesPatterns()); + } + + public CollectorClassFileVisitor(ClassesPatterns excludedClasses) { classes = new HashSet<>(); + this.excludedClasses = excludedClasses; } /** {@inheritDoc} */ @Override public void visitClass(String className, InputStream in) { // inner classes have equivalent compilation requirement as container class - if (className.indexOf('$') < 0) { + if (className.indexOf('$') < 0 && !excludedClasses.isMatch(className)) { classes.add(className); } } diff --git a/src/main/java/org/apache/maven/shared/dependency/analyzer/DefaultClassAnalyzer.java b/src/main/java/org/apache/maven/shared/dependency/analyzer/DefaultClassAnalyzer.java index dfbed05e..43022799 100644 --- a/src/main/java/org/apache/maven/shared/dependency/analyzer/DefaultClassAnalyzer.java +++ b/src/main/java/org/apache/maven/shared/dependency/analyzer/DefaultClassAnalyzer.java @@ -35,10 +35,9 @@ @Singleton public class DefaultClassAnalyzer implements ClassAnalyzer { - /** {@inheritDoc} */ @Override - public Setanalyze.
* - * @param url the JAR file or directory to analyze + * @param url the JAR file or directory to analyze * @return the set of class names referenced by the library * @throws IOException if an error occurs reading a JAR or .class file */ default Setanalyze.
+ * + * @param url the JAR file or directory to analyze + * @param excludeClasses a class list to exclude + * @return the set of class names referenced by the library + * @throws IOException if an error occurs reading a JAR or .class file + */ + default Setanalyze.
+ * + * @param project a {@link org.apache.maven.project.MavenProject} object + * @return a {@link org.apache.maven.shared.dependency.analyzer.ProjectDependencyAnalysis} object + * @throws org.apache.maven.shared.dependency.analyzer.ProjectDependencyAnalyzerException if any + */ + default ProjectDependencyAnalysis analyze(MavenProject project) throws ProjectDependencyAnalyzerException { + return analyze(project, null); + } + /** *analyze.
* * @param project a {@link org.apache.maven.project.MavenProject} object + * @param excludedClasses collection of regular expression of classes name to exclude * @return a {@link org.apache.maven.shared.dependency.analyzer.ProjectDependencyAnalysis} object * @throws org.apache.maven.shared.dependency.analyzer.ProjectDependencyAnalyzerException if any */ - ProjectDependencyAnalysis analyze(MavenProject project) throws ProjectDependencyAnalyzerException; + ProjectDependencyAnalysis analyze(MavenProject project, Collectionorg.objectweb.asm.depend.DependencyVisitor
in the ASM dependencies example.
@@ -180,4 +188,14 @@ private void addTypeSignature(final String signature) {
new SignatureReader(signature).acceptType(signatureVisitor);
}
}
+
+ @Override
+ public void visitInvokeDynamicInsn(
+ String name, String descriptor, Handle bootstrapMethodHandle, Object... bootstrapMethodArguments) {
+ Arrays.stream(bootstrapMethodArguments)
+ .filter(Type.class::isInstance)
+ .map(Type.class::cast)
+ .map(Type::getDescriptor)
+ .forEach(desc -> resultCollector.addMethodDesc(usedByClass, desc));
+ }
}
diff --git a/src/main/java/org/apache/maven/shared/dependency/analyzer/asm/DependencyClassFileVisitor.java b/src/main/java/org/apache/maven/shared/dependency/analyzer/asm/DependencyClassFileVisitor.java
index b37fea6c..7516381e 100644
--- a/src/main/java/org/apache/maven/shared/dependency/analyzer/asm/DependencyClassFileVisitor.java
+++ b/src/main/java/org/apache/maven/shared/dependency/analyzer/asm/DependencyClassFileVisitor.java
@@ -18,17 +18,17 @@
*/
package org.apache.maven.shared.dependency.analyzer.asm;
+import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.UncheckedIOException;
import java.util.Set;
-import org.apache.commons.io.IOUtils;
import org.apache.maven.shared.dependency.analyzer.ClassFileVisitor;
+import org.apache.maven.shared.dependency.analyzer.ClassesPatterns;
import org.apache.maven.shared.dependency.analyzer.DependencyUsage;
import org.objectweb.asm.*;
import org.objectweb.asm.signature.SignatureVisitor;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* Computes the set of classes referenced by visited class files, using
@@ -38,14 +38,26 @@
* @see #getDependencies()
*/
public class DependencyClassFileVisitor implements ClassFileVisitor {
+ private static final int BUF_SIZE = 8192;
+
private final ResultCollector resultCollector = new ResultCollector();
- private final Logger logger = LoggerFactory.getLogger(getClass());
+ private final ClassesPatterns excludedClasses;
+
+ /**
+ * Constructor for DependencyClassFileVisitor.
+ */ + public DependencyClassFileVisitor(ClassesPatterns excludedClasses) { + + this.excludedClasses = excludedClasses; + } /** *Constructor for DependencyClassFileVisitor.
*/ - public DependencyClassFileVisitor() {} + public DependencyClassFileVisitor() { + this(new ClassesPatterns()); + } /** * {@inheritDoc} @@ -53,7 +65,12 @@ public DependencyClassFileVisitor() {} @Override public void visitClass(String className, InputStream in) { try { - byte[] byteCode = IOUtils.toByteArray(in); + byte[] byteCode = toByteArray(in); + + if (excludedClasses.isMatch(className)) { + return; + } + ClassReader reader = new ClassReader(byteCode); final Set
+ * The handler method in {@link Prepare} takes an implicit Consumer<ArtifactResolutionRequest> argument. Analyze
+ * this class to verify the implicit reference.
+ */
+public class AnalyzedClass {
+
+ public void useFirst() {
+ new Prepare().handler(this::doNothing);
+ }
+
+ private void doNothing(final Object object) {}
+}
diff --git a/src/test/java/org/apache/maven/shared/dependency/analyzer/testcases/analyze/ClassToExclude.java b/src/test/java/org/apache/maven/shared/dependency/analyzer/testcases/analyze/ClassToExclude.java
new file mode 100644
index 00000000..bf1771de
--- /dev/null
+++ b/src/test/java/org/apache/maven/shared/dependency/analyzer/testcases/analyze/ClassToExclude.java
@@ -0,0 +1,28 @@
+/*
+ * 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.testcases.analyze;
+
+import java.util.regex.Pattern;
+
+/**
+ * Class to be skipped during analyzed in unit test.
+ */
+public class ClassToExclude {
+ private void doNothing(final Pattern pattern) {}
+}
diff --git a/src/test/java/org/apache/maven/shared/dependency/analyzer/testcases/prepare/Prepare.java b/src/test/java/org/apache/maven/shared/dependency/analyzer/testcases/prepare/Prepare.java
new file mode 100644
index 00000000..2a6a304f
--- /dev/null
+++ b/src/test/java/org/apache/maven/shared/dependency/analyzer/testcases/prepare/Prepare.java
@@ -0,0 +1,36 @@
+/*
+ * 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.testcases.prepare;
+
+import java.util.function.Consumer;
+
+import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
+import org.apache.maven.artifact.resolver.ResolutionErrorHandler;
+
+/**
+ * Class to be used for verifying that analyzer picks up usage of classes with no import.
+ */
+public class Prepare {
+
+ public void handler(Consumer