web-dev-qa-db-ja.com

Java.baseモジュールからパッケージをエクスポートできません

JDK9開発実験にIDEA-EAPを使用します。

次のエラーが表示されます-

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および/または私が見逃したもの以外のものを正しく配置する方法に関するいくつかのヘルプを探しています。

13
Naman

ニコライの答え は、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);

Unsafejdk.unsupportedモジュールにありますが、この手法は JEP 26 に従ってJDK 9でサポートされています。

16
Stuart Marks

モジュールJava.baseexport パッケージjdk.internal.misc.、したがってタイプjdk.internal.misc.Unsafeaccessible ではありません-結果としてコンパイルは失敗します。

次のコマンドラインオプションを追加して、パッケージをエクスポートすることができます。

# 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)ときに(Javaandをコンパイルするときにそれを行う必要があります。

13
Nicolai