跨模块调用时ClassLoader.loadClass出现ClassNotFoundException问题排查
问题分析与解决方案
你的问题根源在于common模块的构建配置错误:你给作为库的common模块添加了org.springframework.boot插件,这个插件默认会把模块打包成可执行的Spring Boot JAR文件,而不是普通的Java库JAR。
可执行Spring Boot JAR的内部结构和普通库JAR不一样——它的类文件都被放在BOOT-INF/classes目录下,当user-manager依赖这个模块时,类加载器无法从这个路径下找到StringValidator类,所以抛出了ClassNotFoundException。
修复步骤
1. 修改common模块的build.gradle
因为common是被其他模块依赖的库,不需要成为可执行的Spring Boot应用,所以我们需要移除spring-boot插件,同时保留依赖管理能力来对齐版本:
替换common/build.gradle的内容为:
plugins { id 'java-library' id 'org.jetbrains.kotlin.jvm' version '1.2.71' id 'org.jetbrains.kotlin.plugin.spring' version '1.2.71' } apply plugin: 'io.spring.dependency-management' group = 'com.simbalarry' version = '0.0.1-SNAPSHOT' sourceCompatibility = '1.8' repositories { mavenCentral() } ext['kotlin.version'] = '1.2.71' ext['spring-boot.version'] = '2.1.3.RELEASE' // 导入Spring Boot的BOM来统一管理依赖版本 dependencyManagement { imports { mavenBom "org.springframework.boot:spring-boot-dependencies:${ext['spring-boot.version']}" } } dependencies { implementation 'org.jetbrains.kotlin:kotlin-reflect' implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' // 如果common需要Spring相关API,可在这里添加,比如: // implementation 'org.springframework.boot:spring-boot-starter' } compileKotlin { kotlinOptions { freeCompilerArgs = ['-Xjsr305=strict'] jvmTarget = '1.8' } }
2. 清理并重新构建项目
在项目根目录执行以下命令,清理旧的构建产物并重新编译:
gradlew clean build
然后切换到user-manager目录,启动应用:
cd user-manager gradlew bootRun
可选方案(如果common需要保留Spring Boot插件)
如果你的common模块确实需要作为Spring Boot应用运行(比如有自己的启动类),但同时要作为库被其他模块依赖,可以在common/build.gradle中添加配置,让Spring Boot插件同时生成普通库JAR和可执行JAR:
// 禁用默认的可执行JAR构建 bootJar { enabled = false } // 启用普通库JAR的构建 jar { enabled = true }
不过这种方式不如直接移除Spring Boot插件简洁,因为你的common模块目前没有独立运行的需求。
内容的提问来源于stack exchange,提问作者Nayan Kurude
相关产品推荐
相关产品推荐

