问题
I'm working on a Java library targeting JDK 8, and I'm building it in Gradle 5 using OpenJDK 11. In order to target JDK 8, I'm javac's --release option.
However, I'd also like my library to be JPMS-compatible. In other words:
- I'd like to provide a
module-info.class
compiled with--release 9
(option 3 in Stephen Colebourne's scale), - while all the rest is compiled with
--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 sets --module-path
for compileJava
** there's no Gradle DSL for --release
yet: #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;
}
This MCVE compiles, but all the classes (instead of only module-info.class
) are in JDK 9 class format (v.53).
Other build tools
What I want to do is certainly possible in:
- Maven
- E.g ThreeTen-Extra (their approach boils down to: first compile everything with
--release 9
, and then compile everything exceptmodule-info.java
with--release 8
).
- E.g ThreeTen-Extra (their approach boils down to: first compile everything with
- Ant
- E.g. Lombok (their approach boils down to: have
module-info.java
in a separate "source set" - main source set is compiled with--release 8
, and "module info" source set is compiled with--release 9
).
- E.g. Lombok (their approach boils down to: have
What I tried
I liked Lombok's approach, so I manipulated the source sets in build.gradle
as follows:
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'
}
}
}
Then, I configured a task dependency and added proper --release
options to both compilation tasks:
classes.dependsOn mainModuleInfoClasses
compileJava.options.compilerArgs.addAll(['--release', '8'])
compileMainModuleInfoJava.options.compilerArgs.addAll(['--release', '9'])
If I compile now, I get:
error: package lombok does not exist
So I still don't know how to instruct org.javamodularity.moduleplugin
to:
- not use
--module-path
formain
- set proper
--module-path
formainModuleInfo
回答1:
EDIT: This functionality is now supported by Gradle Modules Plugin since version 1.5.0.
Here's a working build.gradle
snippet:
plugins {
id 'java'
id 'org.javamodularity.moduleplugin' version '1.5.0'
}
repositories {
mavenCentral()
}
dependencies {
compileOnly 'org.projectlombok:lombok:1.18.6'
}
modularity.mixedJavaRelease 8
OK, I managed to get this working by:
- disabling
org.javamodularity.moduleplugin
- removing the custom source set (it wasn't necessary)
- adding a custom
compileModuleInfoJava
task and setting its--module-path
to the classpath of thecompileJava
task (inspired by this Gradle manual)
Here's the full source code of 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
Notes:
- it compiles 👍
- I verified that
module-info.class
is in JDK 9 format (8th byte is0x35
→ v.53), while other classes are in JDK 8 format (8th byte is0x34
→ v.52) 👍 - however, disabling
org.javamodularity.moduleplugin
is unsatisfactory, because it means that tests will no longer run on module path, etc. 👎
来源:https://stackoverflow.com/questions/55100737/compile-a-jdk-8-project-a-jdk-9-module-info-java-in-gradle