如何使用Maven创建一个可执行jar文件,其中包含主类在Test中的依赖项

时间:2014-07-16 01:47:44

标签: java maven dependencies executable-jar

我是Maven的新手,并且拥有一个具有以下目录结构的项目

project

-src
  -main
    -java
      -org
        -core
          -starter.java
  -test
    -java
      -org
        -core
          -testStarter.java

starter.java和testStarter.java都是Main类。但是,我希望创建一个可执行jar文件(包括依赖项),其中执行testStarter.java。

我将以下内容添加到我的pom文件中:

<groupId>org</groupId>
<artifactId>proj</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>project</name>
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
                <source>1.7</source>
                <target>1.7</target>
            </configuration>
        </plugin>
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                    <configuration>
                        <archive>
                            <manifest>
                                <mainClass>org.core.testStarter</mainClass>
                            </manifest>
                        </archive>
                        <descriptorRefs>
                            <descriptorRef>jar-with-dependencies</descriptorRef>
                        </descriptorRefs>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    <plugins>
</build>

但是每次运行mvn clean包时,它都会创建一个只包含主目录中编译类而不是test目录的包。因此,每次运行jar文件时,它都不会运行,因为创建的jar文件中不存在testStarter.class。

有没有办法可以创建

1)一个包含测试和主类的大jar文件,只执行测试类

2)仅包括测试类,但包括所有依赖项。

4 个答案:

答案 0 :(得分:2)

嗯,这看起来有点奇怪,但你可以做的是将testStarter置于main之下(我想这不会起作用,因为它引用了{{下的其他类) 1}}文件夹,我是对的吗?)。顺便说一下,使用test类名,这是更多Java-ish。

或者,您可以使用test-jar为测试创建一个jar(如果您将原始jar添加到CapitalCamelCase manifest属性中,这可能会有效),或者您可以开始攻击{{3您的项目,但我不推荐。

我建议重新考虑您的项目布局并澄清您的要求。可能你不会需要这个过程。

答案 1 :(得分:2)

根据你pom.xml,你已经有了一个包含清单中所有依赖关系和正确类名的大jar。

现在您只需将测试类包含在工件中。

  1. 一个包含测试和主类的大jar文件,只执行测试类。您可以将/src/test目录指定为另一个源目录(请参阅Maven compile with multiple src directories)。
  2. 仅包含测试类但包含所有依赖项。您可以使用构建部分中的sourceDirectory标记将测试目录标记为唯一的源目录。但我想,您的测试依赖于main中的代码,因此这种配置可能会在编译时失败。
  3. P.S。我强烈建议你为这种情况创建单独的构建配置文件,因为在测试类中使用jar的main方法对我来说似乎很奇怪。

答案 2 :(得分:2)

我建议使用Maven OneJar插件,

看这里:https://code.google.com/p/onejar-maven-plugin/

&#34;让您使用Maven2构建一个可执行jar,包含所有依赖项&#34;

至于您的范围问题 - 您需要将该Main类移动到src文件夹,以便它可以在编译范围内。

干杯!

答案 3 :(得分:2)

我们在项目中使用带有maven-assembly-plugin的assembly.xml来完成此操作。 在POM中我们有:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>2.4</version>
        <configuration>
            <descriptors>
                <descriptor>src/main/resources/assembly.xml</descriptor>
            </descriptors>
        </configuration>
        <executions>
            <execution>
                <id>package-jar-with-dependencies</id>
                <phase>package</phase>
                <goals>
                    <goal>single</goal>
                </goals>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
            </execution>
        </executions>
    </plugin>

然后在src / main / resources中有一个assembly.xml,它告诉我们如何构建该程序集:

<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
    <id>bin</id>
    <formats>
        <format>jar</format>
    </formats>
    <!-- Adds dependencies to jar package under lib directory -->
    <dependencySets>
        <dependencySet>
            <useProjectArtifact>true</useProjectArtifact>
            <outputDirectory></outputDirectory>
            <unpack>true</unpack>
        </dependencySet>
    </dependencySets>
</assembly>