Skip to content

Commit

Permalink
Handle class parsing errors more gracefully
Browse files Browse the repository at this point in the history
Currently there can be some classes in the wild that can not be parsed
by ASM, instead of completely fail, we just print the cause to the log
and go on.
  • Loading branch information
laeubi committed Jan 20, 2025
1 parent 82559f8 commit 2a373e6
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 5 deletions.
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

0 comments on commit 2a373e6

Please sign in to comment.