移动到maven后,我的编译jar文件无法运行

时间:2015-03-16 11:32:13

标签: java maven

实际上我花了很长时间才注意到。当我在netbeans中运行项目时,它的工作方式与预期的一样。但是,当我执行Build时,我得到的PROJECTNAME-1.0-SNAPSHOT.jar文件没有做任何事情。解压缩后,它看起来像这样:

image description

这是可疑的,在Maven之前,我编译的文件看起来像这样:

image description

Main类不应该在jar文件根目录中吗? JVM如何知道要运行哪个主类?

MANIFEST.MF也有令人不安的事情:

旧清单

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.9.1
Created-By: 1.7.0_45-b18 (Oracle Corporation)
Class-Path: lib/alloy.jar lib/jna-platform.jar lib/jna.jar
X-COMMENT: Main-Class will be added automatically by build
Main-Class: Main

新清单

Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: Jakub
Build-Jdk: 1.8.0_31

似乎缺少Main-Class条目......

2 个答案:

答案 0 :(得分:1)

使用maven-jar-plugin制作jar可执行文件。对我来说,实际代码如下:

 <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <version>2.5</version>
        <configuration>
          <archive>
            <manifest>
              <addClasspath>true</addClasspath>
              <classpathPrefix>lib/</classpathPrefix>
              <mainClass>my.main.class</mainClass>
            </manifest>
          </archive>
          <outputDirectory>${project.build.directory}/result</outputDirectory>
        </configuration>
      </plugin>

另外有用的exec-maven-plugin

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>1.3.2</version>
    <configuration>
      <mainClass>my.main.class</mainClass>
      <!--
      <commandlineArgs>-d 5409  -c 467 -t 2  -dlg true</commandlineArgs>
      -->
    </configuration>
  </plugin>

答案 1 :(得分:1)

遗憾的是,许多IDE提供了一种简单的机制,可以将所有库jar包装到主构建jar中。这既皱眉又可能对您的可部署产生危害 - 您应该单独部署所有使用过的库,并使用类路径将它们全部加入。

Maven试图以最简单的方式做到这一点,默认情况下构建你的jar只包含你的代码,而不是更多。如果你坚持使用这个解决方案,那么这样做可能是值得的。

然而,有时候有必要实现这一点,也许是为了在切换到Maven时复制现有的构建结果,或者部署就足以成为一场噩梦而不必部署数十个图书馆。为此,您可以使用Maven Shade插件构建Maven社区称为Uber-Jar的内容。

  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>1.6</version>
    <executions>
      <execution>
        <phase>package</phase>
        <goals>
          <goal>shade</goal>
        </goals>
        <configuration>
          <minimizeJar>true</minimizeJar>
          <filters>
            <filter>
              <!-- Make sure jaxb is included. -->
              <artifact>com.sun.xml.bind:jaxb-impl</artifact>
              <includes>
                <include>*.*</include>
              </includes>
            </filter> 
            <filter>
              <!-- Make sure jtds is included. -->
              <artifact>net.sourceforge.jtds:jtds</artifact>
              <includes>
                <include>**</include>
              </includes>
            </filter> 
            <filter>
              <artifact>*:*</artifact>
              <excludes>
                <exclude>META-INF/*.SF</exclude>
                <exclude>META-INF/*.DSA</exclude>
                <exclude>META-INF/*.RSA</exclude>
                <exclude>META-INF/*.sf</exclude>
                <exclude>META-INF/*.dsa</exclude>
                <exclude>META-INF/*.rsa</exclude>
              </excludes>
            </filter>
          </filters>
        </configuration>
      </execution>
    </executions>
  </plugin>

请注意,构建优步罐子通常不是最好的方法 - 在线讨论很多。 maven-shade-plugin本身也存在许多关系问题,因为它干扰了Maven确定依赖关系的机制。

那就是说 - 如果你必须这样做,那么阴影插件就是你的家伙。

注意:仅仅因为这不包括许可证并不意味着这是一个好主意 - 这是为了避免在超级罐中出现重复的文件名问题。

请参阅MKYong的this有趣博客,了解使用assembly/shade/one-jar的优缺点。