maven打包所有依赖成一个jar包发布

Dec 23, 2017 • kael


前言

在使用maven构建多模块工程的时候,有些模块会打成jar包,有时候我们会依赖一些没有发布在maven仓库的第三方jar包,这个时候 打包就会比较麻烦了,因为其他使用这个模块的包不一定能找到这些没有发布在maven仓库的第三方jar包,当然我们可以将这些包发布到 本地仓库,不过这不利于多人协作开发,最好的方式还是将这些第三方jar包直接打包到这个模块中一起发布。

依赖配置

要依赖没有发布到maven仓库的jar包,一般使用如下配置:

<dependency>
    <groupId>dk.depencency</groupId>
    <artifactId>jradius-dictionary</artifactId>
    <!-- jar包所在目录 -->
    <systemPath>${project.basedir}/src/lib/jradius-dictionary.jar</systemPath>
    <!-- jar包的scope -->
    <scope>system</scope>
    <version>${project.version}</version>
</dependency>

这里scope为system的时候必须指定systemPath

按照以上配置配置好之后,就可以正常编译开发了。

打包配置

按照依赖配置完成之后,打包发布的时候只能打包我们编写的源码,不会将依赖一起打包,现在我们需要配置打包的时候将依赖一起打 包到jar包中。

<build>
    <plugins>
        <!-- 打包插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.4</version>
            <executions>
                <execution>
                    <id>make-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <descriptors>
                    <!-- 打包配置:必须在对应目录下创建repack.xml的打包配置文件 -->
                    <descriptor>src/main/resources/assemblies/repack.xml</descriptor>
                </descriptors>
            </configuration>
        </plugin>
        <!-- install插件,定制在mvn install过程使用哪个jar包安装到本地 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-install-plugin</artifactId>
            <version>2.5.2</version>
            <executions>
                <execution>
                    <id>install-file</id>
                    <goals>
                        <goal>install-file</goal>
                    </goals>
                    <phase>install</phase>
                </execution>
            </executions>
            <configuration>
                <!-- install配置,指定将哪个目录下的jar包install为这个工程的jar -->
                <file>${project.build.directory}/${project.build.finalName}-repack.jar</file>
                <!-- 
                install配置,指定将install的jar打包使用的pom.xml文件,
                即其他依赖这个jar包的工程按照哪个pom.xml文件来解析依赖 
                -->
                <pomFile>src/main/resources/install-pom.xml</pomFile>
            </configuration>
        </plugin>
        <!-- deploy插件,定制在mvn deploy过程使用哪个jar包发布到仓库 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-deploy-plugin</artifactId>
            <version>2.8.2</version>
            <executions>
                <execution>
                    <id>deploy-file</id>
                    <goals>
                        <goal>deploy-file</goal>
                    </goals>
                    <!-- 跳过默认的发布包 -->
                    <phase>none</phase>
                </execution>
            </executions>
            <configuration>
                <!-- deploy配置,指定将哪个目录下的jar包发布为这个工程的jar -->
                <file>${project.build.directory}/${project.build.finalName}-repack.jar</file>
                <!-- 发布地址 -->
                <url>${maven仓库的地址}</url>
                <repositoryId>maven-repository-snapshots</repositoryId>
                <groupId>${project.groupId}</groupId>
                <artifactId>${project.artifactId}</artifactId>
                <version>${project.version}</version>
                <packaging>jar</packaging>
                <!-- 
                deploy配置,指定将deploy的jar打包使用的pom.xml文件,
                即其他依赖这个jar包的工程按照哪个pom.xml文件来解析依赖 
                -->
                <pomFile>src/main/resources/install-pom.xml</pomFile>
            </configuration>
        </plugin>
    </plugins>
</build>

以上配置完成之后,在mvn installmvn deploy的过程会进行如下处理:

  • 解析所有依赖,编译打包成{artifactId}-{version}.jar包
  • 解压指定依赖的jar包和编译打包后的{artifactId}-{version}.jar包,按照repack.xml的配置重新打包成{artifactId}-{version}-repack.jar包,并将install-pom.xml作为这个jar包的依赖配置
  • 将{artifactId}-{version}-repack.jar安装到本地仓库或者发布到maven仓库

现在我们看一下repack.xml的配置:

<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
    <id>repack</id>
    <formats>
        <format>jar</format>
    </formats>
    
    <includeBaseDirectory>false</includeBaseDirectory>
    <dependencySets>
        <dependencySet>
            <!-- 
            重新打包需要包含的jar包,这个过程会解压所有的jar包并按照jar的规则重新组合成一个jar包
            这里需要包含当前这个工程 ,格式是{groupId}:{artifactId}
            -->
            <includes>
                <!-- 包含项目自己 -->
                <include>kael.demo:include-dependencies</include>
                <include>dk.depencency:jradius-dictionary</include>
            </includes>
            <!-- 打包结果目录:/ 表示target/ -->
            <outputDirectory>/</outputDirectory>
            <!-- 是否解压依赖 -->
            <unpack>true</unpack>
            <!-- 打包的scope -->
            <scope>system</scope>
        </dependencySet>
    </dependencySets>
</assembly>

repack.xml的配置表示如何打包这个jar,这里配置了需要先解压kael.demo:include-dependencies这个项目的打包结果和dk.depencency:jradius-dictionary这个依赖的jar包,并重新合并打包成jar包,打包后的jar包名为工程原本的jar包名加上-{id}这个后缀。

再看install-pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
		 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <groupId>kael.demo</groupId>
    <artifactId>include-dependencies</artifactId>
    <version>1.0.0-SNAPSHOT</version>
	<modelVersion>4.0.0</modelVersion>
	<packaging>jar</packaging>
	<dependencies>
		<dependency>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging-api</artifactId>
			<version>1.1</version>
		</dependency>
		<dependency>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
			<version>1.1.3</version>
		</dependency>
	</dependencies>
</project>

一般为项目原始的pom.xml文件,去掉scope为system的依赖(即在repack.xml中已经配置合并的相应依赖)和maven-assembly-plugin,maven-install-plugin,maven-deploy-plugin 这几个插件即可。