项目module依赖关系maven+spring-boot打包可执行jar

原文地址:https://blog.csdn.net/guduyishuai/article/details/60968728    

很蛋疼的问题 project 存在 model 层 dao层 service层 management (项目核心业务层)

    首先 model dao service management 依赖同一个parent 的pom文件 

  dao层依赖model service 依赖于dao management 依赖service  在mangement 进行打包的同时 提示找不到 model层一些实体类 

         

          聚合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这样的错误。

        

[html]  view plain  copy
  1. <properties>  
  2.     <java.version>1.8</java.version>  
  3.     <maven.compiler.source>1.8</maven.compiler.source>  
  4.     <maven.compiler.target>1.8</maven.compiler.target>  
  5.   </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

       

[html]  view plain  copy
  1. <build>  
  2.     <plugins>  
  3.         <plugin>  
  4.             <groupId>org.springframework.boot</groupId>  
  5.             <artifactId>spring-boot-maven-plugin</artifactId>  
  6.              <configuration>  
  7.                 <source>1.8</source>  
  8.                 <target>1.8</target>  
  9.             </configuration>  
  10.             <executions>  
  11.                 <execution>  
  12.                     <goals>  
  13.                         <goal>repackage</goal>  
  14.                     </goals>  
  15.                 </execution>  
  16.             </executions>  
  17.         </plugin>  
  18.     </plugins>  
  19.   </build>  
            moduleB的pom.xml中的builder
[html]  view plain  copy
  1.  <build>  
  2.     <plugins>  
  3.         <plugin>  
  4.             <groupId>org.springframework.boot</groupId>  
  5.             <artifactId>spring-boot-maven-plugin</artifactId>  
  6.             <configuration>  
  7.                 <classifier>exec</classifier>  
  8.             </configuration>  
  9.         </plugin>  
  10.     </plugins>  
  11. </build>  
            其余工程不需要builder

            

             方法二

             parent的pom.xml不提供builder

             moduleA和moduleC的pom.xml中的builder

[html]  view plain  copy
  1. <build>  
  2.     <plugins>  
  3.         <plugin>  
  4.             <groupId>org.springframework.boot</groupId>  
  5.             <artifactId>spring-boot-maven-plugin</artifactId>  
  6.              <configuration>  
  7.                 <source>1.8</source>  
  8.                 <target>1.8</target>  
  9.             </configuration>  
  10.             <executions>  
  11.                 <execution>  
  12.                     <goals>  
  13.                         <goal>repackage</goal>  
  14.                     </goals>  
  15.                 </execution>  
  16.             </executions>  
  17.         </plugin>  
  18.     </plugins>  
  19.   </build>  
    
              最后,两种方法都需要把jersey配置文件中的packages方法换成register方法
[java]  view plain  copy
  1. public class JerseyConfig extends ResourceConfig{  
  2.     public JerseyConfig() {  
  3.        register(RequestContextFilter.class);  
  4.        //配置restful package.  
  5.        //packages("com.zs.vehicle.rpc");  
  6.        //packages("classes/com/zs/vehicle/rpc");  
  7.        register(Base.class);  
  8.        register(Route.class);  
  9.     }  
  10. }  



猜你喜欢

转载自blog.csdn.net/a15835774652/article/details/79725304