You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot2+Kotlin+JDK9集成JPA引发类未找到及编译数组越界问题

解决Kotlin+Spring Boot 2+JDK9下JPA依赖及模块化编译问题

我来帮你一步步拆解并解决这些问题,这些都是JDK9模块化初期搭配Spring Boot很容易踩的坑:

一、先搞清楚问题根源

  1. 第一个NoClassDefFoundError: javax/transaction/SystemException:JDK9开始采用模块化系统,javax.transaction相关包被移出了默认的系统模块,必须显式引入对应的模块或依赖才能正常使用。
  2. 第二个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>

三、执行步骤

  1. 先清理之前的编译产物:mvn clean
  2. 重新编译项目:mvn compile
  3. 启动应用:mvn spring-boot:run

这样应该就能解决你遇到的类找不到、数组越界和编译失败的问题了。

内容的提问来源于stack exchange,提问作者Chris81T

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:56:25