maven学习系列7----将依赖依赖文件打包到jar中

本文介绍使用Maven打包项目时如何将自研代码与依赖库整合到同一个Jar包的方法。提供了两种方案:一是利用maven-assembly-plugin插件;二是通过配置将依赖的Jar包复制到target/classes目录下。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在发布项目的时候有可能会有这样的要求,一个jar包中即包含自研的代码,也包含依赖的库(例如log4j的jar包之后的),maven打包的时候有两种方法可以实现这种要求。

1,使用maven-assembly-plugin插件

pom.xml配置如下

         <build>
		<plugins>
			<plugin>
			    <artifactId>maven-compiler-plugin</artifactId>  
			    <configuration>  
			        <source>1.7</source>  
			        <target>1.7</target>  
			        <encoding>${project.build.sourceEncoding}</encoding>  
			    </configuration>  
			</plugin>
	        <plugin>
	           <artifactId>maven-assembly-plugin</artifactId>
		        <configuration>
		          <descriptorRefs>
		            <descriptorRef>jar-with-dependencies</descriptorRef>
		          </descriptorRefs>
		          <archive>  
                        <manifest>  
                            <mainClass>com.itsenlin.Helloworld</mainClass>
                        </manifest>
                   </archive>
		        </configuration>
		        <executions>
		          <execution>
		            <id>make-assembly</id> <!-- this is used for inheritance merges -->
		            <phase>package</phase> <!-- bind to the packaging phase -->
		            <goals>
		              <goal>single</goal>
		            </goals>
		          </execution>
		        </executions>
	        </plugin>
		</plugins>
	</build>

说明:

  • 1,assembly插件功能强大,不仅可以打jar包还可以打zip、war各种包。
  • 2,打的jar包名会以-with-dependencies结尾
  • 3,这种方式打的jar包中,是将依赖包的classes文件与本项目的classes文件放在一起打成jar包的,如下图所示(com目录是项目代码的classes文件,org目录是引入了org.apache.log4j构件的classes目录,如果依赖其他构件也有可能有其他的classes文件的目录)

                

2,将依赖的jar包拷贝到target/classes目录下

因为maven默认是将target/classes目录下所有文件打成jar包,所以我们可以配置在编译的时候将依赖的构件拷贝到target/classes目录下,注意这种方法需要配置classpath。pom.xml配置如下:

<build>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>  
            <configuration>  
                <source>1.7</source>  
                <target>1.7</target>  
                <encoding>${project.build.sourceEncoding}</encoding>  
            </configuration>  
        </plugin>
         <plugin>  
            <artifactId>maven-jar-plugin</artifactId> 
            <configuration>  
                <archive>  
                    <manifest>  
                        <!-- 告知 maven-jar-plugin添加一个 Class-Path元素到 MANIFEST.MF文件,以及在Class-Path元素中包括所有依赖项 -->  
                        <addClasspath>true</addClasspath>  
                        <!-- 所有的依赖项应该位于 lib文件夹  -->
                        <classpathPrefix>lib/</classpathPrefix>  </span>
                       <!--  当用户使用 lib命令执行JAR文件时,使用该元素定义将要执行的类名  -->
                        <mainClass>com.itsenlin.Helloworld</mainClass>
                    </manifest>
                </archive>
            </configuration>  
        </plugin>
        
        <plugin>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>prepare-package</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <!-- ${project.build.directory}为Maven内置变量,缺省为target --> 
                        <outputDirectory>${project.build.directory}/classes/lib</outputDirectory></strong></span>
                        <!-- 表示是否不包含间接依赖的包  -->
                        <excludeTransitive>false</excludeTransitive>
                        <!-- 表示复制的jar文件去掉版本信息 --> 
                        <stripVersion>true</stripVersion>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
说明:

  • 1,这种方法与不把依赖打到jar包内的配置区别就是拷贝依赖包的位置有变化,见上面红色部分
  • 2,jar包解压之后如下图所示

               

  • 3,这种方式目前测试中发现一个不太好的地方,就是会把scope为test的包也拷贝到jar包中,虽然对功能无影响,但是会增加整个jar包的大小,并且增加了无用的jar包,如下图中的junit,目前还没找到原因,找到原因之后再增加相关内容(有知道的兄弟也可告知一下,谢谢:))。

                  

参考:

http://maven.apache.org/plugins/maven-assembly-plugin/usage.html#Resources

http://blog.csdn.net/laiahu/article/details/7105277


Maven的`maven-jar-plugin`用于创建JAR,如果你想在生成的JAR含系统的(通常是库或框架提供的)依赖,你需要配置`maven-shade-plugin`来合并这些依赖。这是因为默认情况下,`maven-jar-plugin`不会将系统依赖复制到目标JAR中。 首先,在你的`pom.xml`中添加`maven-shade-plugin`: ```xml <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.4</version> <!-- 使用最新的版本 --> <executions> <execution> <phase>package</phase> <!-- 执行阶段 --> <goals> <goal>shade</goal> <!-- 将项目打成fat-jar的目标 --> </goals> <configuration> <transformers> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <mainClass>your.MainClass</mainClass> <!-- 如果有主类指定它 --> </transformer> <!-- 这里可以设置是否含system dependencies --> <transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer"> <resource>META-INF/services/*</resource> </transformer> </transformers> </configuration> </execution> </executions> </plugin> </plugins> </build> ``` 在这个配置中,`ManifestResourceTransformer`用于添加MANIFEST.MF文件,而`AppendingTransformer`则会保留`META-INF/services`目录下的内容(如果有需要)。确保你的`<mainClass>`指向正确的入口点,如果依赖是Spring Boot应用,可能还需要调整一些其他选项。 如果你确实想含所有的系统依赖,可能会遇到jar体积过大的问题,因为每个依赖都会含其所有依赖的二进制内容。这通常在构建工具允许的情况下,仅对特定依赖进行阴影处理,而不是整个项目的依赖树。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值