JNLP 规范说,可选地,可以通过将 JNLP 文件本身包含在 JNLP 应用程序的主 jar 中(它本身必须签名)来对其进行签名。有谁知道 maven-webstart-plugin 是否可以做到这一点?
2 回答
基于MWEBSTART-176,这看起来像是已请求但(尚未)实现的功能。
JNLP 签名(自动生成 APPLICATION.JNLP 或 APPLICATION_TEMPLATE.JNLP)可以通过几个 maven 插件的组合来完成。通常 webstart-maven-plugin 会完成完整的工作,包括在 maven 模块中打包工件(例如 zip 文件)。做 JNLP 签名的关键是把这个任务分成几个步骤:
A) 对于 APPLICATION.JNLP 生成:
- 使用 webstart-maven-plugin 生成 jnlp 并将所有库(包括清单条目更新)签名到目录 /target/jnlp
- 使用 truezip-maven-plugin 将 jnlp 文件从 /target/jnlp 目录复制并重命名为 target/jnlp/main.jar/JNLP-INF/APPLICATION.JNLP
- 使用 maven-jarsigner-plugin 在 target/jnlp/main.jar 中重复签名 main.jar 文件
- 将 /target/jnlp 目录打包到工件,例如使用 maven-war-plugin 或 maven-assembly-plugin
B) 对于 APPLICATION_TEMPLATE.JNLP 生成(第 1 点和第 2 点与前面的步骤不同):
- 生成两者:jnlp,APPLICATION_TEMPLATE.JNLP 并使用 webstart-maven-plugin 将所有库(包括清单条目更新)签名到目录 /target/jnlp
- 使用 truezip-maven-plugin 将 APPLICATION_TEMPLATE.JNLP 文件从 /target/jnlp/APPLICATION_TEMPLATE.JNLP 移动到 target/jnlp/main.jar/JNLP-INF/APPLICATION_TEMPLATE.JNLP
- 使用 maven-jarsigner-plugin 在 target/jnlp/main.jar 中重复签名 main.jar 文件
- 将 /target/jnlp 目录打包到工件,例如使用 maven-war-plugin 或 maven-assembly-plugin
注意 1:main.jar 文件被签名两次(在步骤 1)和 3)),与 maven-jarsigner-plugin 在步骤 3)中仅对所有 jar 进行一次签名相比,这是开销。但是我们需要它这样做,因为 webstart-maven-plugin 更新清单文件(带有权限标头)仅使用配置签名。
注意 2:当您的 webstart 应用程序具有许多不同的构建配置文件时,此方法非常有效,因为 APPLICATION.JNLP 或 APPLICATION_TEMPLATE.JNLP 是根据您的配置文件以自动方式生成的。
注 3:我花了超过一天半的时间来开发和测试这种方法,希望它能让你的生活更轻松;)
下面是两种类型的 JNLP 签名的一些 pom.xml 部分。
A) 对于 APPLICATION.JNLP 生成:
<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) 对于 APPLICATION_TEMPLATE.JNLP 生成:
<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>