Skip to content

Method called from static initializer not @Substitute'd #2721

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
gustavocoding opened this issue Jul 28, 2020 · 3 comments
Closed

Method called from static initializer not @Substitute'd #2721

gustavocoding opened this issue Jul 28, 2020 · 3 comments
Assignees

Comments

@gustavocoding
Copy link

gustavocoding commented Jul 28, 2020

Describe the issue

The class MMapDirectory.java from Apache Lucene has the following static initializer:

static {
    final Object hack = AccessController.doPrivileged((PrivilegedAction<Object>) MMapDirectory::unmapHackImpl);
    // More stuff here ...
  }

A substitution was provided as:

@TargetClass(MMapDirectory.class)
final class MMapDirectoryReplacementJDK {

    @Substitute
    private static Object unmapHackImpl() {
        // Just for testing purposes, return a simple obj
        return new Object();
    }

}

But the original method was still called during the native image generation:

Error: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: Invoke with MethodHandle argument could not be reduced to at most a single call or single field access. The method handle must be a compile time constant, e.g., be loaded from a `static final` field. Method that contains the method handle invocation: java.lang.invoke.MethodHandle.invokeBasic(Object)
To diagnose the issue, you can add the option --report-unsupported-elements-at-runtime. The error is then reported at run time when the invoke is executed.
Trace: 
        at parsing java.lang.invoke.LambdaForm$MH/0x00000007c1254840.invokeExact_MT(LambdaForm$MH)
Call path from entry point to java.lang.invoke.LambdaForm$MH/185227349.invokeExact_MT(Object, Object, Object): 
        at java.lang.invoke.LambdaForm$MH/0x00000007c1254840.invokeExact_MT(LambdaForm$MH)
        at org.apache.lucene.store.MMapDirectory.lambda$null$0(MMapDirectory.java:404)
        at org.apache.lucene.store.MMapDirectory$$Lambda$1164/0x00000007c1459840.run(Unknown Source)
        at com.oracle.svm.core.jdk.Target_java_security_AccessController.doPrivileged(SecuritySubstitutions.java:83)
        at java.security.ProtectionDomain.mergePermissions(ProtectionDomain.java:488)
        at java.security.ProtectionDomain.toString(ProtectionDomain.java:425)
        at java.lang.String.valueOf(String.java:2951)
        at java.io.PrintStream.print(PrintStream.java:745)
        at java.io.PrintStream.println(PrintStream.java:882)
        at com.oracle.svm.jni.functions.JNIFunctions.ExceptionDescribe(JNIFunctions.java:759)

The line MMapDirectory.java:404 is only reached if the original method was called, not the replacement.

Steps to reproduce the issue

todo

Describe GraalVM and your environment:

openjdk version "11.0.7" 2020-04-14
OpenJDK Runtime Environment GraalVM CE 20.1.0 (build 11.0.7+10-jvmci-20.1-b02)
OpenJDK 64-Bit Server VM GraalVM CE 20.1.0 (build 11.0.7+10-jvmci-20.1-b02, mixed mode, sharing)

Linux host 5.6.16-200.fc31.x86_64 #1 SMP Thu Jun 4 18:07:41 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

@cstancu
Copy link
Member

cstancu commented Jul 28, 2020

That doesn't seem to be a problem with the substitution but rather with the lamda form, i.e., the analysis doesn't even reach the substitution, it gets stuck in the method handle.

@gustavocoding
Copy link
Author

Is there any workaround to have that method replaced?

@cstancu
Copy link
Member

cstancu commented Sep 22, 2020

The underlying issue here is incomplete MethodHandle support. That is under development and is being tracked by #2761.

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