If your jar is not signed you will get some message like this:
com.sun.deploy.net.JARSigningException: Se ha encontrado una entrada sin firma en el recurso: https://desarr.local/jnlp/XXXXXXX-jar-with-dependencies.jar
I built my jar by using Maven, and the final output is a file called XXXX-0.0.1-SNAPSHOT-jar-with-dependencies.jar. This jar contains all third party classes and resources that my application need to work.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>xxxxxxxxxx.Main</mainClass>
</manifest>
<manifestEntries>
<Permissions>all-permissions</Permissions>
<Codebase>desarr.local</Codebase>
<Application-Name>xxxxxxxxx</Application-Name>
<Application-Library-Allowable-Codebase>https://desarr.local</Application-Library-Allowable-Codebase>
<Entry-Point>xxxxxxxxxx.Main</Entry-Point>
<Built-By>Sisifo</Built-By>
</manifestEntries>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
Note.
- I hid the application name on purpose because it is a real application I am working with.
- I downloaded the application from a Apache server located in "desarr.local", i.e, this is my htdocs basedir.
To sign my jar I created a self-signed certificate acting as a CA, and with it, I signed a second certificate (kind pro eh).
So, I have a PKCS12 certificate called jar-signer signed with my CA:
- The file is "jar_signer(1234).p12"
- The file format is PKCS12
- The password file is "1234"
- The certificate alias is "jar-signer"
- The alias key is "1234"
With this I now could sign my jar:
"c:\Program Files\Java\jdk1.7.0_21\bin\jarsigner.exe" -keystore jar_signer(1234).p12 -storetype PKCS12 -storepass 1234 -keypass 1234 XXXX-SNAPSHOT-jar-with-dependencies.jar jar-signer
Ok, I have a signed jar. I launch my JNLP file again and... Fail. I still get the exact same error.
The jar was signed properly. By using the "-verify" option of jarsigner I got success verification (although with some warnings), but the jar was fine.
"c:\Program Files\Java\jdk1.7.0_21\bin\jarsigner.exe" -verify XXXX-0.0.1-SNAPSHOT-jar-with-dependencies.jar jar verified. Warning: This jar contains entries whose certificate chain is not validated. Re-run with the -verbose and -certs options for more details.
At this point I checked the following issues:
1) My self signed certificates were not suitable.
I passed the jar to our client and they signed it with a "true" certificate,.
Result: Fail.
2) There were problems with the jarsigner tool.
I signed the jar with the jarsigner shipped with JDK 1.6.0_45, 1.7.0_21 and 1.8.0_51.
Result: Fail
3) Set to checked the java option to "keep temporary files on my computer"
In Control Panel > Java > General > Temporary files > Configuration.
Result: Fail
4) Import the sign certificate and the CA as trusted for java.
In Control Panel > Java > Security > Manage Certificates > User
Result: Fail
So I was quite sure that my configuration was fine and that the problem should be in the dam jar.
I opened the jar and I saw that there were a lot of non essential files in it, like licenses, poms, READMEs, etc...
I decided to manually remove all this "crap" and sign again. The result... Success!!!
After a while doing try-error deletes I found that the real problem was related to the file called "\jboss-as-jms-client-bom-7.3.0.Final-redhat-14.pom". Check the previous image and you will note that there is a slash "\" in this name. I think that, for some unknown reason, the java launcher was not able to process properly that file or that this file was not well signed at all.
Well, once I found the root of the problem, the next step was to modify the procedure I was using to create the jar.
The maven-assembly-plugin (check here http://maven.apache.org/plugins/maven-assembly-plugin/) has a config option called "descriptors" to reference an external descriptor file. Based on this file, the plugin know how to build the jar.
There are four predefined descriptors, being jar-with-dependencies just one of them.
I changed the plugin configuration and created a custom descriptor.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>xxxxxxxxxx.Main</mainClass>
</manifest>
<manifestEntries>
<Permissions>all-permissions</Permissions>
<Codebase>desarr.local</Codebase>
<Application-Name>xxxxxxxxxx</Application-Name>
<Application-Library-Allowable-Codebase>https://desarr.local</Application-Library-Allowable-Codebase>
<Entry-Point>xxxxxxxxxx.Main</Entry-Point>
<Built-By>Sisifo</Built-By>
</manifestEntries>
</archive>
<descriptors>
<descriptor>src/dev/assembly/distribution.xml</descriptor>
</descriptors>
</configuration>
</execution>
</executions>
</plugin>
And this is my distribution.xml file:
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<id>jar-with-dependencies</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory>/</outputDirectory>
<useProjectArtifact>true</useProjectArtifact>
<unpack>true</unpack>
<scope>runtime</scope>
<unpackOptions>
<excludes>
<exclude>**/README</exclude>
<exclude>**/LICENSE</exclude>
<exclude>**/NOTICE</exclude>
<exclude>**/ASL2.0</exclude>
<exclude>**/INDEX.LIST</exclude>
<exclude>**/*.txt</exclude>
<exclude>**/*.html</exclude>
<exclude>**/.project</exclude>
<exclude>**/.classpath</exclude>
<exclude>jboss-as-checkstyle/*</exclude>
<!-- Eclsuiones relacionadas con maven -->
<exclude>META-INF/maven/**</exclude>
<exclude>**/pom.xml</exclude>
<exclude>**/pom.properties</exclude>
<exclude>*.pom</exclude>
<exclude>**/*.pom</exclude>
<!-- Licencias -->
<exclude>META-INF/licenses/*</exclude>
<exclude>licenses/*</exclude>
<exclude>%regex[jboss-as-jms-client-bom]</exclude>
<exclude>\jboss-as-jms-client-bom-7.3.0.Final-redhat-14.pom</exclude>
</excludes>
</unpackOptions>
</dependencySet>
</dependencySets>
With this configuration what I was trying to do was to remove all non-essential files and, specifically, the jboss-as-jms-client-bom-7.3.0.Final-redhat-14.pom.
Result: Fail
Even doing so, this file was still there. I tried all kind of expressions, excludes, fieldsets, etc... but no luck.
So, the plan B was to use a ant task to open the jar file, remove the file, and repack it.
For this I used maven-antrun-plugin.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>elimina-bom</id>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<zip file="${project.build.directory}/${project.build.finalName}-limpio.jar">
<zipfileset src="${project.build.directory}/${project.build.finalName}-jar-with-dependencies.jar">
<exclude name="**/*.pom" />
</zipfileset>
</zip>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
Finally, after long hours of failures, my JNLP app was working...




Hi.
ResponderEliminarThanks for this great tutorial,
I have a question.
How did you create a self-signed certificate acting as a CA??
Please help me. Thanks a lot
Hi
ResponderEliminarWith keyStoreExplorer, when you generate a new key pair, there is an option to "Add Extensions".
There are a lot of extensions types, but I jus marked two:
- Basic Constraints: Subject is a CA
- Key Usage: Certificate signing
This would be your CA.
Once the CA was created, you can use the contextual menu option "Sign New Key Pair" and create a second certificate signed by the first one.
Regards