问题现象:
最近在工作中遇到了需要将某个项目中的子模块提取成单独项目的需求,在提取后运行项目出现报错:
java.lang.AbstractMethodError: null
问题分析:
查看报错信息,发现提示的是抽象方法错误,原因是找不到相关映射关系。
完全看不懂是什么意思,于是就上网搜了一下,发现基本都是说 springboot 和 springcloud 的版本不一致导致的问题。
于是我查看了一下依赖包,发现该子模块中并不需要用到 springcloud 依赖包,由此可知并不是这个原因。
通过测试发现,该子模块只需要引用的父模块中的一个 springboot依赖包 即可,父模块中的 springboot依赖配置 如下:
<properties>
<spring.boot.version>2.1.11.RELEASE</spring.boot.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--其他依赖-->
</dependencies>
</dependencyManagement>
子模块提取成独立项目后的 pom.xml配置 ,如下:
<properties>
<spring.boot.version>2.1.11.RELEASE</spring.boot.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--其他依赖-->
</dependencies>
</dependencyManagement>
由此可知应该是 springboot依赖 的引入 出问题了,父模块中对springboot依赖设置了:
<type>pom</type>
<scope>import</scope>
意思是:将受配置的依赖引入到子模块的pom.xml文件中去中。
所以子模块提取后不需要再这样配置,于是我将子模块提取成独立项目后的 sprinboot依赖 配置修改成:
<properties>
<spring.boot.version>2.1.11.RELEASE</spring.boot.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<!--其他依赖-->
</dependencies>
</dependencyManagement>
但还是报了相同的错误,多次尝试失败后,我想起来springboot依赖的配置好像和一般的依赖包配置是有区别的,于是就去复习了下相关资料,发现了问题:
原来当前模块(无父模块的独立项目)使用springboot依赖包时,需要用到<parent>标签并而不是放在<dependencies>标签内,于是就修改成如下配置:
<properties>
<spring.boot.version>2.1.11.RELEASE</spring.boot.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.11.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<!--其他依赖-->
</dependencies>
</dependencyManagement>
注意 <parent> 中的
<version>2.1.11.RELEASE</version>
不能写成
<version>${spring.boot.version}</version>
因为 <properties> 配置的变量无法在此处生效!
配置完成后
解决方法:
步骤:
1. 首先是将父模块(P)中的子模块(S)复制到出来,然后用IDEA打开 P项目 和 S项目,打开各自的 pom.xml 文件。
2. 注意项目的Project Settings配置问题:
2.1 SDK保证在JDK1.8以上
2.2 Language Level 一般设置为 8-Lambdas...
3.将 S项目 中原有的 <parent>......</parent> 标签(包括其中的所有子标签)删掉,让它成为独立项目。
4. 将 P项目 中的 <plugins> 中的 maven-compiler-plugin插件 复制到 S项目 中去,否则运行项目会报错如下:
5. 将 父模块(P) 中, 子模块(S) 需要引用到的的依赖 导入到 S项目的 </dependencies>标签 中去(注意不要导入springboot依赖)。
6. 在 S项目的 </dependencies>标签 外, 创建 <parent></parent>标签,然后在该标签中导入springboot 依赖,并让版本号保持与 P项目中的springboot依赖一致,如:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.11.RELEASE</version>
</parent>
<dependencies>
<!--该项目所引用的依赖包-->
</dependencies>
7. 在Maven Projects中点击 reimport(重新导入) 依赖,之后如果还看到 依赖包报红(红色下划线)的话,可重启该项目再看看。
8. 启动项目成功,并测试接口可用!
拓展延伸
这里再分享一个技能,就是在将子模块提取成独立项目之后,可能还需要将这个新的项目,提交到代码仓库去。
方式很多,这里只提一下命令:
(如果代码仓库是空库则可以执行以下命令)
1、在git窗口(电脑打开到项目根目录,就是能看见 .idea 和 src文件夹的那个路径,然后右键选择Git Bash Here,就能看见git窗口,但是别忘了,这需要提前安装git)
按顺序输入以下命令即可:
git init
git remote add origin 仓库地址
git add --all
git commit -m”xxx”
git push -u origin master
注意:如果出现 ! [rejected] master -> master (fetch first) 失败提示,说明代码仓库并非空库,则需要先 git pull origin master
2、使用 IDEA 的同伴会更方便,但有一点非常关键必须要注意的就是 :
重点:
项目中必须在根目录下加入一个文件: .gitignore ,内容如下:
作用是在提交和上传时,忽略 .idea文件夹及其下所有文件,.iml文件,target文件夹及其下所有文件,*.log
前面这三类文件是IDEA项目导入和启动后会自动生成的以本地项目所生成的特有配置,因此并不适用于其他使用该git仓库的开发人员,所以这一步很关键,*.log 是我自己加的,用于忽略日志文件。
在 git init 和 git remote add origin 仓库地址 之后,可以在idea中看到右下角有了仓库地址的master分支:
点击绿色的提交按钮即可,弹出以下窗口:
最后再提一下,如果发现pull或者push一直报错,那肯定是再某个提交的环节中除了问题,这时我们可以使用以下,进行commit回退:
git log #查看commit日志
git reset --hard 版本号(版本号在日志里可以看到)
git add --all #回退之后,再重新刷缓存
git commit -m 'X' #提交,正常都会报出黄色警告
git push -f origin master #不用管警告,强制上传即可
日志: