Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle class parsing errors more gracefully #4616

Merged
merged 1 commit into from
Jan 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@ public void execute() throws MojoExecutionException, MojoFailureException {
Map<String, Version> lowestPackageVersion = new HashMap<>();
Map<String, Set<Version>> allPackageVersion = new HashMap<>();
Set<String> packageWithError = new HashSet<>();
Function<String, Optional<ClassMethods>> classResolver = DependencyAnalyzer
DependencyAnalyzer dependencyAnalyzer = new DependencyAnalyzer((m, e) -> getLog().error(m, e));
Function<String, Optional<ClassMethods>> classResolver = dependencyAnalyzer
.createDependencyClassResolver(jrtClassResolver, artifacts);
for (GenericInfo genericInfo : requirements) {
if (PackageNamespace.PACKAGE_NAMESPACE.equals(genericInfo.getNamespace())) {
Expand Down Expand Up @@ -223,7 +224,7 @@ public void execute() throws MojoExecutionException, MojoFailureException {
}
ClassCollection collection = analyzeCache.get(artifact);
if (collection == null) {
collection = DependencyAnalyzer.analyzeProvides(artifact.toFile(), classResolver, null);
collection = dependencyAnalyzer.analyzeProvides(artifact.toFile(), classResolver);
analyzeCache.put(artifact, collection);
}
boolean ok = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.Enumeration;
import java.util.List;
import java.util.Optional;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.jar.JarEntry;
Expand All @@ -34,6 +35,11 @@ public class DependencyAnalyzer {

static final String CLASS_SUFFIX = ".class";
static final int ASM_API = Opcodes.ASM9;
private BiConsumer<String, Throwable> errorConsumer;

public DependencyAnalyzer(BiConsumer<String, Throwable> errorConsumer) {
this.errorConsumer = errorConsumer;
}

public static String getPackageName(String className) {
className = className.replace('/', '.');
Expand All @@ -44,7 +50,7 @@ public static String getPackageName(String className) {
return className;
}

public static Function<String, Optional<ClassMethods>> createDependencyClassResolver(JrtClasses jrtClassResolver,
public Function<String, Optional<ClassMethods>> createDependencyClassResolver(JrtClasses jrtClassResolver,
DependencyArtifacts artifacts) throws MojoFailureException {
ClassCollection allClassMethods = new ClassCollection();
Function<String, Optional<ClassMethods>> function = allClassMethods.chain(jrtClassResolver);
Expand Down Expand Up @@ -76,7 +82,12 @@ public static List<ClassUsage> analyzeUsage(File file, JrtClasses jre) throws Mo
}
}

public static ClassCollection analyzeProvides(File file, Function<String, Optional<ClassMethods>> classResolver,
public ClassCollection analyzeProvides(File file, Function<String, Optional<ClassMethods>> classResolver)
throws MojoFailureException {
return analyzeProvides(file, classResolver, null);
}

public ClassCollection analyzeProvides(File file, Function<String, Optional<ClassMethods>> classResolver,
Consumer<ClassMethods> consumer) throws MojoFailureException {
try {
ClassCollection local = new ClassCollection();
Expand All @@ -88,7 +99,16 @@ public static ClassCollection analyzeProvides(File file, Function<String, Option
String name = jarEntry.getName();
if (name.endsWith(CLASS_SUFFIX)) {
InputStream stream = jar.getInputStream(jarEntry);
ClassMethods methods = new ClassMethods(stream.readAllBytes(), resolver);
ClassMethods methods;
try {
methods = new ClassMethods(stream.readAllBytes(), resolver);
} catch (RuntimeException e) {
// can't analyze this class, example of errors is
// java.lang.ArrayIndexOutOfBoundsException: Index 29 out of bounds for length 9
errorConsumer.accept("Can't analyze class '" + name + "' because of error while parsing",
e);
continue;
}
if (consumer != null) {
consumer.accept(methods);
}
Expand Down
Loading