Spring Boot加载外部Jar包时出现Apache Camel类ClassNotFoundException异常
根本原因
该错误由Spring Boot可执行Jar的类加载机制导致:
Spring Boot 可执行Jar内部的依赖(如内置的Camel核心类、Spring相关类)都存放在BOOT-INF/lib/目录下,由Spring Boot自定义的LaunchedURLClassLoader加载。你通过-cp参数指定的外部Jar由系统类加载器加载,而系统类加载器是LaunchedURLClassLoader的父加载器,根据Java双亲委派模型,父加载器无法访问子加载器加载的类,因此外部Jar中的自定义类找不到主Jar内已存在的org.apache.camel.AggregationStrategy类。
解决步骤
1. 替换启动命令,使用PropertiesLauncher加载外部依赖
Spring Boot提供的PropertiesLauncher支持自定义外部类路径,只需修改启动命令即可解决类加载冲突问题,Windows环境启动命令如下:
java -Dworkdir.path=D:/sample/workdir -Dloader.path=D:/sample/workdir/camel/libs -cp D:/sample/app.jar org.springframework.boot.loader.PropertiesLauncher
Linux/macOS环境命令格式一致,无需调整分隔符。loader.path参数会将指定目录下的所有Jar加入到Spring Boot的类加载器路径中,外部自定义类即可正常访问主Jar内的依赖类。
2. 优化外部Jar的依赖配置(可选,推荐)
修改外部sample-camel项目的build.gradle依赖配置,将主Jar中已存在的依赖设置为compileOnly,避免重复打包依赖导致的类冲突,同时减小外部Jar体积:
plugins { id 'java-library' } sourceCompatibility = JavaVersion.VERSION_1_8 repositories { mavenCentral() } dependencies { compileOnly 'org.springframework.boot:spring-boot:2.5.4' compileOnly 'org.apache.camel.springboot:camel-spring-boot-starter:3.11.1' compileOnly 'com.fasterxml.jackson.core:jackson-databind:2.12.4' compileOnly files('D:\\sample\\app.jar') }
重新打包后的外部Jar即可直接使用。
3. 配置Spring包扫描(若使用@Component等注解)
如果你的自定义Camel类使用了@Component、@Service等Spring注解,需要在主Spring Boot应用中添加外部类的包扫描配置:
- 启动类上添加注解:
@SpringBootApplication(scanBasePackages = {"你的主应用原有包名", "com.example"}) - 或在配置文件中添加配置:
spring.main.scan-base-packages=你的主应用原有包名,com.example
配置完成后,外部Jar中的注解类会被Spring正常扫描注册为Bean,可直接在XML路由中引用。
内容的提问来源于stack exchange,提问作者atultherajput

