8

我们有一个基于 JavaFX 的应用程序,它不是模块化的(有一些原因,涉及到一个遗留库),但我们使用jdepsand构建了一个自定义运行时jlink

我们最近重写了该应用程序并添加了一些新的依赖项,并删除了其他依赖项。现在正在构建应用程序的脚本在jdeps调用期间突然停止工作。

注意:这发生在 Linux 上——我还没有测试其他操作系统,但我预计不会有另一个结果。

当脚本调用

~/path/to/jdk/bin/jdeps -q --multi-release 11 --ignore-missing-deps --print-module-deps --class-path ~/path/to/app/target/package/libs/* target/classes/ch/cnlab/uxtest/MainKt.class

结果总是

Exception in thread "main" java.lang.Error: java.util.concurrent.ExecutionException: com.sun.tools.jdeps.MultiReleaseException
    at jdk.jdeps/com.sun.tools.jdeps.DependencyFinder.waitForTasksCompleted(DependencyFinder.java:271)
    at jdk.jdeps/com.sun.tools.jdeps.DependencyFinder.parse(DependencyFinder.java:133)
    at jdk.jdeps/com.sun.tools.jdeps.DepsAnalyzer.transitiveArchiveDeps(DepsAnalyzer.java:217)
    at jdk.jdeps/com.sun.tools.jdeps.DepsAnalyzer.run(DepsAnalyzer.java:138)
    at jdk.jdeps/com.sun.tools.jdeps.ModuleExportsAnalyzer.run(ModuleExportsAnalyzer.java:74)
    at jdk.jdeps/com.sun.tools.jdeps.JdepsTask$ListModuleDeps.run(JdepsTask.java:1047)
    at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.run(JdepsTask.java:574)
    at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.run(JdepsTask.java:533)
    at jdk.jdeps/com.sun.tools.jdeps.Main.main(Main.java:49)
Caused by: java.util.concurrent.ExecutionException: com.sun.tools.jdeps.MultiReleaseException
    at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
    at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
    at jdk.jdeps/com.sun.tools.jdeps.DependencyFinder.waitForTasksCompleted(DependencyFinder.java:267)
    ... 8 more
Caused by: com.sun.tools.jdeps.MultiReleaseException
    at jdk.jdeps/com.sun.tools.jdeps.VersionHelper.add(VersionHelper.java:62)
    at jdk.jdeps/com.sun.tools.jdeps.ClassFileReader$JarFileReader.readClassFile(ClassFileReader.java:360)
    at jdk.jdeps/com.sun.tools.jdeps.ClassFileReader$JarFileIterator.hasNext(ClassFileReader.java:402)
    at jdk.jdeps/com.sun.tools.jdeps.DependencyFinder.lambda$parse$5(DependencyFinder.java:179)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
    at java.base/java.lang.Thread.run(Thread.java:833)

关于这个特定的例外,我找不到太多,到目前为止我发现的一切都不适用于我们的情况。

为了不等待构建达到这一点,我让程序在执行之前打印出命令并在终端上使用它。然后它变得有点奇怪:

Exception in thread "main" java.lang.module.FindException: Module org.slf4j not found, required by com.dlsc.gmapsfx
        at java.base/java.lang.module.Resolver.findFail(Resolver.java:893)
        at java.base/java.lang.module.Resolver.resolve(Resolver.java:192)
        at java.base/java.lang.module.Resolver.resolve(Resolver.java:141)
        at java.base/java.lang.module.Configuration.resolve(Configuration.java:421)
        at java.base/java.lang.module.Configuration.resolve(Configuration.java:255)
        at jdk.jdeps/com.sun.tools.jdeps.JdepsConfiguration$Builder.build(JdepsConfiguration.java:564)
        at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.buildConfig(JdepsTask.java:603)
        at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.run(JdepsTask.java:557)
        at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.run(JdepsTask.java:533)
        at jdk.jdeps/com.sun.tools.jdeps.Main.main(Main.java:49)

为什么突然我得到一个不同的例外?现在哪一个是正确的?我没有任何线索。
事实上,包含的jarorg.slf4j只有自动模块名称。

我真的不知道,我应该用很少的信息做什么......如果其他人可以指出某事,我会很高兴。

谢谢,丹尼尔

PS:以下代码打印命令并执行它:

echo "detecting required modules"
CMD="$JDK/bin/jdeps -q --multi-release ${JAVA_VERSION} --ignore-missing-deps --print-module-deps --class-path ${OUT_LIBS}/* ${MAIN_CLASS_FILE}"; echo "$CMD"
detected_modules=$("$JDK"/bin/jdeps -q \
  --multi-release ${JAVA_VERSION} \
  --ignore-missing-deps \
  --print-module-deps \
  --class-path "${OUT_LIBS}/*" \
    "${MAIN_CLASS_FILE}") || exit
echo "detected modules: ${detected_modules}"

他们似乎真的创造了不同的结果......

PPS:如果我删除--multi-release部分,我会得到一个不同的错误,即jackson多版本,但我需要指定我想要的......

Error: jackson-core-2.13.0.jar is a multi-release jar file but --multi-release option is not set

编辑#1

在 pom 文件中,我们有以下 deps

<dependency>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-base</artifactId>
    <version>${use.javafx.version}</version>
</dependency>
<dependency>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-controls</artifactId>
    <version>${use.javafx.version}</version>
</dependency>
<dependency>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-fxml</artifactId>
    <version>${use.javafx.version}</version>
</dependency>
<dependency>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-graphics</artifactId>
    <version>${use.javafx.version}</version>
</dependency>
<dependency>
    <groupId>org.openjfx</groupId>
    <artifactId>javafx-web</artifactId>
    <version>${use.javafx.version}</version>
</dependency>

<dependency>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-stdlib-jdk8</artifactId>
    <version>${kotlin.version}</version>
</dependency>
<dependency>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-reflect</artifactId>
    <version>${kotlin.version}</version>
</dependency>
<dependency>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-test-junit</artifactId>
    <version>${kotlin.version}</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.jetbrains.kotlinx</groupId>
    <artifactId>kotlinx-coroutines-core</artifactId>
    <version>${kotlinx.coroutines.version}</version>
</dependency>
<dependency>
    <groupId>org.jetbrains.kotlinx</groupId>
    <artifactId>kotlinx-coroutines-jdk8</artifactId>
    <version>${kotlinx.coroutines.version}</version>
</dependency>

<dependency>
    <groupId>io.insert-koin</groupId>
    <artifactId>koin-core-jvm</artifactId>
    <version>${koin.version}</version>
</dependency>
<dependency>
    <groupId>io.insert-koin</groupId>
    <artifactId>koin-test-jvm</artifactId>
    <version>${koin.version}</version>
</dependency>

<dependency>
    <groupId>org.simpleframework</groupId>
    <artifactId>simple-xml</artifactId>
    <version>${simplexml.version}</version>
</dependency>

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>${log4j.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>${log4j.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-web</artifactId>
    <version>${log4j.version}</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>${jackson.version}</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>${jackson.version}</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>${jackson.version}</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.module</groupId>
    <artifactId>jackson-module-kotlin</artifactId>
    <version>${jackson.version}</version>
</dependency>
<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>${okhttp.version}</version>
</dependency>
<dependency>
    <groupId>net.sf.proguard</groupId>
    <artifactId>proguard-base</artifactId>
    <version>${proguard.version}</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>${junit.version}</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>${junit.version}</version>
    <scope>test</scope>
</dependency>

<dependency>
    <groupId>org.kordamp.ikonli</groupId>
    <artifactId>ikonli-materialdesign2-pack</artifactId>
    <version>${ikonli.mdi2.version}</version>
</dependency>
<dependency>
    <groupId>org.kordamp.ikonli</groupId>
    <artifactId>ikonli-javafx</artifactId>
    <version>${ikonli.version}</version>
</dependency>
<dependency>
    <groupId>org.controlsfx</groupId>
    <artifactId>controlsfx</artifactId>
    <version>${controlsfx.version}</version>
</dependency>
<dependency>
    <groupId>com.dlsc</groupId>
    <artifactId>GMapsFX</artifactId>
    <version>${gmapfx.version}</version>
</dependency>

<dependency>
    <groupId>org.xerial</groupId>
    <artifactId>sqlite-jdbc</artifactId>
    <version>${sqlite.jdbc.version}</version>
</dependency>

<!-- some custom deps from our company -->

<dependency>
    <groupId>org.conscrypt</groupId>
    <artifactId>conscrypt-openjdk</artifactId>
    <version>${conscrypt.version}</version>
    <classifier>${os.detected.classifier}</classifier>
</dependency>

产生以下 JAR 文件(减去我们自己的):

annotations-13.0.jar
apiguardian-api-1.1.2.jar
conscrypt-openjdk-2.5.2-linux-x86_64.jar
controlsfx-11.1.0.jar
GMapsFX-11.0.2.jar
hamcrest-core-1.3.jar
ikonli-core-12.2.0.jar
ikonli-javafx-12.2.0.jar
ikonli-materialdesign2-pack-12.2.0.jar
jackson-annotations-2.13.0.jar
jackson-core-2.13.0.jar
jackson-databind-2.13.0.jar
jackson-module-kotlin-2.13.0.jar
jakarta.activation-1.2.2.jar
jakarta.activation-api-1.2.2.jar
jakarta.xml.bind-api-2.3.3.jar
jaxb-impl-2.3.3.jar
junit-4.12.jar
junit-jupiter-api-5.8.1.jar
junit-jupiter-engine-5.8.1.jar
junit-platform-commons-1.8.1.jar
junit-platform-engine-1.8.1.jar
koin-core-jvm-3.1.3.jar
koin-test-jvm-3.1.3.jar
kotlin-reflect-1.5.31.jar
kotlin-stdlib-1.5.31.jar
kotlin-stdlib-common-1.5.30.jar
kotlin-stdlib-jdk7-1.5.31.jar
kotlin-stdlib-jdk8-1.5.31.jar
kotlin-test-1.5.31.jar
kotlin-test-annotations-common-1.5.30.jar
kotlin-test-common-1.5.30.jar
kotlin-test-junit-1.5.31.jar
kotlinx-coroutines-core-1.5.2.jar
kotlinx-coroutines-core-jvm-1.5.2.jar
kotlinx-coroutines-jdk8-1.5.2.jar
log4j-api-2.14.1.jar
log4j-core-2.14.1.jar
log4j-web-2.14.1.jar
logback-classic-1.2.3.jar
logback-core-1.2.3.jar
okhttp-4.9.2.jar
okio-2.8.0.jar
opentest4j-1.2.0.jar
proguard-base-6.2.2.jar
simple-xml-2.7.1.jar
slf4j-api-1.7.29.jar
sqlite-jdbc-3.36.0.3.jar
stax-1.2.0.jar
stax-api-1.0.1.jar
xpp3-1.1.3.3.jar

使用的 Java 版本是Bell Soft 的 Full Liberica JDK 17,我们使用了自 14 或 15 以来的所有最新版本,在重建 UI之前它运行良好。


编辑#2:

的结果

mvn compile org.apache.maven.plugins:maven-dependency-plugin:3.1.1:resolve -DexcludeTransitive

[INFO] The following files have been resolved:
[INFO]    com.fasterxml.jackson.core:jackson-databind:jar:2.13.0:compile -- module com.fasterxml.jackson.databind
[INFO]    com.squareup.okhttp3:okhttp:jar:4.9.2:compile -- module okhttp3 [auto]
[INFO]    com.fasterxml.jackson.core:jackson-annotations:jar:2.13.0:compile -- module com.fasterxml.jackson.annotation
[INFO]    org.openjfx:javafx-fxml:jar:17.0.1:compile -- module javafx.fxmlEmpty [auto]
[INFO]    org.openjfx:javafx-web:jar:17.0.1:compile -- module javafx.webEmpty [auto]
[INFO]    org.jetbrains.kotlin:kotlin-stdlib-jdk8:jar:1.5.31:compile -- module kotlin.stdlib.jdk8
[INFO]    io.insert-koin:koin-core-jvm:jar:3.1.3:compile -- module koin.core.jvm (auto)
[INFO]    org.jetbrains.kotlin:kotlin-test-junit:jar:1.5.31:test -- module kotlin.test.junit
[INFO]    org.simpleframework:simple-xml:jar:2.7.1:compile -- module simple.xml [auto]
[INFO]    org.apache.logging.log4j:log4j-core:jar:2.14.1:compile -- module org.apache.logging.log4j.core [auto]
[INFO]    io.insert-koin:koin-test-jvm:jar:3.1.3:compile -- module koin.test.jvm (auto)
[INFO]    org.junit.jupiter:junit-jupiter-engine:jar:5.8.1:test -- module org.junit.jupiter.engine
[INFO]    org.xerial:sqlite-jdbc:jar:3.36.0.3:compile -- module org.xerial.sqlitejdbc [auto]
[INFO]    net.sf.proguard:proguard-base:jar:6.2.2:runtime -- module proguard.base (auto)
[INFO]    org.openjfx:javafx-graphics:jar:17.0.1:compile -- module javafx.graphicsEmpty [auto]
[INFO]    org.jetbrains.kotlinx:kotlinx-coroutines-core:jar:1.5.2:compile -- module kotlinx.coroutines.core (auto)
[INFO]    org.apache.logging.log4j:log4j-web:jar:2.14.1:compile -- module org.apache.logging.log4j.web [auto]
[INFO]    ch.<ourgroup>:<our-artifact>:1.8.8:compile -- module <our-lib> (auto)
[INFO]    org.openjfx:javafx-controls:jar:17.0.1:compile -- module javafx.controlsEmpty [auto]
[INFO]    org.controlsfx:controlsfx:jar:11.1.0:compile -- module org.controlsfx.controls
[INFO]    com.fasterxml.jackson.core:jackson-core:jar:2.13.0:compile -- module com.fasterxml.jackson.core
[INFO]    com.fasterxml.jackson.module:jackson-module-kotlin:jar:2.13.0:compile -- module com.fasterxml.jackson.kotlin
[INFO]    org.apache.logging.log4j:log4j-api:jar:2.14.1:compile -- module org.apache.logging.log4j
[INFO]    org.openjfx:javafx-base:jar:17.0.1:compile -- module javafx.baseEmpty [auto]
[INFO]    org.junit.jupiter:junit-jupiter-api:jar:5.8.1:test -- module org.junit.jupiter.api
[INFO]    org.kordamp.ikonli:ikonli-javafx:jar:12.2.0:compile -- module org.kordamp.ikonli.javafx
[INFO]    com.dlsc:GMapsFX:jar:11.0.2:compile -- module com.dlsc.gmapsfx
[INFO]    org.jetbrains.kotlin:kotlin-reflect:jar:1.5.31:compile -- module kotlin.reflect
[INFO]    org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:jar:1.5.2:compile -- module kotlinx.coroutines.jdk8 (auto)
[INFO]    org.kordamp.ikonli:ikonli-materialdesign2-pack:jar:12.2.0:compile -- module org.kordamp.ikonli.materialdesign2
[INFO]    org.conscrypt:conscrypt-openjdk:jar:linux-x86_64:2.5.2:compile -- module org.conscrypt [auto]
4

1 回答 1

8

更新:这些问题已得到修复,并且jdeps作为 JDK 18 早期访问版本的一部分提供了一个补丁版本:http: //jdk.java.net/18/(从 build 26 开始)


将我的评论变成答案。这里似乎有3个错误:

  1. MultiReleaseException似乎是因为jdeps无法处理具有相同名称的不同 jar 中的类,例如module-info.class,但存储在不同的META-INF/versions/xxx目录中。( JDK-8277165 )
  2. 这个异常有时突然没有发生的事实似乎是检查上述情况的代码中的竞争条件的结果;具有多个版本的同名类。( JDK-8277166 )
  3. 缺少它的MultiReleaseException异常消息,因为它是作为异步任务的一部分抛出的,该任务将其包装在 中ExecutionException,然后导致jdeps无法正确报告异常。( JDK-8277123 )

至于解决方法,我认为目前还没有一个好的解决方法,除了可能编辑类路径上的所有 jar 以便它们将它们放在module-info.class同一META-INF/versions/xxx目录中(但是,这也可能产生其他后果,所以您可能不想使用已编辑的 jar 运行,而仅将它们用于jdeps)。

于 2021-11-17T20:23:22.170 回答