Signing java 11 jar with jarsigner duplicate entry module-info.class
您好,我是 java 模块的新手,所以这可能是一个愚蠢的问题。
我试图用密钥库对我的 jar 文件进行签名并收到以下错误。
1 2 3 | user@Ubuntu:libs(master)$ jarsigner -keystore keyStoreFileName Test.jar alias Enter Passphrase for keystore: jarsigner: unable to sign jar: java.util.zip.ZipException: duplicate entry: module-info.class |
我找不到任何有关如何避免这种情况的文档。
所以我做了 jar -tf 来检查 jar 的内容,是的,它确实有多个 module-info.class 文件
有没有办法把它们结合起来?怎么做?
我的 module-info.java 包含以下内容。
1 2 3 4 5 6 7 8 9 10 | module module_name { requires java.desktop; requires java.prefs; requires javafx.controls; requires javafx.fxml; requires javafx.web; requires org.jsoup; opens com.test.apps to javafx.fxml; exports com.test.apps; } |
我正在用这样的 gradle 创建 jar
1 2 3 4 5 6 7 8 9 10 11 | jar { manifest { attributes 'Main-Class': 'com.test.apps.Main' attributes 'Application-Name': 'Test' } from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } } |
我知道我不应该发布屏幕截图,但这是使用存档管理器打开的 jar
有 7 个 module-info.class 文件,第一个在 2018 年 12 月 23 日(今天)生成,其余都是从 18 年 11 月 5 日开始的,我记得那天升级到 java 11,
所以这些是从我的依赖项中添加的,我怎样才能将它们集成到一个类中?还是有其他选择来签署一个罐子?
再次,这是来自一个菜鸟。
[编辑]
如果你正在寻找完整的源代码,它在 GitHub -> https://github.com/CodingOtaku/Animu-Downloaderu
根据您发布的 build.gradle 内容,当您运行时:
1 | ./gradlew jar |
您正在创建一个胖/影子 jar,它将所有依赖项捆绑在一起,包括一个大 jar 中的模块化依赖项。此过程将每个 jar(类和资源)中的所有文件提取到 libs 文件夹中,最后将其压缩到项目的影子 jar 中。
模块化依赖项(至少是 JavaFX jars)在其 jar 文件中包含一个
作为
无论哪种方式,由于您正在创建一个胖罐子,因此您将其运行为:
1 | java -jar my-fat-jar.jar |
为此,您根本不需要模块。
解决方案
所以一个简单的解决方案是从你的 fat jar 中排除模块信息文件:
1 2 3 4 5 6 7 8 9 | jar { manifest { attributes 'Main-Class': 'your.main.class' } from { exclude '**/module-info.class' configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } } |
跨平台jar
请注意,您发布的 jar 不是跨平台的,因为它仅包含 Linux 的本机库。
可以在此处找到创建跨平台 jar 的一个选项,非模块化应用程序 -> Gradle -> 跨平台 jar 部分。
jlink
您也可以考虑使用
在这种情况下,您将为给定平台生成自定义图像。您可以考虑为每个平台创建一个。
请参阅此文档,Modular with Gradle 部分,并使用
jpackage
有一个用于 Java 12 的