-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
[native-image] Invoking MethodHandle in clojure.lang.Reflector does not work #2214
Comments
@borkdude |
@eginez In the above case using the flag Maybe there could be something like a Clojure uses this to be compatible with both JDK8 and JDK11+. Here is the link to the original code: https://github.com/clojure/clojure/blob/f5403e9c666f3281fdb880cb2c21303c273eed2d/src/jvm/clojure/lang/Reflector.java#L27-L57 |
After learning about substitutions in issue #2136, I found out that this fixes the clojure.lang.Reflector issue with java11: import com.oracle.svm.core.annotate.Substitute;
import com.oracle.svm.core.annotate.TargetElement;
import com.oracle.svm.core.annotate.TargetClass;
import com.oracle.svm.core.jdk.JDK11OrLater;
import java.lang.reflect.Method;
public final class ReflectorSubstitutions {
}
@TargetClass(className = "clojure.lang.Reflector")
final class Target_clojure_lang_Reflector {
@Substitute
@TargetElement(onlyWith = JDK11OrLater.class)
private static boolean canAccess(Method m, Object target) {
// JDK9+ use j.l.r.AccessibleObject::canAccess, which respects module rules
try {
return (boolean) m.canAccess(target);
} catch (Throwable t) {
// throw Util.sneakyThrow(t);
return false;
}
}
} |
Also available as library now: https://github.com/borkdude/clj-reflector-graal-java11-fix |
relevant issues: oracle/graal#2214 oracle/graal#955 full exception (fixed): {:cognitect.anomalies/category :cognitect.anomalies/fault, :cognitect.aws.client/throwable #error { :cause 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.Invokers$Holder.invoke_MT(Object, Object, Object, Object) :via [{:type com.oracle.svm.core.jdk.UnsupportedFeatureError :message 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.Invokers$Holder.invoke_MT(Object, Object, Object, Object) :at [com.oracle.svm.core.util.VMError unsupportedFeature VMError.java 86]}] :trace [[com.oracle.svm.core.util.VMError unsupportedFeature VMError.java 86] [clojure.lang.Reflector canAccess Reflector.java 49] [clojure.lang.Reflector toAccessibleSuperMethod Reflector.java 84] [clojure.lang.Reflector lambda$invokeInstanceMethod$0 Reflector.java 99] [java.util.stream.ReferencePipeline$3$1 accept ReferencePipeline.java 195] [java.util.ArrayList$ArrayListSpliterator forEachRemaining ArrayList.java 1655] [java.util.stream.AbstractPipeline copyInto AbstractPipeline.java 484] [java.util.stream.AbstractPipeline wrapAndCopyInto AbstractPipeline.java 474] [java.util.stream.ReduceOps$ReduceOp evaluateSequential ReduceOps.java 913] [java.util.stream.AbstractPipeline evaluate AbstractPipeline.java 234] [java.util.stream.ReferencePipeline collect ReferencePipeline.java 578] [clojure.lang.Reflector invokeInstanceMethod Reflector.java 101] [cognitect.aws.protocols.rest$serialize_uri$fn__12861 invoke rest.clj 29] [clojure.string$replace_by invokeStatic string.clj 69] [clojure.string$replace invokeStatic string.clj 106] [cognitect.aws.protocols.rest$serialize_uri invokeStatic rest.clj 22] [cognitect.aws.protocols.rest$serialize_uri invoke rest.clj 22] [clojure.core$update invokeStatic core.clj 6202] [cognitect.aws.protocols.rest$build_http_request invokeStatic rest.clj 174] [cognitect.aws.protocols.rest_xml$fn__12989 invokeStatic rest_xml.clj 11] [cognitect.aws.protocols.rest_xml$fn__12989 invoke rest_xml.clj 11] [clojure.lang.MultiFn invoke MultiFn.java 234] [cognitect.aws.client$send_request$fn__12660$state_machine__7879__auto____12687$fn__12689$fn__12703 invoke client.clj 99] [cognitect.aws.client$send_request$fn__12660$state_machine__7879__auto____12687$fn__12689 invoke client.clj 96] [cognitect.aws.client$send_request$fn__12660$state_machine__7879__auto____12687 invoke client.clj 84] [clojure.core.async.impl.ioc_macros$run_state_machine invokeStatic ioc_macros.clj 978] [clojure.core.async.impl.ioc_macros$run_state_machine_wrapped invokeStatic ioc_macros.clj 980] [cognitect.aws.client$send_request$fn__12660 invoke client.clj 84] [clojure.lang.AFn run AFn.java 22] [java.util.concurrent.ThreadPoolExecutor runWorker ThreadPoolExecutor.java 1128] [java.util.concurrent.ThreadPoolExecutor$Worker run ThreadPoolExecutor.java 628] [clojure.core.async.impl.concurrent$counted_thread_factory$reify__3362$fn__3363 invoke concurrent.clj 29] [clojure.lang.AFn run AFn.java 22] [java.lang.Thread run Thread.java 834] [com.oracle.svm.core.thread.JavaThreads threadStartRoutine JavaThreads.java 517] [com.oracle.svm.core.posix.thread.PosixJavaThreads pthreadStartRoutine PosixJavaThreads.java 192]]}}
This issue has been fixed in later releases. Closing this ticket |
Describe GraalVM and your environment :
java -Xinternalversion
:Describe the issue
Compiling Clojure code that uses
clojure.lang.Reflector
does not work with java11 due to the invocation of aMethodHandle
that cannot be reduced to a constant at compile time. The code works on java 8 where it does not use theMethodHandle
invocation.Code snippet or code repository that reproduces the issue
reflection.json:
Reflector.java:
Steps to reproduce the issue
Please include both build steps as well as run steps
Expected behavior
I'm not sure what should happen yet. Since this issue is likely to come up often when Clojure projects will migrate to java11 builds of GraalVM, I think it's good to discuss the options that either GraalVM or Clojure could offer to solve this issue.
Note: it seems that adding the option
--report-unsupported-elements-at-runtime
does seem to help with this issue:Full output of compilation
The text was updated successfully, but these errors were encountered: