maven - 如何使用maven向多个.jar添加 list 属性?

标签 maven maven-2 maven-3

我正在进行一个相当复杂的 Java Web Start 应用程序项目。简而言之,我已经按照下面的文件结构成功地组装了一个包含我需要的所有内容的 bundle :

--[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 文件的 list 中

有人知道怎么做吗?

最佳答案

我没有找到此问题的解决方案。甚至尝试修复 http://jira.codehaus.org/browse/MWEBSTART-224但这个缺陷超出了我的理解范围。另外,我想编写一个 Maven 插件来处理 list 操作,但它对我来说似乎太官僚了(参见 https://maven.apache.org/guides/mini/guide-central-repository-upload.html )

因此,我决定编写自己的解决方案并发布在这里以供将来引用(希望它对其他人有帮助)。

简单地说,我将构建过程分解为不同的步骤:

  • 编译和组装:由 webstart-maven-plugin 处理

  • 添加 list 属性:由运行我的自定义类 codesigning.AddManifestAttributes 的 exec-maven-plugin 处理

  • Unsing 和 sing 文件:由 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();
    }

}

关于maven - 如何使用maven向多个.jar添加 list 属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22410139/

相关文章:

java - Maven Central 中提供哪些 EL 2.2 实现?

Maven 自定义归档扩展 - 我如何使用解包依赖项?

java - 将多个jar合并为一个(使用maven)

java - 模块化项目中的资源过滤

java - maven 未使用新的内部版本号更新本地存储库中的 jar

maven - 关于在 Maven 3 中使用 project.parent.version 作为模块版本的警告

java - 无法销毁线程组 org.codehaus.mojo.exec.ExecJavaMojo$IsolatedThreadGroup[name=SitemapCheck.SitemapAction,maxpri=10]

java - "Managed by CM"CM是什么意思

java - Eclipse 使用Maven更改项目版本?

xml - 多模块 Java/Maven 项目中 DBUnit 的 XML DTD 路径?