聚合maven+spring-boot打包可执行jar

星辰      2022-04-16     661

关键词:

整整搞了一天,终于解决这个问题了。这里是四个module,module之间存在依赖,打包两个可执行jar,看下最终效果吧

          聚合maven+spring-boot的搭建很简单,和普通的聚合maven没有什么区别。聚合maven+spring-boot打包成可执行jar就不是那么容易了,主要是因为spring-boot的坑有点多啊。普通聚合maven打包我就不说了。就说说和spring-boot一起打包的那些比较大的坑吧。

         一、spring-boot-maven-plugin打包出来的jar是不可依赖的

         比如我有一个root工程,type为pom,下面两个spring-boot工程作为它的module,分别为moduleA和moduleB。假如moduleA依赖于moduleB。如果你在moduleB中使用了spring-boot-maven-plugin的默认配置build,或者在root中使用spring-boot-maven-plugin的默认配置build。很遗憾,你在clean package的时候会发现moduleA找不到moduleB中的类。原因就是默认打包出来的jar是不可依赖的。

         解决方案:

        1、调整你的代码,把spring-boot的东西从moduleB中移走。官方文档是这样说的,但是大部分人不会

              这么干吧。

        2、官方告诉我们,你如果不想移代码,好吧,我这样来给你解决,给你打两个jar包,一个用来直接执

              行,一个用来依赖。于是,你需要指定一个属性classifier,这个属性为可执行jar包的名字后缀。比

              如我设置<classifier>exec</classifier>,原项目名为Vehicle-business。

              那么我会得到两个jar:Vehicle-business.jar和Vehicle-bussiness-exec.jar

         官方文档位置:84.5 Use a Spring Boot application as a dependency

         总结:回到聚合maven上,如果你在root工程中使用了spring-boot-maven-plugin作为builder,那么你的依赖module一定要用解决方案二来设置。否则你不在root工程中用spring-boot-maven-plugin作为builder,而在需要打包的module上使用。

         二、jdk8一定要指明

         不指明的话在开发工具里运行没有一点问题,如果你没有用到java8的特性打包也没有问题。一旦你用到了java8的特性,而且使用spring-boot-maven-plugin作为builder,一定要指明jdk版本。不然你会收到类似不识别Lambda,请使用resource8这样的错误。

 <properties>
    <java.version>1.8</java.version>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

     三、BOOT-INF陷阱
          这个问题就很恶心了。这个时候你已经打包成功,你会发现运行jar的时候报错为file not found,而且不告诉你是什么文件。你打开jar去看,发现需要的lib,配置文件,class一样也不缺。

          其实这里要说一个概念,spring-boot在打包后,会把文件拷贝到BOOT-INF/Classes之下,这个时候你原来定义的扫描包路径将失效。而这个问题官方文档根本没讲,还是我没有看到。

          这个陷阱在你使用packages定义扫描路径的时候等着你。或者获取工程下文件的时候。对于获取文件的话,可以在原路径前加上classes,当然你要区分开发环境或生产环境的话,你可以使用profile或者conditional来解决。如果是扫描包路径就恶心了,因为你加上classes之后,不报file not found了。而是不报错,只是警告你找不到hibernate的某些xml。但是你很可能根本没有使用hibernate。

          目前我的解法是使用register方法代替packages方法,但是问题就是,如果你的类很多,那将是一件痛苦的事情。还好我这里只需要配置两个基于jersey的公共类。

          顺便吐槽一下官方文档在配置jersey的时候根本没有提到packages方法,自然也就把这个BOOT-INF陷阱给忽略了。官方关于jersey的配置章节为27.2 JAX-RS and Jersey

最后、举个例子。

          假设工程结构如下

          parent

                 moduleA

                 moduleB

                 moduleC

          其中moduleB被moduleA依赖,A使用jersey,moduleA和moduleC需要打包为可执行jar

          那么我们有两种方式聚合

         方式一 在parent中指定spring-boot-maven-plugin

         parent的pom.xml中的builder

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
             <configuration>
                  <source>1.8</source>
                  <target>1.8</target>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
  </build>

           moduleB的pom.xml中的builder

 <build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <classifier>exec</classifier>
            </configuration>
        </plugin>
    </plugins>
</build>

  其余工程不需要builder

 方法二

             parent的pom.xml不提供builder

             moduleA和moduleC的pom.xml中的builder

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
             <configuration>
                  <source>1.8</source>
                  <target>1.8</target>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
  </build>

    最后,两种方法都需要把jersey配置文件中的packages方法换成register方法

public class JerseyConfig extends ResourceConfig{
    public JerseyConfig() {
       register(RequestContextFilter.class);
       //配置restful package.
       //packages("com.zs.vehicle.rpc");
       //packages("classes/com/zs/vehicle/rpc");
       register(Base.class);
       register(Route.class);
    }
}

 

maven项目用assembly打包可执行jar包

该方法只可打包非spring项目的可执行jar包,spring项目可参考:http://www.cnblogs.com/guazi/p/6789679.html1.添加maven插件:<!--MavenAssemblyPlugin--><plugin><groupId>org.apache.maven.plugins</groupId><art 查看详情

maven打包可执行jar的方法

1.修改pom.xml增加如下内容<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-jar-plugin</artifactId><version>2.4</version><configuration><ar 查看详情

maven生成打包可执行jar包

...0c;好好学习一下Maven-assembly,在此记录一下1.需求项目打包,满足以下要求:整个项目打一个Zip包下面包括应用程序、应用程序依赖的jar包、说明文档项目打的jar包可以执行不同类里的Main函数项目源码打的jar包要与依... 查看详情

Spring Boot 与 POM 打包聚合器

...使用打包模式POM时,是否可以使用SpringBootsMaven插件命令spring-boot:run?我有一个带有“主”POM的多模块maven项目,它是SpringBoot父模块的子模块。看起来像这样:<mod 查看详情

maven笔记-将本地jar包打包进可执行jar中

参考资料:http://www.cnblogs.com/richard-jing/archive/2013/01/27/Maven_localjar.html使用本地jar<dependencies><dependency><groupId>org.richard</groupId><artifactId>my-jar</artif 查看详情

java生成(可执行)jar包的全面详解说明[打包][springboot][eclipse][idea][maven][gradle][分离][可执行](代码片段)

...plerosa/p/9739007.html  得空整理了关于java开发中,所有打包方式的一个操作方法,有基于IDE的,有基于构建工具的.这里还是比较建议新手朋友尽快习惯maven和gradle等构建工具自带的打包方式.不是说逼格高,的确是因为不依赖IDE,配... 查看详情

如何在spring-boot可执行jar文件中配置java logging.properties

】如何在spring-boot可执行jar文件中配置javalogging.properties【英文标题】:Howtoconfigurejavalogging.propertiesinspring-bootexecutablejarfile【发布时间】:2016-07-0309:43:07【问题描述】:我将我的应用程序打包为spring-boot可执行jar文件。我在jar文件... 查看详情

maven项目用assembly打包可执行jar包(代码片段)

        该方法只可打包非spring项目的可执行jar包,spring项目可参考:http://www.cnblogs.com/guazi/p/6789679.html        1、添加maven插件<!--MavenAssemblyPlugin--><plugin> <groupId>org.apache.maven.plugins</groupId> <artifa... 查看详情

maven项目用assembly打包可执行jar包(代码片段)

        该方法只可打包非spring项目的可执行jar包,spring项目可参考:http://www.cnblogs.com/guazi/p/6789679.html        1、添加maven插件<!--MavenAssemblyPlugin--><plugin> <groupId>org.apache.maven.plugins</groupId> <artifa... 查看详情

如何使用 maven 创建基于 spring 的可执行 jar?

...述】:我有一个基于Maven的Spring-WS客户端项目,我想将其打包为单个jar。在eclipse中,一切运行正常。当我尝试将其打包为可执行jar时,我收到ClassNotFound异常,因为Springjar不包含 查看详情

springboot+maven多模块项目(创建依赖打包可执行jar包部署测试)完整流程

转:https://blog.csdn.net/baidu_41885330/article/details/81875395 开发环境:IDEA,         SprngBoot2.0.4,        &nbs 查看详情

javamaven打包总结(jenkins多模块编译部署)

参考技术A原文地址:JavaMaven打包总结(Jenkins多模块编译部署)依次执行了clean、resources、compile、testResources、testCompile、test、jar(打包)等7个阶段。完成了项目编译、单元测试、打包功能,但没有把打好的可执行jar包(war包或其它... 查看详情

如何使用 Maven 创建具有依赖关系的可执行 JAR?

...布时间】:2010-10-0903:27:17【问题描述】:我想将我的项目打包到单个可执行JAR中以进行分发。如何让一个Maven项目将所有依赖JAR打包到我的输出JAR中?【问题讨论】:请说明您所指的依赖插件的目标。我知道没有任何目标可以满... 查看详情

如何使用 Maven 创建具有依赖项的可执行 JAR?

...布时间】:2021-09-0402:36:59【问题描述】:我想将我的项目打包到一个可执行的JAR中进行分发。如何让一个Maven项目将所有依赖JAR打包到我的输出JAR中?【问题讨论】:请解释您所指的依赖插件的目标。我知道没有目标可以满足原... 查看详情

spring-boot构建多模块依赖工程时,maven打包异常:程序包xxx不存在

在qizhi项目改版的时候,所有代码都迁移好了,但是compile的时候报程序包*****不存在,具体到某一个类就是:找不到符号.下面这篇文章是正解http://hbxflihua.iteye.com/blog/2431537具体内容如下:===========================+===========================+========... 查看详情

maven_进阶

...打包(package)/安装(install)/发布(deploy) maven工程的拆分与聚合:拆分:为了可重用,所有将一个项目,拆分成多个模块(项目).  /  聚合:单个模块不是完整的项目,聚合在一起才是完整 查看详情

maven聚合工程

Maven聚合工程Maven聚合工程概念概述:Maven聚合工程:就是可以在一个Maven父工程中创建多个组件,这个多个组件之间可以相互依赖,实现组件的复用创建Maven聚合工程2.1创建Maven父工程Maven聚合工程的夫工程packing必须为pom创建一个ma... 查看详情

mavenmaven打包生成可执行jar文件

http://blog.csdn.net/u013177446/article/details/53944424************************************************************ maven默认打包生成的jar是不能够直接运行的,因为在jar文件的META-INF/MANIFEST.MF文中没有Main-Class一行,为了生成可执行 查看详情