2017-03-01 101 views
8

使用IDEA-EAP進行JDK9開發實驗。無法從java.base模塊導出包

我收到以下錯誤 -

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(); 
    ... 
} 

我試過,包括module-info.java文件,以及使用創建的模塊內帶有以下語句的IDE -

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

目錄結構現在看起來如圖片描述 -

Directory Structure

的IDE雖然反映了module-info.java爲未使用,可能這是我無法定義module com.jigsaw.npe如上嘗試的原因。

尋找一些關於如何正確放置module-info.java和/或除了我錯過的東西以外的任何幫助。

+0

@StefanZobel這個命令究竟做了什麼,它有什麼先決條件嗎? – nullpointer

+3

你的設置非常好,這與IntelliJ無關。我建議編輯問題(和標籤)以刪除該部分。 – Nicolai

回答

11

Nicolai's answer對於從java.base模塊或從任何其他模塊中導出其他未導出包的必要技術是正確的。

但是,如果目標是使用Unsafe,那麼這樣做的方法是使用由jdk.unsupported模塊導出的sun.misc.Unsafe。如果您正在編譯未命名模塊的代碼,則無需對模塊進行任何特殊的操作即可訪問它。如果你在一個模塊中編譯代碼,你需要

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); 

即使Unsafejdk.unsupported模塊,根據JEP 260,此技術在JDK 9中受支持。

8

模塊java.baseexportjdk.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 

你將有運行(java)的代碼編譯時(javac時這樣做。

+0

'--add-exports'不存在 – madduci

+1

是的,它的確如此。調用'java -X'並看一看:'--add-exports / = (,)*' – Nicolai

+0

是命令行上的選項,它確實存在,但是if你用--add-exports設置了java選項,它不起作用,抱怨說它是一個未知的命令行參數 – madduci