如何使用 maven-compiler-plugin 配置 Lombok?

How to configure Lombok with maven-compiler-plugin?

我在项目的maven中有一个根模块和子模块。我正在尝试使用龙目岛。 我已经添加

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.12</version>
    <scope>provided</scope>
</dependency>

到 root pom.xml。 在子模块中,我有一个带有 Lombok 注释的 class。 当我尝试构建项目时,我得到了很多

cannot find symbol

我尝试调用 getter 和 setter 的地方。

我尝试在根 pom 和子 pom 中以及 delombok 中使用具有相同版本 (1.16.12) 的 lombok-maven-plugin 并移动我的注释 class 到 src/main/lombok, SO 里几乎所有的问题我都看了一遍, 尝试了所有变体, 但没有成功.

我正在使用 Maven 3, Java 8, maven-compiler-plugin with 3.6.1 version.

项目应该如何配置才能使用lombok?或者我做错了。

我不确定 lombok 和 lombok-maven-plugin 之间有什么区别,但是我的项目配置了这个依赖项:

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok-maven-plugin</artifactId>
        <version>1.16.12.0</version>
    </dependency>

我还没有尝试过根和子模块 pom,因为我的项目都倾向于相互隔离。不确定这是否会给您带来问题。

如果您使用的是 Eclipse,您是否 运行 lombok.jar 文件并将其指向您的 eclipse.exe 文件?它需要修改 .exe 以便 Eclipse 知道那些 getter 和 setter 即将到来,这样 Eclipse 就不会在开发过程中抱怨。

编辑: 我正在使用 maven-compiler-plugin:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.6.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>

我使用的是 Java 8 和 @Getter(onMethod = @__({@NoSerialization})) 以及 @Getter(onMethod = @__({@Translation(messageKey = "translation.key")})) onX 注释。我在错误输出中得到 duplicate element '<any?>' in annotation @<any?>. 。看起来 Lombok 的人对 Java 8 这样的问题已经有很长时间了 link to issue on github。 Lombok 不处理上面注释中带有 messageKey 等参数的注释。它仅适用于不带参数的注释和仅带 value 参数的注释(当您不写参数名称时)。

使用:

<scope>provided</scope>

在 pom.xml 中这样:

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.16.20</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

这不是对似乎已经解决的问题的直接回答,但可以作为以后搜索者的参考:

如果您使用 Dagger(或其他工具)来处理您的注释,例如

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.7.0</version>
      <configuration>
        <annotationProcessorPaths>
          <path>
            <groupId>com.google.dagger</groupId>
            <artifactId>dagger-compiler</artifactId>
            <version>2.15</version>
          </path>
        </annotationProcessorPaths>
        <source>1.8</source>
        <target>1.8</target>
      </configuration>
    </plugin>
    ....
  </plugins>
</build>

你必须添加 lombok 作为路径,如

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.7.0</version>
      <configuration>
        <annotationProcessorPaths>
          <path>
            <groupId>com.google.dagger</groupId>
            <artifactId>dagger-compiler</artifactId>
            <version>2.15</version>
          </path>

          <!-- SOLUTION --> 
          <path>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.20</version>
          </path>


        </annotationProcessorPaths>
        <source>1.8</source>
        <target>1.8</target>
      </configuration>
    </plugin>
    ....
  </plugins>
</build>

您仍然必须将 lombok 列为提供的依赖项。

如果有人使用 JDK 11

    <build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.8.0</version>
            <configuration>
                <source>${java.version}</source>
                <target>${java.version}</target>
                <annotationProcessorPaths>
                    <path>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok</artifactId>
                        <version>${lombok.version}</version>
                    </path>
                </annotationProcessorPaths>
                <compilerArgs>
                    <arg>-sourcepath</arg>
                    <arg>${project.basedir}/src/main/java${path.separator}${project.basedir}/target/generated-sources/annotations${path.separator}/</arg>
                </compilerArgs>
            </configuration>
        </plugin>
    </plugins>
</build>

Maven Groovy and Java + Lombok

这个堆栈溢出答案的解决方案对我有用。我之前错过了添加 javaAgentClass

我遇到了同样的问题,但没有任何效果,即 maven 插件版本、annotationProcessorPaths、提供的范围等。

最后,我将范围缩小到从同一项目中的 class 静态导入 @UtilityClass 方法,即不是从依赖项引入。这导致注释处理失败,即使是不相关的 classes,并且看起来 lombok 代码没有被正确编译。摆脱静态导入使一切正常。

Github 上有一个未解决的问题,但显然很难修复。

如果maven构建在访问项目lombok注释方法时找不到符号,那么我们必须显式配置annotationProcessorPathsmaven-compiler-plugin

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>${maven.compiler.plugin.version}</version>
            <configuration>
                <annotationProcessorPaths>
                    <path>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok</artifactId>
                        <version>${lombok.version}</version>
                    </path>
                </annotationProcessorPaths>
            </configuration>
        </plugin>
    </plugins>
</build>

以上解决方案对我来说很有魅力!

在使用之前的答案进行一些实验之后,这是我使用 ListAppender 而不是使用 Rule 的简单示例的总结:

package example;

import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.read.ListAppender;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.slf4j.LoggerFactory;

import static org.junit.jupiter.api.Assertions.assertEquals;

class AllMineTest {
    AllMine allMine = new AllMine();
    Logger logger = (Logger)         
    LoggerFactory.getLogger(AllMine.class.getName());
    ListAppender<ILoggingEvent> appender = new ListAppender<>();

    @BeforeEach
    public void setUp() {
        logger.addAppender(appender);
        appender.start();
    }

    @AfterEach
    private void teardown() {
        appender.stop();
        appender.list.clear();
        logger.detachAppender(appender);
    }

    @Test
    void shouldWriteLogs() {
        // When:
        allMine.writeLogs();
        // Then:
        List<String> logMessages = appender.list.stream()
            .map(ILoggingEvent::getMessage)
            .collect(Collectors.toList());
        assertEquals("Dogs are great", logMessages.get(0));
        assertEquals("I prefer cats", logMessages.get(1));
    }
}

我的作品class:

package example;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class AllMine {
    public void writeLogs() {
        log.info("Dogs are great");
        log.info("I prefer cats");
    }
}

我的 POM 中不需要 provided 作用域,但是 YMMV:

<?xml version="1.0" encoding="UTF-8"?>
<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>
  <groupId>org.example</groupId>
  <artifactId>example-maven</artifactId>
  <version>1.0-SNAPSHOT</version>
  <properties>
    <java.version>11</java.version>
    <lombok.version>1.18.12</lombok.version>
    <maven-plugin.version>3.8.1</maven-plugin.version>
    <slf4j.version>1.7.30</slf4j.version>
    <junit.version>5.7.2</junit.version>
    <logback.version>1.2.3</logback.version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>${lombok.version}</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>${slf4j.version}</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>${logback.version}</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.junit.jupiter</groupId>
      <artifactId>junit-jupiter-api</artifactId>
      <version>${junit.version}</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>${maven-plugin.version}</version>
        <configuration>
          <source>${java.version}</source>
          <target>${java.version}</target>
          <annotationProcessorPaths>
            <path>
              <groupId>org.projectlombok</groupId>
              <artifactId>lombok</artifactId>
              <version>${lombok.version}</version>
            </path>
          </annotationProcessorPaths>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>