Skip to content

Allocate annotation proxy instances at runtime #999

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

Closed
dsyer opened this issue Feb 20, 2019 · 3 comments
Closed

Allocate annotation proxy instances at runtime #999

dsyer opened this issue Feb 20, 2019 · 3 comments

Comments

@dsyer
Copy link

dsyer commented Feb 20, 2019

Seems to be related to trying to create a proxy for an Annotation, which is something the JDK does, but maybe in a different way because those ones seem to work (when you ask for MyClass.class.getAnnotation(MyAnnotation.class)). Spring uses synthetic annotations a lot and likes to create the proxy manually in this way, so the NPE is a blocker for a large class of Spring app (using @Value for instance, or @ConfigurationProperties).

[target/demo:25999]    classlist:   1,774.59 ms
[target/demo:25999]        (cap):     780.59 ms
[target/demo:25999]        setup:   1,778.58 ms
Warning: class initialization of class org.apache.commons.logging.LogAdapter$Log4jLog failed with exception java.lang.NoClassDefFoundError: org/apache/logging/log4j/LogManager. This class will be initialized at run time because either option --report-unsupported-elements-at-runtime or option --allow-incomplete-classpath is used for image building. Use the option --delay-class-initialization-to-runtime=org.apache.commons.logging.LogAdapter$Log4jLog to explicitly request delayed initialization of this class.
[target/demo:25999]     analysis:   3,883.40 ms
Fatal error: java.lang.NullPointerException
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:598)
	at java.util.concurrent.ForkJoinTask.get(ForkJoinTask.java:1005)
	at com.oracle.svm.hosted.NativeImageGenerator.run(NativeImageGenerator.java:427)
	at com.oracle.svm.hosted.NativeImageGeneratorRunner.buildImage(NativeImageGeneratorRunner.java:285)
	at com.oracle.svm.hosted.NativeImageGeneratorRunner.build(NativeImageGeneratorRunner.java:407)
	at com.oracle.svm.hosted.NativeImageGeneratorRunner.main(NativeImageGeneratorRunner.java:106)
Caused by: java.lang.NullPointerException
	at com.oracle.svm.hosted.code.CFunctionSubstitutionProcessor.lookup(CFunctionSubstitutionProcessor.java:44)
	at com.oracle.graal.pointsto.infrastructure.SubstitutionProcessor$ChainedSubstitutionProcessor.lookup(SubstitutionProcessor.java:128)
	at com.oracle.graal.pointsto.infrastructure.SubstitutionProcessor$ChainedSubstitutionProcessor.lookup(SubstitutionProcessor.java:128)
	at com.oracle.graal.pointsto.infrastructure.SubstitutionProcessor$ChainedSubstitutionProcessor.lookup(SubstitutionProcessor.java:128)
	at com.oracle.graal.pointsto.meta.AnalysisUniverse.lookupAllowUnresolved(AnalysisUniverse.java:389)
	at com.oracle.graal.pointsto.meta.AnalysisUniverse.lookup(AnalysisUniverse.java:369)
	at com.oracle.graal.pointsto.meta.AnalysisUniverse.lookup(AnalysisUniverse.java:73)
	at com.oracle.graal.pointsto.infrastructure.UniverseMetaAccess.lookupJavaMethod(UniverseMetaAccess.java:99)
	at com.oracle.graal.pointsto.meta.AnalysisMetaAccess.lookupJavaMethod(AnalysisMetaAccess.java:66)
...

Simple sample code: https://github.com/sdeleuze/graal-issues/tree/master/config-props

@cstancu cstancu self-assigned this Feb 20, 2019
@cstancu
Copy link
Member

cstancu commented Mar 7, 2019

Update: as of #1001 the image build crash has been fixed. The NPE was caused by a missing constructor in our annotation substitution type. Now that constructor is intrinsified into an UnreachedCode node. This, however, only pushes the problem to run time:

Exception in thread "main" com.oracle.svm.core.jdk.UnsupportedFeatureError: Code that was considered unreachable by closed-world analysis was reached
	at com.oracle.svm.core.util.VMError.unsupportedFeature(VMError.java:102)
	at com.oracle.svm.core.snippets.SnippetRuntime.unreachedCode(SnippetRuntime.java:178)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:739)
	at com.sample.App.main(App.java:17)

The underlying problem, i.e., allocating of annotation proxy instances at runtime, requires more work.

@cstancu cstancu changed the title NPE during native image generation in app that creates dynamic proxy Allocate annotation proxy instances at runtime Mar 7, 2019
@cstancu cstancu added the feature label Mar 7, 2019
@sdeleuze
Copy link
Collaborator

FYI this is the last known blocker to run regular Spring Boot annotation-based application as native image.

@cstancu
Copy link
Member

cstancu commented Apr 19, 2019

This is fixed by 1a68d88. This changeset maintains the optimized implementation for ahead-of-time allocated annotation instances, but it also preserves the default JDK implementation for run-time allocated annotations. See this comment for more details.

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