我正处于相当复杂的Java Web Start应用程序项目中。简而言之,我已经设法在下面的文件结构中组装了我需要的所有内容:
--[PROJECT_ROOT]
|--...
|--jnlp
|--...
|--plugins
|--[DEPENDENCY_01.JAR]
|--[DEPENDENCY_02.JAR]
|--...
目前,我的pom.xml指示maven将所有项目依赖项放入:[PROJECT_ROOT] / jnlp / plugins
我需要告诉maven将属性“Trusted-Library:true”添加到位于[PROJECT_ROOT] / jnlp / plugins
的所有.jar文件的清单中有人知道怎么做吗?
答案 0 :(得分:2)
我找不到解决此问题的方法。甚至试图修复http://jira.codehaus.org/browse/MWEBSTART-224,但这个缺陷超出了我的理解范围。另外,我想写一个maven插件来处理清单操作,但它对我来说似乎太官僚了(见https://maven.apache.org/guides/mini/guide-central-repository-upload.html)
因此,我决定编写自己的解决方案,并在此发布以供将来参考(希望它能帮助其他人)。
简单地说,我已经在不同的步骤中打破了我的构建过程:
编译和汇编:由webstart-maven-plugin处理
添加清单属性:由运行我的自定义类的exec-maven-plugin处理.ignign.AddManifestAttributes
取消和唱歌档案:由maven-jarsigner-plugin处理
以下是我的pom.xml的样子:
<plugin>
<groupId>org.codehaus.mojo.webstart</groupId>
<artifactId>webstart-maven-plugin</artifactId>
...
<configuration>
<libPath>plugins</libPath>
<makeArchive>false</makeArchive>
...
</configuration>
</plugin>
<!-- Adds manifest attributes to every file in a single directory -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<!-- Add manifest attributes to all files in a given location using the JDK 'jar umf' command line -->
<mainClass>codesigning.AddManifestAttributes</mainClass>
<arguments>
<!-- The first argument indicates a single directory where the files are located -->
<argument>${project.basedir}/target/jnlp/plugins</argument>
<!-- The other arguments indicates the manifest attributes to be added to each file -->
<argument>Permissions: all-permissions</argument>
<argument>Codebase: *</argument>
<argument>Trusted-Library: true</argument>
</arguments>
</configuration>
</execution>
</executions>
</plugin>
<!-- Unsing and sign all java archives. You can also use the command line -> mvn jarsigner:sign -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jarsigner-plugin</artifactId>
<executions>
<execution>
<id>sign</id>
<phase>install</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
<configuration>
<archiveDirectory>${project.basedir}/target/jnlp/plugins</archiveDirectory>
<!-- Indicates whether existing signatures should be removed from the processed JAR files prior to signing them. If enabled, the resulting JAR will appear as being signed only once. -->
<removeExistingSignatures>true</removeExistingSignatures>
...
</configuration>
</plugin>
以下是codesigning.AddManifestAttributes的样子:
package codesigning;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.logging.Level;
import java.util.logging.Logger;
public class AddManifestAttributes {
private static Logger logger = Logger.getLogger(AddManifestAttributes.class.getName());
/**
* This application adds manifest attributes to every file in a single directory.
*
* arguments[0]: Directory where files to be updated are located
* arguments[1..]: Attributes to be added to manifest
*
* @param arguments
*/
public static void main(String[] arguments) {
String arquivesStringPath = arguments[0];
logger.info("Atempting to update archives located at: " + arquivesStringPath);
String manifestAddition = getManifestContent(arguments);
logger.info("Manifest content to be added:\n " + manifestAddition);
logger.info("Creating temporary manifest file");
File manifestFile = null;
try {
manifestFile = createsTemporaryManifestFile(manifestAddition);
logger.info("Temporary manifest file has been created at: " + manifestFile.getAbsolutePath());
} catch (IOException ioe) {
logger.log(Level.SEVERE, "Error when creating temporary manifest file. Message: " + ioe.getMessage());
}
logger.info("Reading files from: " + arquivesStringPath);
File arquivesPath = new File(arquivesStringPath);
if (arquivesPath.exists() && arquivesPath.isDirectory()) {
File[] files = arquivesPath.listFiles();
for (File f : files) {
try {
logger.info("Adding attributes from manifest [".concat(manifestFile.getAbsolutePath()).concat("] into [").concat(f.getAbsolutePath()).concat("]"));
logger.info(addManifestAttributes(manifestFile, f));
} catch (Exception e) {
logger.log(Level.SEVERE, "Error when unsigning archive [" + f.getAbsolutePath() + "]. Message: " + e.getMessage());
}
}
}
}
/**
* Breaks down an array of strings (starting from position [1]) in several lines.
* @param args
* @return String in manifest format
*/
private static String getManifestContent(String[] args) {
StringBuffer result = new StringBuffer();
for (int i = 1; i < args.length; i++) {
result.append(args[i]);
result.append("\n");
}
return result.toString();
}
/**
* Creates a temporary manifest file
* @return File pointing to the temporary manifest file created
* @throws IOException
*/
private static File createsTemporaryManifestFile(String content) throws IOException {
File file = File.createTempFile("UnsignArchiveTempManifest", ".mf");
FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw);
bw.write(content);
bw.close();
return file;
}
/**
* Adds the attributes from <i>manifestFile</i> into <i>jarFile</i> using
* the jar tool included in the JDK issuing the command line
*
* <pre>
* jar cfm jar-file manifest-addition input-file(s)
* </pre>
*
* . More details at:
* http://docs.oracle.com/javase/tutorial/deployment/jar/modman.html
*
* @param manifestFile
* @param jarFile
* @return The output from the command line execution
* @throws IOException
*/
private static String addManifestAttributes(File manifestFile, File jarFile) throws IOException {
StringBuffer result = new StringBuffer();
/*
* This class is meant to run with maven which depends on JAVA_HOME
* environment variable (see http://maven.apache.org/download.cgi).
* Therefore it is reasonable to JAVA_HOME as a dependency to this
* class.
*/
String commandLine = System.getenv("JAVA_HOME").concat(File.separator).concat("bin").concat(File.separator).concat("jar");
ProcessBuilder processBuilder = new ProcessBuilder(commandLine, "ufm", jarFile.getAbsolutePath(), manifestFile.getAbsolutePath());
logger.info("Executing command line: " + commandLine + " ufm " + jarFile.getAbsolutePath() + " " + manifestFile.getAbsolutePath());
Process process = processBuilder.start();
BufferedReader stdInput = new BufferedReader(new InputStreamReader(process.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String s = null;
while ((s = stdInput.readLine()) != null) {
result.append(s);
}
while ((s = stdError.readLine()) != null) {
result.append(s);
}
return result.toString();
}
}