一、问题现象

VS Code / Cursor 或其它使用 m2e 的 IDE 中,对 dragon-mall、continew-starter 等多模块 Maven 项目进行自动构建、刷新或导入时,出现如下错误:

Failed to execute mojo com.diffplug.spotless:spotless-maven-plugin:2.43.0:apply {execution: default}

Caused by: java.lang.NoClassDefFoundError: lombok/patcher/Symbols
    at org.eclipse.jdt.internal.formatter.DefaultCodeFormatter.$lombok$$wrapper$0$createAST(DefaultCodeFormatter.java)
    ...

Caused by: java.lang.ClassNotFoundException: lombok.patcher.Symbols

特点:

  • 命令行执行正常

mvn compile
mvn install

都不会报错。

  • 只有 IDE 触发 Maven 构建时才会失败

例如:

  • VS Code 自动构建

  • Maven Reload

  • 项目导入

相关 Issue:

https://github.com/redhat-developer/vscode-java/issues/4284

问题核心:

Spotless + Eclipse JDT formatter + Lombok 在 m2e 的类加载环境中找不到 Lombok 类。


二、问题原因

Spotless 在格式化 Java 代码时使用:

Eclipse JDT formatter

而 Lombok 在 JDT 中是通过 patcher 机制工作的。

命令行 Maven 中:

Maven 独立 JVM
完整 classpath

因此 Lombok 类可以正常加载

但在 IDE 内嵌 Maven(m2e) 中:

插件运行在 IDE ClassLoader
Lombok patcher 类不可见

因此出现:

NoClassDefFoundError: lombok/patcher/Symbols

三、尝试过的解决方案

方案一:使用 m2e lifecycle-mapping(未生效)

pom.xml 中加入:

<plugin>
    <groupId>org.eclipse.m2e</groupId>
    <artifactId>lifecycle-mapping</artifactId>
    <version>1.0.0</version>
    <configuration>
        <lifecycleMappingMetadata>
            <pluginExecutions>
                <pluginExecution>
                    <pluginExecutionFilter>
                        <groupId>com.diffplug.spotless</groupId>
                        <artifactId>spotless-maven-plugin</artifactId>
                        <versionRange>[1.0.0,)</versionRange>
                        <goals>
                            <goal>apply</goal>
                            <goal>check</goal>
                        </goals>
                    </pluginExecutionFilter>
                    <action>
                        <ignore />
                    </action>
                </pluginExecution>
            </pluginExecutions>
        </lifecycleMappingMetadata>
    </configuration>
</plugin>

作用:

让 IDE 忽略 Spotless 插件执行。

但在 VS Code / Cursor + Red Hat Java 扩展 中:

仍然会执行 Spotless 插件并报错。

因此该方案 未采用


四、最终解决方案(推荐)

去掉 Spotless 的生命周期绑定

从 Spotless 插件中 移除 <executions> 配置,不再把 spotless:apply 绑定到 Maven 生命周期。


修改前

<plugin>
    <groupId>com.diffplug.spotless</groupId>
    <artifactId>spotless-maven-plugin</artifactId>

    <executions>
        <execution>
            <phase>compile</phase>
            <goals>
                <goal>apply</goal>
            </goals>
        </execution>
    </executions>

    <dependencies>...</dependencies>
    <configuration>...</configuration>

</plugin>

修改后

<!-- 不绑定生命周期,避免 IDE/m2e 下 Lombok 类加载错误 -->
<!-- 需要格式化时手动执行 mvn spotless:apply -->

<plugin>
    <groupId>com.diffplug.spotless</groupId>
    <artifactId>spotless-maven-plugin</artifactId>

    <dependencies>...</dependencies>

    <configuration>...</configuration>

</plugin>

五、去掉 executions 后会发生什么?

去掉 <executions> 后:

Spotless 不再自动执行。

只有手动执行 Maven 命令时才会运行。

目的 命令
格式化代码 mvn spotless:apply
仅检查格式 mvn spotless:check

项目根目录执行即可,多模块项目会自动处理所有模块。


六、CI 中如何检查代码格式

可以在 CI 流水线中增加一步:

mvn spotless:check

如果代码格式不符合规则,CI 会直接失败。


七、小结

问题总结:

  • 问题原因

Spotless + Eclipse JDT + Lombok
在 IDE m2e ClassLoader 下找不到 Lombok patcher
  • 问题表现

NoClassDefFoundError: lombok/patcher/Symbols
  • 解决方案

删除 Spotless 插件中的:

<executions>

避免其绑定到 compile 等生命周期。

  • 格式化方式

需要时手动执行:

mvn spotless:apply

mvn spotless:check

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐