在发布项目的时候有可能会有这样的要求,一个jar包中即包含自研的代码,也包含依赖的库(例如log4j的jar包之后的),maven打包的时候有两种方法可以实现这种要求。
使用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文件的目录)
将依赖的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包内,在jar包中的lib中都是依赖的包。配置区别就是拷贝依赖包的位置有变化,见上面红色部分
jar包解压之后如下图所示
3,这种方式目前测试中发现一个不太好的地方,就是会把scope为test的包也拷贝到jar包中,虽然对功能无影响,但是会增加整个jar包的大小,并且增加了无用的jar包,如下图中的junit,目前还没找到原因,找到原因之后再增加相关内容(有知道的兄弟也可告知一下,谢谢:))。
转载于:https://blog.csdn.net/ITsenlin/article/details/51419639
方法三:
现有项目的目录结构是,在lib中包含了依赖的jar包和自己代码的jar包,生成的lib文件夹下放该项目的所有依赖以及该服务jar包.通过编写.sh文件。java -*.jar来启动文件。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>assembly.xml</descriptor>
</descriptors>
<appendAssemblyId>false</appendAssemblyId>
<outputDirectory>
${user.dir}${file.separator}build${file.separator}release${file.separator}pro
</outputDirectory>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
最关键的是这个assembly.xml文件。
下面参考相同打包依赖的方式:
二、配置步骤及其他事项
1.首先我们需要在pom.xml中配置maven的assembly插件
1 <build>
2 <plugins>
3 <plugin>
4 <groupId>org.apache.maven.plugins</groupId>
5 <artifactId>maven-jar-plugin</artifactId>
6 <version>2.3.1</version>
7 <configuration>
8 <archive>
9 <manifest>
10 <!--运行jar包时运行的主类,要求类全名-->
11 <mainClass>com.hafiz.Runner</mainClass>
12 <!-- 是否指定项目classpath下的依赖 -->
13 <addClasspath>true</addClasspath>
14 <!-- 指定依赖的时候声明前缀 -->
15 <classpathPrefix>./</classpathPrefix>
16 </manifest>
17 </archive>
18 </configuration>
19 </plugin>
20 <plugin>
21 <groupId>org.apache.maven.plugins</groupId>
22 <artifactId>maven-assembly-plugin</artifactId>
23 <executions>
24 <execution><!-- 配置执行器 -->
25 <id>make-assembly</id>
26 <phase>package</phase><!-- 绑定到package生命周期阶段上 -->
27 <goals>
28 <goal>single</goal><!-- 只运行一次 -->
29 </goals>
30 <configuration>
31 <finalName>${project.name}</finalName>
32 <descriptor>src/main/assembly/assembly.xml</descriptor><!--配置描述文件路径-->
33 </configuration>
34 </execution>
35 </executions>
36 </plugin>
37 </plugins>
38 </build>
2.接着我们在src/main/assembly文件中配置assembly.xml文件
1 <assembly>
2 <id></id>
3 <formats>
4 <format>tar.gz</format><!--打包的文件格式,也可以有:war zip-->
5 </formats>
6 <!--tar.gz压缩包下是否生成和项目名相同的根目录-->
7 <includeBaseDirectory>true</includeBaseDirectory>
8 <dependencySets>
9 <dependencySet>
10 <!--是否把本项目添加到依赖文件夹下-->
11 <useProjectArtifact>true</useProjectArtifact>
12 <outputDirectory>lib</outputDirectory>
13 <!--将scope为runtime的依赖包打包-->
14 <scope>runtime</scope>
15 </dependencySet>
16 </dependencySets>
17 <fileSets>
18 <fileSet>
19 <directory>src/main/bin</directory>
20 <outputDirectory>/</outputDirectory>
21 </fileSet>
22 </fileSets>
23 </assembly>
其中,生成的lib文件夹下放该项目的所有依赖以及该服务jar包,src/main/bin文件夹下我们一般放start.sh和stop.sh两个脚本文件用来开启和关闭该服务,打包后直接放到根目录下。生成的tar.gz文件的名字为:[maven-assembly-plugin插件中配置的finalName]-[assembly.xml配置的id(若assembly中没有指定id,则只有前半部分)].
assembly的具体语法,请参见官网:http://maven.apache.org/plugins/maven-assembly-plugin/assembly.html
这里面涉及到如何生成可执行的jar包,具体参见:用Maven快速生成带有依赖的可执行jar包
3.项目目录结构
其中红色方框内就是通过assembly插件是生成的tar.gz文件,解压后里面的结构如下:
其中lib目录下是本项目生成的可执行jar包以及它的所有依赖jar包。若assembly插件中配置<useProjectArtifact>为false,则不会生成assembly-demo文件夹,直接就是lib文件夹以及两个脚本文件。
代码Github地址:https://github.com/hafizzhang/assembly-demo.git
4.打包方式思考
我们通过这种方式,每个微服务就是一个以服务名称命名的tar.gz文件,解压后里面lib目录下是该服务生成的可执行jar包以及它所有的依赖jar包,我们直接运行根目录下start.sh和stop.sh两个脚本文件来进行服务的开启和关闭。风格统一,简单明了!