Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JDK18] j.l.RuntimeException: InvocationTargetException was thrown not due to error while initialization! #14080

Closed
babsingh opened this issue Dec 6, 2021 · 8 comments · Fixed by #14352

Comments

@babsingh
Copy link
Contributor

babsingh commented Dec 6, 2021

OpenJDK Tests

TEST: java/lang/reflect/classInitialization/ExceptionInClassInitialization.java

Error

[2021-11-17T18:49:53.414Z] java.lang.RuntimeException: InvocationTargetException was thrown not due to error while initialization!
[2021-11-17T18:49:53.414Z]      at ExceptionInClassInitialization.testFieldAccess(ExceptionInClassInitialization.java:72)
[2021-11-17T18:49:53.414Z]      at ExceptionInClassInitialization.main(ExceptionInClassInitialization.java:38)
[2021-11-17T18:49:53.414Z]      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[2021-11-17T18:49:53.414Z]      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:76)
[2021-11-17T18:49:53.414Z]      at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:52)
[2021-11-17T18:49:53.414Z]      at java.base/java.lang.reflect.Method.invoke(Method.java:577)
[2021-11-17T18:49:53.414Z]      at com.sun.javatest.regtest.agent.MainActionHelper$AgentVMRunnable.run(MainActionHelper.java:312)
[2021-11-17T18:49:53.414Z]      at java.base/java.lang.Thread.run(Thread.java:884)
[2021-11-17T18:49:53.414Z] Caused by: java.lang.reflect.InvocationTargetException
[2021-11-17T18:49:53.414Z]      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[2021-11-17T18:49:53.414Z]      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:76)
[2021-11-17T18:49:53.414Z]      at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:52)
[2021-11-17T18:49:53.414Z]      at java.base/java.lang.reflect.Method.invoke(Method.java:577)
[2021-11-17T18:49:53.414Z]      at ExceptionInClassInitialization.testFieldAccess(ExceptionInClassInitialization.java:60)
[2021-11-17T18:49:53.414Z]      ... 7 more
[2021-11-17T18:49:53.414Z] Caused by: java.lang.NoClassDefFoundError: Test (initialization failure)
[2021-11-17T18:49:53.414Z]      at java.base/java.lang.J9VMInternals.initializationAlreadyFailed(J9VMInternals.java:134)
[2021-11-17T18:49:53.414Z]      at java.base/jdk.internal.misc.Unsafe.ensureClassInitialized0(Native Method)
[2021-11-17T18:49:53.414Z]      at java.base/jdk.internal.misc.Unsafe.ensureClassInitialized(Unsafe.java:1522)
[2021-11-17T18:49:53.414Z]      at java.base/jdk.internal.reflect.UnsafeFieldAccessorFactory.newFieldAccessor(UnsafeFieldAccessorFactory.java:42)
[2021-11-17T18:49:53.414Z]      at java.base/jdk.internal.reflect.ReflectionFactory.newFieldAccessor(ReflectionFactory.java:178)
[2021-11-17T18:49:53.414Z]      at java.base/java.lang.reflect.Field.acquireFieldAccessor(Field.java:1169)
[2021-11-17T18:49:53.414Z]      at java.base/java.lang.reflect.Field.getFieldAccessor(Field.java:1148)
[2021-11-17T18:49:53.414Z]      at java.base/java.lang.reflect.Field.set(Field.java:818)
[2021-11-17T18:49:53.414Z]      at Initializer.fieldAccess(Initializer.java:27)
[2021-11-17T18:49:53.414Z]      ... 12 more
[2021-11-17T18:49:53.414Z] Caused by: MyException
[2021-11-17T18:49:53.414Z]      at SuperTest.<clinit>(Test.java:29)
[2021-11-17T18:49:53.414Z]      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[2021-11-17T18:49:53.414Z]      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:76)
[2021-11-17T18:49:53.414Z]      at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:52)
[2021-11-17T18:49:53.414Z]      at java.base/java.lang.reflect.Method.invoke(Method.java:577)
[2021-11-17T18:49:53.414Z]      at Initializer.execMethod(Initializer.java:32)
[2021-11-17T18:49:53.414Z]      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[2021-11-17T18:49:53.414Z]      at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:76)
[2021-11-17T18:49:53.414Z]      at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:52)
[2021-11-17T18:49:53.414Z]      at java.base/java.lang.reflect.Method.invoke(Method.java:577)
[2021-11-17T18:49:53.415Z]      at ExceptionInClassInitialization.testExecMethod(ExceptionInClassInitialization.java:43)
[2021-11-17T18:49:53.415Z]      at ExceptionInClassInitialization.main(ExceptionInClassInitialization.java:37)
[2021-11-17T18:49:53.415Z]      ... 6 more

Related: #13946

@babsingh babsingh added this to the Release 0.31 (Java 18) milestone Dec 6, 2021
babsingh added a commit to babsingh/aqa-tests that referenced this issue Dec 6, 2021
babsingh added a commit to babsingh/aqa-tests that referenced this issue Dec 6, 2021
llxia pushed a commit to adoptium/aqa-tests that referenced this issue Dec 7, 2021
@EricYangIBM EricYangIBM self-assigned this Jan 17, 2022
@DanHeidinga
Copy link
Member

Is there a spec reference for this change?

@babsingh
Copy link
Contributor Author

Test classInitialization/ExExceptionInClassInitialization was added to verify JEP416 support which re-implements core reflection with MethodHandles. If the test passes by disabling JEP416, then there may be no spec change. Instead, we may be missing JEP416 support since the core reflection API should work the same with and without JEP416.

@EricYangIBM Can you disable JEP416 and verify if the test passes? Commit to disable JEP416: 3c9e602.

@babsingh
Copy link
Contributor Author

Another perspective: This issue may be identical to https://bugs.openjdk.java.net/browse/JDK-8048190 (NoClassDefFoundError omits original ExceptionInInitializerError). 45 older comments are hidden, which should be expanded to read more about the issue.

@EricYangIBM
Copy link
Contributor

Can you disable JEP416 and verify if the test passes?

The test still fails

@EricYangIBM
Copy link
Contributor

https://bugs.openjdk.java.net/browse/JDK-8048190 looks like it is identical to this issue. The solution to it sets the cause of the NoClassDefFoundError to be the original ExceptionInInitializerError, but I don't think it is based on any spec. Not sure why this test was created as part of JEP416 but this other test was created specifically for the solution.

@babsingh
Copy link
Contributor Author

Is there a spec reference for this change?

@EricYangIBM We have to refer to the JVM specification. Section 5.5 mentions about ExceptionInInitializerError, which is to be thrown during class or interface initialization. For spec changes, we have to see if the spec has changed between JDK17 and JDK18. I did a quick check, and I did not find any spec changes. You can confirm this detail.

JDK17 JVM spec: https://cr.openjdk.java.net/~iris/se/17/latestSpec/java-se-17-jvms-fr-diffs.pdf
JDK18 JVM spec: https://cr.openjdk.java.net/~iris/se/18/latestSpec/java-se-18-jvms-pr-diffs.pdf

re #14080 (comment) other test

Test ClassInitErrors/InitExceptionUnloadTest.java relies upon sun.hotspot.WhiteBox, which makes it a Hotspot specific test. OpenJ9 does not support sun.hotspot.WhiteBox. The test can be run with OpenJ9 if we replace the WhiteBox dependencies with OpenJ9-equivalent.

Existing OpenJ9 code related to Section 5.5 ... ExceptionInInitializerError

if (err instanceof ExceptionInInitializerError) {
cause = ((ExceptionInInitializerError)err).getException();
if (cause == null) {
/* Use the original ExceptionInInitializerError */
cause = err;
}
}
exceptions.put(clazz, new SoftReference(copyThrowable(cause)));

re #14291

In #14291, you created a completely new ExceptionInInitializerError, which may not be needed. In J9VMInternals.recordInitializationFailure, we can use the original ExceptionInInitializerError to get the correct exception for the failing test. Currently, we store the non-null cause of ExceptionInInitializerError in Map exceptions. If we find the right conditions to store ExceptionInInitializerError itself in Map exceptions, then the failing test should pass. We will also need to make sure that no other test fails because of this change.

@EricYangIBM
Copy link
Contributor

I looked at the language spec 12.4.2: https://cr.openjdk.java.net/~iris/se/18/latestSpec/java-se-18-jls-pr-diffs.pdf#page=448&zoom=100,96,678
Step 5 specifies to throw NoClassDefFoundError but nothing about its cause.

If this test isn't based on spec changes then is it necessary? It seems like this behaviour was only implemented by OpenJDK as an enhancement

@pshipton
Copy link
Member

It's good to match the behaviour of the reference so that user's don't experience different behaviour, that might cause problems, when moving to OpenJ9.

EricYangIBM added a commit to EricYangIBM/openj9 that referenced this issue Jan 18, 2022
When initialization has already failed for a class before, throw
`NoClassDefFoundError` with `ExceptionInInitializerError` as its cause
instead of the `Throwable` that caused the first initialization failure.

Fixes: eclipse-openj9#14080
Signed-off-by: Eric Yang <[email protected]>
EricYangIBM added a commit to EricYangIBM/openj9 that referenced this issue Jan 24, 2022
When initialization has already failed for a class before, throw
`NoClassDefFoundError` with `ExceptionInInitializerError` as its cause
instead of the `Throwable` that caused the first initialization failure.

Fixes: eclipse-openj9#14080
Signed-off-by: Eric Yang <[email protected]>
EricYangIBM added a commit to EricYangIBM/openj9 that referenced this issue Jan 27, 2022
When initialization has already failed for a class before, throw
`NoClassDefFoundError` with `ExceptionInInitializerError` as its cause
instead of the `Throwable` that caused the first initialization failure.

Fixes: eclipse-openj9#14080
Signed-off-by: Eric Yang <[email protected]>
EricYangIBM added a commit to EricYangIBM/aqa-tests that referenced this issue Jan 27, 2022
smlambert pushed a commit to adoptium/aqa-tests that referenced this issue Jan 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment