当前位置: 首页 > 知识库问答 >
问题:

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

亢嘉茂
2023-03-14

所以Java9就在那里,接下来是Java10。是时候让我们的库准备好在Java9个项目中使用了。我是通过以下方式做到的:

  1. 提供module-info.java
  2. build.gradle
  3. 中添加了(实验性)拼图插件
  4. 根据gradle网站上的指南手动进行更改,而不是使用拼图插件。

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

问题是,生成的 Jar 与 Java 8 不兼容,尽管除了模块信息.java之外,我没有使用 Java 9 功能。当我设置 targetCompatibility = 8 时,一条错误消息告诉我也相应地设置 sourceCompatibility = 8然后拒绝模块信息.java我应该为此设置 sourceCompatibility = 9

这怎么解决?

我再次删除了拼图插件,并尝试了这个,但卡住了:

  1. 设置sourceCompatibility=8targetCompatibility=8<-code>
  2. 创建一个新的源集moduleInfo,其中包含单个文件模块信息。java
  3. 为新源集设置sourceCompatibility=9targetCompatibility=9

现在编译工作正常,Gradle在尝试编译module-info.java时使用Java9。但是,模块(在本例中为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'

这是模块信息.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;
}

共有3个答案

司徒经纶
2023-03-14

我为此开发了一个Gradle插件:https://github.com/Glavo/module-info-compiler

我试过Gradle Modules Plugin,但还是有一些麻烦的问题,所以我开发了这个插件,一个专门用于编译module-info.java的编译器。

它不是通过调用javac实现的。它是一个完整的编译器,可以运行在Java 8之上。它识别< code>module-info.java的语法,并根据它生成相应的< code>module-info.class文件

它只检查语法,实际上不检查那些包、类或模块,因此它可以在不配置任何模块路径的情况下工作。

这个Gradle插件已经为您处理了一切。对于包含<code>模块信息的Java 8项目。java,您只需要执行以下操作:

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).

卓嘉良
2023-03-14

这个问题已经有一年多了,但万一有人在这里绊倒了,从 1.5.0 版开始,Gradle 模块插件现在支持此功能。

使用此插件,您不必创建自定义源代码集,只需要调用<code>模块化即可。mixedJavaRelease方法。

下面是一个如何将插件应用到主< code>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)
}
黎震博
2023-03-14
匿名用户

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

>

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

    sourceCompatibility = 8

    配置模块名称

    ext.moduleName = com.dua3.utility

    添加一个仅由module-info.java组成的新源集:

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

    将moduleInfo、sourceSet、configure模块的兼容性设置为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
    }
    

    如果您使用<code>SpotBugs</code>插件,您还必须显式配置sourceSet,否则当它尝试处理ModuleInfo sourceSet时将失败。

    我最终得到了这个版本的< code>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'
    

  •  类似资料:
    • 我有一个多模块梯度构建。我想使用root为一个模块执行目标。例如:

    • 部署到AWS时,我遇到以下错误 你知道这将如何解决吗? 这将工作,如果我指定的引擎在package.json

    • 问题内容: 我想构建一个将与所有内核发行版兼容的内核模块。例如,如果我在内核3.2.0-29上构建内核模块并尝试在3.2.0-86上加载它,则会出现以下错误: modprobe my_driver 致命:插入my_driver(/lib/modules/3.2.0-86-generic/kernel/fs/my_drv/my_drv.ko)时出错:无效的模块格式 [在日志消息中:my_drv:对符

    • 我想在Gradle上的Android项目中集成以下库: 隆坡 使用AspectJ进行机器人绑定 匕首 为了将RoboBinding与AspectJ和android工具1.1结合使用。0我使用此修复程序编译了aspectj插件。 所有库都使用一些编译时注释处理。我发现Lombok与AspectJ不兼容。我注意到Robobind的注释处理器使用的是apt,而lombok只在提供的情况下工作(Dagge

    • 主要内容:1- 介绍,2- 示例模型,3-创建项目数学库,4- 创建另一个项目:MathWebApp,5- 创建GradleMain项目,6- 构建项目,7- 运行MathWebApp1- 介绍 本教程文章基于: Eclipse Java EE IDE for Web Developers. Version: Mars.1 Release (4.5.1) 如果您是初学者Gradle的。那么建议先看看初学者Gradle(Gradle Hello world)的文章: http://www.yiib

    • 我正在尝试使用java 8运行一个Spring hibernate项目。但是面对这个问题 我检查了一下,如果我们在java 8中使用spring 3。*会导致这种情况。但由于我在java 8中使用spring 4。*,所以它不应该发生 pom.xml 如果java 8不再与spring兼容,我们现在无法下载java 7。那么,我们如何将应用程序与java集成呢。 请帮忙