首页 文章

如何使用Maven将所有必需的JAR文件放在最终JAR文件中的库文件夹中?

提问于
浏览
88

我在我的独立应用程序中使用Maven,并且我想将我的JAR文件中的所有依赖项打包到库文件夹中,如下面的答案中所述:

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

我希望我的最终JAR文件有一个库文件夹,其中包含作为JAR文件的依赖项,而不像 maven-shade-plugin 将依赖项放在.m2文件夹中的Maven层次结构等文件夹形式中 .

好吧,实际上当前的配置做了我想要的,但是我在运行应用程序时加载JAR文件时遇到了问题 . 我无法加载这些类 .

这是我的配置:

<plugins>

    <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}/classes/lib</outputDirectory>
                    <overWriteReleases>false</overWriteReleases>
                    <overWriteSnapshots>false</overWriteSnapshots>
                    <overWriteIfNewer>true</overWriteIfNewer>
                </configuration>
            </execution>
        </executions>
    </plugin>

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
            <archive>
                <manifest>
                    <addClasspath>true</addClasspath>
                    <classpathPrefix>lib/</classpathPrefix>
                    <mainClass>com.myapp.MainClass</mainClass>
                </manifest>
            </archive>
        </configuration>
    </plugin>

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

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <executions>
            <execution>
                <id>install</id>
                <phase>install</phase>
                <goals>
                    <goal>sources</goal>
                </goals>
            </execution>
        </executions>
    </plugin>

    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-resources-plugin</artifactId>
        <version>2.5</version>
        <configuration>
            <encoding>UTF-8</encoding>
        </configuration>
    </plugin>

</plugins>

该项目从Eclipse运行良好,JAR文件根据我的需要放在我最终的JAR文件中的库文件夹中,但是当从目标文件夹运行最终的JAR文件时,我总是得到 ClassNotFoundException

Exception in thread "main" java.lang.NoClassDefFoundError: org/springframework/context/ApplicationContext
Caused by: java.lang.ClassNotFoundException: org.springframework.context.ApplicationContext
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
Could not find the main class: com.myapp.MainClass. Program will exit.

我该如何解决这个异常?

8 回答

  • 6

    以下是我的解决方案 . 测试它是否适合您:

    <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}/classes/lib</outputDirectory>
                    <overWriteReleases>false</overWriteReleases>
                    <overWriteSnapshots>false</overWriteSnapshots>
                    <overWriteIfNewer>true</overWriteIfNewer>
                </configuration>
            </execution>
        </executions>
    </plugin>
    
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-jar-plugin</artifactId>
        <configuration>
            <archive>
                <manifest>
                    <addClasspath>true</addClasspath>
                    <!-- <classpathPrefix>lib</classpathPrefix> -->
                    <!-- <mainClass>test.org.Cliente</mainClass> -->
                </manifest>
                <manifestEntries>
                    <Class-Path>lib/</Class-Path>
                </manifestEntries>
            </archive>
        </configuration>
    </plugin>
    

    第一个插件将所有依赖项放在target / classes / lib文件夹中,第二个插件包含最终JAR文件中的库文件夹,并配置 Manifest.mf 文件 .

    但是,您需要添加自定义类加载代码来加载JAR文件 .

    或者,为了避免自定义类加载,您可以使用“$ / lib,但在这种情况下,您在最终的JAR文件中没有依赖项,这会破坏目的 .

    问题被问到已经两年了 . 尽管如此,嵌套JAR文件的问题仍然存在 . 我希望它对某人有所帮助 .

  • 25

    更新:

    <build> 
      <plugins> 
        <plugin> 
        <artifactId>maven-dependency-plugin</artifactId> 
        <executions> 
          <execution> 
            <phase>install</phase> 
              <goals> 
                <goal>copy-dependencies</goal> 
              </goals> 
              <configuration> 
                 <outputDirectory>${project.build.directory}/lib</outputDirectory> 
              </configuration> 
            </execution> 
          </executions> 
        </plugin> 
      </plugins> 
    </build>
    
  • 12

    最简单,最有效的方法是使用这样的超级插件:

    <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <finalName>uber-${artifactId}-${version}</finalName>
                </configuration>
            </plugin>
    

    您将在一个JAR文件中对所有内容进行反规范化 .

  • 3

    executable packer maven plugin可用于此目的:创建包含所有依赖项的独立Java应用程序作为特定文件夹中的JAR文件 .

    只需将以下内容添加到 <build><plugins> 部分内的 pom.xml (确保相应地替换 mainClass 的值):

    <plugin>
        <groupId>de.ntcomputer</groupId>
        <artifactId>executable-packer-maven-plugin</artifactId>
        <version>1.0.1</version>
        <configuration>
            <mainClass>com.example.MyMainClass</mainClass>
        </configuration>
        <executions>
            <execution>
                <goals>
                    <goal>pack-executable-jar</goal>
                </goals>
            </execution>
        </executions>
    </plugin>
    

    运行 mvn package 后,生成的JAR文件位于 target/<YourProjectAndVersion>-pkg.jar . 它的所有编译时和运行时依赖项都将包含在JAR文件中的 lib/ 文件夹中 .

    免责声明:我是该插件的作者 .

  • 1

    点击此链接:

    How To: Eclipse Maven install build jar with dependencies

    我发现这不是可行的解决方案,因为类加载器不会从jar中加载jar,所以我认为我将解压缩jar中的依赖项 .

  • 69

    我是这样做的:

    <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <appendAssemblyId>false</appendAssemblyId>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <manifest>
                            <mainClass>com.project.MainClass</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
    

    然后我就跑了:

    mvn assembly:assembly
    
  • 22

    我找到了这个问题的答案:

    http://padcom13.blogspot.co.uk/2011/10/creating-standalone-applications-with.html

    您不仅可以在lib文件夹中获取依赖的lib文件,还可以获得具有unix和dos可执行文件的bin控制器 .

    可执行文件最终使用-cp参数调用java,该参数列出了所有从属库 .

    整个批次位于目标文件夹内的appasembly文件夹中 . 史诗 .

    =============是的我知道这是一个老线程,但它仍然在搜索结果上很高,所以我认为它可能会帮助像我这样的人 .

  • 0

    这显然是一个类路径问题 . 考虑到在IDE外部运行程序时类路径必须稍微改变一下 . 这是因为IDE相对于项目的根文件夹加载其他JAR,而在最终JAR的情况下,这通常不正确 .

    在这些情况下我喜欢做的是手动构建JAR . 它花了我最多5分钟,它总能解决问题 . 我不建议你这样做 . 找到一种使用Maven的方法,这就是它的目的 .

相关问题