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

使用jarsigner重复输入模块信息对java 11 jar进行签名。班

樊宏邈
2023-03-14

嗨,我是java模块新手,所以这可能是个愚蠢的问题。

我试图签署我的jar文件与keystore和得到以下错误。

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文件

有没有合并它们的选项?怎么做?

我的模块信息。java包含以下内容。

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 {
    manifest {
        attributes 'Main-Class': 'com.test.apps.Main'
        attributes 'Application-Name': 'Test'
    }

    from {
        configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
    }

}

有7个module-info.class文件,第一个生成于23-Dec-18(今天),其余都是从05-Nov-18,我记得那天升级到java 11,

所以这些都是从我的依赖项中添加的,我如何将它们集成到一个类中?还是有其他选择来签署一个罐子?

同样,这是来自新手。

[编辑]如果你正在寻找完整的源代码,它在GitHub-

共有1个答案

冯永长
2023-03-14

根据你发布的build.gradle,当你运行时:

./gradlew jar

您正在创建一个fat/shadowjar,它将所有依赖项捆绑在一个大jar中,包括模块化依赖项。这个过程将每个jar(类和资源)中的所有文件提取到libs文件夹中,最后将其压缩到项目的shadowjar中。

模块依赖项(至少javafxjar)包括模块信息。类的jar文件中的文件。因此,这些将被添加到libs文件夹中。

由于执行了jar任务,并且取决于您的平台,您可能只会得到其中一个文件(如果将同名文件粘贴到一个文件中,则会添加第一个或最后一个文件),或者得到所有文件(如果保留了所有同名文件,就像您的情况一样)。

无论哪种方式,由于您正在创建一个胖罐子,您将以以下方式运行它:

java -jar my-fat-jar.jar

为此,您根本不需要模块。

解决方案

因此,一个简单的解决方案是从fat jar中排除模块信息文件:

jar {
    manifest {
        attributes 'Main-Class': 'your.main.class'
    }
    from {
        exclude '**/module-info.class'
        configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
    }
}

跨平台罐

请注意,您发布的jar不是跨平台的,因为它只包含Linux的本机库。

创建跨平台jar的一个选项可以在这里找到,非模块化应用程序部分-

jlink

或者,您可以考虑使用jlink进行分发,因为您的应用已经是模块化的。

在这种情况下,您将为给定平台生成一个自定义映像。您可以考虑为每个平台创建一个。

请参阅本文档中的模块化Gradle部分,并使用jlink任务,或者尝试使用糟糕的jlink插件。

包装

Java12有一个jpack工具的预览。有了它,您可以为每个平台创建一个安装程序。

 类似资料:
  • 我尝试对Corda workflows jar进行签名,并对其执行以下命令: 但是我得到了这个错误: 当我再次运行下面的命令时,我的jar

  • 但是,在查看REST API文档时,会指出API在将选项卡发送给接收者时检索选项卡的原始值(originalValue)。 这正是我发现的行为。是否存在其他方法来检索签名者输入的数据?

  • 我正在构建一个java应用程序,但每次我想导出到jar文件的终端显示此错误,我的jar文件是不可执行的。但是,如果我运行VS代码,它不会显示任何错误。这是我得到的错误,当我要导出到jar文件 在我的发布会上。json{} } 如果我在src文件中创建module-info.java,则会出现错误 javafx.controls不能解析为模块

  • 在Google关于应用程序包的官方指南:https://developer.android.com/guide/app-bundle/configure#base_build_config中,它说只需要在基本模块build.config文件中指定签名信息。动态模块签名信息与基本模块一起使用。 我使用的是自己的密钥库文件,因此我只在基模块中包含signingConfig。然而,当我在设备上构建和运行

  • 我有这样的代码,它对名为'username'的变量的用户输入进行了净化: 我想对这个页面上的每个输入执行相同的过程,但我有大约12个不同的输入,因为它是一个注册表单。有没有更简单的方法来清理和检查每个输入,而不是对每个输入应用preg_replace()和if语句?

  • 我有一个原型项目,它的外观如下所示(有两个模块,和): 并且,当我使用工件id为“infra”的原型生成一个项目时,它应该生成如下结构: 不起作用的是,在父pom.xml中,我包含了以下模块: 这些模块条目不会被重命名为类似于(在生成时): 这就是我想要的。 知道怎么做吗,谢谢。 更新我在这里按要求添加元数据xml文件,但我不想修改archetype-metadata.xml文件。因为我想使用cr