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

Build time initialization for substitution class is wrong #2936

Closed
ziyilin opened this issue Oct 21, 2020 · 1 comment
Closed

Build time initialization for substitution class is wrong #2936

ziyilin opened this issue Oct 21, 2020 · 1 comment
Assignees

Comments

@ziyilin
Copy link
Contributor

ziyilin commented Oct 21, 2020

Describe the issue
For clarity, I refer the original class to be substituted as target class, and the substitution class annotated with @TargetClass as substitution class.
Current class initialization attempts to initialize the target class at build time, which is unnecessary and causes initialization errors.
Current initialization process firstly initializes all unconfigured classes as safe, and then checks whether the class is safe in method com.oracle.svm.hosted.classinitialization.TypeInitializerGraph.tryPromoteToUnsafe:
image

type.getClassInitializer() here gets the wrapped type's initializer which is actually the substitution class' initializer.
image

However, at last when the method com.oracle.svm.hosted.classinitialization.ClassInitializationFeature.initializeSafeDelayedClasses initializes the safe classes, it initializes the class c which is actually the target class.
image

The problem to initialize a class with substitution is the class under safety checking and initialization are inconsistency. Therefore, if the substitution class is safe but the target class is not, the initialization will lead to build time errors. Actually when the class is substituted with @Substitute or @Delete, the target class will never appear at runtime, and it's not necessary to initialize it at build time at all.

A patch to fix this issue is proposed: #2935

Steps to reproduce the issue
This issue was discovered from a realistic application using log4j, and can be reproduced with the attached simplified test:
testClinit.zip

  1. Unzip testClinit.zip
  2. Edit clinitTest.sh to set GRAALVM_CP to GRAALVM_CP_8 or GRAALVM_CP_11 according to your own environment.
  3. Run clinitTest.sh and it fails with the follows messges:
To see how the classes got initialized, use --trace-class-initialization=org.apache.logging.log4j.util.LoaderUtil,org.apache.logging.log4j.util.PropertiesUtil
[com.alibaba.test.clinittest:77312]        write:     198.52 ms,  2.35 GB
Error: Classes that should be initialized at run time got initialized during image building:
 org.apache.logging.log4j.util.LoaderUtil was unintentionally initialized at build time. To see why org.apache.logging.log4j.util.LoaderUtil got initialized use --trace-class-initialization=org.apache.logging.log4j.util.LoaderUtil
org.apache.logging.log4j.util.PropertiesUtil was unintentionally initialized at build time. To see why org.apache.logging.log4j.util.PropertiesUtil got initialized use --trace-class-initialization=org.apache.logging.log4j.util.PropertiesUtil

com.oracle.svm.core.util.UserError$UserException: Classes that should be initialized at run time got initialized during image building:
 org.apache.logging.log4j.util.LoaderUtil was unintentionally initialized at build time. To see why org.apache.logging.log4j.util.LoaderUtil got initialized use --trace-class-initialization=org.apache.logging.log4j.util.LoaderUtil
org.apache.logging.log4j.util.PropertiesUtil was unintentionally initialized at build time. To see why org.apache.logging.log4j.util.PropertiesUtil got initialized use --trace-class-initialization=org.apache.logging.log4j.util.PropertiesUtil

Describe GraalVM and your environment:

  • GraalVM version: 9d0a251
  • JDK major version: 8 and 11
  • OS: Linux
  • Architecture: [e.g.: AMD64]
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