如何使用 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注释方法时找不到符号,那么我们必须显式配置annotationProcessorPaths
到maven-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>
我在项目的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注释方法时找不到符号,那么我们必须显式配置annotationProcessorPaths
到maven-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>