用maven构建可执行jar?

发布于 2024-08-13 01:15:21 字数 5177 浏览 10 评论 0原文

我正在尝试使用 maven 为名为“logmanager”的小型家庭项目生成可执行 jar,如下所示:

如何使用 Maven 创建具有依赖项的可执行 JAR?

我将其中显示的代码段添加到 pom.xml 中,并运行 mvn assembly: assembly。它在 logmanager/target 中生成两个 jar 文件:logmanager-0.1.0.jar 和 logmanager-0.1.0-jar-with-dependency.jar。双击第一个 jar 时出现错误:

Could not find the main class: com.gorkwobble.logmanager.LogManager. Program will exit.

双击 jar-with-dependency.jar 时出现略有不同的错误:

Failed to load Main-Class manifest attribute from: C:\EclipseProjects\logmanager\target\logmanager-0.1.0-jar-with-dependencies.jar

我复制并粘贴了路径和类名,并检查了 POM 中的拼写。我的主类从 Eclipse 启动配置中启动良好。有人可以帮我找出为什么我的 jar 文件无法运行吗?另外,为什么一开始就有两个罐子?如果您需要更多信息,请告诉我。

这是完整的pom.xml,供参考:

<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.gorkwobble</groupId>
  <artifactId>logmanager</artifactId>
  <name>LogManager</name>
  <version>0.1.0</version>
  <description>Systematically renames specified log files on a scheduled basis. Designed to help manage MUSHClient logging and prevent long, continuous log files.</description>
  <build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.2</version>
            <!-- nothing here -->
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.2-beta-4</version>
            <configuration>
              <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
              </descriptorRefs>
              <archive>
                <manifest>
                  <mainClass>com.gorkwobble.logmanager.LogManager</mainClass>
                </manifest>
              </archive>
            </configuration>
            <executions>
              <execution>
                <phase>package</phase>
                <goals>
                  <goal>single</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
              <source>1.6</source>
              <target>1.6</target>
            </configuration>
          </plugin>
    </plugins>
  </build>
  <dependencies>
    <!-- commons-lang -->
    <dependency>
        <groupId>commons-lang</groupId>
        <artifactId>commons-lang</artifactId>
        <version>2.4</version>
    </dependency> 

    <!-- Quartz scheduler -->
    <dependency>
        <groupId>opensymphony</groupId>
        <artifactId>quartz</artifactId>
        <version>1.6.3</version>
    </dependency>
    <!-- Quartz 1.6.0 depends on commons collections -->
    <dependency>
      <groupId>commons-collections</groupId>
      <artifactId>commons-collections</artifactId>
      <version>3.1</version>
    </dependency>
    <!-- Quartz 1.6.0 depends on commons logging -->
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.1</version>
    </dependency>
    <!-- Quartz 1.6.0 requires JTA in non J2EE environments -->
    <dependency>
      <groupId>javax.transaction</groupId>
      <artifactId>jta</artifactId>
      <version>1.1</version>
      <scope>runtime</scope>
    </dependency>

    <!-- junitx test assertions -->
    <dependency>
        <groupId>junit-addons</groupId>
        <artifactId>junit-addons</artifactId>
        <version>1.4</version>
        <scope>test</scope>
    </dependency>

    <!-- junit dependency; FIXME: make this a separate POM -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.1</version>
    </dependency>

  </dependencies>
  <dependencyManagement>
  </dependencyManagement>
</project>

I am trying to generate an executable jar for a small home project called "logmanager" using maven, just like this:

How can I create an executable JAR with dependencies using Maven?

I added the snippet shown there to the pom.xml, and ran mvn assembly:assembly. It generates two jar files in logmanager/target: logmanager-0.1.0.jar, and logmanager-0.1.0-jar-with-dependencies.jar. I get an error when I double-click on the first jar:

Could not find the main class: com.gorkwobble.logmanager.LogManager. Program will exit.

A slightly different error when I double-click the jar-with-dependencies.jar:

Failed to load Main-Class manifest attribute from: C:\EclipseProjects\logmanager\target\logmanager-0.1.0-jar-with-dependencies.jar

I copied and pasted the path and classname, and checked the spelling in the POM. My main class launches fine from an eclipse launch configuration. Can someone help me figure out why my jar file won't run? Also, why are there two jars to begin with? Let me know if you need more information.

Here is the full pom.xml, for reference:

<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.gorkwobble</groupId>
  <artifactId>logmanager</artifactId>
  <name>LogManager</name>
  <version>0.1.0</version>
  <description>Systematically renames specified log files on a scheduled basis. Designed to help manage MUSHClient logging and prevent long, continuous log files.</description>
  <build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.2</version>
            <!-- nothing here -->
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.2-beta-4</version>
            <configuration>
              <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
              </descriptorRefs>
              <archive>
                <manifest>
                  <mainClass>com.gorkwobble.logmanager.LogManager</mainClass>
                </manifest>
              </archive>
            </configuration>
            <executions>
              <execution>
                <phase>package</phase>
                <goals>
                  <goal>single</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
              <source>1.6</source>
              <target>1.6</target>
            </configuration>
          </plugin>
    </plugins>
  </build>
  <dependencies>
    <!-- commons-lang -->
    <dependency>
        <groupId>commons-lang</groupId>
        <artifactId>commons-lang</artifactId>
        <version>2.4</version>
    </dependency> 

    <!-- Quartz scheduler -->
    <dependency>
        <groupId>opensymphony</groupId>
        <artifactId>quartz</artifactId>
        <version>1.6.3</version>
    </dependency>
    <!-- Quartz 1.6.0 depends on commons collections -->
    <dependency>
      <groupId>commons-collections</groupId>
      <artifactId>commons-collections</artifactId>
      <version>3.1</version>
    </dependency>
    <!-- Quartz 1.6.0 depends on commons logging -->
    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.1</version>
    </dependency>
    <!-- Quartz 1.6.0 requires JTA in non J2EE environments -->
    <dependency>
      <groupId>javax.transaction</groupId>
      <artifactId>jta</artifactId>
      <version>1.1</version>
      <scope>runtime</scope>
    </dependency>

    <!-- junitx test assertions -->
    <dependency>
        <groupId>junit-addons</groupId>
        <artifactId>junit-addons</artifactId>
        <version>1.4</version>
        <scope>test</scope>
    </dependency>

    <!-- junit dependency; FIXME: make this a separate POM -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.1</version>
    </dependency>

  </dependencies>
  <dependencyManagement>
  </dependencyManagement>
</project>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

睫毛上残留的泪 2024-08-20 01:15:21

实际上,我认为 中给出的答案您提到的问题只是错误更新 - 20101106:有人修复了它,这个答案指的是编辑之前的版本),这至少部分地解释了您遇到麻烦的原因。


它在 logmanager/target 中生成两个 jar 文件:logmanager-0.1.0.jar 和 logmanager-0.1.0-jar-with-dependency.jar。

第一个是在 package 阶段由 jar:jar 生成的 logmanager 模块的 JAR(因为该模块有一个 jar 类型的打包) )。第二个是由 assembly: assembly 生成的程序集,应包含当前模块中的类及其依赖项(如果您使用描述符 jar-with-dependencies )。

双击第一个 jar 时出现错误:

找不到主类:com.gorkwobble.logmanager.LogManager。程序将退出。

如果您应用了作为参考发布的链接的建议配置,则您配置了 jar 插件以生成可执行工件,如下所示:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
      <archive>
        <manifest>
          <addClasspath>true</addClasspath>
          <mainClass>com.gorkwobble.logmanager.LogManager</mainClass>
        </manifest>
      </archive>
    </configuration>
  </plugin>

So logmanager-0.1. 0.jar 确实是可执行的,但 1. 这不是您想要的(因为它不具有所有依赖项)并且 2. 它不包含 com.gorkwobble.logmanager.LogManager (这就是错误的意思,检查 jar 的内容)。

双击 jar-with-dependency.jar 时出现略有不同的错误:

无法从以下位置加载主类清单属性:C:\EclipseProjects\logmanager\target\logmanager-0.1.0-jar-with-dependency.jar

同样,如果您按照建议配置了程序集插件,则会出现如下所示的内容:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <configuration>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
    </configuration>
  </plugin>

通过此设置,logmanager-0.1.0-jar- with-dependency.jar 包含当前模块中的类及其依赖项,但根据错误,其 META-INF/MANIFEST.MF 包含Main-Class条目(它可能与logmanager-0.1.0.jar中的MANIFEST.MF不同)。该 jar 实际上不可可执行,这也不是您想要的。


因此,我的建议是从 maven-jar-plugin 中删除 configuration 元素,并像这样配置 maven- assembly-plugin:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.2</version>
    <!-- nothing here -->
  </plugin>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.2-beta-4</version>
    <configuration>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
      <archive>
        <manifest>
          <mainClass>org.sample.App</mainClass>
        </manifest>
      </archive>
    </configuration>
    <executions>
      <execution>
        <phase>package</phase>
        <goals>
          <goal>single</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

当然,替换 org.sample.App< /code> 与您想要执行的类。额外的好处是,我已将 assembly:single 绑定到 package 阶段,这样您就不必再运行 assembly: assembly 了。只需运行mvn install,程序集就会在标准构建过程中生成。

因此,请使用上面给出的配置更新您的 pom.xml 并运行 mvn clean install。然后,cd 进入 target 目录并重试:

java -jar logmanager-0.1.0-jar-with-dependencies.jar

如果出现错误,请用它更新您的问题并发布 META-INF/MANIFEST.MF 的内容文件和 pom.xml 的相关部分(插件配置部分)。另请发布结果:

java -cp logmanager-0.1.0-jar-with-dependencies.jar com.gorkwobble.logmanager.LogManager

以证明它在命令行上工作正常(无论 eclipse 说什么)。

编辑:对于 Java 6,您需要配置 maven-compiler-plugin。将其添加到您的 pom.xml 中:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
      <source>1.6</source>
      <target>1.6</target>
    </configuration>
  </plugin>

Actually, I think that the answer given in the question you mentioned is just wrong (UPDATE - 20101106: someone fixed it, this answer refers to the version preceding the edit) and this explains, at least partially, why you run into troubles.


It generates two jar files in logmanager/target: logmanager-0.1.0.jar, and logmanager-0.1.0-jar-with-dependencies.jar.

The first one is the JAR of the logmanager module generated during the package phase by jar:jar (because the module has a packaging of type jar). The second one is the assembly generated by assembly:assembly and should contain the classes from the current module and its dependencies (if you used the descriptor jar-with-dependencies).

I get an error when I double-click on the first jar:

Could not find the main class: com.gorkwobble.logmanager.LogManager. Program will exit.

If you applied the suggested configuration of the link posted as reference, you configured the jar plugin to produce an executable artifact, something like this:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
      <archive>
        <manifest>
          <addClasspath>true</addClasspath>
          <mainClass>com.gorkwobble.logmanager.LogManager</mainClass>
        </manifest>
      </archive>
    </configuration>
  </plugin>

So logmanager-0.1.0.jar is indeed executable but 1. this is not what you want (because it doesn't have all dependencies) and 2. it doesn't contain com.gorkwobble.logmanager.LogManager (this is what the error is saying, check the content of the jar).

A slightly different error when I double-click the jar-with-dependencies.jar:

Failed to load Main-Class manifest attribute from: C:\EclipseProjects\logmanager\target\logmanager-0.1.0-jar-with-dependencies.jar

Again, if you configured the assembly plugin as suggested, you have something like this:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <configuration>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
    </configuration>
  </plugin>

With this setup, logmanager-0.1.0-jar-with-dependencies.jar contains the classes from the current module and its dependencies but, according to the error, its META-INF/MANIFEST.MF doesn't contain a Main-Class entry (its likely not the same MANIFEST.MF as in logmanager-0.1.0.jar). The jar is actually not executable, which again is not what you want.


So, my suggestion would be to remove the configuration element from the maven-jar-plugin and to configure the maven-assembly-plugin like this:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <version>2.2</version>
    <!-- nothing here -->
  </plugin>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <version>2.2-beta-4</version>
    <configuration>
      <descriptorRefs>
        <descriptorRef>jar-with-dependencies</descriptorRef>
      </descriptorRefs>
      <archive>
        <manifest>
          <mainClass>org.sample.App</mainClass>
        </manifest>
      </archive>
    </configuration>
    <executions>
      <execution>
        <phase>package</phase>
        <goals>
          <goal>single</goal>
        </goals>
      </execution>
    </executions>
  </plugin>

Of course, replace org.sample.App with the class you want to have executed. Little bonus, I've bound assembly:single to the package phase so you don't have to run assembly:assembly anymore. Just run mvn install and the assembly will be produced during the standard build.

So, please update your pom.xml with the configuration given above and run mvn clean install. Then, cd into the target directory and try again:

java -jar logmanager-0.1.0-jar-with-dependencies.jar

If you get an error, please update your question with it and post the content of the META-INF/MANIFEST.MF file and the relevant part of your pom.xml (the plugins configuration parts). Also please post the result of:

java -cp logmanager-0.1.0-jar-with-dependencies.jar com.gorkwobble.logmanager.LogManager

to demonstrate it's working fine on the command line (regardless of what eclipse is saying).

EDIT: For Java 6, you need to configure the maven-compiler-plugin. Add this to your pom.xml:

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
      <source>1.6</source>
      <target>1.6</target>
    </configuration>
  </plugin>
野稚 2024-08-20 01:15:21

Pascal Thivent 的回答也帮助了我。
但是如果您在 元素中管理插件,则必须在插件管理之外再次定义程序集,否则依赖项不会打包在如果您运行 mvn install,则将其添加到 jar 中。

<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>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>


    <build>
        <pluginManagement>
            <plugins>

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.1</version>
                    <configuration>
                        <source>1.6</source>
                        <target>1.6</target>
                    </configuration>
                </plugin>

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-assembly-plugin</artifactId>
                    <version>2.4</version>
                    <configuration>
                        <archive>
                            <manifest>
                                <mainClass>main.App</mainClass>
                            </manifest>
                        </archive>
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                    </configuration>
                    <executions>
                        <execution>
                            <id>make-assembly</id>
                            <phase>package</phase>
                            <goals>
                                <goal>single</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>

            </plugins>

        </pluginManagement>

        <plugins> <!-- did NOT work without this  -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
            </plugin>
        </plugins>

    </build>


    <dependencies>
       <!--  dependencies commented out to shorten example -->
    </dependencies>

</project>

The answer of Pascal Thivent helped me out, too.
But if you manage your plugins within the <pluginManagement>element, you have to define the assembly again outside of the plugin management, or else the dependencies are not packed in the jar if you run mvn install.

<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>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>


    <build>
        <pluginManagement>
            <plugins>

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.1</version>
                    <configuration>
                        <source>1.6</source>
                        <target>1.6</target>
                    </configuration>
                </plugin>

                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-assembly-plugin</artifactId>
                    <version>2.4</version>
                    <configuration>
                        <archive>
                            <manifest>
                                <mainClass>main.App</mainClass>
                            </manifest>
                        </archive>
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                    </configuration>
                    <executions>
                        <execution>
                            <id>make-assembly</id>
                            <phase>package</phase>
                            <goals>
                                <goal>single</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>

            </plugins>

        </pluginManagement>

        <plugins> <!-- did NOT work without this  -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
            </plugin>
        </plugins>

    </build>


    <dependencies>
       <!--  dependencies commented out to shorten example -->
    </dependencies>

</project>
感情旳空白 2024-08-20 01:15:21

如果你不想在包上执行汇编目标,你可以使用下一个命令:

mvn package assembly:single

这里package是关键字。

If you don't want execute assembly goal on package, you can use next command:

mvn package assembly:single

Here package is keyword.

春庭雪 2024-08-20 01:15:21

右键单击项目并进行maven build、maven clean、mavengenerateresource和maveninstall。jar文件将自动生成。

Right click the project and give maven build,maven clean,maven generate resource and maven install.The jar file will automatically generate.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文