- add-exports / add-opens によるパッケージ公開
- Gradle Kotlin DSL でコマンドライン引数を指定する
- オプションをまとめて定義する
- MANIFEST での Add-Exports 指定
add-exports / add-opens によるパッケージ公開
Java モジュールシステムにおいて、如何ともしがたい理由で、非公開のクラスを使いたいケースは、やはりたまに発生する。
その場合、コマンドライン引数で以下を指定することになる。
--add-exports <src-module>/<pkg-name>=<target-module>
- 指定モジュールの指定パッケージの内部APIにアクセスする
--add-opens <src-module>/<pkg-name>=<<target.module>
- 指定モジュールの指定パッケージの内部にリフレクションアクセスする
Gradle Kotlin DSL でコマンドライン引数を指定する
コンパイル、テスト実行、実行、およびJavaDoc時それぞれにコマンドライン引数を指定するには、build.gradle.kts
で以下のスニペットを使用できる。
tasks.withType<JavaCompile>().configureEach { options.compilerArgs.addAll(arrayOf( "--add-exports", "jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED", "--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED")) } tasks.withType<Test>().configureEach { jvmArgs("--add-exports", "jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED", "--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED") } tasks.withType<JavaExec>().configureEach { jvmArgs("--add-exports", "jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED", "--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED") } tasks.withType<Javadoc>().configureEach { options { this as StandardJavadocDocletOptions addMultilineStringsOption("-add-exports").setValue(listOf( "jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED")) } }
それぞれ指定方法が異なるのでややこしい。
- コンパイル時の
compilerArgs
にはコレクションを指定する - テスト/実行時の
jvmArgs
には可変長引数で指定する - JavaDoc には、
addStringOption()
では同一キーのオプションを複数登録できないため、addMultilineStringsOption()
を使う- キー先頭の
-
は指定しない
- キー先頭の
オプションをまとめて定義する
以下のように定義することもできる。
val exportsOpt = arrayOf( "--add-exports", "jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED", "--add-exports", "jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED") tasks.withType<JavaCompile>().configureEach { options.compilerArgs.addAll(exportsOpt) } tasks.withType<Test>().configureEach { jvmArgs(*exportsOpt) } tasks.withType<JavaExec>().configureEach { jvmArgs(*exportsOpt) } tasks.withType<Javadoc>().configureEach { options { this as StandardJavadocDocletOptions addMultilineStringsOption("-add-exports").setValue( exportsOpt.slice(1..exportsOpt.size step 2)) } }
jvmArgs()
には可変長引数を渡すため spread operator で展開
addMultilineStringsOption()
には値を取り出して設定
なお、アプリケーションプラグインでVMオプションを指定する場合は以下のように applicationDefaultJvmArgs
に設定する。
application {
applicationDefaultJvmArgs = listOf("...")
}
MANIFEST での Add-Exports 指定
Executable JAR にする場合は、MANIFEST.MF に Add-Exports
を指定することで、実行時オプションが不要となる。
tasks.named<Jar>("jar") { manifest { attributes( "Main-Class" to application.mainClass, "Add-Exports" to "jdk.compiler/com.sun.tools.javac.jvm jdk.compiler/com.sun.tools.javac.api" ) } }
複数ある場合にはスペース区切りで記載する。
指定したものが、ターゲットモジュール ALL-UNNAMED
で指定されたものとして扱われる。