一文看懂!Maven工程与打包目录映射

内容分享1个月前发布
0 0 0

应用一启动就报错:MyBatis 抛出 Invalid bound statement,控制台还夹带着 FileNotFoundException。最后查出来,mapper 的 XML 根本没打进最终的 JAR,程序在运行时找不到它们。

这种情况很常见。调试过程一般是先看到异常,再去检查资源是不是在包里。把打好的 JAR 解压一看,发现根目录下只有 class 文件和 resources 里常规的配置,但原本以为会一起打进去的 XML 不见了。发生这种事的根源,基本上和 Maven 的目录规则有关——它把源码和资源“按约定”搬到不同位置,然后在打包时把两者合并,但并不是把每个文件都自动带上。

程序员常犯的一个操作是把 mapper XML 和对应的接口放在同一个包里,列如把 UserMapper.xml 放到了
src/main/java/com/demo/mapper/ 下。看起来组织得挺舒服,但 Maven 默认只会在 src/main/java 里找 .java 来编译,其他类型的文件会被忽略。换句话说,那些放在 java 目录下的 XML 根本不会被复制到 target/classes,也就不会进 JAR。等到 Spring 或 MyBatis 根据 classpath 去加载 mapper 时,自然找不到,报错就是必然的结果。

要理解这个问题,需要先弄清楚 Maven 打包时的几个基本规则。概括来说,mvn package 做的事并不复杂:把 src/main/java 下的 Java 源文件编译成 class,按包路径输出到 target/classes;把 src/main/resources 下的内容原封不动地复制到 target/classes;src/test 下的文件只在测试阶段用,既不会被编译进主包,也不会出目前最终的 JAR 里。按这个逻辑,最终的 classpath(也就是运行时去找资源和类的地方)实际对应的是 JAR 的根目录,开发环境下则是 target/classes 目录。

举个具体的映射关系来说明。源代码里有这些文件:

– src/main/java/com/demo/User.java

– src/main/resources/application.yml

– src/main/resources/mybatis-config.xml

– src/main/resources/mapper/UserMapper.xml

– src/test/java/xxxTest.java

打包后对应的结构会是:

– com/demo/User.class(编译后的字节码,按包结构放)

– application.yml(直接在 JAR 根)

– mybatis-config.xml(同样在根)

– mapper/UserMapper.xml(位于根下的 mapper 目录)

– 测试代码不会出目前 JAR 中

注意这里的关键点:resources 目录下的东西会和编译后的 class 混在一起,放到同一个输出目录。如果你的 XML 被正确放在 src/main/resources 的 mapper 文件夹里,运行时它就能按路径被找到。问题出在把资源放错地方——放在 src/main/java 下的非 .java 文件默认不会被当作资源处理。

修复办法也很直接。如果你的确 想把 XML 和接口放在同一个源码包下,可以告知 Maven 把 java 目录里的特定文件也当作资源来复制。需要在 pom.xml 里添加一段配置,大致像这样(把 src/main/java 里的 XML 包含进来):

src/main/java

**/*.xml

src/main/resources

加了配置后来,mvn package 会把匹配到的 XML 一并复制到 target/classes,然后这些文件就会出目前最终的 JAR 根路径下,MyBatis 加载 mapper 时就不会再报找不到文件的错了。

还有一个容易混淆的点是 classpath 的含义。在运行时说 classpath:,指的就是运行时能访问到的资源根——要么是 JAR 的根目录,要么是在 IDE 里运行时的 target/classes。许多人只在 IDE 里测试,文件都能被找到,但发布到服务器上运行打好的 JAR,就出现了差异。自己动手把打好的 JAR 解压检查一遍,能立刻看出哪些文件在包内,哪些不在。遇到加载不到资源的问题,先别急着怀疑框架,先把包打开看看文件结构。

碰到这类问题的现场调查一般是这样的:先从异常日志定位缺哪个资源,接着检查源码目录确认该文件放在哪儿,再看 target/classes 或解压 JAR,最后决定是移动资源到 src/main/resources,还是在 pom.xml 里声明额外的资源目录。按步骤走,问题就能定位清楚。

许多新人碰到这个坑,会以为是框架配置错了,或者是类路径写错了。实则大多数时候,只是文件被放到了一个默认流程不会处理的位置。页面上、文章里常看到“约定优于配置”这句话,用对了就是省事,没搞清楚约定就容易踩坑。要不然就是把资源塞在 java 目录里,或者以为测试里的东西也会被带出去,那就等着运行时报找不到文件吧。

要验证,不复杂:把项目打包,解压 JAR,看看有没有你想要的 XML 和配置文件;或者在 target/classes 下查找对应路径。看到实际的文件映射关系之后,再决定是调整源码布局,还是在 pom 上做点额外配置。把这些具体步骤做一遍,印象会更深。

© 版权声明

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
none
暂无评论...