Java Gradle jlink插件在createMergedModule过程中失败,带有“0”;服务实现没有默认构造函数";

Java Gradle jlink插件在createMergedModule过程中失败,带有“0”;服务实现没有默认构造函数";,java,gradle,javafx,xmlbeans,jlink,Java,Gradle,Javafx,Xmlbeans,Jlink,我在JDK 12.0.1和org.beryx.jlinkplugin(2.10.4)中使用Gradle(4.10.3,但我已经尝试了5.4.1至5.4.1的大多数版本),但每次尝试创建jlink映像时都会遇到这个错误: ->任务:createMergedModule 无法从中的服务加载程序调用派生uses子句: com/fasterxml/jackson/databind/ObjectMapper$2.run() 无法从中的服务加载程序调用派生uses子句: com/fasterxml/jack

我在JDK 12.0.1和
org.beryx.jlink
plugin(2.10.4)中使用Gradle(4.10.3,但我已经尝试了5.4.1至5.4.1的大多数版本),但每次尝试创建jlink映像时都会遇到这个错误:

->任务:createMergedModule

无法从中的服务加载程序调用派生uses子句: com/fasterxml/jackson/databind/ObjectMapper$2.run()

无法从中的服务加载程序调用派生uses子句: com/fasterxml/jackson/databind/ObjectMapper.secureGetServiceLoader()

无法从中的服务加载程序调用派生uses子句: org/apache/commons/compress/utils/ServiceLoaderIterator.()

C:\Users\MyName\IdeaProjects\myapp\build\jlinkbase\tmpjars\myapp.merged.module\module info.java:393: 错误:服务实现没有默认构造函数: XBeansXPath 为org.apache.xmlbeans.impl.store.PathDelegate.SelectPathInterface提供 org.apache.xmlbeans.impl.xpath.saxon.XBeansXPath

C:\Users\MyName\IdeaProjects\myapp\build\jlinkbase\tmpjars\myapp.merged.module\module info.java:394: 错误:服务实现没有默认构造函数: XBeansXQuery 提供org.apache.xmlbeans.impl.store.QueryDelegate.QueryInterface与 org.apache.xmlbeans.impl.xquery.saxon.XBeansXQuery; 2个错误

->任务:createMergedModule失败

当我点击合并的
模块info.java
中抛出错误的行时,它指向以下两个:

provides org.apache.xmlbeans.impl.store.PathDelegate.SelectPathInterface with org.apache.xmlbeans.impl.xpath.saxon.XBeansXPath;
provides org.apache.xmlbeans.impl.store.QueryDelegate.QueryInterface with org.apache.xmlbeans.impl.xquery.saxon.XBeansXQuery;
我的
build.gradle
文件如下所示:

plugins {
    id 'application'
    id 'idea'
    id 'java'
    id 'org.openjfx.javafxplugin' version '0.0.7'
    id 'org.beryx.jlink' version '2.10.4'
}

repositories {
    mavenCentral()
}

dependencies {
    compile 'org.apache.commons:commons-csv:1.6'
    compile 'org.apache.poi:poi-ooxml:4.1.0'
    compile 'com.fasterxml.jackson.core:jackson-core:2.9.9'
    compile 'com.fasterxml.jackson.core:jackson-annotations:2.9.9'
    compile 'com.fasterxml.jackson.core:jackson-databind:2.9.9'
    testCompile 'org.junit.jupiter:junit-jupiter-api:5.5.0-M1'
    testRuntime 'org.junit.jupiter:junit-jupiter-engine:5.5.0-M1'
}

// ### Application plugin settings
application {
    mainClassName = "$moduleName/path.to.myapp"
}

// ### Idea plugin settings
idea {
    module {
        outputDir = file("out/production/classes")
    }
}

// ### Java plugin settings
sourceCompatibility = JavaVersion.VERSION_11

compileJava {
    options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
}

test {
    useJUnitPlatform()
    testLogging {
        events 'PASSED', 'FAILED', 'SKIPPED'
    }
}

// ### JavaFX plugin settings
javafx {
    version = "12.0.1"
    modules = ['javafx.controls', 'javafx.fxml']
}

// ### jlink plugin settings
jlink {
    options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
    launcher {
        name = 'myapp'
    }
}
插件{
id“应用程序”
“主意”
id‘java’
id“org.openjfx.javafxplugin”版本“0.0.7”
id“org.beryx.jlink”版本“2.10.4”
}
存储库{
mavenCentral()
}
依赖关系{
编译“org.apache.commons:commons csv:1.6”
编译“org.apache.poi:poi ooxml:4.1.0”
编译'com.fasterxml.jackson.core:jackson-core:2.9.9'
编译'com.fasterxml.jackson.core:jackson注释:2.9.9'
编译'com.fasterxml.jackson.core:jackson数据绑定:2.9.9'
testCompile'org.junit.jupiter:junit-jupiter-api:5.5.0-M1'
testRuntime'org.junit.jupiter:junit-jupiter引擎:5.5.0-M1'
}
//####应用程序插件设置
应用{
mainClassName=“$moduleName/path.to.myapp”
}
//####创意插件设置
意念{
模块{
outputDir=文件(“输出/生产/类”)
}
}
//####Java插件设置
sourceCompatibility=JavaVersion.VERSION\u 11
内贾瓦{

options.compilerArgs以下可能的解决方案仅基于您的生成文件,而不知道您的模块信息或项目代码,因此可能无法工作

jlink插件的存储库也基于此

首先,让我解释一下这个插件是如何工作的:由于(JDK)
jlink
工具不允许非模块依赖关系,该插件将尝试收集所有依赖关系并动态创建一个模块,该模块可以添加到模块路径中。该模块名为
$yourModuleName.mergedModule

现在,我正在将您的依赖项添加到一个简单的JavaFX项目中。当我运行
/gradlew jlink
时,我会收到与您发布的错误相同的错误。如果您检查错误:

myapp\build\jlinkbase\tmpjars\myapp.merged.module\module info.java:394:error

这表明创建的模块名为
myapp.merged.module
,并且它有一个
module info
描述符。如果打开它,您将看到所有的
导出
(默认情况下,模块将导出依赖项的每个包),
需要
,而
提供

open module myapp.merged.module {
    exports com.fasterxml.jackson.annotation;
    exports com.fasterxml.jackson.core;
    exports com.fasterxml.jackson.core.async;
    ...
    exports schemaorg_apache_xmlbeans.system.sXMLTOOLS;
    requires java.xml.crypto;
    requires java.logging;
    requires java.sql;
    requires java.xml;
    requires java.desktop;
    requires java.security.jgss;
    requires jdk.javadoc;
    uses java.nio.file.spi.FileSystemProvider;
    provides com.fasterxml.jackson.core.JsonFactory with com.fasterxml.jackson.core.JsonFactory;
    provides com.fasterxml.jackson.core.ObjectCodec with com.fasterxml.jackson.databind.ObjectMapper;
    provides org.apache.xmlbeans.impl.store.QueryDelegate.QueryInterface with org.apache.xmlbeans.impl.xquery.saxon.XBeansXQuery;
    provides org.apache.xmlbeans.impl.store.PathDelegate.SelectPathInterface with org.apache.xmlbeans.impl.xpath.saxon.XBeansXPath;
}
现在的问题是:您是否应该为自己的模块添加更多需求?答案如下:这将增加项目的大小。更好的方法是使用脚本块:

mergedModule块允许您配置合并模块的模块描述符

以及:

模块描述符是使用
suggestMergedModuleInfo
任务实现的算法创建的

如果运行
/gradlew suggestMergedModuleInfo
,您将基本上获得与上述相同的合并模块描述符内容

一种可能的解决方案是开始向合并的模块描述符添加一些需求,然后重试

我从以下几点开始:

jlink {

    mergedModule {
        requires "java.xml"
    }

    options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
    launcher {
        name = 'myapp'
    }
}
我可以成功运行
/gradlew jlink

如果您现在检查合并模块描述符,它将如下所示:

open module myapp.merged.module {
    requires java.xml;

    exports com.fasterxml.jackson.annotation;
    exports com.fasterxml.jackson.core;
    exports com.fasterxml.jackson.core.async;
    ...
    exports schemaorg_apache_xmlbeans.system.sXMLTOOLS;
}
只包含显式的
需要
,但不包含
的所有导出都提供
,因此错误将消失


由于我没有您的代码,我不能说这是否适用于您,但它适用于具有相同依赖关系的我。

以下可能的解决方案仅基于您的构建文件,而不知道您的模块信息或项目代码,因此它可能不起作用

jlink插件的存储库也基于此

首先,让我解释一下这个插件是如何工作的:由于(JDK)
jlink
工具不允许非模块依赖关系,该插件将尝试收集所有依赖关系并动态创建一个模块,该模块可以添加到模块路径中。该模块名为
$yourModuleName.mergedModule

现在,我正在将您的依赖项添加到一个简单的JavaFX项目中。当我运行
/gradlew jlink
时,我会收到与您发布的错误相同的错误。如果您检查错误:

myapp\build\jlinkbase\tmpjars\myapp.merged.module\module info.java:394:error

这表明创建的模块名为
myapp.merged.module
,并且它有一个
module info
描述符。如果打开它,您将看到