[java] Catch additional TypeNotPresentExceptions / LinkageErrors

These exceptions are indications of an incomplete auxclasspath
but should not fail PMD entirely.

Incomplete auxclasspath can still result in invalid violations,
either false positives or false negatives.
This commit is contained in:
Andreas Dangel committed 2020-11-21 16:38:26 +01:00
1 parent 74c0c020e1
commit e701f52d96
3 files changed
+48 -16

No files matched your search

@@ -508,7 +508,8 @@ public class ClassTypeResolver extends JavaParserVisitorAdapter implements Nulla
}
} catch (final NoSuchFieldException ignored) {
// swallow
} catch (final LinkageError e) {
} catch (final TypeNotPresentException | LinkageError e) {
// might be thrown by getGenericType()
if (LOG.isLoggable(Level.WARNING)) {
String message = "Error during type resolution of field '" + fieldImage + "' in "
+ typeToSearch.getType() + " due to: " + e;
@@ -518,8 +519,21 @@ public class ClassTypeResolver extends JavaParserVisitorAdapter implements Nulla
return null;
}
// transform the type into it's supertype
typeToSearch = typeToSearch.resolveTypeDefinition(typeToSearch.getType().getGenericSuperclass());
try {
// transform the type into it's supertype
typeToSearch = typeToSearch.resolveTypeDefinition(typeToSearch.getType().getGenericSuperclass());
} catch (final TypeNotPresentException | LinkageError e) {
// might be thrown by getGenericSuperclass()
// Note: This try block can't be moved up, because we need to go to the super type
// in case of NoSuchFieldException and search there. Otherwise we have a endless loop.
if (LOG.isLoggable(Level.WARNING)) {
String message = "Error during type resolution of field '" + fieldImage + "' in "
+ typeToSearch.getType() + " due to: " + e;
LOG.log(Level.WARNING, message);
}
// TODO : report a missing class once we start doing that...
return null;
}
}
return null;
@@ -482,22 +482,34 @@ public final class MethodTypeResolution {
// search it's supertype
if (!contextClass.equals(Object.class)) {
List<MethodType> inheritedMethods = getApplicableMethods(context.resolveTypeDefinition(contextClass.getGenericSuperclass()),
try {
List<MethodType> inheritedMethods = getApplicableMethods(context.resolveTypeDefinition(contextClass.getGenericSuperclass()),
methodName, typeArguments, argArity, accessingClass);
// but only add the found methods of the supertype, if they have not been overridden
// TODO: verify whether this simplified overriding detection is good enough and at the correct place
for (MethodType inherited : inheritedMethods) {
if (!result.contains(inherited)) {
result.add(inherited);
// but only add the found methods of the supertype, if they have not been overridden
// TODO: verify whether this simplified overriding detection is good enough and at the correct place
for (MethodType inherited : inheritedMethods) {
if (!result.contains(inherited)) {
result.add(inherited);
}
}
} catch (TypeNotPresentException | LinkageError e) {
// might be thrown by contextClass.getGenericSuperclass()
// This is an incomplete classpath, report the missing class
LOG.log(Level.FINE, "Possible incomplete auxclasspath: Error while processing methods", e);
}
}
// search it's interfaces
for (Type interfaceType : contextClass.getGenericInterfaces()) {
result.addAll(getApplicableMethods(context.resolveTypeDefinition(interfaceType),
methodName, typeArguments, argArity, accessingClass));
try {
for (Type interfaceType : contextClass.getGenericInterfaces()) {
result.addAll(getApplicableMethods(context.resolveTypeDefinition(interfaceType),
methodName, typeArguments, argArity, accessingClass));
}
} catch (TypeNotPresentException | LinkageError e) {
// might be thrown by contextClass.getGenericInterface()
// This is an incomplete classpath, report the missing class
LOG.log(Level.FINE, "Possible incomplete auxclasspath: Error while processing methods", e);
}
return result;
@@ -349,13 +349,19 @@ import java.util.logging.Logger;
protected Set<JavaTypeDefinition> getSuperTypeSet(Set<JavaTypeDefinition> destinationSet) {
destinationSet.add(this);
if (this.clazz != Object.class) {
try {
if (this.clazz != Object.class) {
resolveTypeDefinition(clazz.getGenericSuperclass()).getSuperTypeSet(destinationSet);
resolveTypeDefinition(clazz.getGenericSuperclass()).getSuperTypeSet(destinationSet);
for (Type type : clazz.getGenericInterfaces()) {
resolveTypeDefinition(type).getSuperTypeSet(destinationSet);
for (Type type : clazz.getGenericInterfaces()) {
resolveTypeDefinition(type).getSuperTypeSet(destinationSet);
}
}
} catch (TypeNotPresentException | LinkageError e) {
// might be thrown by clazz.getGenericSuperclass(), clazz.getGenericInterfaces()
// This is an incomplete classpath, report the missing class
LOG.log(Level.FINE, "Possible incomplete auxclasspath: Error while processing methods", e);
}
return destinationSet;