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

Spring Boot jar包运行时InMemoryJavaCompiler编译依赖类失败求助

解决Spring Boot Jar启动时InMemoryJavaCompiler无法识别依赖类的问题

这个问题我之前也碰到过,核心原因是Spring Boot Jar的类加载机制和IDE启动时完全不一样:

问题根源

当你用java -jar启动Spring Boot应用时,所有依赖(包括你的业务实体项目)都被打包在BOOT-INF/lib目录下,Spring Boot会用自定义的LaunchedURLClassLoader来加载这些类。而InMemoryJavaCompiler默认使用的是系统类加载器(System ClassLoader),这个类加载器根本看不到BOOT-INF/lib里的内容,自然找不到你的BaseClass和Entity。

反观IntelliJ启动时,它是把所有项目的类和依赖都直接放到系统类路径里,系统类加载器能轻松找到这些类,所以编译一切正常。

解决方案

1. 让InMemoryJavaCompiler使用Spring Boot的应用类加载器

这是最简单有效的办法,在创建编译器实例时,指定它使用当前应用的类加载器:

// 获取Spring Boot的应用类加载器
ClassLoader appClassLoader = getClass().getClassLoader();
// 初始化编译器并绑定类加载器
InMemoryJavaCompiler compiler = InMemoryJavaCompiler.newInstance()
        .useClassloader(appClassLoader);

这样编译器就能通过应用类加载器访问到BOOT-INF/lib里的业务实体类了。

2. 手动添加依赖到编译器Classpath(备选方案)

如果第一种方法没生效,你可以手动把业务实体项目的Jar路径添加到编译器的Classpath中。借助应用类加载器获取所有依赖的URL,再逐个添加:

ClassLoader appClassLoader = getClass().getClassLoader();
InMemoryJavaCompiler compiler = InMemoryJavaCompiler.newInstance();

// 从应用类加载器中提取所有依赖URL
if (appClassLoader instanceof URLClassLoader) {
    URL[] classpathUrls = ((URLClassLoader) appClassLoader).getURLs();
    for (URL url : classpathUrls) {
        compiler.addClasspath(url.getPath());
    }
}

不过一般第一种方法就足够覆盖场景了。

3. 确认业务项目依赖配置正确

最后检查一下API项目的build.gradle,确保业务实体项目被正确声明为依赖:

dependencies {
    implementation project(':your-business-entity-module-name')
    // 其他Spring Boot依赖...
}

这样bootJar任务才会把业务项目的Jar打包到BOOT-INF/lib目录下。

验证

修改后重新打包API项目:

./gradlew bootJar

然后用java -jar启动,再调用POST接口测试动态编译,应该就能正常通过了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:02:33