Question

The JNLP spec says that, optionally, the JNLP file itself can be signed by including it in the JNLP app's main jar (which itself must be signed). Does anyone know if the maven-webstart-plugin can be made to do this?

No correct solution

OTHER TIPS

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:

  1. generate jnlp and sign all libraries(including manifest entries update) to directory /target/jnlp with webstart-maven-plugin
  2. copy & rename jnlp file from /target/jnlp dir to target/jnlp/main.jar/JNLP-INF/APPLICATION.JNLP with truezip-maven-plugin
  3. repeately sign main.jar file in target/jnlp/main.jar with maven-jarsigner-plugin
  4. 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):

  1. generate both: jnlp,APPLICATION_TEMPLATE.JNLP and sign all libraries(including manifest entries update) to directory /target/jnlp with webstart-maven-plugin
  2. 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
  3. repeately sign main.jar file in target/jnlp/main.jar with maven-jarsigner-plugin
  4. 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>

Based on MWEBSTART-176 this looks like a feature that has been requested but not (yet) been implemented.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top