无法从java.base模块导出包

时间:2017-03-01 17:57:17

标签: java java-9 jigsaw java-module module-info

使用IDEA-EAP进行JDK9开发实验。

我收到以下错误 -

Error:(3, 20) java: package jdk.internal.misc is not visible  
(package jdk.internal.misc is declared in module java.base, which does
not export it to module com.jigsaw.npe)

类定义为 -

package experiment;
import jdk.internal.misc.Unsafe;

public class CompareAndSwap {

    static Unsafe UNSAFE = Unsafe.getUnsafe();
    ...
}

我已经尝试在使用IDE创建的模块中包含module-info.java文件,并带有以下语句 -

module com.jigsaw.npe {
    requires java.base;
}

目录结构现在看起来如图所示 -

Directory Structure

IDE虽然将module-info.java反映为未使用,但这可能是我无法定义上面尝试的module com.jigsaw.npe的原因。

寻求关于如何正确放置module-info.java和/或除了我错过的其他内容之外的任何帮助。

2 个答案:

答案 0 :(得分:15)

Nicolai's answer关于从java.base模块或任何其他模块导出未导出的包所需的技术是正确的。

但如果目标是使用Unsafe,那么执行此操作的方法是使用由sun.misc.Unsafe模块导出的jdk.unsupported。如果您要为未命名的模块编译代码,则无需对模块执行任何特殊操作即可访问它。如果您要在模块中编译代码,则需要添加

requires jdk.unsupported;

到您的module-info.java文件。

要使用Unsafe,您必须使用反射setAccessible技术来访问该字段,这与以前的JDK版本中的操作相同:

import sun.misc.Unsafe;

...

Field theUnsafeField = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafeField.setAccessible(true);
Unsafe theUnsafe = (Unsafe)theUnsafeField.get(null);

即使Unsafe模块中有jdk.unsupported,但JDK 9支持此技术,符合JEP 260

答案 1 :(得分:13)

模块 java.base 不会exportjdk.internal.misc.,因此类型jdk.internal.misc.Unsafe不是accessible - 因此编译失败。

您可以通过添加以下命令行选项导出包:

# if you want to access it from com.jigsaw.npe only:
--add-exports java.base/jdk.internal.misc=com.jigsaw.npe
# if you want to access from all code:
--add-exports java.base/jdk.internal.misc=ALL-UNNAMED

在运行代码(javac)时编译(java时,您必须这样做。