导读:本期聚焦于小伙伴创作的《Maven pom.xml build resources 怎么把XML文件正确打包进JAR?》,敬请观看详情。打包后的JAR里找不到Mapper映射或Spring配置文件,往往是resources配置没写对。Maven默认只复制src/main/resources下的非过滤文件,若XML放在源码目录或被排除规则拦截,就不会进包。可以用build标签下的resources指定目录、包含模式和是否过滤,也可以用maven-resources-plugin精准控制。需要注意directory、targetPath和includes的写法,避免把XML过滤成空文件。掌握这些配置,就能让MyBatis、Log4j或自定义XML随JAR一起发布,省去运行时手动补文件的麻烦。

在Java项目里,我们经常需要把XML文件如MyBatis的Mapper、Spring的上下文或者一些规则配置打进最终的JAR包中。Maven作为主流构建工具,其资源复制机制决定了哪些文件会被放到classpath里。如果配置不当,编译没问题,但运行起来却报文件找不到,这多半是pom.xml里build resources的设置没有覆盖到你的XML位置。

Maven pom.xml build resources 怎么把XML文件正确打包进JAR?

一、Maven默认资源打包行为

Maven的standard directory layout规定,src/main/resources目录下的文件会在process-resources阶段复制到target/classes,并最终进入JAR。但如果你把XML放在src/main/java的某个包下,或者文件名带特殊后缀,默认规则就不会复制它们。

另外,Maven对资源文件有“过滤”概念。开启filtering后,文件里的${}占位符会被替换。XML里常出现类似Spring的占位符,若误开过滤又没配属性,文件内容可能被破坏甚至清空。理解默认行为,是写对配置的前提。

1.1 默认不复制源码目录中的XML

比如你在src/main/java/com/demo/下写了UserMapper.xml,执行package后,JAR里根本没有这个文件。因为Maven只把java文件交给编译器,其他类型留在源码树,不进resources流程。

这种结构在MyBatis老项目中很常见。要解决这个问题,就得在pom.xml明确告诉Maven:这个目录里的XML也是资源,请帮我复制。

二、用build resources标签打包XML

最核心的方式是在pom.xml的<build>内写<resources>,每一个<resource>描述一个资源集合。你可以指定directory、includes、excludes和targetPath。

下面示例把源码目录里的XML和resources目录里的所有文件都打进JAR,并且关闭过滤以防内容被改:

<build>
  <resources>
    <resource>
      <directory>src/main/resources</directory>
      <includes>
        <include>**/*.xml</include>
        <include>**/*.properties</include>
      </includes>
      <filtering>false</filtering>
    </resource>
    <resource>
      <directory>src/main/java</directory>
      <includes>
        <include>**/*.xml</include>
      </includes>
      <filtering>false</filtering>
    </resource>
  </resources>
</build>

2.1 directory与targetPath说明

directory是项目中的源目录,targetPath是打进JAR后的目标路径,默认就是根(对应classpath根)。如果你想把XML放到JAR里的config目录,可写<targetPath>config</targetPath>,但注意代码里加载路径也要随之改变。

includes使用Ant风格匹配,**/*.xml表示任意级子目录下的XML。如果只想要某个包,可以写<include>com/demo/mapper/*.xml</include>。excludes则用来排除,比如测试用XML不进生产包。

2.2 避免过滤导致XML损坏

如果某个resource开了<filtering>true</filtering>,而XML里有<property name="${name}"/>之类内容,Maven会尝试找属性替换。找不到就可能留空或报错。对XML资源,一般建议保持false。

当你确实需要对properties过滤、但不想动XML时,就把它们拆成两个resource块,一个开过滤一个关过滤,互不干扰。

三、使用maven-resources-plugin精确控制

除了在build里声明,也可以显式用插件绑定阶段。适合需要多套资源、或者想在不同profile里复制不同XML的场景。

示例插件配置如下,效果等同于上面的resources声明,但更直观,也方便加executions:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-resources-plugin</artifactId>
  <version>3.3.1</version>
  <executions>
    <execution>
      <id>copy-xml</id>
      <phase>process-resources</phase>
      <goals>
        <goal>copy-resources</goal>
      </goals>
      <configuration>
        <outputDirectory>${project.build.outputDirectory}</outputDirectory>
        <resources>
          <resource>
            <directory>src/main/java</directory>
            <includes>
              <include>**/*.xml</include>
            </includes>
            <filtering>false</filtering>
          </resource>
        </resources>
      </configuration>
    </execution>
  </executions>
</plugin>

3.1 插件方式优缺点

优点是可以利用profile激活不同execution,比如开发环境复制mock XML,生产环境复制真实XML。也可以把文件复制到任意outputDirectory,不限于classes。

缺点是配置比纯resources标签啰嗦,新手容易把phase写错导致没执行。一般小项目直接用build resources就够了,复杂多环境再上插件。

四、验证与常见问题

打包后,用jar tf target/your-app.jar列出内容,确认XML路径符合预期。若用Spring Boot,默认也会尊重你pom里的resources,但注意它的repackage会把原JAR嵌套,看内容要解开boot包。

常见坑:XML放在resources但被<excludes>误杀;或者IDE里能跑,因为IDE自己复制了,而Maven没配。还有就是把directory写成绝对路径,导致换机器就失败。坚持用相对路径和清晰includes,基本能稳住。

4.1 简单校验代码

可以在程序里写个简单检查,确认XML确实在classpath:

import java.io.InputStream;

public class CheckXml {
    public static void main(String[] args) {
        // 尝试从classpath加载MapperXML
        InputStream in = CheckXml.class.getClassLoader()
            .getResourceAsStream("com/demo/UserMapper.xml");
        if (in == null) {
            System.out.println("XML未打包进JAR");
        } else {
            System.out.println("XML已存在");
        }
    }
}

这段程序打进同一个JAR运行,如果输出未打包,就回头查pom的directory和include是否匹配。路径要对应targetPath,默认无前缀就是根开头。

五、总结建议

把XML打进JAR并不难,关键是让Maven知道去哪找、复制什么、别乱改。首选在build resources里加directory和includes,关闭filtering;特殊需求再用resources-plugin。打包后务必用jar命令或代码验证,别等上线才发现缺文件。

只要配置清晰,MyBatis映射、Spring自定义schema、规则引擎脚本等都能随包发布,部署时少踩很多坑。

Mavenpom_xmlbuild_resources修改时间:2026-08-03 22:12:21

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。