项目背景
采用IDEA+Maven+Spring boot+Spring Cloud搭建了以微服务为框架的系统。由于各个子项目需要继承自己写的父pom,于是把原本spring boot的parent去掉,改为用dependencyManagement引入,代码如下:
//去掉原本的parent
<!--<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath/>
</parent>-->
//添加新的parent
<parent>
<groupId>xxx</groupId>
<artifactId>xxx</artifactId>
<version>xxx</version>
</parent>
//引入dependencyManagement
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.0.4.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
坑一:子项目启动报错:java.lang.NoSuchMethodError
问题描述:
修改完子项目的pom之后,启动报错:Caused by: java.lang.NoSuchMethodError:org.springframework.web.accept.ContentNegotiationManagerFactoryBean.build()Lorg/springframework/web/accept/ContentNegotiationManager;
原因分析:
经过排查发现,原来新引入的父pom里引用了4.3版本的spring web依赖,导致原本spring boot web里面的spring web依赖版本从5.0.8降到了4.3,所以报错。
解决方法:
把父pom里面的spring web依赖version升级到5.0.8,问题解决。
总结:
凡是涉及到maven依赖继承需要注意版本是否冲突,不仅是父子之间的关系,当继承多个父pom时需要特别注意这些父pom里面有没有重复的不同版本的依赖。
坑二:打包后运行java -jar命令,报错:没有主清单属性
问题描述:
通过maven命令打包成可执行jar包后,用java -jar命令运行报错:没有主清单属性。
原因分析:
查看该jar包内容,发现被打包成了普通jar包,而不是可执行的jar的目录结构。原来采用dependencyManagement方式引用后,spring-boot-maven-plugin插件缺少了配置,导致不能生成正确的可执行jar。
原来的代码:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.0.4.RELEASE</version>
</plugin>
</plugins>
</build>
解决方法:
往spring-boot-maven-plugin插件添加以下属性
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.0.4.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
加上executions后,打包时会产生可执行的jar包和original后缀的文件,这个original后缀的文件就是普通jar包加上original的后缀,去掉.original后能得到普通jar包(可以被其他项目引用)。