28

I have a root module and submodule in maven in the project. I am trying to use Lombok. I have added

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

to root pom.xml. In submodule I have a class with Lombok annotations. When I am trying to build the project I get a lot of

cannot find symbol

where I am trying to call getters and setters.

I have tried to use lombok-maven-plugin with same version (1.16.12) in root pom and in the sub pom as well with delombok and moving my annotated class to src/main/lombok, I have looked through almost all questions in SO, try all the variants, but not succeed.

I am using Maven 3, Java 8, maven-compiler-plugin with 3.6.1 version.

How should I configure the project to be able to use lombok? Or maybe I am doing smth wrong.

Oleksandr Zaiats
  • 768
  • 2
  • 10
  • 15
  • 1
    did you add it as a dependency? you need to configure it as plugin to be executed before the compile plugin: http://awhitford.github.io/lombok.maven/lombok-maven-plugin/usage.html – wemu Feb 15 '17 at 18:37
  • what kind of IDE are you using? – pezetem Feb 15 '17 at 20:41
  • How are you building your project? Are you using an IDE? Have you tried building it using maven directly? – Michele Da Ros Feb 15 '17 at 20:43
  • @wemu Yes, I have tried with a plugin as well : ` org.projectlombok lombok-maven-plugin 1.16.12.0 generate-sources delombok ` Also I have put annotated classes in src/main/lombok instead of src/main/java – Oleksandr Zaiats Feb 15 '17 at 22:22
  • 1
    @MicheleDaRos IDE does not matter. I am running maven commands – Oleksandr Zaiats Feb 15 '17 at 22:24

8 Answers8

31

This is not a direct answer to the question which seems to be solved but acts as reference for future searchers:

If you're using Dagger (or something else) to process your annotations like

<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>

You have to add lombok as path like

<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>

You still have to list lombok as provided dependency tho.

Ore
  • 972
  • 2
  • 12
  • 24
  • this is the solution for me. I did not use dagger but mapstruct-processor, and I did not recognize the "set" and "get" at compile time. Adding lombok also in the plugin, It identifies the "set" and "get" in both the build and compile times. – pagurix Sep 05 '18 at 09:11
  • 1
    Maybe move this answer to https://stackoverflow.com/questions/50361786/using-dagger2-with-lombok – Markus Schulte Mar 29 '19 at 13:05
14

In case of anyone using 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>
Edgar Asatryan
  • 687
  • 9
  • 13
3

I had this same issue and nothing worked, i.e. maven plugin version, annotationProcessorPaths, provided scope, etc.

In the end I narrowed it down to having a static import on an @UtilityClass method from a class within the same project, i.e. not brought in from a dependency. This caused annotation processing to fail, even for unrelated classes, and made it look like lombok code was just not being compiled properly. Getting rid of the static import made it all work.

There's an open issue on Github for this, though apparently it's too hard to fix.

muhmud
  • 4,474
  • 2
  • 15
  • 22
  • This was my issue as well, I was attempting to statically import the builder methods from a handful of classes and it caused a compiler error on the tests. Very tricky, because intellij acts like everything is fine. – bheklilr Feb 21 '23 at 13:50
  • Same issue - I had a static import that I used within an annotation. Compiler fails and I thought it was Lombok. You saved my night. – Kostadinov Sep 01 '23 at 19:21
1

I'm not sure what the difference is between lombok and lombok-maven-plugin, but my projects are configured with this dependency:

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

I haven't experimented with root and submodule poms yet, as my projects all tend to be rather isolated from each other. Not sure if that could be causing an issue for you.

If you are using Eclipse, have you run the lombok.jar file and pointed it to your eclipse.exe file? it needs to modify the .exe in order for Eclipse to know that those getters and setters are coming, so that Eclipse doesn't complain during development.

Edit: I'm using 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>
Dan N
  • 98
  • 1
  • 1
  • 6
  • Are you using maven-compile-plugin? IDE does not matter. – Oleksandr Zaiats Feb 15 '17 at 22:26
  • Looks like Lombok could not work with maven-compiler-plugin and annotations like `@Getter(onMethod = @__(@Translation(messageKey = "translation.key")))`. I get an `cannot find symbol symbol: class __` compilation error. But it works fine with `@Getter(onMethod = @__(@NoSerialization))`-like annotations – Oleksandr Zaiats Feb 16 '17 at 13:38
  • @O.Zaiats Given your post about @Getter(onMethod = @__..., I suspect my configuration may not help you, since I'm not using that annotation, and the bug report you linked makes it clear it is something particular to that annotation syntax and Java 1.8. For what it's worth, I am using JDK 1.8.0_60 and Maven 3.3.9 (embedded in Eclipse Neon). – Dan N Feb 16 '17 at 13:43
1

I was using Java 8 and @Getter(onMethod = @__({@NoSerialization})) and @Getter(onMethod = @__({@Translation(messageKey = "translation.key")})) onX annotations. And I get duplicate element '<any?>' in annotation @<any?>. in error output. Looks like guys from Lombok have such issue with Java 8 for a long time link to issue on github. Lombok does not handle annotations with parameters like messageKey in annotation above. it works only with annotations without parameters and annotations with only value parameter (when you don't write the name of parameter).

Oleksandr Zaiats
  • 768
  • 2
  • 10
  • 15
  • 1
    @AJT_82 It was not a new question, it was real answer with a request for some help (if somebody will look at this question in future when Lombok will have support of such annotations). So you should remove -1 vote. – Oleksandr Zaiats Feb 20 '17 at 08:12
  • I did not downvote. But you probably got a downvote because you had a question in your answer (which is not allowed) Now you have formatted your answer, and it seems to be a proper answer now :) – AT82 Feb 20 '17 at 08:16
  • This is due to a bug in javac. We figured out a way to work around the issue. You can track our progress and follow the discussion via: https://github.com/rzwitserloot/lombok/issues/778 – rzwitserloot Feb 27 '17 at 23:52
1

If the maven build cannot find the symbol when accessing project lombok annotated methods, then we explicitly have to configure annotationProcessorPaths into 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>

Above solution works like a charm for me!

Chintan Panchal
  • 721
  • 6
  • 11
1

After some experimentation using the previous answers, here is my summary of a simple example using ListAppender and not using a 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));
    }
}

For my production 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");
    }
}

I didn't need the provided scope in my POM but 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>
Adrian Redgers
  • 364
  • 3
  • 9
-1

use:

<scope>provided</scope>

in pom.xml like that:

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.16.20</version>
        <scope>provided</scope>
    </dependency>
</dependencies>
Jan Nielsen
  • 10,892
  • 14
  • 65
  • 119
  • 2
    While this code snippet may be the solution, [including an explanation](//meta.stackexchange.com/questions/114762/explaining-entirely-‌​code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. – peacetype Jan 19 '18 at 21:50
  • @RafaelLemes As you can see in my question, I have used provided – Oleksandr Zaiats Jan 24 '18 at 09:10
  • Why would this work? – Software Engineer Aug 14 '23 at 14:54