Valid JAR signature for JavaFX projects

I've been working through various recipes to produce a runnable JAR file for a JavaFX project using a Maven POM. Each of these Stackoverflow questions describes the same problem. It is frustrating that there seems to be several different solutions for the same goal.

problem:

java.lang.SecurityException: Invalid signature file digest for Manifest main attributes

Error when executing a JAR file on the command line. Although Netbeans can happily run the program and debug the program.

diagnosis

There are several Stackoverflow and forum questions about this (most helpful ones below). Even though is a known problem I'm yet to find a clear solution to work with JavaFX. The procedures described in these answers do NOT with the JavaFxPackager tool used to bundle-up your JavaFX JAR:

  • "Invalid signature file digest" error adding Janino package through Maven
  • Error (org.codehaus.mojo) when adding persistence to Maven-Java-project? ... This looks the most promising since it is also a JavaFX project. Same error here so far.

usual approach: The post popular answer for this question (255 votes at time of writing): works with non-JavaFX modules in our project:

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

However when we put the same plug-in in the POM that builds the JavaFX JAR file, we still get the: "Invalid signature file digest ..." error. Specifically, I placed the <artifactId>maven-shade-plugin</artifactId> first before and then after the JavaFxPackager exec rule. The result is

  • Maven gives the: "Invalid signature file digest for Manifest main attributes..." error

**question*:

How does one manage to package a JavaFX application. This is the POM <build> section Netbeans sets-up for JavaFX:

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

The shard plugin configuration used based on the answer in: "Invalid signature file" when attempting to run a .jar currently looks like this:

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

To keep Netbeans out of the equation as much as possible, I just run

  • mvn package

On the command line. This just issue seems to be a frequent problem and I'm hoping someone has cracked the code for JavFX bundling in other JAR files for a JavaFX build.

Other links:

  • 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

Solution 1:

I had a very similar problem; when I included a signed JAR (bouncycastle) in the project. Its signature was repackaged verbatim, resulting in an obvious SecurityException:

java.lang.SecurityException: Invalid signature file digest for Manifest main attributes

Filtering of all sorts failed; the solution that works for me looks like this in the 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>

I omitted some lines after the new one with the "excludes" pattern. This single line was the solution for me - I include the other lines so you can see the placement. (I had trouble with many other postings which omitted the context of a tag, so I try to save others this trouble).

Hope that helps others with the same problem.

Solution 2:

After a lot of research I found a solution that works for my project using JavaFX, Maven and NetBeans.

I'm working on a simple REST client that uses jersey and moxy to decode JSON. After adding the dependency jersey-media-moxy application reports the error of invalid signature.

I found that this depends on the presence of the signature file ECLIPSE_.RSA and ECLIPSE_.SF inside the META-INF for some libraries. In my case were the org.eclipse.persistence.moxy-2.5.0.jar, org.eclipse.persistence.antlr-2.5.0.jar, org.eclipse.persistence.asm-2.5.0.jar and org.eclipse.persistence.core-2.5.0.jar

The pom.xml in Netbeans that you indicated running two separate step. The first invoke maven-dependency-plugin that expands all the external jar. The second use exec-maven-plugin that call javafxpackager to create the final jar file e finally run it.

By performing the two steps in sequence signature in org.eclipse libraries are placed in the META-INF of the final jar file and this generates the error on the signature.

My solution is add an intermediate step between the execution of the maven-dependency-plugin and exec-maven-plugin. In this step I'm going to delete all signature file inside the directory

${project.build.directory}/classes

To do this I used a plugin 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>