错误原因

该错误主要是由于从 Java 9 开始引入的模块系统(Jigsaw)限制了对某些内部类和方法的访问。Spring 框架在运行时需要通过反射访问一些类和方法,而这些类和方法在 Java 9 及以上版本中默认是不公开的,因此会抛出 InaccessibleObjectException。具体来说,ClassLoader.defineClass 方法在 java.base 模块中是受保护的,外部模块默认无法访问。

解决方法

以下是几种解决方法:

1. 添加 JVM 启动参数

在启动 Spring Boot 应用时,添加以下 JVM 参数:

--add-opens java.base/java.lang=ALL-UNNAMED

  • 在 IDEA 中添加:打开 Run/Debug Configurations,在 VM options 字段中添加上述参数。

  • 在命令行中添加:在运行 java -jar 命令时,添加参数,如 java --add-opens java.base/java.lang=ALL-UNNAMED -jar your-app.jar

2. 修改项目 JDK 版本

如果项目使用的是 JDK 9 或更高版本,可以尝试将项目 JDK 版本换成 JDK 1.8。在 IDEA 中,通过 File -> Project Structure -> Project,修改 Project SDKProject language level,然后重启 IDEA 并重新加载项目。

3. 使用 Spring 的修正版 cglib

Spring 官方提供了一个修正版的 cglib,它与原版 cglib 的 API 完全一致,无需重新实现代码。可以在项目中使用这个修正版来解决因 cglib 导致的此类问题。

4. 配置 Maven 打包参数

pom.xml 文件中添加以下配置,确保在打包时正确处理模块访问权限:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>3.0.0-M5</version>
            <configuration>
                <argLine>--add-opens java.base/java.lang=ALL-UNNAMED</argLine>
            </configuration>
        </plugin>
    </plugins>
</build>

然后重新打包项目。

5. 检查依赖冲突

检查项目中的依赖是否有冲突,特别是与 Spring Boot 相关的依赖,如 Spring Framework、Spring Boot Starter 等。确保所有依赖项的版本一致。可以通过以下命令检查依赖冲突:

mvn dependency:tree

根据依赖树的输出,排除冲突的依赖。

6. 使用更高版本的 Spring Boot

升级 Spring Boot 版本到 2.3.0 或更高版本,这些版本对 Java 9 及以上版本有更好的支持。在 pom.xml 文件中修改 Spring Boot 版本:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.0.RELEASE</version>
</parent>

然后重新打包项目。

7. 检查配置类路径

确保 ServerApp 类所在的包路径正确,并且类上标注了正确的注解,如 @SpringBootApplication。同时,检查 application.propertiesapplication.yml 文件中是否有错误的配置。

8. 避免使用反射访问受限类

如果可能,尽量避免在代码中使用反射来访问受限的类和方法。改用其他方式实现相同的功能。

Logo

技术共进,成长同行——讯飞AI开发者社区

更多推荐