maven-pmd-plugin执行失败:Absent Code attribute错误求助
我在PrimeFaces项目的POM中配置了maven-pmd-plugin 3.9.0版本,搭配自定义规则集后执行mvn validate或mvn clean install时遇到了ClassFormatError错误,以下是详细的问题排查和解决步骤:
我的配置
POM中的PMD插件配置
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-pmd-plugin</artifactId> <version>3.9.0</version> <executions> <execution> <id>pmd-check</id> <phase>validate</phase> <goals> <goal>check</goal> </goals> </execution> </executions> <configuration> <printFailingErrors>true</printFailingErrors> <rulesets> <ruleset>code-analysis/ruleset.xml</ruleset> </rulesets> </configuration> </plugin>
自定义ruleset.xml
<?xml version="1.0"?> <ruleset name="Custom ruleset" xmlns="http://pmd.sourceforge.net/ruleset/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd"> <description> The default ruleset </description> <rule ref="rulesets/java/strings.xml"> <exclude name="AvoidDuplicateLiterals"/> </rule> <rule ref="rulesets/java/strings.xml/AvoidDuplicateLiterals"> <properties> <property name="skipAnnotations" value="true"/> </properties> </rule> <rule ref="rulesets/java/unusedcode.xml"/> <rule ref="rulesets/java/strictexception.xml"/> </ruleset>
遇到的错误
Failed to execute goal org.apache.maven.plugins:maven-pmd-plugin:3.9.0:pmd (pmd) on project primefaces: Execution pmd of goal org.apache.maven.plugins:maven-pmd-plugin:3.9.0:pmd failed: An API incompatibility was encountered while executing org.apache.maven.plugins:maven-pmd-plugin:3.9.0:pmd: java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/faces/application/FacesMessage$Severity
问题原因分析
这个错误的核心是PMD在分析类文件时,遇到了仅包含API定义但无实际代码实现的JAR包(比如Java EE的API依赖,通常是provided scope的空实现)。PMD 7.0.0(对应插件3.9.0版本)在类文件解析逻辑上做了变更,对这类空实现类的处理和旧版本(比如3.3.9)不同,导致抛出ClassFormatError。
解决方案
方案1:调整PMD插件的依赖,排除空API包
在maven-pmd-plugin的配置中,添加对PMD核心依赖的调整,确保它使用完整的JSF实现类而非仅API包,或者直接排除有问题的空API依赖:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-pmd-plugin</artifactId> <version>3.9.0</version> <!-- 其他配置保持不变 --> <dependencies> <dependency> <groupId>org.apache.pmd</groupId> <artifactId>pmd-java</artifactId> <version>7.0.0</version> <exclusions> <!-- 排除可能引入空API的依赖 --> <exclusion> <groupId>javax.faces</groupId> <artifactId>javax.faces-api</artifactId> </exclusion> </exclusions> </dependency> <!-- 可选:添加完整的JSF实现依赖供PMD使用 --> <dependency> <groupId>org.glassfish</groupId> <artifactId>javax.faces</artifactId> <version>2.3.14</version> <scope>runtime</scope> </dependency> </dependencies> </plugin>
方案2:配置PMD跳过有问题的类/包
在ruleset.xml中添加exclude规则,跳过javax.faces相关的类分析,避免PMD解析这些空API类:
<?xml version="1.0"?> <ruleset name="Custom ruleset" xmlns="http://pmd.sourceforge.net/ruleset/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd"> <description> The default ruleset </description> <!-- 跳过javax.faces包下的所有类 --> <exclude-pattern>.*/javax/faces/.*</exclude-pattern> <!-- 原有规则保持不变 --> <rule ref="rulesets/java/strings.xml"> <exclude name="AvoidDuplicateLiterals"/> </rule> <rule ref="rulesets/java/strings.xml/AvoidDuplicateLiterals"> <properties> <property name="skipAnnotations" value="true"/> </properties> </rule> <rule ref="rulesets/java/unusedcode.xml"/> <rule ref="rulesets/java/strictexception.xml"/> </ruleset>
方案3:降级PMD插件版本
如果上述方案都不适用,可以暂时降级到能正常工作的版本(比如3.3.9),但这只是临时方案,长期建议适配新版本:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-pmd-plugin</artifactId> <version>3.3.9</version> <!-- 其他配置保持不变 --> </plugin>
验证方法
修改配置后,执行mvn clean validate命令,如果不再抛出ClassFormatError,说明问题已解决。
内容的提问来源于stack exchange,提问作者Kalle Richter

