MethodInfo.loadClassAndGetMethod fails on Java 11
See original GitHub issueI have a case where classgraph is failing when calling MethodInfo.loadClassAndGetMethod()
on Java 11 since v4.8.19. The code works on Java 8. This stack trace is from v4.8.19 (it still fails on the latest version).
java.lang.IllegalArgumentException: Could not load class com.opengamma.service.sublambda.request.ApiGatewayRequest : java.lang.ClassNotFoundException: Could not load classfile for class com.opengamma.service.sublambda.request.ApiGatewayRequest
at io.github.classgraph.ScanResult.loadClass(ScanResult.java:1230)
at io.github.classgraph.ScanResultObject.loadClass(ScanResultObject.java:188)
at io.github.classgraph.ClassRefTypeSignature.loadClass(ClassRefTypeSignature.java:161)
at io.github.classgraph.ScanResultObject.loadClass(ScanResultObject.java:203)
at io.github.classgraph.ClassRefTypeSignature.loadClass(ClassRefTypeSignature.java:174)
at io.github.classgraph.MethodInfo.loadClassAndGetMethod(MethodInfo.java:539)
at com.opengamma.carma.clientapi.healthcheck.models.EndpointInfo.ofSubLambda(EndpointInfo.java:81)
at ...
(The class ApiGatewayRequest
is on the classpath. Its a fairly normal bean generated by Joda-Beans, with two inner classes. Verbose logging includes it I suspect it would fail to load any class, not just this one.)
I’ve cloned classgraph and tried local builds to find the bad commit. Everything works up to e6568f3e7c8eb582303da621680549f9f560428b, but one of these three commits caused the break: 15086253034434f8ab5d6b1d1fc62eff70b59558, 8292ea18c651562c1f1ca2c35dbeb344912b8987 and 4ba4503902408a2055c31cf256f6dc88f8e537c6.
The search is:
private static List<EndpointInfo> getEndpoints() {
ClassGraph classgraph =
new ClassGraph().whitelistPackages(CLIENT_API_CLASSPATH).enableMethodInfo().enableAnnotationInfo();
try (ScanResult scan = classgraph.scan()) {
return scan.getClassesImplementing(ClientApiEndpoint.class.getName()).stream()
.flatMap(classInfo -> classInfo.getMethodInfo().stream())
.filter(methodInfo -> methodInfo.hasAnnotation(SubLambda.class.getName()))
.map(EndpointInfo::ofSubLambda)
.sorted(comparing(EndpointInfo::toString))
.collect(toImmutableList());
}
}
Adding initializeLoadedClasses()
does not solve the problem. Adding verbose()
doesn’t seem to show anything useful (but I may be mistaken).
Debugging shows that the class loader it is trying to use in ScanResult
is io.github.classgraph.ClassGraphClassLoader
. Inside that class:
findLoadedClass(className)
returns nullscanResult.getClassInfo(className)
is non-nullscanResult.getClassLoaderOrderRespectingParentDelegation()
is emptyclassInfo.classLoader
is nullclassInfo.classpathElement
is nullscanResult.getClassLoaderOrderRespectingParentDelegation()
is an empty arrayscanResult.getResourcesWithPath
is an empty array- the method throws at the end
On Java 8, the classloader order array is size 2 and contains sun.misc.Launcher$ExtClassLoader
and sun.misc.Launcher$AppClassLoader
. The sun.misc.Launcher$AppClassLoader
is the one that actually succeeds in loading the class. So for whatever reason, the result of scanResult.getClassLoaderOrderRespectingParentDelegation()
is empty on Java 11 and that causes the problem.
Not sure how easy this will be for you to look at without a reproducer, but I’m raising this in case you have any ideas. If you have something you want me to try I’ll be able to look next week. Thanks!
Issue Analytics
- State:
- Created 4 years ago
- Comments:10 (7 by maintainers)
Top GitHub Comments
Yes it works, thanks
I’ve tested v4.8.29 on Java 8 and Java 11 and it works, so the issue is fixed 😃 Thanks!