简体   繁体   English

用Maven构建可执行jar?

[英]Building executable jar with maven?

I am trying to generate an executable jar for a small home project called "logmanager" using maven, just like this: 我正在尝试使用maven为名为“ logmanager”的小型家庭项目生成可执行jar,如下所示:

How can I create an executable JAR with dependencies using Maven? 如何使用Maven创建具有依赖项的可执行JAR?

I added the snippet shown there to the pom.xml, and ran mvn assembly:assembly. 我将此处显示的代码段添加到pom.xml中,并运行了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. 它在logmanager / target中生成两个jar文件:logmanager-0.1.0.jar和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: 当我双击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. 我复制并粘贴了路径和类名,并检查了POM中的拼写。 My main class launches fine from an eclipse launch configuration. 我的主课从Eclipse启动配置启动正常。 Can someone help me figure out why my jar file won't run? 有人可以帮我弄清楚为什么我的jar文件无法运行吗? 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: 这是完整的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>

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. 实际上,我认为您提到的问题给出的答案是错误的UPDATE-20101106:有人对其进行了修复, 答案指的是编辑之前的版本 ),这至少部分地说明了您为什么会遇到麻烦的原因。


It generates two jar files in logmanager/target: logmanager-0.1.0.jar, and logmanager-0.1.0-jar-with-dependencies.jar. 它在logmanager / target中生成两个jar文件:logmanager-0.1.0.jar和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 ). 第一个是jar:jarpackage阶段期间生成的logmanager模块的jar:jar (因为该模块的包装类型为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 ). 第二个是由assembly:assembly assembly生成的assembly:assembly ,它应包含当前模块中的类及其依赖项(如果使用描述符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: 如果您应用了作为参考发布的链接的建议配置,则将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 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). 因此logmanager-0.1.0.jar确实是可执行文件,但是1.这不是您想要的(因为它不具有所有依赖项),并且2.它不包含com.gorkwobble.logmanager.LogManager (这就是错误是说,检查罐子的内容)。

A slightly different error when I double-click the jar-with-dependencies.jar: 当我双击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). 采用这种设置, logmanager-0.1.0-jar-with-dependencies.jar包含从当前模块中的类及其依赖性,但根据该错误,它的META-INF/MANIFEST.MF 包含Main-Class条目(它可能与logmanager-0.1.0.jar中的MANIFEST.MF不同)。 The jar is actually not executable, which again is not what you want. 该jar实际上不是可执行文件,这又不是您想要的。


So, my suggestion would be to remove the configuration element from the maven-jar-plugin and to configure the maven-assembly-plugin like this: 因此,我的建议是从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>

Of course, replace org.sample.App with the class you want to have executed. 当然,将org.sample.App替换为要执行的类。 Little bonus, I've bound assembly:single to the package phase so you don't have to run assembly:assembly anymore. 没什么大不了的,我已经将assembly:single绑定到了package阶段,因此您不必再运行assembly:assembly Just run mvn install and the assembly will be produced during the standard build. 只需运行mvn install ,程序集将在标准构建期间生成。

So, please update your pom.xml with the configuration given above and run mvn clean install . 因此,请使用上述配置更新您的pom.xml并运行mvn clean install Then, cd into the target directory and try again: 然后,cd进入target目录,然后重试:

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). 如果遇到错误,请使用它来更新您的问题,然后发布META-INF/MANIFEST.MF文件的内容以及pom.xml的相关部分(插件配置部分)。 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). 以证明它在命令行上工作正常(无论eclipse怎么说)。

EDIT: For Java 6, you need to configure the maven-compiler-plugin. 编辑:对于Java 6,您需要配置maven-compiler-plugin。 Add this to your pom.xml: 将此添加到您的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>

The answer of Pascal Thivent helped me out, too. Pascal Thivent的回答帮助了我。 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 . 但是,如果您在<pluginManagement>元素内管理插件,则必须在插件管理之外再次定义程序集,否则,如果运行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>

If you don't want execute assembly goal on package, you can use next command: 如果不想在程序包上执行组装目标,则可以使用下一个命令:

mvn package assembly:single

Here package is keyword. 这里的是关键字。

右键单击该项目,然后进行maven构建,maven清理,maven生成资源和maven安装。jar文件将自动生成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM