How to ignore the Java Source directory during Maven Compilation?
Asked Answered
L

6

27

I am trying to use the Lombok Maven Plugin to ensure the correct creation of Javadocs when using Lombok.

Lombok Maven introduces a new code generation goal, just prior to compilation. In my configuration, my sourceDirectory (Java with Lombok annotations, src/main/java) is processed to create Java (without Lombok annotations) in target/generated-sources/delombok.

However, every file in sourceDirectory now has a corresponding (identically named) file in target/generated-sources/delombok, resulting in compilation failures due to duplicate classes.

How can I tell the Java compiler to ignore the sources in sourceDirectory?

Note that the default Lombok Maven configuration would have the developer put Java (with Lombok annotations) in the src/main/lombok folder instead of src/main/java. However, I do not wish to do this because it confuses IDEs and my code compiles just fine (if I remove the Maven plugin).

Also note that simply redefining sourceDirectory will also upset IDEs (they no longer know where to find the Java source code!).

Lutist answered 4/7, 2012 at 13:22 Comment(0)
G
35

I recently switched from using the flakey maven-exec-plugin approach to generate raw sources for the javadoc tool to using lombok-maven-plugin

My setup

  • All sources in src/main/java
  • Generated sources go in target/generated-sources/delombok

I initially ran into this problem but it seems to be an easy fix: Don't let lombok-maven-plugin add the delombok path to the compiler source paths with addOutputDirectoy. IE

<plugin>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok-maven-plugin</artifactId>
    <version>0.11.2.0</version>
    <executions>
        <execution>
            <phase>generate-sources</phase>
            <goals>
                <goal>delombok</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <addOutputDirectory>false</addOutputDirectory>
        <sourceDirectory>src/main/java</sourceDirectory>
    </configuration>
</plugin>

This seems to of solved the issue for now

EDIT: Bonus, how to generate proper javadocs with this setup

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-javadoc-plugin</artifactId>
    <version>2.8.1</version>
    <configuration>
        <defaultVersion>${project.version}</defaultVersion>
        <sourcepath>target/generated-sources/delombok</sourcepath>
    </configuration>
</plugin>
Ganof answered 13/8, 2012 at 8:53 Comment(5)
it's a good workaround! But it doesn't help with Javadoc generation which will be created using the src/main/java. Lombok has an RFE to start generating a lot more Javadocs so that might actually be a requirement for a future solutionLutist
@Lutist Sure it can, see the edit. Just did a test and it worked for meGanof
excellent! This obviously slows down the typical compile/run phases, is there a way that it will only run when creating javadocs?Lutist
@Lutist Not really. I honestly just wait, 94 classes that use lombok heavily only take 5-10 seconds to process. 2 options though I could think of: 1) Run mvn lombok:delombok whenever you run javadoc or 2) Bind to pre-site instead, although it won't run unless you do mvn siteGanof
@Lutist Just some follow up, I've found that replacing generate-sources with process-sourcesGanof
W
3

Create a new Maven profile, and in the new profile, just redefine the sources:

<sourceDirectory>target/generated-sources/delombok</sourceDirectory>

Alternatively

  1. Build helper: there's a build helper which seems to provide this functionality, but I have not used this before.
  2. Hack: there's a hack described here, but the author recommends against it, and besides: if you're going to take the time to modify your POM and create this hack, you may as well do things The Right Way and implement a profile.
Wive answered 4/7, 2012 at 14:7 Comment(4)
the profile approach could be a good way to do this - that way the profile could be used to build the package and javadocs, whereas the default profile could just ignore the delomboking altogether. Thanks! I'll leave this as unanswered for a little while to see if anyone comes up with a solution that doesn't require a separate profile for development and packaging.Lutist
OK, I've updated my answer with a hack you can implement, but neither me not the original author would recommend it :)Wive
Argh... turns out it is not possible to reset the <code>sourceDirectory</code> in a profile. It is one of the <code>build</code> elements that cannot be changed.Lutist
It is possible to set the source directory within a profile by using an additional property which is set in the profile: https://mcmap.net/q/386867/-change-source-directory-in-profile-mavenJermainejerman
T
2

The delombok goal is designed to transform java code from src/main/lombok to target/generated-source/delombok. Then, the other java code found in src/main/java is combined with target/generated-source/delombok to produce the combined java classes.

It helps to think of delombok as a source code generator.

So how can you get what you really want? (Note that Maven has an addCompileSourceRoot method, but not a corresponding removeCompileSourceRoot.) Imagine the following hack:

  1. Override the default <build><sourceDirectory> from src/main/java to be ${project.build.directory}/generated-sources/delombok.
  2. Override the default delombok sourceDirectory from src/main/lombok to be src/main/java, and disable addOutputDirectory.

Basically, you will use src/main/java, but Maven will ignore it and instead use target/generated-sources/delombok. The Lombok plugin will transform src/main/java into elaborated code in target/generated-sources/delombok.

<build>
  <sourceDirectory>${project.build.directory}/generated-sources/delombok</sourceDirectory>
  <plugins>
    <plugin>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok-maven-plugin</artifactId>
      <version>1.16.6.1</version>
      <executions>
        <execution>
          <id>delombok</id>
          <phase>generate-sources</phase>
          <goals>
            <goal>delombok</goal>
          </goals>
          <configuration>
            <addOutputDirectory>false</addOutputDirectory>
            <sourceDirectory>src/main/java</sourceDirectory>
          </configuration>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

Note that you should not need to hack other plugins, like maven-jar-plugin or maven-javadoc-plugin, because they should respect the sourceDirectory.

Use this hack at your own risk. (My guess is that this may confuse your IDE and some other developers.)

Trioecious answered 1/9, 2015 at 7:19 Comment(0)
S
2

I tried to use the solutions from the other answers, but IntelliJ would still mark my source files from src/main/java as duplicated. So I just decided to get rid of the delombok's content after compilation. In the end that folder only server as an intermediary stage for compilation (in my case it was required to use lombok with AspectJ compiler) and there's no real need to keep it. I did it by configuring an additional execution of the clean plugin which would specifically target the delombok folder.

Your POM should contain

<build>

    <sourceDirectory>${project.build.directory}/generated-sources/delombok</sourceDirectory>

    <plugins>
        <!-- will delombok source files into /target/generated-sources/delombok -->
        <plugin>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok-maven-plugin</artifactId>
            <version>1.16.16.0</version>
            <executions>
                <execution>
                    <phase>generate-sources</phase>
                    <goals>
                        <goal>delombok</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <addOutputDirectory>false</addOutputDirectory>
                <sourceDirectory>src/main/java</sourceDirectory>
            </configuration>
        </plugin>

        <!-- other plugins bound to compile phase should go here -->

        <plugin>
            <artifactId>maven-clean-plugin</artifactId>
            <executions>
                <execution>
                    <id>delombok-removal</id>
                    <phase>compile</phase>
                    <goals>
                        <goal>clean</goal>
                    </goals>
                    <configuration>
                        <excludeDefaultDirectories>true</excludeDefaultDirectories>
                        <filesets>
                            <fileset>
                                <directory>${project.build.sourceDirectory}/com</directory> <!-- assuming your root package is something like com.mycompany -->
                            </fileset>
                        </filesets>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
Sulphate answered 24/12, 2019 at 12:52 Comment(0)
N
1

Hit similar issue in Intellj, this worked for me:

IntellIJ IDEA -> Preferences -> Build, Execution, Deployment -> Compiler -> User-local build process VM options (overrides Shared options): -Djps.track.ap.dependencies=false

Niemann answered 12/9, 2022 at 5:13 Comment(0)
L
0

It would appear that there is no nice way to set up Lombok Maven. The "profile" approach suggested by @opyate doesn't work because of

http://jira.codehaus.org/browse/MNG-5310

However, a really ugly workaround is to simply have another pom.xml, identical in every way except with the sourceDirectory redefined, using the command line arguments to use the file like in:

Maven alternate pom

Lutist answered 12/7, 2012 at 14:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.