Reputation: 515
I was using Lombok with JDK8 and everything was working fine. However, when I tried upgrading to JDK17, compilation fails with error
error: cannot find symbol
[ERROR] symbol: class Builder
cannot find symbol
[ERROR] symbol: method getKey()
In my parent pom, I have
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.26</version>
</dependency>
Project structure is :
MainProject
|
-subProject1 --> pom1.xml
-subProject2 --> pom2.xml
-subProject3 --> pom3.xml
|
- Main pom.xml
- lombok.config
The main pom.xml has
<modules>
<module>subProject1</module>
<module>subProject2</module>
<module>subProject3</module>
</modules>
I am getting same issue in Intellij as well as Mac terminal so this issue is not specific to Intellij.
Tried multiple things from internet. Added lombok.addLombokGeneratedAnnotation = true in lombok.config.
Tried <annotationProcessorPaths>
in maven-compiler plugin.But nothing is working.I am totally blocked.Kindly suggest.
Upvotes: 1
Views: 7005
Reputation: 56
When adding Lombok to the project in IntelliJ IDEA, I considered several important factors. First, I reviewed the SDK version in the project settings, along with the language level. It's crucial to ensure that these settings align with the appropriate versions specified in the project's POM.xml file. This consistency is essential for Lombok to function correctly within the development environment.
If you're building the project using Maven, there are additional steps to consider. First, navigate to Edit Configuration and add Maven. Here, you can view both Maven settings and Java JRE options. It's crucial to ensure that the JRE version in this configuration aligns with the Java version settings mentioned earlier.
Alternatively, you can configure these settings through the main IDE preferences. To do this, access Settings using Ctrl+Alt+S, then navigate to Build, Execution, Deployment. Within this section, locate the Maven subsection and click on the Runner option. Here, you can also set the JRE configuration.
Another crucial consideration when integrating Lombok into your project is the configuration of your pom.xml file. If you're using either the spring-boot-maven-plugin or the maven-compiler-plugin, you must exclude Lombok from these plugins to prevent potential conflicts. Here's how you can do this:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
The Java version plays a significant role in this process. To ensure compatibility, you can override the default version inherited from the parent project by specifying the java.version property in your pom.xml file. This allows you to precisely control the Java version used in your project, which is crucial for proper Lombok integration. We can specify the desired Java version in the compiler plugin as well.
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>17</java.version>
<maven.compiler.target>17</maven.compiler.target>
<maven.compiler.source>17</maven.compiler.source>
</properties>
Also, for the compiled classes to be compatible with JVM 17, the –target value should be 17. Alternatively, we can configure the compiler plugin directly:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
...
<configuration>
...
<source>17</source>
<target>17</target>
</configuration>
</plugin>
Last but not least, I’d like to mention something that might seem a little odd but is something I occasionally encounter when initializing a new project in Spring Boot. When using Spring Initializr, it generates a pom.xml file where Lombok's version is inherited from spring-boot-starter-parent. However, I’ve noticed that explicitly specifying a fixed version for Lombok in the dependency section, as shown below, and ensuring consistency in any plugin configurations surprisingly resolves the issue.
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.36</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
Upvotes: 0
Reputation: 1
In response to the answer of Chris S - I had the exact same issue with pretty much identical versions as he specified. Lombok would work in Module 1 but not in Module 2.
What eventually solved it - I had specified a Maven compiler plugin in the parent pom and also Module 1 and Module 2 pom files. After removing the entries in the child pom, everything Lombok related began to work across the whole project.
I had also set up the maven compiler in the parent POM as below (but this had been done originally on the project and not at the time I resolved the issue, so it may not be relevant) so YMMV. Lombok Version is 1.18.26:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
Upvotes: 0
Reputation: 31
Folks, after migrating from Spring Boot 2.7 (JDK 8) to Spring Boot 3.1.5 (JDK17; Maven 3.9.5) I was also facing this issue: cannot find symbol
Starting a new project shows the setup is working as expected. So its project related.
Verification:
pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.db.orinoco.soa.sb</groupId>
<artifactId>javaelevenstarter</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>javaelevenstarter</name>
<description>Demo project for Spring Boot 3 and JDK 17 (maven 3.9.5)</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
lombok.config
# Tell the @Slf4j annotation to generate the field 'LOG'.
lombok.log.fieldName = LOG
person.java
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
@Builder
@Getter
@NoArgsConstructor
@AllArgsConstructor
class Person {
private String name;
private String surname;
private String town;
}
JavaElevenStarterApplicationTests.java
@Slf4j
@SpringBootTest
class JavaElevenStarterApplicationTests {
@Test
void contextLoads_lombock_AllArgsConstructor_Getter() {
final Person person = new Person("Dave", "Developer", "Davetown");
final String name = person.getName();
final String surname = person.getSurname();
final String town = person.getTown();
LOG.info("Person data - Name: {}, surname: {}, town: {}", name, surname, town);
Assert.hasText(name, "Dave");
Assert.hasText(surname, "Developer");
Assert.hasText(town, "Davetown");
}
@Test
void contextLoads_Builder_pattern() {
final Person person = Person.builder()
.name("Dave")
.surname("Developer")
.town("Davetown")
.build();
final String name = person.getName();
final String surname = person.getSurname();
final String town = person.getTown();
LOG.info("Person data - Name: {}, surname: {}, town: {}", name, surname, town);
Assert.hasText(name, "Dave");
Assert.hasText(surname, "Developer");
Assert.hasText(town, "Davetown");
}
}
Tests passed: 2
console:
...JavaElevenStarterApplicationTests: Person data - Name: Dave, surname: Developer, town: Davetown
...JavaElevenStarterApplicationTests: Person data - Name: Dave, surname: Developer, town: Davetown
This leads me to the assumption some dependency are causing the issue and lombok fails first.
Inspect your project dependencies and try to get your project compile.
Upvotes: 0
Reputation: 97507
The configuration in maven-compiler-plugin should look like this. The property lombok.version
(version:
<properties>
<maven.compiler.release>20</maven.compiler.release>
<spring.boot.version>3.2.0-M2</spring.boot.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<lombok.version>1.18.28</lombok.version>
</properties>
<dependencyManagement>
<dependencies>
...
<dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
</dependency>
</dependencies>
</dependencyManagement>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
It is also important to define the lombok project as a dependency in the modules which really use it like this:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
Upvotes: 3