【问题标题】:Maven build no main manifest attributeMaven 构建没有主要清单属性
【发布时间】:2019-10-17 20:09:19
【问题描述】:

我正在使用 Maven 构建一个小应用程序,它具有依赖项并且是一个可执行的 jar 文件。

这是我的pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.company</groupId>
    <artifactId>site-downloader</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>

    <properties>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.source>1.8</maven.compiler.source>
    </properties>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>3.141.59</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>
        <dependency>
            <groupId>com.company.siteripper</groupId>
            <artifactId>common-interfaces</artifactId>
            <version>1.0.0</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                        <configuration>
                            <archive>
                                <manifest>
                                    <mainClass>
                                        com.company.Main
                                    </mainClass>
                                </manifest>
                            </archive>
                            <descriptorRefs>
                                <descriptorRef>jar-with-dependencies</descriptorRef>
                            </descriptorRefs>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

构建完成没有问题,但是在执行它写入的 jar 时

没有主要清单属性,在 本地 maven repo / 我的 jar 中。

我也在docsBaeldung 寻求帮助,但无济于事。

我寻求帮助以使 jar 包含其依赖项并同时可执行。

编辑:

我更新了我的pom 以使用 jar 和依赖项插件而不是程序集。这是更新的 pom:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.company</groupId>
    <artifactId>site-downloader</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>

    <properties>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.source>1.8</maven.compiler.source>
    </properties>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>3.141.59</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>
        <dependency>
            <groupId>com.company.siteripper</groupId>
            <artifactId>common-interfaces</artifactId>
            <version>1.0.0</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>
                                com.company.Main
                            </mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <executions>
                    <execution>
                        <id>copy-dependencies</id>
                        <phase>prepare-package</phase>
                        <goals>
                            <goal>copy-dependencies</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>
                                ${project.build.directory}/libs
                            </outputDirectory>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

但我在运行它时得到一个NoClassDefFoundError

C:\Users\myusername\Documents\Commands>调用 java -jar D:.m2\repository\com\company\site-downloader\1.0.0\site-downloader-1.0.0.jar -9gag https://9gag.com/gag/arGEvRX?ref C:\Users\myusername\Documents\sites\data\android 错误:JNI 错误 已发生,请检查您的安装并重试异常 在线程“主”java.lang.NoClassDefFoundError: org/openqa/selenium/WebDriver 在 java.lang.Class.getDeclaredMethods0(本机方法) 在 java.lang.Class.privateGetDeclaredMethods(未知来源) 在 java.lang.Class.privateGetMethodRecursive(未知来源) 在 java.lang.Class.getMethod0(未知来源) 在 java.lang.Class.getMethod(未知来源) 在 sun.launcher.LauncherHelper.validateMainClass(未知来源) 在 sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source) 引起:java.lang.ClassNotFoundException: org.openqa.selenium.WebDriver 在 java.net.URLClassLoader.findClass(未知来源) 在 java.lang.ClassLoader.loadClass(未知来源) 在 sun.misc.Launcher$AppClassLoader.loadClass(未知来源) 在 java.lang.ClassLoader.loadClass(未知来源) ... 7 更多

【问题讨论】:

    标签: java maven


    【解决方案1】:

    要创建可执行 jar,您必须使用以下 maven jar 插件。我在下面提供代码sn-p。

    <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-jar-plugin</artifactId>
                    <configuration>
                        <archive>
                            <manifest>
                                <mainClass>
                                    your main class
                                </mainClass>
                            </manifest>
                        </archive>
                    </configuration>
                </plugin>
    

    有关更多详细信息,请参阅下面的 github 链接以了解如何创建可执行/可运行的 jar。

    https://github.com/debjava/runnableJar

    根据文档,适用于 Maven 的 Maven 程序集插件主要用于 允许用户聚合项目输出及其 依赖项、模块、站点文档和其他文件到一个 单个可分发存档。

    请参阅下面的 Maven Assembly 插件的详细信息。 http://maven.apache.org/plugins/maven-assembly-plugin/

    【讨论】:

    • 谢谢,马上试试。但是组装插件不应该也可以工作吗? AFAIK 程序集插件将依赖项复制到单个 jar 中(包 - 我的 pom 中的单个)并使其也可执行。
    • 嗨 @agiro,我已经更新了关于 maven 程序集插件的答案。
    • 在 jar 插件之后,我也添加了依赖项插件 maven.apache.org/plugins/maven-dependency-plugin/…,这一次它启动但失败,NoClassDefFoundError 用于我的依赖项之一,Selenium。我当然删除了我的旧程序集插件。
    • 当然,我用新的 pom 和错误更新了问题。
    【解决方案2】:

    这就是我解决您问题的方法:
    请忽略业务逻辑, 由于我使用的是 MongoDB,因此添加了 MongoDB 驱动程序作为依赖项,并且能够使用 java -jar 命令运行。
    最终目标与您的相同。
    我正在使用 maven-shade 插件。

    来自Github source code:的结帐项目
    解压、构建、测试

    1.创建了一个maven项目
    mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.4

    1. 使用以下内容更新 pom.xml,添加来自 OP 的 mongo 客户端代码并打印集合名称
    2. 执行 mvn clean package
    3. 执行 java -jar test.jar 我得到的输出是:
    INFO: Opened connection [connectionId{localValue:1, serverValue:9}] to localhost:27017
    Jun 01, 2019 8:17:22 PM com.mongodb.diagnostics.logging.JULLogger log
    INFO: Monitor thread successfully connected to server with description ServerDescription{address=localhost:27017, type=STANDALONE, state=CONNECTED, ok=true, version=ServerVersion{versionList=[4, 0, 5]}, minWireVersion=0, maxWireVersion=7, maxDocumentSize=16777216, logicalSessionTimeoutMinutes=30, roundTripTimeNanos=2249770}
    Jun 01, 2019 8:17:22 PM com.mongodb.diagnostics.logging.JULLogger log
    INFO: Opened connection [connectionId{localValue:2, serverValue:10}] to localhost:27017
    admin
    config
    local
    test
    [XenonSuite] Successfully connected to MongoDB
    

    pom.xml(忽略包名)
    检查shade插件配置

    <?xml version="1.0" encoding="UTF-8"?>
    
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>test</groupId>
      <artifactId>test</artifactId>
      <version>1.0-SNAPSHOT</version>
    
      <name>test</name>
      <!-- FIXME change it to the project's website -->
      <url>http://www.example.com</url>
    
      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <mainClass>test.App</mainClass>
      </properties>
    
      <packaging>jar</packaging>
    
      <dependencies>
    
      <!-- https://mvnrepository.com/artifact/org.mongodb/mongo-java-driver -->
        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongo-java-driver</artifactId>
            <version>3.10.2</version>
        </dependency>
    
    
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.11</version>
          <scope>test</scope>
        </dependency>
      </dependencies>
    
      <build>
          <plugins>
            <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-assembly-plugin</artifactId>
              <version>3.1.1</version>
            </plugin>
            <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-dependency-plugin</artifactId>
              <version>3.1.1</version>
            </plugin>
            <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-jar-plugin</artifactId>
              <version>3.1.1</version>
            </plugin>
            <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-shade-plugin</artifactId>
              <version>3.2.1</version>
              <executions>
                <execution>
                  <phase>package</phase>
                  <goals>
                    <goal>shade</goal>
                  </goals>
                  <configuration>
                    <shadedArtifactAttached>true</shadedArtifactAttached>
                    <transformers>
                      <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                        <mainClass>test.App</mainClass>
                      </transformer>
                    </transformers>
                    <finalName>test</finalName>
                  </configuration>
                </execution>
              </executions>
            </plugin>
          </plugins>
      </build>
    </project>
    
    

    有多种方法可以解决这个问题 参考:https://www.baeldung.com/executable-jar-with-maven

    【讨论】:

    • 当签出test 并启动mvn clean install 时,我得到了一个成功的构建,但是当我使用java -jar test-1.0-SNAPSHOT.jar 运行jar 文件时,我得到了一个没有清单的问题。我要重新安装我的 Maven 吗?
    • 不,你需要运行mvn clean package作为答案中提到的,如果你想在安装阶段使用jar,将&lt;phase&gt;package&lt;/phase&gt;更改为&lt;phase&gt;install&lt;/phase&gt;,你也在执行错误的jar文件,正确的一个是test.jar在同一路径,执行java -jar test.jar
    • 抱歉,我停止阅读 OR。事实上,它适用于test.jar。我不明白的是,为什么它也会生成 test-1.0-SNAPSHOT.jar 以及为什么那个 jar 给我 no main manifest 属性?
    • 原因是 test.jar 是由 shaded 插件创建的,并创建了清单文件。 test-1.0-SNAPSHOT.jar 不是这种情况@
    • 我们可以设置 maven 不创建快照 jar 吗? :D
    猜你喜欢
    • 2019-07-19
    • 1970-01-01
    • 2015-01-06
    • 1970-01-01
    • 1970-01-01
    • 2015-12-10
    • 2015-03-14
    • 2019-05-18
    • 1970-01-01
    相关资源
    最近更新 更多