JavaFX 项目的有效 JAR 签名

Posted

技术标签:

【中文标题】JavaFX 项目的有效 JAR 签名【英文标题】:Valid JAR signature for JavaFX projects 【发布时间】:2014-11-08 15:44:19 【问题描述】:

我一直在研究各种方法,使用 Maven POM 为 JavaFX 项目生成可运行的 JAR 文件。这些 *** 问题中的每一个都描述了相同的问题。令人沮丧的是,同一目标似乎有几种不同的解决方案。

问题

java.lang.SecurityException: Manifest 主要属性的签名文件摘要无效

在命令行上执行 JAR 文件时出错。虽然 Netbeans 可以愉快地运行程序并调试程序。

诊断

有几个关于此的 *** 和论坛问题(最有帮助的问题如下)。尽管这是一个已知问题,但我还没有找到使用 JavaFX 的明确解决方案。这些答案中描述的过程不适用于用于捆绑 JavaFX JAR 的 JavaFxPackager 工具:

"Invalid signature file digest" error adding Janino package through Maven Error (org.codehaus.mojo) when adding persistence to Maven-Java-project? ... 这看起来最有前途,因为它也是一个 JavaFX 项目。到目前为止同样的错误。

常用方法: 这个问题的热门答案(在撰写本文时有 255 票):在我们的项目中使用 non-JavaFX 模块:

"Invalid signature file" when attempting to run a .jar ...

但是,当我们将相同的插件放入构建 JavaFX JAR 文件的 POM 中时,我们仍然会得到:“无效的签名文件摘要 ...”错误。具体来说,我将<artifactId>maven-shade-plugin</artifactId> 先放在JavaFxPackager exec 规则之前,然后放在它之后。结果是

Maven 给出:“Manifest 主要属性的签名文件摘要无效...”错误

**问题*:

如何打包 JavaFX 应用程序。这是用于 JavaFX 的 POM <build> section Netbeans 设置:

      <build>
          <resources>
             <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
             </resource>
          </resources>

          <plugins>
             <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-dependency-plugin</artifactId>
                  <version>2.8</version>
                  <executions>
                      <execution>
                          <id>unpack-dependencies</id>
                          <phase>package</phase>
                          <goals>
                              <goal>unpack-dependencies</goal>
                          </goals>
                          <configuration>
                              <excludeScope>system</excludeScope>
                              <excludeGroupIds>junit,org.mockito,org.hamcrest</excludeGroupIds>
                              <outputDirectory>$project.build.directory/classes</outputDirectory>
                          </configuration>
                      </execution>
                  </executions>
              </plugin>

              <plugin>
                  <groupId>org.codehaus.mojo</groupId>
                  <artifactId>exec-maven-plugin</artifactId>
                  <version>1.3.2</version>
                  <executions>
                      <execution>
                          <id>unpack-dependencies</id>
                          <phase>package</phase>
                          <goals>
                              <goal>exec</goal>
                          </goals>
                          <configuration>
                              <executable>$java.home/../bin/javafxpackager</executable>
                              <arguments>
                                  <argument>-createjar</argument>
                                  <argument>-nocss2bin</argument>
                                  <argument>-appclass</argument>
                                  <argument>$mainClass</argument>
                                  <argument>-srcdir</argument>
                                  <argument>$project.build.directory/classes</argument>
                                  <argument>-outdir</argument>
                                  <argument>$project.build.directory</argument>
                                  <argument>-outfile</argument>
                                  <argument>$project.build.finalName.jar</argument>
                              </arguments>
                          </configuration>
                      </execution>
                      <execution>
                          <id>default-cli</id>
                          <goals>
                              <goal>exec</goal>
                          </goals>
                          <configuration>
                              <executable>$java.home/bin/java</executable>
                              <commandlineArgs>$runfx.args</commandlineArgs>
                          </configuration>
                      </execution>
                  </executions>
              </plugin>

              <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-compiler-plugin</artifactId>
                  <version>3.1</version>
                  <configuration>
                      <source>1.8</source>
                      <target>1.8</target>
                      <compilerArgument>-Xlint:unchecked</compilerArgument>  <!-- all -->
                      <showWarnings>true</showWarnings>
                      <showDeprecation>true</showDeprecation>
                      <compilerArguments>
                          <bootclasspath>$sun.boot.class.path$path.separator$java.home/lib      /jfxrt.jar</bootclasspath>
                      </compilerArguments>
                  </configuration>
              </plugin>

              <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-surefire-plugin</artifactId>
                  <version>2.16</version>
                  <configuration>
                      <additionalClasspathElements>
                          <additionalClasspathElement>$java.home/lib/jfxrt.jar</additionalClasspathElement>
                      </additionalClasspathElements>
                  </configuration>
              </plugin>
          </plugins>
      </build>

根据"Invalid signature file" when attempting to run a .jar 中的答案使用的shard plugin 配置目前看起来像这样:

              <plugin>
                  <groupId>org.apache.maven.plugins</groupId>
                  <artifactId>maven-shade-plugin</artifactId>
                      <!--    http://maven.apache.org/plugins/maven-shade-plugin/     -->
                      <!--    http://docs.codehaus.org/display/MAVENUSER/Shade+Plugin -->
                      <!--    http://zhentao-li.blogspot.com.au/2012/06/maven-shade-plugin-invalid-signature.html     -->
                  <version>2.3</version>
                  <executions>
                      <execution>
                        <id>remove-sign-files</id>
                        <phase>package</phase>
                        <goals>
                          <goal>shade</goal>
                        </goals>
                        <configuration>
                          <filters>
                              <filter>
                                  <artifact>*:*</artifact>
                                  <excludes>
                                      <exclude>classes/META-INF/*.SF</exclude>
                                      <exclude>classes/META-INF/*.DSA</exclude>
                                      <exclude>classes/META-INF/*.RSA</exclude>
                                  </excludes>
                              </filter>
                          </filters>
                        </configuration>
                      </execution>
                  </executions>
              </plugin>

为了尽可能避免 Netbeans 出现问题,我只是运行

mvn 包

在命令行上。这个问题似乎是一个常见问题,我希望有人已经破解了 JavaFX 构建的其他 JAR 文件中的 JavFX 捆绑代码。

其他链接

How to tell the maven-shade-plugin to preserve signatures? Packaging jar is invalid Aggregator project need pom as packaging Apache Maven Shade Plug-in Executable JAR

【问题讨论】:

***.com/questions/34738653/… 【参考方案1】:

经过大量研究,我找到了一个适用于我的项目的解决方案,它使用 JavaFX、Maven 和 NetBeans。

我正在开发一个简单的 REST 客户端,它使用 jersey 和 moxy 来解码 JSON。 添加依赖jersey-media-moxy应用后报invalid signature的错误。

我发现这取决于某些库的 META-INF 中是否存在签名文件 ECLIPSE_.RSAECLIPSE_.SF。 在我的例子中是org.eclipse.persistence.moxy-2.5.0.jarorg.eclipse.persistence.antlr-2.5.0.jarorg.eclipse.persistence.asm-2.5.0.jarorg.eclipse.persistence.core-2.5.0.jar

您指示运行两个单独步骤的 Netbeans 中的 pom.xml。 第一个调用扩展所有外部 jar 的 maven-dependency-plugin。 第二种使用exec-maven-plugin调用javafxpackager创建最终的jar文件e最后运行。

通过按顺序执行这两个步骤,org.eclipse 库中的签名被放置在最终 jar 文件的 META-INF 中,这会在签名上生成错误。

我的解决方案是在执行 maven-dependency-plugin 和 exec-maven-plugin 之间添加一个中间步骤。在这一步中,我将删除目录中的所有签名文件

$project.build.directory/classes

为此,我使用了插件 maven-antrun-plugin

<plugin>
    <artifactId>maven-antrun-plugin</artifactId>
    <version>1.8</version>
    <executions>
         <execution>
              <phase>package</phase>
              <goals>
                   <goal>run</goal>
              </goals>
              <configuration>
                   <target>
                       <delete>
                           <fileset dir="$project.build.directory/classes" includes="**/META-INF/*.DSA"/>
                           <fileset dir="$project.build.directory/classes" includes="**/META-INF/*.RSA"/>
                           <fileset dir="$project.build.directory/classes" includes="**/META-INF/*.SF"/>
                    </delete>
                </target>
            </configuration>
        </execution>
    </executions>
</plugin>

【讨论】:

【参考方案2】:

我有一个非常相似的问题;当我在项目中包含一个签名的 JAR(bouncycastle)时。它的签名被逐字重新包装,导致明显的 SecurityException:

java.lang.SecurityException:签名文件摘要无效 体现主要属性

各种过滤失败;适合我的解决方案在 pom.xml 中如下所示:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-dependency-plugin</artifactId>
  <version>2.8</version>
  <executions>
    <execution>
      <id>unpack-dependencies</id>
      <phase>package</phase>
      <goals>
        <goal>unpack-dependencies</goal>
      </goals>
      <configuration>
        <excludes>META-INF/*.SF,META-INF/*.DSA,META-INF/*.RSA</excludes>
        ...
      </configuration>
    </execution>
  </executions>
</plugin>

我用“排除”模式省略了新行之后的一些行。 这条线是我的解决方案 - 我包括其他线,所以你可以看到放置。 (我在许多其他帖子中都忽略了标签的上下文时遇到了麻烦,所以我试图为其他人省去这个麻烦)。

希望能帮助遇到同样问题的其他人。

【讨论】:

终于!我一直在用 de shade 插件受苦了几个小时,但无济于事。 我知道这种感觉——它促使我写下这个答案。 顺便说一句 - 如果 JAR 被签名,通常是有原因的。考虑单独分发/安装 JAR 而不是重新打包是否有意义。对于像 BouncyCastle 这样的加密货币提供商,有一些很好的理由说明您应该尝试将其单独保存并签名。

以上是关于JavaFX 项目的有效 JAR 签名的主要内容,如果未能解决你的问题,请参考以下文章

该应用程序没有有效的签名 Xcode 7.3

如何使用嵌入式数据库 H2 创建 jar 文件?

在 java 中创建带有标头、有效负载和签名的 JWT

未找到具有有效签名身份的 Provisiong 配置文件,并且无法找到或生成匹配的签名资产

即使有有效的链接证书,也缺少代码签名证书

带有 JavaFX 的 Maven 项目(在 `lib` 中有 jar 文件)