[英]Gradle: Building a modularized library that is compatible with Java 8
所以 Java 9 就在那里,很快就會有 Java 10。是時候讓我們的庫准備好在 Java 9 項目中使用了。 我是通過以下方式做到的:
到目前為止,這兩種方法都可以正常工作,我可以在 Java 9 個項目中使用生成的 Jar。
問題是,生成的 Jar 與 Java 8 不兼容,盡管我沒有使用 Java 9 功能,除了module-info.java
。 當我設置targetCompatibility = 8
時,一條錯誤消息告訴我還相應地設置sourceCompatibility = 8
。 然后拒絕我應該為其設置sourceCompatibility = 9
的module-info.java
。
如何解決?
我再次刪除了拼圖插件,並嘗試了這個,但卡住了:
sourceCompatibility = 8
和targetCompatibility = 8
moduleInfo
,其中包含單個文件module-info.java
sourceCompatibility = 9
和targetCompatibility = 9
現在編譯工作正常,並且 Gradle 在嘗試編譯module-info.java
時使用 Java 9 。 但是,缺少模塊(在本例中為 log4j),我收到此錯誤:
:compileJava UP-TO-DATE
:processResources NO-SOURCE
:classes UP-TO-DATE
:jar UP-TO-DATE
:sourcesJar UP-TO-DATE
:assemble UP-TO-DATE
:spotbugsMain UP-TO-DATE
:compileModuleInfoJava
classpath:
compilerArgs: [--module-path, , --add-modules, ALL-SYSTEM]
D:\git\utility\src\module-info\java\module-info.java:14: error: module not found: org.apache.logging.log4j
requires org.apache.logging.log4j;
^
warning: using incubating module(s): jdk.incubator.httpclient
1 error
1 warning
:compileModuleInfoJava FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':compileModuleInfoJava'.
> Compilation failed; see the compiler error output for details.
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
* Get more help at https://help.gradle.org
BUILD FAILED in 1s
5 actionable tasks: 1 executed, 4 up-to-date
這是使用的build.gradle
(Gradle 版本是 4.5.1):
plugins {
id "com.github.spotbugs" version "1.6.0"
}
apply plugin: 'maven'
apply plugin: 'maven-publish'
apply plugin: 'java-library'
apply plugin: 'com.github.spotbugs'
sourceCompatibility = 8
targetCompatibility = 8
group = 'com.dua3.utility'
repositories {
mavenLocal()
jcenter()
}
dependencies {
compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.10.0'
testRuntime group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.10.0'
// Use JUnit test framework
testImplementation 'junit:junit:4.12'
}
ext.moduleName = 'com.dua3.utility'
sourceSets {
moduleInfo {
java {
srcDir 'src/module-info/java'
}
}
}
compileModuleInfoJava {
sourceCompatibility = 9
targetCompatibility = 9
inputs.property("moduleName", moduleName)
doFirst {
options.compilerArgs = [
'--module-path', classpath.asPath,
'--add-modules', 'ALL-SYSTEM'
]
classpath = files()
System.out.println("classpath: "+classpath.asPath)
System.out.println("compilerArgs: "+options.compilerArgs)
}
}
tasks.withType(com.github.spotbugs.SpotBugsTask) {
reports {
xml.enabled false
html.enabled true
}
}
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
}
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
}
artifacts {
archives sourcesJar
// fails with jigsaw: archives javadocJar
}
defaultTasks 'build', 'publishToMavenLocal', 'install'
這是module-info.java
:
module com.dua3.utility {
exports com.dua3.utility;
exports com.dua3.utility.io;
exports com.dua3.utility.jfx;
exports com.dua3.utility.swing;
exports com.dua3.utility.lang;
exports com.dua3.utility.math;
exports com.dua3.utility.text;
requires javafx.controls;
requires javafx.web;
requires java.xml;
requires java.desktop;
requires org.apache.logging.log4j;
}
好的,我終於搞定了 。 如果其他人想知道如何做,這就是我所做的:
將Java版本設置為8,以便Java 8應用程序可以使用該庫:
sourceCompatibility = 8
targetCompatibility = 8
配置模塊名稱
ext.moduleName
= com.dua3.utility
添加僅包含module-info.java
的新module-info.java
:
sourceSets { moduleInfo { java { srcDir 'src/module-info/java' } } }
為moduleInfo,sourceSet,configure modules設置與Java 9的兼容性,並設置輸出目錄:
compileModuleInfoJava { sourceCompatibility = 9 targetCompatibility = 9 inputs.property("moduleName", moduleName) doFirst { classpath += sourceSets.main.compileClasspath options.compilerArgs = [ '--module-path', classpath.asPath, '--add-modules', 'ALL-SYSTEM,org.apache.logging.log4j', '-d', sourceSets.main.output.classesDirs.asPath ] } }
配置jar
任務以包含moduleInfo
:
jar { from sourceSets.main.output from sourceSets.moduleInfo.output }
如果您使用的是SpotBugs
插件,則還必須顯式配置sourceSet,否則在嘗試處理ModuleInfo sourceSet時會失敗。
我終於得到了這個版本的build.gradle
:
plugins {
id "com.github.spotbugs" version "1.6.0"
}
apply plugin: 'maven'
apply plugin: 'maven-publish'
apply plugin: 'java-library'
apply plugin: 'com.github.spotbugs'
sourceCompatibility = 8
targetCompatibility = 8
group = 'com.dua3.utility'
repositories {
mavenLocal()
jcenter()
}
dependencies {
compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.10.0'
testRuntime group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.10.0'
// Use JUnit test framework
testImplementation 'junit:junit:4.12'
}
ext.moduleName = 'com.dua3.utility'
sourceSets {
moduleInfo {
java {
srcDir 'src/module-info/java'
}
}
}
compileModuleInfoJava {
sourceCompatibility = 9
targetCompatibility = 9
inputs.property("moduleName", moduleName)
doFirst {
classpath += sourceSets.main.compileClasspath
options.compilerArgs = [
'--module-path', classpath.asPath,
'--add-modules', 'ALL-SYSTEM',
'-d', sourceSets.main.output.classesDirs.asPath
]
}
}
jar
{
from sourceSets.main.output
from sourceSets.moduleInfo.output
}
spotbugs {
sourceSets = [sourceSets.main]
}
tasks.withType(com.github.spotbugs.SpotBugsTask) {
reports {
xml.enabled false
html.enabled true
}
}
task sourcesJar(type: Jar, dependsOn: classes) {
classifier = 'sources'
from sourceSets.main.allSource
}
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
}
artifacts {
archives sourcesJar
archives javadocJar
}
defaultTasks 'build', 'publishToMavenLocal', 'install'
問題已經超過一年了,但是如果有人在這里遇到麻煩,那么從1.5.0版本開始, Gradle Modules Plugin現在支持此功能。
使用此插件,您不必創建自定義源集,只需調用modularity.mixedJavaRelease
方法即可。
這是一個如何將插件應用於一個主build.gradle
:
plugins {
// your remaining plugins here
id 'org.javamodularity.moduleplugin' version '1.5.0' apply false
}
subprojects {
// your remaining subproject configuration here
apply plugin: 'org.javamodularity.moduleplugin'
modularity.mixedJavaRelease 8 // sets "--release 8" for main code, and "--release 9" for "module-info.java"
// test.moduleOptions.runOnClasspath = true // optional (if you want your tests to still run on classpath)
}
我為此開發了一個 Gradle 插件: https://github.com/Glavo/module-info-compiler
試過Gradle Modules Plugin,但是還是有些麻煩的問題,所以開發了這個插件,專門用來編譯module-info.java
的編譯器。
它不是通過調用javac實現的。 是一個可以運行在Java上面的完整編譯器 8.識別module-info.java
的語法,並根據它生成對應的module-info.class
文件。
它只檢查語法,並不實際檢查那些包、類或模塊,因此它可以在不配置任何模塊路徑的情況下工作。
這個 Gradle 插件已經為你處理好了一切。 對於包含module-info.java
的 Java 8 項目,你只需要這樣做:
plugins {
id("java")
id("org.glavo.compile-module-info-plugin") version "2.0"
}
tasks.compileJava {
options.release.set(8)
}
這個答案復制了自己在另一個問題下寫的答案( https://stackoverflow.com/a/72074642/7659948 )。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.