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

Unexpected "Unsupported type jdk.internal.reflect.MethodAccessorGenerator is reachable" error #2192

Closed
galderz opened this issue Feb 26, 2020 · 14 comments
Assignees

Comments

@galderz
Copy link
Contributor

galderz commented Feb 26, 2020

Just spotted a Quarkus/Graal master issue, see (quarkusio/quarkus#7422):

$ mvn clean install -Dnative -pl integration-tests/optaplanner-jackson
...
Error: com.oracle.svm.hosted.substitute.DeletedElementException: Unsupported type jdk.internal.reflect.MethodAccessorGenerator is reachable
To diagnose the issue, you can add the option --report-unsupported-elements-at-runtime. The unsupported element is then reported at run time when it is accessed the first time.
Detailed message:
Trace:
	at parsing jdk.internal.reflect.ReflectionFactory.generateConstructor(ReflectionFactory.java:513)
Call path from entry point to jdk.internal.reflect.ReflectionFactory.generateConstructor(Class, Constructor):
	at jdk.internal.reflect.ReflectionFactory.generateConstructor(ReflectionFactory.java:513)
	at jdk.internal.reflect.ReflectionFactory.newConstructorForSerialization(ReflectionFactory.java:506)
	at java.io.ObjectStreamClass.getSerializableConstructor(ObjectStreamClass.java:1516)
	at java.io.ObjectStreamClass$2.run(ObjectStreamClass.java:509)
	at java.io.ObjectStreamClass$2.run(ObjectStreamClass.java:484)
	at com.oracle.svm.core.jdk.Target_java_security_AccessController.doPrivileged(SecuritySubstitutions.java:81)
	at sun.security.pkcs11.SunPKCS11.initToken(SunPKCS11.java:1028)
	at sun.security.pkcs11.SunPKCS11$TokenPoller.run(SunPKCS11.java:852)
	at java.lang.Thread.run(Thread.java:834)
	at com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:517)
	at com.oracle.svm.core.posix.thread.PosixJavaThreads.pthreadStartRoutine(PosixJavaThreads.java:193)
	at com.oracle.svm.core.code.IsolateEnterStub.PosixJavaThreads_pthreadStartRoutine_e1f4a8c0039f8337338252cd8734f63a79b5e3df(generated:0)

I suspect this is caused by the following change eab7e93

The call path above is not under Quarkus control, so I'd assume this is a regression on svm?

@galderz
Copy link
Contributor Author

galderz commented Feb 26, 2020

Testing a substitution to get ReflectionFactory.generateConstructor() to return null...

@galderz
Copy link
Contributor Author

galderz commented Feb 26, 2020

PR sent #2194

@olpaw
Copy link
Member

olpaw commented Feb 27, 2020

@galderz I think the problem already starts at sun.security.pkcs11.SunPKCS11$TokenPoller.run. Its potential execution at image runtime ultimately drags in MethodAccessorGenerator which does bytecode generation and dynamic class loading. If that code would get executed at image runtime it would fail. If we cut the problem at the root (i.e. TokenPoller.run we can avoid having lots of code in an image that wouldn't work at image runtime anyway. I will provide a PR that deals with SunPKCS11$TokenPoller.run. cc @christianwimmer

@olpaw olpaw self-assigned this Feb 27, 2020
@galderz
Copy link
Contributor Author

galderz commented Feb 27, 2020

@olpaw That's not the only way in which this appears. See Quarkus issue for at least 2 other different stack traces leading to the same error (here and here).

@olpaw
Copy link
Member

olpaw commented Feb 27, 2020

@galderz thanks for the pointers. It looks like we have a general problem with allowing serialization specific code to wander off into stuff that we cannot support.

@christianwimmer
Copy link
Member

The underlying issue is probably not related to SunPKCS11. It is an unfortunate side effect of the static analysis that everything below a AccessController.doPrivileged call is more or less random. Since the analysis is not context sensitive, every call to doPrivileged has a call edge to every action, and our printing of the shortest call path leads to a stack trace that cannot happen at run time.

I'm trying to come up with an earlier cut-off of serialization code so that we get the true call path that causes the problem.

@christianwimmer
Copy link
Member

My idea is to add the following code to disallow serialization:

@Delete("Object serialization is currently not supported")
@TargetClass(java.io.ObjectStreamClass.class)
final class Target_java_io_ObjectStreamClass {
}

Adding just that fails our gates, so I have to investigate further. But it might still help you, so you can give it a try if you want.

@galderz
Copy link
Contributor Author

galderz commented Feb 28, 2020

@christianwimmer Tried your suggestion but didn't work, we've got failures early on (e.g. here).

@christianwimmer
Copy link
Member

@galderz Thanks, I'm always amazed how bad Java code can be: https://github.com/google/gson/blob/4d735f190336ddf241eee48fa8495eabf637a330/gson/src/main/java/com/google/gson/internal/UnsafeAllocator.java#L62

@christianwimmer
Copy link
Member

@galderz Here is a less restrictive code to prevent usage of ObjectStreamClass. It deletes the methods that produce or return an instance, so I hope it is sufficient to narrow down your problem. But since it does not prevent usage of ObjectStreamClass itself it should not fail in the gson use case.

@TargetClass(java.io.ObjectStreamClass.class)
@SuppressWarnings({"unused"})
final class Target_java_io_ObjectStreamClass {

    @Delete("Object serialization is currently not supported")
    private static native ObjectStreamClass lookup(Class<?> cl, boolean all);

    @Delete("Object serialization is currently not supported")
    private Target_java_io_ObjectStreamClass(final Class<?> cl) {
    }

    @Delete("Object serialization is currently not supported")
    private Target_java_io_ObjectStreamClass() {
    }
}

@galderz
Copy link
Contributor Author

galderz commented Mar 5, 2020

@christianwimmer Apologies for the delay, testing your suggestion.

@galderz
Copy link
Contributor Author

galderz commented Mar 6, 2020

This doesn't yet work for us (see here). I'm checking with the other Quarkus devs to see where these xstream dependency is coming from and its use.

@galderz
Copy link
Contributor Author

galderz commented Mar 6, 2020

Btw @christianwimmer, your latest suggestion would still make the original reported error appear eventually since you're forbidding paths to ObjectStreamClass(Class) constructor, wouldn't it?

@galderz
Copy link
Contributor Author

galderz commented Mar 6, 2020

Oh,I think this is only to diagnose the real root path to lookup... right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants