JNLP signing (with automatic generation of APPLICATION.JNLP or APPLICATION_TEMPLATE.JNLP) could be done with composition of several maven plugins. Normally webstart-maven-plugin does the complete job including packaging of artifact (e.g. zip file) in maven module. The key to do JNLP signing is to split this task into several steps:
A) for APPLICATION.JNLP generation:
- generate jnlp and sign all libraries(including manifest entries update) to directory /target/jnlp with webstart-maven-plugin
- copy & rename jnlp file from /target/jnlp dir to target/jnlp/main.jar/JNLP-INF/APPLICATION.JNLP with truezip-maven-plugin
- repeately sign main.jar file in target/jnlp/main.jar with maven-jarsigner-plugin
- package /target/jnlp directory to artifact e.g. with maven-war-plugin or maven-assembly-plugin
B) for APPLICATION_TEMPLATE.JNLP generation (points 1. and 2. differ from previous steps):
- generate both: jnlp,APPLICATION_TEMPLATE.JNLP and sign all libraries(including manifest entries update) to directory /target/jnlp with webstart-maven-plugin
- move APPLICATION_TEMPLATE.JNLP file from /target/jnlp/APPLICATION_TEMPLATE.JNLP to target/jnlp/main.jar/JNLP-INF/APPLICATION_TEMPLATE.JNLP with truezip-maven-plugin
- repeately sign main.jar file in target/jnlp/main.jar with maven-jarsigner-plugin
- package /target/jnlp directory to artifact e.g. with maven-war-plugin or maven-assembly-plugin
Note 1: main.jar file is signed twice (in steps 1) and 3)), this is overhead with comparison to sign all jars only once in step 3) by maven-jarsigner-plugin. But we need it to do this way, because webstart-maven-plugin update manifest files (with permission header) only with configured signing.
Note 2: this approach works very well when your webstart application have many different build profiles, because APPLICATION.JNLP or APPLICATION_TEMPLATE.JNLP are generated in automatic way based on your profiles.
Note 3: it takes me more than 1 and half of the day to develop and test this approach, hopefully it makes your life easier ;)
Below are some pom.xml parts for both types of JNLP signing.
A) for APPLICATION.JNLP generation:
<project ....>
...
<build>
<plugins>
<plugin>
<!-- Step 1) your obvious configuration, also with signing,
assume that generated jnlp file has name: launch.jnlp -->
<groupId>org.codehaus.mojo</groupId>
<artifactId>webstart-maven-plugin</artifactId>
<executions>
<execution>
<id>generate-jnlp-and-sign-libs</id>
<phase>generate-resources</phase>
<goals>
<goal>jnlp-inline</goal>
</goals>
...
</execution>
</executions>
...
</plugin>
<plugin>
<!-- Step 2) copy & rename of jnlp to APPLICATION_JNLP in main.jar -->
<groupId>org.codehaus.mojo</groupId>
<artifactId>truezip-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<id>copy-jnlp-template</id>
<goals>
<goal>copy</goal>
</goals>
<phase>prepare-package</phase>
<configuration>
<files>
<file>
<source>${project.build.directory}/jnlp/launch.jnlp</source>
<outputDirectory>${project.build.directory}/jnlp/main.jar/JNLP-INF</outputDirectory>
<destName>APPLICATION.JNLP</destName>
</file>
</files>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<!-- Step 3) repeat signing of main.jar -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jarsigner-plugin</artifactId>
<version>1.2</version>
<executions>
<execution>
<id>sign</id>
<phase>prepare-package</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
<configuration>
<archiveDirectory>${project.build.directory}/jnlp</archiveDirectory>
<includes>
<include>main.jar</include>
</includes>
<keystore>...</keystore>
<storepass>...</storepass>
<alias>...</alias>
<verbose>true</verbose>
</configuration>
</plugin>
<plugin>
<!-- Step 4) custom packaging -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>${maven-war-plugin.version}</version>
<configuration>
...
<webResources>
<resource>
<directory>${project.build.directory}/jnlp</directory>
</resource>
...
</webResources>
...
</configuration>
</plugin>
</build>
</project>
B) for APPLICATION_TEMPLATE.JNLP generation:
<project ....>
...
<build>
<plugins>
<plugin>
<!-- Step 1) your obvious configuration + added one new execution
for APPLICATION_TEMPLATE.jnlp file generation from template stored
in /templates/APPLICATION_TEMPLATE.jnlp dir -->
<groupId>org.codehaus.mojo</groupId>
<artifactId>webstart-maven-plugin</artifactId>
<executions>
<execution>
<!-- This is new execution block, don't be afraid,
inspite of multiple executions
signing and manifest update is performed only once -->
<id>generate-jnlp-template-for-signing</id>
<phase>generate-resources</phase>
<goals>
<goal>jnlp-inline</goal>
</goals>
<configuration>
<jnlp>
<inputTemplateResourcePath>${project.basedir}/templates
</inputTemplateResourcePath>
<inputTemplate>APPLICATION_TEMPLATE.jnlp</inputTemplate>
<outputFile>APPLICATION_TEMPLATE.jnlp</outputFile>
<mainClass>...</mainClass>
</jnlp>
</configuration>
</execution>
<execution>
<id>generate-jnlp-and-sign-libs</id>
<phase>generate-resources</phase>
<goals>
<goal>jnlp-inline</goal>
</goals>
<configuration>
<jnlp>
<!-- JNLP settings from your obvious configuration -->
...
</jnlp>
</configuration>
...
</execution>
</executions>
...
</plugin>
<plugin>
<!-- Step 2) move to APPLICATION_TEMPLATE from /target/jnlp
to target/jnlp/main.jar/JNLP-INF dir -->
<groupId>org.codehaus.mojo</groupId>
<artifactId>truezip-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<id>move-jnlp-template</id>
<goals>
<goal>move</goal>
</goals>
<phase>prepare-package</phase>
<configuration>
<from>${project.build.directory}/jnlp/APPLICATION_TEMPLATE.jnlp
</from>
<to>${project.build.directory}/jnlp/lib/main.jar/JNLP-INF/APPLICATION_TEMPLATE.jnlp
</to>
</configuration>
</execution>
</executions>
</plugin>
<!-- Steps 3) and 4) are same as in previous code block -->
</build>
</project>