首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Gradle:构建与Java 8兼容的模块化库

Gradle:构建与Java 8兼容的模块化库
EN

Stack Overflow用户
提问于 2018-02-22 21:32:51
回答 2查看 1.4K关注 0票数 6

所以Java 9出现了,紧随其后的是Java 10。是时候让我们的库准备好在Java 9项目中使用了。我是通过以下方式完成的:

gradle

  • 提供一个插件build.gradle

  • Manually中的(实验性) jigsaw plugin根据gradle站点上的guide进行了更改,而不是使用拼图插件。

到目前为止,这两种方法都工作得很好,我可以在Java 9项目中使用生成的Jar。

问题是,生成的Jar与Java8不兼容,尽管我除了module-info.java之外没有使用Java9的特性。当我设置targetCompatibility = 8时,一条错误消息告诉我也相应地设置sourceCompatibility = 8。然后,它拒绝我应该为其设置sourceCompatibility = 9module-info.java

如何解决这个问题呢?

我再次移除了这个拼图插件,并尝试了一下,但还是卡住了:

  1. set sourceCompatibility = 8targetCompatibility = 8
  2. 为新的源集创建一个包含单个文件module-info.java
  3. set sourceCompatibility = 9targetCompatibility = 9的新源集

现在编译可以工作了,Gradle在尝试编译module-info.java时使用Java9。但是,模块(在本例中是log4j)丢失了,我得到了这个错误:

代码语言:javascript
复制
: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):

代码语言:javascript
复制
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

代码语言:javascript
复制
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;
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-02-23 16:36:59

好的,我终于让它工作了,。如果其他人想知道如何做到这一点,这是我所做的:

  • 将Java设置为8,以便Java8应用程序可以使用该库:

sourceCompatibility = 8targetCompatibility =8

  • 配置模块名称

ext.moduleName = com.dua3.utility

  • 添加一个仅包含module-info.java的新源集:

sourceSets { moduleInfo { java { srcDir 'src/module-info/ Java‘}

  • 将moduleInfo、sourceSet、配置模块设置为Java9兼容性,并设置输出目录:

compileModuleInfoJava { sourceCompatibility =9 targetCompatibility =9 inputs.property("moduleName",moduleName) doFirst { classpath += sourceSets.main.compileClasspath options.compilerArgs =‘--模块路径’,classpath.asPath,‘--添加模块’,‘所有系统,org.apache.logging.log4j','-d',sourceSets.main.output.classesDirs.asPath }}

  • jar任务配置为包括moduleInfo

jar {来自sourceSets.moduleInfo.output的sourceSets.main.output }

如果您使用的是SpotBugs插件,则还必须显式配置sourceSet,否则它在尝试处理ModuleInfo sourceSet时将失败。

我最终使用了这个版本的build.gradle

代码语言:javascript
复制
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'
票数 3
EN

Stack Overflow用户

发布于 2019-04-08 01:59:34

这个问题已经有一年多了,但是如果有人在这里遇到困难,这个功能现在已经被1.5.0版本的Gradle模块插件所支持。

使用此插件,您不必创建自定义源集,只需调用modularity.mixedJavaRelease方法即可。

下面是如何将该插件应用于主build.gradle的示例

代码语言:javascript
复制
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)
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48928723

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档