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

Mah*_*leh 95 java build-process jar classloader maven

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

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

我希望我的最终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>
Run Code Online (Sandbox Code Playgroud)

该项目从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.
Run Code Online (Sandbox Code Playgroud)

我该如何解决这个异常?

gmo*_*ode 77

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

<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>
Run Code Online (Sandbox Code Playgroud)

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

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

或者,为了避免自定义类加载,您可以使用"$ {project.build.directory}/lib,但在这种情况下,您在最终的JAR文件中没有依赖项,这会使目的失败.

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

  • 在将“ $ {project.build.directory} / classes / lib”更改为$ {project.build.directory} / lib后,此方法起作用了 (2认同)
  • 不幸的是,包括所提供的声明的依赖项。 (2认同)

Ahm*_*aya 27

更新:

<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> 
Run Code Online (Sandbox Code Playgroud)

  • 这将lib文件夹放在jar之外(这不是我想要的).比将lib放入jar中更好吗?以及在这种情况下如何将应用程序交付给客户端? (2认同)

And*_*sov 23

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

          <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>
Run Code Online (Sandbox Code Playgroud)

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

  • 我不希望我的jar文件看起来像这样,我希望将所有依赖项放在jar文件中的lib文件夹中,就像netbean一样. (15认同)

Cyb*_*ran 12

可执行打包机Maven插件可以用来正是出于这个目的:创建包含特定文件夹中的所有依赖关系的JAR文件独立的Java应用程序.

只需将以下内容添加到您的pom.xml内部<build><plugins>(请务必替换相应的值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>
Run Code Online (Sandbox Code Playgroud)

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

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


Mah*_*leh 5

点击此链接:

如何:Eclipse Maven安装带有依赖项的构建jar

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