在Gradle中编译一个JDK8项目+一个JDK9"module-info.java"
Compile a JDK 8 project + a JDK 9 "module-info.java" in Gradle
我正在开发一个针对 JDK 8 的 Java 库,我正在使用 OpenJDK 11 在 Gradle 5 中构建它。为了目标 JDK 8,我是 javac 的 --release
选项。
但是,我还希望我的库与 JPMS 兼容。换句话说:
- 我想提供一个用
--release 9
编译的module-info.class
(Stephen Colebourne's scale中的选项3),
- 其余的都是用
--release 8
编译的。
MCVE
build.gradle:
plugins {
id 'java'
id 'org.javamodularity.moduleplugin' version '1.4.1' // *
}
repositories {
mavenCentral()
}
dependencies {
compileOnly 'org.projectlombok:lombok:1.18.6'
}
compileJava.options.compilerArgs.addAll(['--release', '9']) // **
* org.javamodularity.moduleplugin
为 compileJava
设置 --module-path
** --release
还没有 Gradle DSL:#2510
src/main/java/module-info.java:
module pl.tlinkowski.sample {
requires lombok;
exports pl.tlinkowski.sample;
}
src/main/java/pl/tlinkowski/sample/Sample.java:
package pl.tlinkowski.sample;
@lombok.Value
public class Sample {
int sample;
}
此 MCVE 编译,但所有 classes(而不是仅 module-info.class
)都是 JDK 9 class 格式(v.53)。
其他构建工具
我想做的事肯定可以在:
- 行家
- 例如ThreeTen-Extra(他们的方法归结为:首先用
--release 9
编译所有东西,然后用--release 8
编译除module-info.java
之外的所有东西)。
- 蚂蚁
- 例如Lombok(他们的方法归结为:在单独的 "source set" 中有
module-info.java
- 主要源代码集是用 --release 8
编译的,而 "module info" 源代码集是用 "module info" 编译的--release 9
).
我试过的
我喜欢 Lombok 的方法,所以我对 build.gradle
中的源集进行了如下操作:
sourceSets {
main { // all but module-info
java {
exclude 'module-info.java'
}
}
mainModuleInfo { // module-info only
java {
srcDirs = ['src/main/java']
outputDir = file("$buildDir/classes/java/main")
include 'module-info.java'
}
}
}
然后,我配置了一个任务依赖项,并为两个编译任务添加了适当的 --release
选项:
classes.dependsOn mainModuleInfoClasses
compileJava.options.compilerArgs.addAll(['--release', '8'])
compileMainModuleInfoJava.options.compilerArgs.addAll(['--release', '9'])
如果我现在编译,我得到:
error: package lombok does not exist
所以我仍然不知道如何指示org.javamodularity.moduleplugin
:
- 不使用
--module-path
作为 main
- 为
mainModuleInfo
设置适当的 --module-path
编辑: Gradle 模块插件 现在支持此功能,因为版本 1.5.0。
这是一个有效的 build.gradle
片段:
plugins {
id 'java'
id 'org.javamodularity.moduleplugin' version '1.5.0'
}
repositories {
mavenCentral()
}
dependencies {
compileOnly 'org.projectlombok:lombok:1.18.6'
}
modularity.mixedJavaRelease 8
好的,我通过以下方式成功完成了这项工作:
- 禁用
org.javamodularity.moduleplugin
- 删除自定义源集(没有必要)
- 添加自定义
compileModuleInfoJava
任务并将其 --module-path
设置为 compileJava
任务的类路径(受 this Gradle manual 启发)
这里是build.gradle
的完整源代码:
plugins {
id 'java'
}
repositories {
mavenCentral()
}
dependencies {
compileOnly 'org.projectlombok:lombok:1.18.6'
}
compileJava {
exclude 'module-info.java'
options.compilerArgs = ['--release', '8']
}
task compileModuleInfoJava(type: JavaCompile) {
classpath = files() // empty
source = 'src/main/java/module-info.java'
destinationDir = compileJava.destinationDir // same dir to see classes compiled by compileJava
doFirst {
options.compilerArgs = [
'--release', '9',
'--module-path', compileJava.classpath.asPath,
]
}
}
compileModuleInfoJava.dependsOn compileJava
classes.dependsOn compileModuleInfoJava
备注:
我为此开发了一个 Gradle 插件:https://github.com/Glavo/module-info-compiler
我试过GradleModules Plugin,但是还是有些麻烦的问题,所以我开发了这个插件,一个专门用来编译module-info.java
.
的编译器
不是调用javac实现的。是一个完整的编译器,可以运行 above Java 8. 识别module-info.java
的语法,并根据它生成对应的module-info.class
文件。
它只检查语法,并不实际检查那些包,类或模块,所以它可以在不配置任何模块路径的情况下工作。
这个 Gradle 插件已经为您处理了一切。对于一个包含module-info.java
的Java8项目,你只需要这样做:
plugins {
id("java")
id("org.glavo.compile-module-info-plugin") version "2.0"
}
tasks.compileJava {
options.release.set(8)
}
我正在开发一个针对 JDK 8 的 Java 库,我正在使用 OpenJDK 11 在 Gradle 5 中构建它。为了目标 JDK 8,我是 javac 的 --release
选项。
但是,我还希望我的库与 JPMS 兼容。换句话说:
- 我想提供一个用
--release 9
编译的module-info.class
(Stephen Colebourne's scale中的选项3), - 其余的都是用
--release 8
编译的。
MCVE
build.gradle:
plugins {
id 'java'
id 'org.javamodularity.moduleplugin' version '1.4.1' // *
}
repositories {
mavenCentral()
}
dependencies {
compileOnly 'org.projectlombok:lombok:1.18.6'
}
compileJava.options.compilerArgs.addAll(['--release', '9']) // **
* org.javamodularity.moduleplugin
为 compileJava
--module-path
** --release
还没有 Gradle DSL:#2510
src/main/java/module-info.java:
module pl.tlinkowski.sample {
requires lombok;
exports pl.tlinkowski.sample;
}
src/main/java/pl/tlinkowski/sample/Sample.java:
package pl.tlinkowski.sample;
@lombok.Value
public class Sample {
int sample;
}
此 MCVE 编译,但所有 classes(而不是仅 module-info.class
)都是 JDK 9 class 格式(v.53)。
其他构建工具
我想做的事肯定可以在:
- 行家
- 例如ThreeTen-Extra(他们的方法归结为:首先用
--release 9
编译所有东西,然后用--release 8
编译除module-info.java
之外的所有东西)。
- 例如ThreeTen-Extra(他们的方法归结为:首先用
- 蚂蚁
- 例如Lombok(他们的方法归结为:在单独的 "source set" 中有
module-info.java
- 主要源代码集是用--release 8
编译的,而 "module info" 源代码集是用 "module info" 编译的--release 9
).
- 例如Lombok(他们的方法归结为:在单独的 "source set" 中有
我试过的
我喜欢 Lombok 的方法,所以我对 build.gradle
中的源集进行了如下操作:
sourceSets {
main { // all but module-info
java {
exclude 'module-info.java'
}
}
mainModuleInfo { // module-info only
java {
srcDirs = ['src/main/java']
outputDir = file("$buildDir/classes/java/main")
include 'module-info.java'
}
}
}
然后,我配置了一个任务依赖项,并为两个编译任务添加了适当的 --release
选项:
classes.dependsOn mainModuleInfoClasses
compileJava.options.compilerArgs.addAll(['--release', '8'])
compileMainModuleInfoJava.options.compilerArgs.addAll(['--release', '9'])
如果我现在编译,我得到:
error: package lombok does not exist
所以我仍然不知道如何指示org.javamodularity.moduleplugin
:
- 不使用
--module-path
作为main
- 为
mainModuleInfo
设置适当的
--module-path
编辑: Gradle 模块插件 现在支持此功能,因为版本 1.5.0。
这是一个有效的 build.gradle
片段:
plugins {
id 'java'
id 'org.javamodularity.moduleplugin' version '1.5.0'
}
repositories {
mavenCentral()
}
dependencies {
compileOnly 'org.projectlombok:lombok:1.18.6'
}
modularity.mixedJavaRelease 8
好的,我通过以下方式成功完成了这项工作:
- 禁用
org.javamodularity.moduleplugin
- 删除自定义源集(没有必要)
- 添加自定义
compileModuleInfoJava
任务并将其--module-path
设置为compileJava
任务的类路径(受 this Gradle manual 启发)
这里是build.gradle
的完整源代码:
plugins {
id 'java'
}
repositories {
mavenCentral()
}
dependencies {
compileOnly 'org.projectlombok:lombok:1.18.6'
}
compileJava {
exclude 'module-info.java'
options.compilerArgs = ['--release', '8']
}
task compileModuleInfoJava(type: JavaCompile) {
classpath = files() // empty
source = 'src/main/java/module-info.java'
destinationDir = compileJava.destinationDir // same dir to see classes compiled by compileJava
doFirst {
options.compilerArgs = [
'--release', '9',
'--module-path', compileJava.classpath.asPath,
]
}
}
compileModuleInfoJava.dependsOn compileJava
classes.dependsOn compileModuleInfoJava
备注:
我为此开发了一个 Gradle 插件:https://github.com/Glavo/module-info-compiler
我试过GradleModules Plugin,但是还是有些麻烦的问题,所以我开发了这个插件,一个专门用来编译module-info.java
.
不是调用javac实现的。是一个完整的编译器,可以运行 above Java 8. 识别module-info.java
的语法,并根据它生成对应的module-info.class
文件。
它只检查语法,并不实际检查那些包,类或模块,所以它可以在不配置任何模块路径的情况下工作。
这个 Gradle 插件已经为您处理了一切。对于一个包含module-info.java
的Java8项目,你只需要这样做:
plugins {
id("java")
id("org.glavo.compile-module-info-plugin") version "2.0"
}
tasks.compileJava {
options.release.set(8)
}