SpringBoot 应用升级 GraalVM 踩坑
我们不再具体介绍GraalVM,直接介绍改造过程。项目使用Spring Boot 2.0.8,使用了Eureka、Mybatis、TKMyBatis、MySQL结论:Spring Boot 官方在3.x版本对于GraalVM做了很多的工作,兼容性较好。但是一旦引入了MyBatis以及TKMyBatis 后,各种问题。
背景
我们不再具体介绍GraalVM,直接介绍改造过程。
项目使用Spring Boot 2.0.8,使用了Eureka、Mybatis、TKMyBatis、MySQL
结论:Spring Boot 官方在3.x版本对于GraalVM做了很多的工作,兼容性较好。但是一旦引入了MyBatis以及TKMyBatis 后,各种问题。
最终改造后的版本:
组件 | 版本 |
---|---|
GraalVM | 17 |
Spring boot | 3.2 |
Spring Cloud | 2023 |
Mybatis | 3.5.19 |
mybatis-spring-boot-autoconfigure | 3.0.5 |
mybatis-spring | 3.0.5 |
1、升级 Spring Boot
即使Spring官方提供了 Native 工具用于适配Spring Boot 2.x的版本,但是实际上版本对应关系等问题还是比较多的。因此项目首先升级到了Spring Boot 3.2,选择了GraalVM 17。
问题一:
项目从Spring Boot 2.x升级到Spring Boot3.x后,以及使用GraalVM 17后,要关注一些拦截器、javax的类替换,在新的版本中这些组件都有相应的变换。
问题二:
需要升级Mybatis、Mybatis Spring相应版本,兼容Spring Boot 3.x。
Mybatis 3.5.19
mybatis-spring-boot-autoconfigure 3.0.5
mybatis-spring 3.0.5
问题三:
升级Spring Cloud至2023,兼容Spring Boot 3.x。由于项目只用到了Eureka,升级相对简单。
解决上述问题后,在pom里添加GraalVM插件依赖.
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
</plugin>
在application配置文件里,关闭refresh功能
spring:
cloud:
refresh:
enabled: false
2、Mybatis适配
上述升级完成后,使用mvn clean package -Pnative
还是会报错的。
问题一:
tkmyabtis适配问题,AOT会提示以下报错。
failed to generate code for applicationservletenvironment
最后项目不得不把tkmybatis的依赖移除,才不会有该报错。
问题二:
重新AOT和编译为可执行文件后,运行会新的错误。报错类似以下内容
org.mybatis.spring.mapper.classpathmapperscanner case java.lang.NullPointerException
这时候需要做以下2个步骤:
- 复制网页内容 https://github.com/mybatis/spring-boot-starter/wiki/MyBatisNativeConfiguration.java 到自己的工程。
- 同时再参考 https://github.com/nieqiurong/mybatis-native-demo/commit/7c8977a 调整类里的以下内容。
如果步骤二没做,项目里需要注入Mapper的地方,会报错
org mybatis spring mapper mapperfactorybean required a bean of type java.lang.class that could not be found
问题三:
重新AOT和编译为可执行文件后,运行会新的错误。
IllegalArgumentException: property sqlsessionfactory or sqlsessiontemplate are required
如果工程中使用到了@MapperScanner注解,需要指定sqlSessionTemplateRef
@MapperScan(basePackages = "com.example.mybatisnativesample.mapper", sqlSessionTemplateRef = "sqlSessionTemplate")
问题四:
重新AOT和编译为可执行文件后,运行会新的错误。意思为接口无法绑定XML。
invalid bound statement (not found) com.xxxx.xxx
这个问题大概原因是没有把xml扫描加载成功。虽然我们在application配置里配置了xmlLocation和mapper-locations,但是在GraalVM下是无效的。官方有一个方法 https://github.com/mybatis/spring-native/blob/master/docs/src/site/zh/markdown/index.md#%E4%BD%BF%E7%94%A8-mybatisresourcesscan 使用@MyBatisResourcesScan注解。
该注解需要依赖mybatis-spring-native-core,使用myabtis的Maven仓库,参考 https://github.com/mybatis/spring-native?tab=readme-ov-file#how-to-install-on-your-application
由于我的项目在内网,所以我最后把xml的SQL都改造成了Mybatis 注解模式使用。
通过上述的改造,项目成功使用GraalVM 17编译打包,并能稳定运行。
更多推荐
所有评论(0)