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

[WIP] Strict constant reflection #10693

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Aca-S
Copy link

@Aca-S Aca-S commented Feb 14, 2025

Currently, the constant reflection analysis used by Native Image is optimization dependent. This can lead to unexpected results during image run-time when using reflection. For example, the Class.forName call in the following snippet will be folded by the analysis:

static boolean isEven(int n) {
    return n % 2 == 0;
}

Class<?> grabClass() throws ClassNotFoundException {
    var className = isEven(4) ? "A" : "B";
    return Class.forName(className); // returns Class A
}

However, adding a simple printing statement to isEven or toggling different optimizations during build-time can cause the method to be non-inlinable and Class.forName call won't be folded:

static boolean isEven(int n) {
    System.out.print("isEven was called");
    return n % 2 == 0;
}

Class<?> grabClass() throws ClassNotFoundException {
    var className = isEven(4) ? "A" : "B";
    return Class.forName(className); // throws ClassNotFoundException / MissingReflectionRegistrationError
}

In order to prevent this behavior, we can run a constant reflection analysis directly on the bytecode used as input to Native Image.

This PR implements a JVMTI agent (com.oracle.svm.reflectionagent.NativeImageReflectionAgent) which intercepts user provided class files, analyzes them for constant reflection usage and marks such reflective methods as constant by redirecting them to their counterparts in the org.graalvm.nativeimage.impl.reflectiontags.ConstantTags) class. If a reflective method invocation in a user provided class gets folded by com.oracle.svm.hosted.snippets.ReflectionPlugins without it being marked as constant by the agent, the user gets a warning during build-time:

Warning: Call to java.lang.Class.forName(String) reached in Demo.main(Demo.java:14) with arguments (A) was reduced to the constant class A outside of the strict constant reflection mode. Consider adding the appropriate entry to your reachability metadata (https://www.graalvm.org/latest/reference-manual/native-image/metadata/#reflection).

To enable the agent and warnings, use the -H:+EnableStrictReflection. In addition, three new options are provided for more accurate logging of constant reflection folding done by ReflectionPlugins:

  • -H:ReflectionPluginTraceLocation=<log_location> - Location for the log file. If not set, the log isn't created.
  • -H:ReflectionPluginTraceFormat=json|plain - Specify the format of the location log. Default value is json. If ReflectionPluginTraceLocation isn't set, this option has no effect.
  • -H:+ReflectionPluginTraceUserOnly - Log only the constant folding which occurred in user classes. Default value is true. If ReflectionPluginTraceLocation isn't set, this option has no effect.

Copy link

Thank you for your pull request and welcome to our community! To contribute, please sign the Oracle Contributor Agreement (OCA).
The following contributors of this PR have not signed the OCA:

To sign the OCA, please create an Oracle account and sign the OCA in Oracle's Contributor Agreement Application.

When signing the OCA, please provide your GitHub username. After signing the OCA and getting an OCA approval from Oracle, this PR will be automatically updated.

If you are an Oracle employee, please make sure that you are a member of the main Oracle GitHub organization, and your membership in this organization is public.

@oracle-contributor-agreement oracle-contributor-agreement bot added the OCA Required At least one contributor does not have an approved Oracle Contributor Agreement. label Feb 14, 2025
@vjovanov vjovanov self-requested a review February 14, 2025 17:51
@Aca-S Aca-S force-pushed the strict_constant_reflection branch from 1343fba to a400faa Compare February 19, 2025 06:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
OCA Required At least one contributor does not have an approved Oracle Contributor Agreement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant