80

I recently found out that the lombok.jar ends up in our final artifact, which shouldn't be necessary. In my understanding lombok is compile-time only.

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.14.4</version>
        </dependency>

But when I set it to scope provided, I get strange behaviour in unit tests. They crash with ClassNotFoundExceptions then when trying to resolve

java.lang.NoClassDefFoundError: com/svv/esp/serviceimpl/dataimport/common/validation/LongValidator

Which maven scope is in general used for lombok?

I'm using Oracle JDK build 1.8.0_25-b17 on MacOSX 10.9

mkraemerx
  • 1,713
  • 2
  • 17
  • 21
  • 1
    well, you may need to set the scope to test. as for your question, i usually set it to compile but it just because i'm to lazy to bother with it :p – kucing_terbang Apr 01 '15 at 08:31

4 Answers4

171

Lombok should be used at the provided scope (see the official docs).

The reason (as has been stated in the comments) is that lombok is a compile-time-only tool. That is, it is not needed at runtime at all. By making the scope provided, you make the lombok libraries available to the compiler but it is not a dependency of your compiled jar. As such, your final jar will not depend on Lombok and it does not need to be included in any deployment, which reduces the dependencies and size of your deployables.

Taoufik Mohdit
  • 1,910
  • 3
  • 26
  • 39
agentgonzo
  • 3,473
  • 3
  • 25
  • 30
  • 74
    As a side note, cause this might be confusing for a lot of people: maven scope `compile` means it's available at compile time and at run time. If scope is `provided` it's only available at compile time. See http://stackoverflow.com/questions/6646959 – Tim Büthe Feb 09 '17 at 10:19
  • 3
    I, too, was confused of this `compile` versus `provided` thing in java when i used lombok [here](https://asciinema.org/a/VDw2z6tqFsR1aAinR9tQM8QiV). Thanks for the explanation. – daparic Oct 17 '19 at 15:59
5

One can work with compile and true for <optional/>.

<scope>compile</scope>
<optional>true</optional>

See Maven – Optional Dependencies and Dependency Exclusions.

Jin Kwon
  • 20,295
  • 14
  • 115
  • 184
  • 6
    https://projectlombok.org/setup/maven Official Lombok documentation says to use the `provided` scope – Cardin Jun 28 '21 at 07:14
0

You must configure the spring-boot-maven-plugin to exclude the lombok jar from the Spring executable jar file.

Here is an example plugin configuration from a pom.xml:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <addResources>true</addResources>
        <classifier>module</classifier>
        <excludes>
            <exclude>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
            </exclude>
        </excludes>
    </configuration>
</plugin>
DwB
  • 37,124
  • 11
  • 56
  • 82
-1

Usually compile. provided is for jars that are usually shipped with the application server that will host the application. If you don't want the jar in the final application, it is maybe best to use the maven plugin rather than the jar directly: http://awhitford.github.io/lombok.maven/lombok-maven-plugin/index.html

EmirCalabuch
  • 4,756
  • 1
  • 25
  • 20
  • 1
    +1 for the lombok plugin, didn't know that. But still, it isn't obvious to me why provided does not work in this case. It should be available during compile time and not be necessary anymore in later phases. – mkraemerx Apr 10 '15 at 11:37
  • To be certain I would need to at least see the `LongValidator` class that is reported missing and probably other elements in the pom, but most probably the problem with `provided` is that Lombok must perform its work when compilation takes places, or in runtime. If you do not include it nor generate the Lombok code when compiling, your class will be as if is was not processed by Lombok. – EmirCalabuch Apr 10 '15 at 14:57
  • 1
    To clarify further: Lombok is not just a library, it is a processor that modifies the code when compilation takes place. So you need to execute it when compiling, if you switch it to `provided` scope this will not happen by default (you can force maven to run the lombok processor adding `-Dexec.classpathScope="compile"`to the command line.) – EmirCalabuch Apr 10 '15 at 15:30
  • 4
    This answer just isn't correct. The plugin doesn't need to be used, and the documentation says provided scope – OneCricketeer Jun 01 '21 at 23:29