gpt4 book ai didi

java - 无法使用修饰符 "public"访问类 java.nio.DirectByteBuffer(在模块 java.base 中)的成员

转载 作者:搜寻专家 更新时间:2023-10-31 19:36:45 56 4
gpt4 key购买 nike

得到了一个仍然支持 Java 6 的项目。下面的代码位于一个 jar 文件中,该文件使用 Compiler compliance level 1.6

该 jar 文件应该从为 java 6 或更新版本构建的 java 应用程序中调用。它在 Java 8 中也运行良好。

现在使用 Java9,我遇到了 nio.DirectByteBuffer 的问题,我尝试使用反射以这种方式解决它:

@SuppressWarnings("unchecked")
static void cleanDirectBuffer(sun.nio.ch.DirectBuffer buffer) {
if (JAVA_VERSION < 1.9) {
sun.misc.Cleaner cleaner = buffer.cleaner();
if (cleaner != null) cleaner.clean();
} else {
// For java9 do it the reflection way
@SuppressWarnings("rawtypes")
Class B = buffer.getClass();
// will be a java.nio.DirectBuffer, which is unknown if compiled in 1.6 compliance mode
try {
java.lang.reflect.Method CleanerMethod = B.getMethod("cleaner");
CleanerMethod.setAccessible(true); // fails here !
Object cleaner = CleanerMethod.invoke(buffer);
if (cleaner == null) return;
@SuppressWarnings("rawtypes")
Class C = cleaner.getClass();
java.lang.reflect.Method CleanMethod = C.getMethod("clean");
CleanMethod.invoke(cleaner);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (Exception other) {
other.printStackTrace();
}
}
}

JAVA_VERSION 检测很好并且可以很好地切换,具体取决于我的调用代码使用的版本。jre6 到 jre8 环境很好地使用了 sun.misc.Cleaner 路径,但这在 java9 中不起作用

您可能会注意到我不是 java.reflection 方面的专家。通过猜测,我找到了.setAccessible(true);

lance-java 的回答(到目前为止感谢)有点帮助:

版本 2:

    Class B = buffer.getClass(); 
try {
java.lang.reflect.Method CleanerMethod = B.getDeclaredMethod("cleaner");
CleanerMethod.setAccessible(true);
Object cleaner = CleanerMethod.invoke(buffer);
if (cleaner == null) return;
@SuppressWarnings("rawtypes")
Class C = cleaner.getClass();
java.lang.reflect.Method CleanMethod = C.getDeclaredMethod("clean");
CleanMethod.setAccessible(true); // Now it fails here !
CleanMethod.invoke(cleaner);
} catch (InaccessibleObjectException e) {
// ** causes: Unable to make public void jdk.internal.ref.Cleaner.clean() accessible: module java.base does not "exports jdk.internal.ref" to unnamed module **
}

另外还有第一个 CleanerMethod.setAccessible(true)

的警告
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by my.package.MyClass (file:/xyz.jar) to method java.nio.DirectByteBuffer.cleaner()
...
WARNING: All illegal access operations will be denied in a future release

...听起来不太健康?但是,唉,这只是一个警告:)

我还缺少什么,或者是否有不同/更好的方法来解决我的问题?

最佳答案

在 Java 9 中引入了模块的概念(https://blog.codefx.org/java/java-module-system-tutorial/)。

A module lists the packages it exports. For code in one module (say org.codefx.demo.jpms) to access types in another (say String in java.base), the following accessibility rules must be fulfilled:

the accessed type ( String) must be public

the package containing the type ( java.lang) must be exported by its module (java.base)

the accessing module (org.codefx.demo.jpms) must read the accessed one (java.base), which is typically achieved by requiring it

If any of these rules are violated at compile or run time, the module systems throws an error. This means that public is no longer really public. A public type in a non-exported package is as inaccessible to the outside world as a non-public type in an exported package. Also note that reflection lost its superpowers.

现在可以定义可在包外访问的类/方法。所有其他未指定的类/方法将无法被其他模块访问,即使它们是公共(public)的。这是 java.basemodule-info 的链接 http://people.redhat.com/mbalaoal/webrevs/jdk_8029661_tls_12_sunpkcs11/2018_02_02/8029661.webrev.02/src/java.base/share/classes/module-info.java.html .如您所见,jdk.internal.ref 仅导出到这些模块:java.desktopjdk.unsupported

关于java - 无法使用修饰符 "public"访问类 java.nio.DirectByteBuffer(在模块 java.base 中)的成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47891295/

56 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com