DebugEN
科技森
专注于Java开发~每天都会更新文章~
  1. 首页
  2. Java
  3. 正文

java maven项目的几种打包方式

2021年02月07日 1770点热度 0人点赞 0条评论 作者: kejisen

maven项目开发完成后,我们需要部署到线上,这时候我们希望将我们的整个项目或者单个模块打包起来,形成可以部署的包,方便我们进行部署.

最近在整理一个跟spring boot无关的项目,整个项目就是在main方法中创建了一个线程池然后开始run...;

所以这篇文章主要是用来针对类似的传统maven项目(非spring 非spring boot).

spring boot这种约定优于配置的方式用起来是真香啊!

一. 常用的几种打包方式和比较通用的demo

基本打包命令:
  • 进入单独模块并打包

    cd ${module_name} && mvn clean install -Dmaven.test.skip=true
  • 在项目中直接打包指定模块

    mvn clean install -Dmaven.test.skip=true -pl ${moudle_name} -am

    install会往本地仓库也丢一份,单纯打包 package 命令即可

常用的四种打包方式
  1. maven compiler plugin----单纯的jar

    一般maven项目基本都会配置这个plugin,用于进行项目模块的打包

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

这种打包方式只会打包当前项目的所有文件,依赖的jar包及其文件不会被打包;

  1. maven jar plugin----jar包和lib目录
   <!-- 打包jar文件时,配置manifest文件,加入lib包的jar依赖 -->
   <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-jar-plugin</artifactId>
       <version>3.1.1</version>
       <configuration>
           <classesDirectory>target/classes/</classesDirectory>
           <archive>
               <manifest>
                   <!-- 主函数的入口 -->
                   <mainClass>com.kris.TestApplication</mainClass>
                   <!-- 打包时 MANIFEST.MF文件不记录的时间戳版本 -->
                   <useUniqueVersions>false</useUniqueVersions>
                   <addClasspath>true</addClasspath>
                   <classpathPrefix>lib/</classpathPrefix>
               </manifest>
               <manifestEntries>
                   <Class-Path>.</Class-Path>
               </manifestEntries>
           </archive>
       </configuration>
   </plugin>

这种打包方式会生成一个只包含当前项目文件的jar包,依赖的jar被放置在classpathPrefix指定的文件夹中,所以启动时必须要有专门的lib文件夹来管理相关的依赖,否则无法正常启动;

需要在manifest里面指定启动类;

由于不是单独可以运行的jar,局限性较大;

  1. maven assembly plugin----项目及其依赖项打包成一个jar包
   <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-assembly-plugin</artifactId>
       <version>2.5.5</version>
       <configuration>
           <appendAssemblyId>false</appendAssemblyId>
           <descriptorRefs>
               <descriptorRef>jar-with-dependencies</descriptorRef>
           </descriptorRefs>
           <archive>
               <manifest>
                   <addClasspath>true</addClasspath>
                   <classpathPrefix>lib/</classpathPrefix>
                   <mainClass>com.kris.TestApplication</mainClass>
               </manifest>
           </archive>
       </configuration>
       <executions>
           <execution>
               <phase>package</phase>
               <goals>
                   <goal>single</goal>
               </goals>
           </execution>
       </executions>
   </plugin>

通过phase指定在打包的时候运行插件,构建成独立的jar包;

需要在manifest指定启动类,不然没办法直接启动;

  1. maven shard plugin----项目及其依赖项打包成一个jar包,并支持修改/屏蔽指定jar/class
   <plugin>
       <groupId>org.apache.maven.plugins</groupId>
       <artifactId>maven-shade-plugin</artifactId>
       <version>3.2.0</version>
       <configuration>
           <!-- put your configurations here -->
       </configuration>
       <executions>
           <execution>
               <phase>package</phase>
               <goals>
                   <goal>shade</goal>
               </goals>
               <configuration>
                   <transformers>
                       <transformer
                            implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                           <mainClass>com.kris.TestApplication</mainClass>
                       </transformer>
                   </transformers>
                   <filters>
                       <filter>
                           <artifact>org.elasticsearch:elasticsearch</artifact>
                           <excludes>
                               <exclude>org/elasticsearch/action/bulk/*
                               </exclude>
                           </excludes>
                       </filter>
                       <filter>
                           <artifact>com.kris.test:test-core
                           </artifact>
                           <includes>
                               <include>**</include>
                           </includes>
                       </filter>
                   </filters>
               </configuration>
           </execution>
       </executions>
   </plugin>

将本地模块打包成jar,指定了启动类;

通过filter中的exclude功能将elasticsearch依赖下的org/elasticsearch/action/bulk/这个包下面的所有class屏蔽掉,这样我们在本地复写的类就能出现在我们打包好的jar包中,实现替换的目标;

总结:

  • 目前大部分场景都是将本地项目及其依赖打包成一个可执行的jar包然后进行部署;

  • maven-assembly-plugin的主要局限性在于当有多个同名的class出现在不同的包的时候,他只会根据pom.xml文件中的依赖顺序添加类到jar包中,后续的同名类会被直接跳过,所以如果存在同名类,需要谨慎处理;

  • 当你需要对某些类或者库进行特殊处理时,maven-shade-plugin可以提供一些过滤等方面的配置功能,方便用户进行个性化的配置;

  • 个人踩坑记录(仅个人本地环境):

  <dependency>
      <groupId>org.elasticsearch</groupId>
      <artifactId>elasticsearch</artifactId>
      <version>6.8.1</version>
  </dependency>

我在本地要打包的模块复写了一些elasticsearch的一些代码,本地运行时是正常的,类加载顺序是本地优先;

但是使用maven-assembly-plugin进行构建时,发现打包好的jar包中复写的类都没有生效,class文件反编译出来还是elasticsearch原生代码,没有生效,经过仔细观察整个生成的过程,发现最开始maven-compiler-plugin会将本地模块打包一次,这时候是正确的,等到maven-assembly-plugin执行时,发现模块又被打包了一次,并且使用了elasticsearchjar包中的原生代码,最终导致复写的类没有生效;

后面尝试使用了maven shard plugin,发现遵循的原则时本地优先,并且通过filter这样的过滤功能可以做一些个性化的配置,用起来比较方便点.

标签: java maven 打包
最后更新:2021年03月03日

kejisen

保持饥渴的专注,追求最佳的品质

点赞
< 上一篇
下一篇 >

文章评论

取消回复
最新 热点 随机
最新 热点 随机
【原创】记录一次失败的折腾——使用jkeymaster实现的按键监听 【原创】这些年我用过的IDEA插件 【原创】在windows上使用VNC远程连接linux桌面 我在RxJava使用线程池时遇到的问题 [原创文章] Swagger生成pdf格式的接口文档 [个人翻译]Java HTTP工具类的客户端证书认证 [原创] 如何从 Git 的提交历史记录中删除大文件 [翻译] 创建一个只读的Repository接口(Spring Data) [翻译] 反射的用法——用Java调用私有方法 Java 虚拟机最多可以支持多少个线程? 排查Hibernate的慢查询日志–这是查找慢查询的最简单方法 [翻译] 使用apache poi在excel文件中插入一行数据 [翻译] 在Spring 中@EntityScan与@ComponentScan注解有什么区别 [原创] 从QQ音乐网页版扒歌词的补充说明 [原创] 介绍java maven项目的多种打包方式 原创——在Java中生成随机数 将G1垃圾回收的内存使用量减少20%(翻译) [原创] java8 lambda表达式的toMap造成的空指针异常 [原创] 在Spring Boot中使用CommandLineRunner来在启动时执行代码 [转载] Kafka 节点重启失败导致数据丢失的分析排查与解决之道
我在RxJava使用线程池时遇到的问题 【原创】在windows上使用VNC远程连接linux桌面 java maven项目的几种打包方式 [原创]javaslang(vavr.io)中Try的使用 [原创] Spring Boot使用CommandLineRunner [原创] 在spring-boot中使用querydsl Linux截图软件推荐-flameshot [原创] 在ubuntu18.04上安装chromedriver 【原创】记录一次失败的折腾——使用jkeymaster实现的按键监听 中通Elasticsearch集群运维实践 使用Spring RestTemplate压缩请求 【原创】这些年我用过的IDEA插件 [翻译] 创建一个只读的Repository接口(Spring Data) Java 虚拟机最多可以支持多少个线程? [原创] 从QQ音乐网页版扒歌词的补充说明 中通Elasticsearch集群运维实践(二)--监控告警 [原创] 介绍java maven项目的多种打包方式 如何设置Servlet的session超时时间 [原创] java8 lambda表达式的toMap造成的空指针异常 [翻译] 在Spring 中@EntityScan与@ComponentScan注解有什么区别
标签聚合
elasticsearch json java maven qq音乐 歌词 base64 linux spring springboot

COPYRIGHT © 2020 Kejisen. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS