Spring Boot2+Kotlin+JDK9集成JPA引发类未找到及编译数组越界问题
解决Kotlin+Spring Boot 2+JDK9下JPA依赖及模块化编译问题
我来帮你一步步拆解并解决这些问题,这些都是JDK9模块化初期搭配Spring Boot很容易踩的坑:
一、先搞清楚问题根源
- 第一个
NoClassDefFoundError: javax/transaction/SystemException:JDK9开始采用模块化系统,javax.transaction相关包被移出了默认的系统模块,必须显式引入对应的模块或依赖才能正常使用。 - 第二个
ArrayIndexOutOfBoundsException和Maven编译失败:你用的maven-compiler-plugin:3.7.0版本太老了,它对JDK9的模块化编译支持不完善,才会导致这种奇怪的数组越界错误。
二、具体解决方案
1. 升级Maven Compiler Plugin版本
打开你的pom.xml,找到maven-compiler-plugin的配置,把版本升级到3.8.1及以上(推荐用3.11.0,兼容性更好):
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.11.0</version> <configuration> <release>9</release> <!-- 显式补充JDK9移除的核心模块 --> <compilerArgs> <arg>--add-modules</arg> <arg>javax.transaction.api,java.xml.bind</arg> </compilerArgs> </configuration> </plugin>
同时,确保kotlin-maven-plugin版本和Spring Boot 2兼容(比如用1.6.x系列对应Spring Boot 2.7.x),并配置模块编译支持:
<plugin> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-plugin</artifactId> <version>1.6.21</version> <executions> <execution> <id>compile</id> <phase>compile</phase> <goals> <goal>compile</goal> </goals> <configuration> <sourceDirs> <sourceDir>${project.basedir}/src/main/kotlin</sourceDir> <sourceDir>${project.basedir}/src/main/java</sourceDir> </sourceDirs> <arguments> <argument>-module-path</argument> <argument>${project.module.path}</argument> </arguments> </configuration> </execution> </executions> </plugin>
2. 修正module-info.java的配置
模块化下,Spring和Hibernate需要通过反射访问你的实体类、组件,必须显式开放对应的包给它们。修改你的module-info.java:
module de.sample.backend { // 开放实体类所在包给Hibernate和Spring(替换成你实际的实体包路径) opens de.sample.backend.domain to hibernate.jpa, spring.core, spring.context; // 开放控制器/服务类所在包给Spring扫描 opens de.sample.backend.controller to spring.webmvc; opens de.sample.backend.service to spring.context; // 导出对外暴露的包(比如控制器包) exports de.sample.backend.controller; exports de.sample.backend.service; // 保留你之前的依赖声明 requires javax.transaction.api; requires hibernate.jpa; requires spring.beans; requires spring.core; requires spring.context; requires spring.tx; requires spring.web; requires spring.webmvc; requires spring.data.commons; requires spring.data.jpa; requires spring.boot; requires spring.boot.autoconfigure; }
关键说明:opens语句是允许其他模块通过反射访问该包下的类,这对Hibernate映射实体、Spring的依赖注入和AOP都是必须的,没有这个配置后续运行时会出现反射访问被拒绝的错误。
3. 验证依赖完整性
确保pom.xml里显式引入javax.transaction-api依赖(虽然Spring Boot Starter Data JPA会间接引入,但显式声明更稳妥):
<dependency> <groupId>javax.transaction</groupId> <artifactId>javax.transaction-api</artifactId> <version>1.3</version> </dependency>
三、执行步骤
- 先清理之前的编译产物:
mvn clean - 重新编译项目:
mvn compile - 启动应用:
mvn spring-boot:run
这样应该就能解决你遇到的类找不到、数组越界和编译失败的问题了。
内容的提问来源于stack exchange,提问作者Chris81T
相关产品推荐
相关产品推荐

