2

我正在使用带有 JDK 12.0.1 和org.beryx.jlink插件 (2.10.4) 的 Gradle(4.10.3,但我已经尝试了 5.4.1 以上的大多数版本),但是每次我尝试创建jlink 图片:

-> 任务:createMergedModule

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

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

无法从服务加载程序调用派生使用子句: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 失败

当我单击在合并中抛出错误的行时module-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'
    }
}

关于如何解决这个问题的任何想法?

4

1 回答 1

6

以下可能的解决方案仅基于您的构建文件,不知道您的模块信息或项目代码,因此它可能无法正常工作。

它也是基于 jlink 插件存储库中的这个问题

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

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

myapp\build\jlinkbase\tmpjars\myapp.merged.module\module-info.java:394: 错误

这表明创建的模块名为myapp.merged.module,并且它有一个module-info描述符。如果你打开它,你会看到所有的exports(默认情况下模块会导出依赖包的每个包),requiresprovides

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脚本块:

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

和:

模块描述符是使用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;
}

仅包含显式requires,所有导出,但不包含provides,因此错误将消失。

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

于 2019-06-09T11:38:25.617 回答