java - 由于 IllegalAccessException,Clojure 无法在 Java 11 上调用接口(interface)默认方法

标签 java clojure java-11

我已将我的 Clojure 应用程序从 jdk8 移动到 jdk11 (Zulu JRE 11),它开始无法调用 default method在接口(interface)上,其实现是机器生成的(看起来像 #object[com.sun.proxy.$Proxy110 0x28466aa5 nil])。

我愿意

(.someDefaultMethod iinterface-impl)

得到

java.lang.IllegalAccessException: access to public member failed: 
   my.IInterface.someDefaultMethod[Ljava.lang.Object;@172aedbe/invokeSpecial, from my.IInterface/2 (unnamed module @627551fb)
    at java.base/java.lang.invoke.MemberName.makeAccessException(MemberName.java:942)
    at java.base/java.lang.invoke.MethodHandles$Lookup.checkAccess(MethodHandles.java:2206)
    at java.base/java.lang.invoke.MethodHandles$Lookup.checkMethod(MethodHandles.java:2146)
    at java.base/java.lang.invoke.MethodHandles$Lookup.getDirectMethodCommon(MethodHandles.java:2290)
    at java.base/java.lang.invoke.MethodHandles$Lookup.getDirectMethodNoSecurityManager(MethodHandles.java:2283)
    at java.base/java.lang.invoke.MethodHandles$Lookup.unreflectSpecial(MethodHandles.java:1798)
    at my.SomeService.invoke(SomeService.java:305)

有什么解决办法吗?谢谢!

最佳答案

事实证明错误不是由于 Clojure 引起的,而是由于在代理处理程序的 invoke 中编码调用默认方法的方式:

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.println("Proxy: calling " + method);
    // Default methods are public non-abstract instance methods
    // declared in an interface.
    if (((method.getModifiers() & (Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC)) ==
            Modifier.PUBLIC) && method.getDeclaringClass().isInterface()) {
    // see https://rmannibucau.wordpress.com/2014/03/27/java-8-default-interface-methods-and-jdk-dynamic-proxies/
    final Constructor<MethodHandles.Lookup> constructor = MethodHandles.Lookup.class.getDeclaredConstructor(Class.class, int.class);
        if (!constructor.isAccessible()) {
            constructor.setAccessible(true);
        }
        final Class<?> declaringClass = method.getDeclaringClass();
        return constructor.newInstance(declaringClass, MethodHandles.Lookup.PRIVATE)
                .unreflectSpecial(method, declaringClass)
                .bindTo(proxy)
                .invokeWithArguments(args);

    }
    return null;
}

关于java - 由于 IllegalAccessException,Clojure 无法在 Java 11 上调用接口(interface)默认方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59897831/

相关文章:

asynchronous - 在 clojure 中编写异步 api – 可以使用 channel 进行单个放置/获取吗?

java模块访问问题: "Class in a module cannot access class in unnamed module because module x does not read unnamed module y"

java - org.json.JSONException : Value <html><body>&lt;script of type java. lang.String 无法转换为 JSONObject

java - 如何使用安全 :authentication tag in Spring? 获取用户名

clojure - 在 LightTable 中运行 leiningen Clojure 项目

clojure - 在文件处理任务中使用正确的功能风格

VSCode 中的 JavaFX-11 : Error: Could not find or load main class Files\Java\javafx-sdk-11. 0.2\lib

java - 我尝试序列化不可序列化的对象列表不起作用

java - JTable-绘制单元格中的内容(文本)

java - 如何在 docker 容器中运行瘦 jar