项目背景

采用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包(可以被其他项目引用)。

更多推荐

spring boot不用parent引入,采用dependencyManagement引入后的坑