gradle默认仅处理src/main/resources,自定义资源目录需在sourcesets.main.resources.srcdirs中显式添加;jar任务默认包含resources输出,shadowjar需用mergeservicefiles()避免覆盖;ide运行路径与jar不同,资源加载路径斜杠使用需谨慎。

build.gradle里没配resources目录
Gradle默认只处理src/main/resources下的文件,但如果你把配置文件、图片等放到了src/main/config或src/main/assets这类自定义路径,它压根不会扫描——连打包动作都不会触发。
解决办法是显式声明资源目录:
- 在
sourceSets.main.resources.srcDirs里追加你的路径,比如["src/main/resources", "src/main/config"] - 确保路径是相对项目根目录的,且实际存在(别拼错大小写)
- 改完后必须执行
./gradlew clean再构建,否则旧的build/resources缓存可能还在用
jar任务没继承resources输出
Gradle的jar任务默认只打包classes,不自动合并resources。哪怕src/main/resources里的文件已正确复制到build/resources/main,jar任务仍可能忽略它。
常见错误写法:task myJar(type: Jar) —— 这是个全新任务,和默认流程完全脱钩。
正确做法是复用默认行为:
- 直接用
jar任务(不用重定义),它默认会包含sourceSets.main.output,而后者已含resources - 如果必须自定义,明确加上
from sourceSets.main.output - 验证是否生效:解压生成的jar,检查
META-INF/MANIFEST.MF同级是否存在你的application.properties
用了ShadowJar却漏了resources
shadowJar插件默认会打包resources,但如果你手动覆盖了from或exclude规则,就容易把整个resources目录干掉。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
典型翻车点:
-
shadowJar { from("lib") }—— 这个from会清空默认输入源,只剩lib/目录 -
shadowJar { exclude "**/*.xml" }—— 顺手把logback.xml也过滤了 - 没设
mergeServiceFiles(),导致多个jar里的META-INF/services/被覆盖而非合并
安全写法是只做增量配置:shadowJar { mergeServiceFiles(); manifest { attributes "Main-Class": "com.example.Main" } }
IDE运行时类路径和jar不一致
你在IntelliJ里点绿色三角能读到application.properties,但java -jar xxx.jar就报FileNotFoundException——这说明IDE没走jar包,而是直接加载了build/resources/main目录。
这不是打包问题,是运行环境错觉。验证方法:
- 终端进
build/libs,执行java -jar your-app.jar - 用
jar -tf your-app.jar | grep properties确认文件真在jar里 - 如果不在,回到前三个副标题排查;如果在,检查代码里是不是用了绝对路径或硬编码路径
最容易被忽略的是资源加载方式:getClass().getResource("/config/app.conf")开头的/会让查找从classpath根开始,但若文件实际在config/app.conf,就得去掉斜杠,否则永远找不到。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










