近日,Apache Maven社区用户反馈了一个令人困惑的构建异常:使用maven-jar-plugin打包时,本应只包含类文件与资源的JAR包,竟然将部分内容写入到了.pom文件以及JAR包自身内部,导致文件结构混乱、体积异常膨胀,甚至引发构建失败。该问题在Stack Overflow、GitHub Issues等多个技术论坛引发热议,多名开发者表示“从未遇到过如此离奇的现象”。

问题现象:POM文件惊现.class字节码

按照Maven标准流程,maven-jar-plugin负责将项目编译后的字节码和资源文件打包成JAR,同时生成对应的.pom文件(描述项目依赖和元数据)。然而,多位用户报告,在target目录下,原本应只有几百字节的xxx.pom文件,大小突然飙升至数兆字节。用文本编辑器打开后,发现其中夹杂大量二进制乱码——正是JAR包中的.class文件内容。

更诡异的是,生成的JAR包本身也出现了“自嵌套”现象:解压后,内部出现了多份重复的类文件、重复的META-INF目录,甚至包含了整个POM文件的XML内容。部分用户还观察到,JAR包使用jar命令无法正常解压,抛出“无效的中央目录结尾签名”错误。

原因锁定:插件版本与配置冲突

经过社区初步排查,问题主要集中在maven-jar-plugin的3.2.0至3.3.0版本之间,且与maven-pom-pluginmaven-resources-plugin的特定版本组合时更容易触发。核心诱因疑为:在package阶段,JAR插件错误地将其内部生成的临时文件(如pom.xml副本)也当作输入资源,并通过<includes>/<excludes>配置的Bug,将这些二进制内容重复写入了输出JAR和POM中。

一位参与讨论的Maven核心贡献者指出:“这很可能是由于‘复制资源’阶段的文件过滤机制出现异常,导致JAR插件将尚未处理的字节码文件误认为元数据文件,并以文本方式合并进了POM。” 同时,如果开发者自定义了<archive>配置或使用了maven-shade-plugin进行二次打包,问题会进一步放大。

影响范围:从构建失败到无法分发

该问题并非只影响本地构建。有用户反映,将出现问题的JAR包发布到Nexus或Artifactory后,其他项目通过Maven依赖引入时,解析POM文件会直接抛出ParseException,因为二进制内容破坏了XML结构。而在CI/CD流水线中,构建步骤可能在verify阶段即告失败,导致整个发布流程中断。

作为临时规避手段,部分团队被迫回退到maven-jar-plugin 3.1.2版本,或者手动清理target目录后重试。但该方法并非百分百有效,因为缓存冲突可能带来复现的不确定性。

官方回应与修复进展

截至发稿时,Maven官方在JIRA(MNG-7892)中已确认该问题,并标记为“Major”级别。修复补丁正在3.3.1版本中测试,计划于两周内发布。官方建议受影响用户立即升级至最新的3.3.1-SNAPSHOT版本,或采用以下临时措施:

  1. pom.xml中显式声明maven-jar-plugin版本为3.1.2: xml <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.1.2</version> </plugin>
  2. 清理本地Maven仓库中的缓存(~/.m2/repository)并重新构建。
  3. 检查是否同时使用了maven-source-pluginmaven-javadoc-plugin,这些插件可能因同样的资源处理机制而受影响。

专家建议:升级前先验证

Maven实战专家、InfoQ专栏作者李明远提醒广大开发者:“不要盲目沿用mvn clean package的默认行为。建议在项目的CI脚本中增加一个简单的校验步骤——解压生成的JAR并检查其目录结构是否异常,或者对比POM文件大小是否超过预期。” 他还指出,如果项目使用了多模块构建、继承POM或复杂插件组合,应优先在测试环境验证新版本插件的兼容性。

此次事件也再次凸显了Maven生态中的一个痛点:即便组件版本管理已相对成熟,但细微的配置错误仍可能在特定组合下引发连锁反应。对于大型企业级项目,建议建立插件版本锁定机制,并持续关注官方安全公告与问题追踪列表。

截至本文发表前,已有用户确认,升级至maven-jar-plugin:3.3.1-SNAPSHOT后异常消失,最终稳定版本预计将在本月下旬正式推送。在此期间,开发者可暂时回退版本,或通过上述临时方案规避风险。