引入common模块后,后端使用getResource()无法获取资源文件的问题
getResource()找不到资源的问题 看起来你遇到的问题是在引入Kotlin多平台common模块后,IntelliJ运行后端时无法加载app.properties,但打包成fat jar后却能正常工作。这大概率是类加载器上下文或者IntelliJ的运行类路径配置问题,下面是几个针对性的解决方案:
1. 切换到上下文类加载器加载资源
你当前代码用的是javaClass.classLoader,在多模块(尤其是多平台模块)场景下,这个类加载器可能无法访问到backend模块的资源目录。改用线程上下文类加载器通常能解决这个问题:
object Configuration { val content = Thread.currentThread().contextClassLoader.getResource("app.properties")?.readText() ?: error("Failed to load app.properties - check if it's in backend's resources directory") }
线程上下文类加载器是专门用来处理跨模块资源加载的,能正确遍历所有依赖模块的类路径。
2. 确保IntelliJ正确识别backend的资源目录
有时候IntelliJ会因为多模块配置的变化,忘记标记backend的src/main/resources为资源根目录:
- 打开
Project Structure(快捷键:Ctrl+Alt+Shift+S) - 定位到
Modules->backend->Sources标签 - 找到
src/main/resources目录,右键选择Mark Directory as->Resources Root - 完成后执行
File->Invalidate Caches...->Invalidate and Restart,让IntelliJ重新构建索引
3. 调整Gradle配置,明确资源处理规则
在backend模块的build.gradle中添加资源集的明确配置,确保Gradle(以及IntelliJ同步后的构建)能正确打包和加载资源:
sourceSets { main { resources { srcDirs = ["src/main/resources"] include "**/*" // 确保所有资源文件都被包含 } } }
另外,检查common模块的build.gradle,避免它的资源配置影响backend(比如不要设置resources的输出路径和backend冲突)。
4. 使用Gradle的run任务启动应用,而非直接运行Kotlin类
直接在IntelliJ中右键运行App.kt时,IDE可能没有正确构建所有依赖模块的类路径,导致资源缺失。改用Gradle的run任务启动:
- 在Gradle工具窗口中找到
backend->Tasks->application->run - 双击这个任务启动应用,Gradle会自动处理所有模块的依赖和资源路径
为什么fat jar能正常运行?
shadow插件打包时会把所有模块的类和资源合并到一个jar文件中,此时类加载器是从这个单一jar中加载资源,不存在跨模块的类路径问题,所以能正常找到app.properties。而你提到的out文件夹存在时正常,是因为之前的构建已经把资源复制到了out目录,类加载器能直接读取;当out被删除后,IntelliJ的增量构建可能没有及时把backend的资源复制到运行类路径中。
内容的提问来源于stack exchange,提问作者allnex

