java - 使用 java -cp 等类路径描述 MANIFEST.MF

标签 java maven command-line-interface maven-assembly-plugin

我有一个命令行 Java 应用程序,它依赖于其他库/jar。因此,我使用 -cp 运行应用程序,例如java -cp libs/* <package.MainClass> <args>

我想做的是复制 Java 应用程序中的依赖项 libs/jars 并正确描述 MANIFEST.MF,因为我不需要选项 -cp libs/*不再了。

我的项目是一个 Maven 项目,因此我使用 maven-assembly-plugin复制我的 JAR 中的库并描述 MANIFEST.MF。我现在的情况如下:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>3.1.1</version>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>MainClass</mainClass>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                    </manifest>
                </archive>
            </configuration>
            <executions>
                <execution>
                    <id>dist</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

我的 MANIFEST.MF 看起来像这个 atm:

Manifest-Version: 1.0
Built-By: user
Class-Path: lib/deps_A.jar lib/deps_B.jar
Created-By: Apache Maven 3.6.0
Build-Jdk: 1.8.0_202
Main-Class: MainClass

我的问题是:如何描述 MANIFEST.MF 文件,以便我使用 java -jar <my-jar-application.jar> <args> 运行我的应用程序?

最佳答案

list 条目未在 SystemClassLoader 的 URL 中列出。

您必须手动从 list 文件中获取它们。

            ClassLoader cl = ClassLoader.getSystemClassLoader();
            if (cl instanceof URLClassLoader) {
                URLClassLoader ucl = (URLClassLoader) cl;
                URL[] urLs = ucl.getURLs();
                for (URL url : urLs) {
                    File file = new File(URLDecoder.decode(url.getFile()));

                    try (JarFile jarFile = new JarFile(file)){
                        Manifest manifest = jarFile.getManifest();
                        String attrs = manifest.getMainAttributes().getValue(Attributes.Name.CLASS_PATH.toString());
                        if(attrs!=null) {
                            String[] splits = attrs.split(" ");
                            for (String split:  splits) {
                                // This is the name of the jar referenced in manifest.
                                System.out.println(split);
                            }
                        }

                        System.out.println(file);
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }

我的灵感来自 guava lib,您还可以查看 Classpath 的来源类。

关于java - 使用 java -cp 等类路径描述 MANIFEST.MF,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56000002/

相关文章:

java - Impala单个插入语句创建多个文件

Java 和多核

java - 如何强制 IntelliJ 中的 Maven 从本地 .m2 存储库中提取特定依赖项

java - Linux 上的 Protocol Buffer 符号查找错误

java - 重构java命令行参数

javascript - CLI NodeJS(并发、回调、.methods)

java - 在刷新重新加载之前清除 ListView

java - 我可以同时使用默认构造函数和@UiConstructor吗?

java - 将 Guava 添加到新的 Maven IntelliJ 模块

Python argparse 静态参数