This seems to fail with the stack trace similar to JDK-8155659, but this time it fails reliably when an external profiler, like Solaris Studio Perf Analyzer is attached to the process, and tests are loaded on bootclasspath. This blocks performance work.
This simple test with attached profiler fails:
$ perfanal ~/trunks/jdk9-dev/build/linux-x86_64-normal-server-release/images/jdk/bin/java -Xbootclasspath/a:. Test
$ alias perfanal='~/Install/solstudio/bin/collect -o test.1.er -S on -j on -A on '
public class Test {
public static void main(String... args) {
for (int c = 0; c < 1000000; c++) {
m(new Test()::run);
}
}
static void m(Runnable r) {
// do nothing
}
public void run() {
// do nothing
}
}
Exception in thread "main" java.lang.InternalError: java.lang.NullPointerException
at java.lang.invoke.MethodHandles$LookupHelper.createClass(java.base@9-internal/MethodHandles.java:2204)
at java.lang.invoke.MethodHandles$LookupHelper.access$200(java.base@9-internal/MethodHandles.java:2178)
at java.lang.invoke.MethodHandles$LookupHelper$2.run(java.base@9-internal/MethodHandles.java:2212)
at java.lang.invoke.MethodHandles$LookupHelper$2.run(java.base@9-internal/MethodHandles.java:2210)
at java.security.AccessController.doPrivileged(java.base@9-internal/Native Method)
at java.lang.invoke.MethodHandles$LookupHelper.<clinit>(java.base@9-internal/MethodHandles.java:2215)
at java.lang.invoke.MethodHandles.publicLookup(java.base@9-internal/MethodHandles.java:140)
at java.lang.invoke.MethodHandles$Lookup.canBeCached(java.base@9-internal/MethodHandles.java:2146)
at java.lang.invoke.MethodHandles$Lookup.linkMethodHandleConstant(java.base@9-internal/MethodHandles.java:2111)
at java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(java.base@9-internal/MethodHandleNatives.java:499)
at Test.main(Test.java:5)
Caused by: java.lang.NullPointerException
at java.lang.invoke.MethodHandles$Lookup.canBeCached(java.base@9-internal/MethodHandles.java:2147)
at java.lang.invoke.MethodHandles$Lookup.linkMethodHandleConstant(java.base@9-internal/MethodHandles.java:2111)
at java.lang.invoke.MethodHandleNatives.linkMethodHandleConstant(java.base@9-internal/MethodHandleNatives.java:499)
at jdk.internal.loader.BuiltinClassLoader.findResource(java.base@9-internal/BuiltinClassLoader.java:267)
at jdk.internal.loader.BootLoader.findResource(java.base@9-internal/BootLoader.java:136)
at java.lang.ClassLoader.getResource(java.base@9-internal/ClassLoader.java:1299)
at java.lang.ClassLoader.defineClass1(java.base@9-internal/Native Method)
at java.lang.ClassLoader.defineClass(java.base@9-internal/ClassLoader.java:942)
at java.lang.ClassLoader.defineClass(java.base@9-internal/ClassLoader.java:806)
at java.lang.invoke.MethodHandles$LookupHelper$1.findClass(java.base@9-internal/MethodHandles.java:2198)
at java.lang.ClassLoader.loadClass(java.base@9-internal/ClassLoader.java:486)
at java.lang.ClassLoader.loadClass(java.base@9-internal/ClassLoader.java:419)
at java.lang.invoke.MethodHandles$LookupHelper.createClass(java.base@9-internal/MethodHandles.java:2202)
... 10 more
The circularity is caused by BuiltinClassLoader usage of lambdas. This particular instance happens when Main class links the lambdas, which initializes MH$LookupHelper when doing MH$Lookup.canBeCached. This leads to MH$LH.createClass, which doubles back on BuiltinClassLoader.findResource, which has lambdas, which goes back to MH$LookupHelper... and the circle is complete.
The minimal patch that solves this particular circularity:
http://cr.openjdk.java.net/~shade/8156930/poc.patch