maven resources导致打包失败分析与解决

本文记录了在maven打包时遇到的问题,由于maven-resource-plugin配置不当,导致资源文件过滤过程中损坏二进制文件。通过分析官方文档,了解到不应过滤二进制文件,特别是ttf字体文件。解决方案是精细化资源目录,排除不需要过滤的二进制文件,通过修改资源文件设置成功解决了问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天在工作时遇到一个测试环境maven打包失败的问题。一开始的时候jenkins只显示了打包失败,没有其他的信息展示出来,在将项目拉取到本地之后,项目又可以完好地启动,于是判断可能是maven打包时出错,于是终端进入对应目录之后,输入以下命令:

mvn package -U -Denv=pre -DskipTests

果然,build failed。

现场失败信息如下:

于是Google了一下这个
maven-resource-plugin

官网对它的介绍是:

The Resources Plugin handles the copying of project resources to the output directory. There are two different kinds of resources: main resources and test resources. The difference is that the main resources are the resources associated to the main source code while the test resources are associated to the test source code.

查看了官方的介绍之后,我对它的总结如下:

我们可以使用maven-resource-plugin在构建项目时对pom文件进行动态的变量替换,比如:

<project>
    ...
    <properties>
        <your.name>world</your.name>
    </properties>
    ...
</project>

可以结合filter来读取资源文件中的变量设置,以此来进行变量的动态替换。

...
<filters>
  <filter>my-filter-values.properties</filter>
</filters>
...

properties文件中可以这么存:

your.name=hello

然后maven在进行打包的过程中会将filter中的文件内容和所有resource中的内容进行全部替换。这样的话我们可以在项目中定义一些特定的值,并且在打包过程中进行动态替换。需要替换的资源是这么指定的:

...
<resources>
   <resource>
      <directory>src/main/resources</directory>
      <filtering>true</filtering>
   </resource>
</resources>
...

官方在这里对其进行了说明:

Warning: Do not filter files with binary content like images! This will most likely result in corrupt output.

If you have both text files and binary files as resources it is recommended to have two separated folders. One folder src/main/resources (default) for the resources which are not filtered and another folder src/main/resources-filtered for the resources which are filtered.

也就是说指定资源范围内如果存在二进制文件和图片的话可能会有文件在进行过滤替换的过程中被损坏。

看到这里,我翻看了一下项目提交日志,发现有同事在最近的提交中新增了ttf文件,并且正好在我们的项目过滤替换范围之内。

看来问题可能出现在这了。按照官方文档的指示,继续查看相关说明。
官方给的方案如下:

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-resources-plugin</artifactId>
        <version>3.0.2</version>
        <configuration>
          ...
          <nonFilteredFileExtensions>
            <nonFilteredFileExtension>pdf</nonFilteredFileExtension>
            <nonFilteredFileExtension>swf</nonFilteredFileExtension>
          </nonFilteredFileExtensions>
          ...
        </configuration>
      </plugin>
    </plugins>
    ...
  </build>
  ...
</project>

还有一个自定义过滤器机制,可以自己查看>>自定义Custom resources filters

看完语法之后发现,其实设置过滤和上面的include域exclude用法类似。官方说明如下:

When specifying a resource directory, every file within that directory may not be used. Thus, we may have to specify only the files that we want to include or specify the files that we want to exclude.

To include a resource, we only need to add an element.

And to exclude a resource, we only need to add an element.

For example, we can have both and elements. For example, if we want to include all text files that does not contain the word “test” in their filename.

<project>
  ...
  <name>My Resources Plugin Practice Project</name>
  ...
  <build>
    ...
    <resources>
      <resource>
        <directory>src/my-resources</directory>
        <includes>
          <include>**/*.txt</include>
        </includes>
        <excludes>
          <exclude>**/*test*.*</exclude>
        </excludes>
      </resource>
      ...
    </resources>
    ...
  </build>
  ...
</project>

看来解决办法就在这儿了。

原有的资源文件设置如上所示,经过修改之后,变更如下:

再次打包试一下:

完美。分享一下,挖坑填坑是个技术活。

### 使用 `classfinal-maven-plugin` 打包后启动失败的原因分析 在使用 `classfinal-maven-plugin` 进行项目打包时,如果遇到启动失败的情况,通常可能是由于以下几个原因引起的: #### 1. **主类未正确定义** 如果项目的入口类(即包含 `public static void main(String[] args)` 方法的类)未被正确指定,则可能导致无法找到主类而启动失败。这可能是因为 `pom.xml` 文件中的 `<mainClass>` 配置项缺失或错误。 解决方案是在 `pom.xml` 中正确配置 `spring-boot-maven-plugin` 插件的 `<mainClass>` 属性[^1]: ```xml <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>com.example.MyApplication</mainClass> </configuration> </plugin> </plugins> </build> ``` #### 2. **依赖冲突** 当项目中存在多个版本的相同依赖库时,可能会导致运行时异常。这种情况下,即使编译成功,也可能因为加载了不兼容的类而导致启动失败解决方法是通过 Maven 的依赖树工具检查并排除不必要的依赖版本: ```bash mvn dependency:tree ``` 排除冲突依赖可以通过以下方式实现: ```xml <dependency> <groupId>example.group</groupId> <artifactId>conflicting-artifact</artifactId> <exclusions> <exclusion> <groupId>problematic.group</groupId> <artifactId>problematic-artifact</artifactId> </exclusion> </exclusions> </dependency> ``` #### 3. **资源文件路径问题** 在某些场景下,`classfinal-maven-plugin` 或其他插件可能会改变默认的资源文件处理逻辑,从而导致必要的配置文件(如 `application.properties` 或 `application.yml`)未能被打入最终的 JAR 包中。 确保资源目录设置正确,并将其显式声明为构建的一部分: ```xml <resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.yml</include> </includes> </resource> </resources> ``` #### 4. **插件配置不当** 如果 `classfinal-maven-plugin` 的配置其他插件(如 `spring-boot-maven-plugin`)发生冲突,也有可能引发启动失败。例如,在尝试自定义分类器 (`<classifier>`) 时,如果没有正确调整目标输出路径,可能会丢失 `-exec.jar` 文件[^2]。 调整插件顺序或将特定阶段绑定到生命周期的不同部分可以缓解此问题: ```xml <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <executions> <execution> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin> ``` --- ### 综合解决方案 为了彻底解决问题,建议按照以下步骤逐一排查和修复: 1. 明确指定主类位置; 2. 清理重复或冗余的依赖关系; 3. 检查资源配置是否遗漏重要文件; 4. 审核各插件之间的交互行为是否存在潜在矛盾。 以下是完整的 `pom.xml` 示例片段供参考: ```xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <!-- ... --> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${spring-boot.version}</version> <configuration> <mainClass>com.example.MainApp</mainClass> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>3.2.0</version> <executions> <execution> <id>copy-resources</id> <phase>validate</phase> <goals> <goal>copy-resources</goal> </goals> <configuration> <outputDirectory>${basedir}/target/classes</outputDirectory> <resources> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> </resources> </configuration> </execution> </executions> </plugin> </plugins> </build> </project> ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值