-
Notifications
You must be signed in to change notification settings - Fork 721
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
Invoking Class.forName through old reflection failed with ClassNotFound exception #20155
Comments
I added change in OpenJ9 to also check if the method is AsAVarargsCollector.invoke and added it to places where we also give special treatments to MethodHandle.invoke methods in [1]. @babsingh / @TobiAjila I am testing the fix in [1] to make sure that it passes the functional tests but given that this is in the VM side, would appreciate if I can get your POV on the failure as well. [1]. r30shah@ea51632 |
Can we do this with the caller sensitive annotation instead? |
I think I mean the frame iterator skip annotation. |
Note: |
See eclipse-openj9/openj9#20155 for more details on the failure and the fix. Fixes: eclipse-openj9/openj9#20155 Signed-off-by: Babneet Singh <sbabneet@ca.ibm.com>
See eclipse-openj9/openj9#20155 for more details on the failure and the fix. Fixes: eclipse-openj9/openj9#20155 Signed-off-by: Babneet Singh <sbabneet@ca.ibm.com>
Do we need similar changes for newer (or any other) versions, e.g. https://github.com/ibmruntimes/openj9-openjdk-jdk23 and https://github.com/ibmruntimes/openj9-openjdk-jdk? |
As #20155 (comment) notes, |
I am looking into running sanity.openjdk tests with setting
-Djdk.reflect.useDirectMethodHandle=false
to switch to old core reflection for method.invoke calls instead of Method Handles. While testing the SDK with that option, it fails test in [1]. I am pasting here simplified version of the test here that reproduces the problem.I printed bunch of statements in Class.forName to see why it fails with ClassNotFoundException.
What I see that in the failing case when it calls the Class.forName with the caller class at [2], it considers
java.lang.invoke.MethodHandleImpl$AsVarargsCollector.invokeWithArguments
as the caller class and as that class is being loaded by system class loader, it tries to find Test class in system class loader which did not load Test class hence it fails with ClassNotFoundException. As ways to invoke the Class.forName works in [1], I looked into the difference, also checked out the getCallerClassJEP176Iterator, I see that when we iterate the stack frames, if we reach the depth 0 and the class at that depth is one of the reflection classes or method handle.invoke classes, it keeps iterating the stack.I see that we do not check for MethodHandleImpl$AsVarargsCollector.invokeWithArguments causing us to think that the caller is that method.
I am opening up to discuss this failure and potential fix.
[1]. https://github.com/ibmruntimes/openj9-openjdk-jdk21/blob/openj9/test/jdk/java/lang/invoke/7196190/ClassForNameTest.java
[2].
openj9/jcl/src/java.base/share/classes/java/lang/Class.java
Line 406 in cf5af08
The text was updated successfully, but these errors were encountered: