spring boot项目fat jar瘦身的实现

一、项目背景

spring cloud构建spring boot项目,精细化各项目的层次,达到降低耦合度的目的,项目间基于restful通信。

在对项目打包过程中,使用spring-boot-maven-plugin插件打包,生成的是fat jar,解压该jar包,会发现项目依赖的jar包存放于BOOT-INF下的lib文件夹中,分析多个子项目后会发现,相同的jar包占绝大多数,然后每次部署于线上环境,各系统的共同jar在服务器上其实是重复搁置的,因此自然会想到是否有方法将共同的jar包,或是不经常改动的jar包,抽离出来,整理出单独的一份,然后由各子项目启动时使用外部加载,达到fat jar瘦身的目的。

二、fat jar瘦身

经过以上分析,及查阅相关资料,整理出以下步骤进行jar包瘦身:

1.各项目配置spring-boot-maven-plugin插件(官方文档),生成fat jar中留存的jar包 

      <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
        <configuration>
          <layout>ZIP</layout>
          <!-- <excludeGroupIds>
            org.springframework.boot,
            org.springframework.cloud,
            org.mybatis.spring.boot,
            tk.mybatis,
            mysql,
            com.alibaba,
            javax.persistence,
            io.springfox,
            org.springframework.session
          </excludeGroupIds> -->
          <includes>
            <include>
              <groupId>xx</groupId>
              <artifactId>xx</artifactId>
            </include>
            <include>
              <groupId>xx</groupId>
              <artifactId>xx</artifactId>
            </include>
          </includes>
        </configuration>
      </plugin>

如以上代码,可以使用excludeGroupIds,或者includes,或其他标签,具体看情况。

2.在项目依赖jar中抽离出不想存放于fat jar的jar包。

方法一(推荐):在项目pom文件中添加maven依赖插件(官方文档

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-dependency-plugin</artifactId>
        <version>3.1.1</version>
        <executions>
          <execution>
            <id>copy-dependencies</id>
            <phase>package</phase>
            <goals>
              <goal>copy-dependencies</goal>
            </goals>
            <configuration>
              <!-- <outputDirectory>E:/lib</outputDirectory> -->
              <excludeGroupIds>
                <!-- 留存于fat jar中的jar包的groupId属性值(多个,分隔)-->
              </excludeGroupIds>
              <overWriteSnapshots>true</overWriteSnapshots>
            </configuration>
          </execution>
        </executions>
      </plugin>

标签具体含义查看官方文档。

使用maven对项目进行打包时,使用maven命令:

mvn clean install -Dmaven.test.skip=true -DoutputDirectory=E:/lib(-DoutputDirectory=E:/lib是命令动态指定项目依赖的jar包导出的路径,若在项目中指定了outputDirectory的标签值,则将覆盖此动态路径)

配置插件执行此命令后,项目中除excludeGroupIds标签中配置的jar包外,其余都将导入到指定目录中,至此完成抽离fat jar中多余的jar包。

方法二:项目中不添加maven依赖插件,直接在对项目使用mvn复制依赖jar包的命令,这种方式需要挨个对各个子项目进行依赖复制,子项目少可以使用。

mvn dependency:copy-dependencies -DoutputDirectory=E:/lib(若无动态指定目录,默认在项目的target路径下生成dependency目录)

将各项目导出的依赖jar包,统一放入一个文件夹中,去除重复,并删除fat jar中预留存的依赖jar包,至此完成抽离fat jar中多余的jar包。

3.将抽离出的jar包,放置服务器某一路径下,配置项目启动脚本,进行外部加载。

nohup java -Dloader.path="xx/lib" -jar xx.jar

-Dloader.path即外部加载地址。

至此瘦身完毕,可以在项目打包后的jar包看到,BOOT-INF下的lib中,仅有所需的jar包,大大减少了fat jar的大小。

pom的配置可以通用于微服务体系中,形成统一的配置,各个项目中的jar包依赖关系视具体情况更改。

三、遇到的问题及解决办法

在瘦身过程中,并不是一帆风顺的,当我认为大功告成,启动项目时,发现启动失败,jar冲突。

1.解决jar包冲突,通过mvn命令分析jar包的依赖关系,并找到冲突jar包,并统一版本。

在eclipse中,创建新Maven Build,一开始我尝试了mvn dependency:tree,整体分析一遍jar包依赖,但并没有找到问题jar包的依赖关系,接着我尝试了mvn dependency:tree -Dverbose,将所有间接的隐性的依赖也分析了一遍仍未找到问题jar包的依赖关系。

至此,我怀疑项目中没有这个jar包,反复打包后,我看到,此问题jar包的确在项目依赖中,只是隐藏的太深。于是,只能针对单个jar包进行分析:

mvn dependency:tree -Dverbose -Dincludes=xx:xx:xx(xx:xx:xx对应jar包的groupId:artifactId:version)

使用Dincludes后,找到了对应jar包的依赖关系,并在项目中排除了该jar包,再次打包后项目启动成功,问题解决。

2.打包过程中,一些细分的子项目,并未使用spring-boot-maven-plugin插件,而是使用maven-jar-plugin直接打包成一个可运行jar,再结合了fat jar瘦身配置后发现,原本可以依赖互通的jar,现在失效了。由于fat jar瘦身后的lib中,仅剩代码经常改动的项目的jar,依赖关系在可运行jar中,并未传递,因此需要在本项目中显性依赖所需的项目的jar包,才能保证项目的完整。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 详解SpringBoot迭代发布JAR瘦身配置

    默认情况下,插件 spring-boot-maven-plugin 会把整个项目打包成一个可运行的Jar包(即所谓的Flat Jar),导致了这个Jar包很大(通常有几十M+).如今迭代发布时常有的事情,每次都上传一个如此庞大的文件,会浪费很多时间,有些时候上传的过程中还会出错. 造成Jar包很大的根本原因就是依赖第三方的jar很多,很大,下面我们就把第三方的JAR与项目代码分离,第三方的JAR把移除到lib文件夹中,即可实现为我们的可执行JAR瘦身,配置如下: <plugins> <!

  • spring boot项目fat jar瘦身的实现

    一.项目背景 spring cloud构建spring boot项目,精细化各项目的层次,达到降低耦合度的目的,项目间基于restful通信. 在对项目打包过程中,使用spring-boot-maven-plugin插件打包,生成的是fat jar,解压该jar包,会发现项目依赖的jar包存放于BOOT-INF下的lib文件夹中,分析多个子项目后会发现,相同的jar包占绝大多数,然后每次部署于线上环境,各系统的共同jar在服务器上其实是重复搁置的,因此自然会想到是否有方法将共同的jar包,或是不

  • Spring Boot项目中jar包在服务器上启动的正确姿势

    关于 一般上来说,我们在服务器上启动一个jar,最简单的方式就是java -jar xx.jar,虽然这种方式简单但有时候我们的场景需要更多,例如常驻后台运行,在命令行窗口关闭的时候不中断项目,指定端口,并且输出日志到文件中等.所以这个时候我们通常会采用脚本启动和关闭项目,方便项目的统一管理. 脚本启动和关闭的案例 1.启动脚本 nohup java -jar ../webapp/xxx.jar --server.port=9002 >> ../logs/xxx.log & tail

  • Spring Boot 直接用jar运行项目的方法

    概述 在 Spring Boot 开篇-创建和运行 一文中,介绍了如何创建一个Sprint Boot项目并且运行起来.但是运行的方式是在IDEA中直接Run起来的.还有另一中方式可以可以把Spring Boot程序运行起来,就是直接在命令行中执行jar包. 打成jar包 以往的WEB程序需要打成WAR包,部署到Tomcat上,而Spring Boot支持打包成JAR的形式,就算是JAR里面包含图片.页面等,也是支持的.另外使用JAR包的方式也方便部署到Docker上. 要想把Spring Boo

  • Spring boot项目打包成jar运行的二种方法

    前言 最近公司有个项目需要移植到SpringBoot框架上,项目里面又有许多第三方jar包,在linux服务器上最方便的就是用jar的方式来运行SpringBoot项目了,因此我研究了2种打jar包的方式,记录如下,供大家参考: 1.通过maven插件,将所有依赖包都打包成一个jar包,然后通过java -jar xxx.jar方式运行 由于项目中有些jar包是第三方的,maven官方仓库没有,需要使用mvn install命令打包到本地,然后将其写入到pom.xml的依赖中,maven仓库有的

  • Spring Boot项目添加外部Jar包以及配置多数据源的完整步骤

    前言 最近项目需要和Oracle数据库进行交互,然后我从Maven中央仓库下载数据库驱动jar包,但怎么都下不下来,我到Oracle官网上一看,我去,居然不让用Maven直接下(大学时候用过Oracle,很久远的事情了0rz),没办法我还是直接下载jar包放到我的项目里面吧.SpringBoot项目引入外部jar包是非常方便的,包含打引入外部jar等操作. 我的做法如下: 首先在src同级目录建一个lib文件夹,将第三方jar包放到这个文件内,比如我将ojdbc6.jar 这个jar包放到这个地

  • spring boot 部署为jar包的方法示例

    前言 一直在ide中敲代码,使用命令行 mvn spring-boot:run 或者 gradlew bootRun 来运行spring boot项目.想来放到prod上面也应该很简单.然而今天试了下,各种问题.最大错误是1.4的bug: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jp

  • Spring Boot 的java -jar命令启动原理详解

    导语 在运用Spring Boot 后,我们基本上摆脱之前项目每次上线的时候把项目打成war包.当然也不排除一些奇葩的规定,必须要用war包上线,不过很多时候,我们对一些东西只是处在使用的阶段,并不会去深入的研究使用的原理是什么,这貌似也是大多数人的固定思维. 或许正是如此,总会有些没有固定思维的人会去积极的探索原理,当然这话不是说我是积极的,我其实也是只原理的搬运工.今天和大家来简单的说下Spring Boot 的项目在运行Java -jar的原理. jar包目录和jar命令启动入口 在正式开

  • Spring Boot打包war jar 部署tomcat

    概述 1.Spring Boot聚合工程打包war部署Tomcat 2.Spring Boot打包Jar,通过Java -jar直接运行. 3.提供完整pom.xml测试项目 至github 解决问题 1.xxxx中没有主清单属性 2.解决没有web.xml而报错 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-war-plugin:2.2:war (default-war) on project provider: E

  • 把spring boot项目发布tomcat容器(包含发布到tomcat6的方法)

    spring boot因为内嵌tomcat容器,所以可以通过打包为jar包的方法将项目发布,但是如何将spring boot项目打包成可发布到tomcat中的war包项目呢? 1. 既然需要打包成war包项目,首先需要在pom.xml文件中修改打包类型,将spring boot默认的<packaging>jar</packaging>修改为<packaging>war</packaging>形式: 2. 其次spring boot的web项目中内嵌tomca

随机推荐