classgraph: FD leak causes invalid ScanResults when run on large classpath
After upgrading Atomix to ClassGraph i’m seeing that it fails to load public inner classes yet I haven’t changed anything wrt class loaders…
java.lang.IllegalArgumentException: Could not load class io.atomix.protocols.backup.MultiPrimaryProtocol$Type
at io.github.classgraph.ScanResult.loadClass(ScanResult.java:720)
at io.github.classgraph.ScanResultObject.loadClass(ScanResultObject.java:145)
at io.github.classgraph.ClassInfo.loadClass(ClassInfo.java:1691)
at io.atomix.core.impl.ClasspathScanningAtomixRegistry.lambda$new$0(ClasspathScanningAtomixRegistry.java:56)
at java.util.ArrayList.forEach(ArrayList.java:1249)
at io.atomix.core.impl.ClasspathScanningAtomixRegistry.<init>(ClasspathScanningAtomixRegistry.java:52)
at io.atomix.core.impl.ClasspathScanningAtomixRegistry.<init>(ClasspathScanningAtomixRegistry.java:41)
at io.atomix.core.AtomixRegistry.registry(AtomixRegistry.java:49)
at io.atomix.core.Atomix.builder(Atomix.java:288)
at io.atomix.core.Atomix.builder(Atomix.java:275)
at io.atomix.core.AbstractAtomixTest.buildAtomix(AbstractAtomixTest.java:76)
at io.atomix.core.AbstractAtomixTest.createAtomix(AbstractAtomixTest.java:110)
at io.atomix.core.AbstractAtomixTest.createAtomix(AbstractAtomixTest.java:103)
at io.atomix.core.AbstractPrimitiveTest.setupCluster(AbstractPrimitiveTest.java:82)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.IllegalArgumentException: No classloader was able to load class io.atomix.protocols.backup.MultiPrimaryProtocol$Type
at io.github.classgraph.ScanResult.loadClass(ScanResult.java:682)
at io.github.classgraph.ScanResult.loadClass(ScanResult.java:715)
... 28 more
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 40 (40 by maintainers)
Commits related to this issue
- Test for #223 — committed to classgraph/classgraph by lukehutch 6 years ago
- Check loading inner interfaces works (#223) — committed to classgraph/classgraph by lukehutch 6 years ago
- Fix FD leak (#223) — committed to classgraph/classgraph by lukehutch 6 years ago
- Make resource closing logic more obvious (#223) — committed to classgraph/classgraph by lukehutch 6 years ago
@johnou Great, and yes, you’re absolutely right about that. What was happening is that the inner interface class was being referenced somewhere else on the classpath, and since the class itself had not been scanned (because it couldn’t be, because all the fds were used up), it was created as a placeholder
ClassInfo
for an “external class” (just as with class references for superclasses that are not in a whitelisted path).I really appreciate you catching this, and for helping me track down the cause. It was a very serious bug!