Search code examples
javamavenlombok

Create and install de-lomboked source jar in maven


Disclaimer: I have solved this problem and am documenting the solution for the world to know.

How do I create and install a *-sources.jar containing "delomboked" source code in maven?

By default, The maven-source-plugin creates a sources jar without delomboking the source files, which causes projects that depend on the library binaries to complain about mismatching source files.


Solution

  • TL;DR (explained beneath)

    Add the following plugins configuration to your plugins configuration in the project.build element of your pom.xml

    <project>
        ...
    <build>
    <plugins>
        ...
    <plugin>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok-maven-plugin</artifactId>
        <version>1.18.0.0</version>
        <executions>
            <execution>
                <phase>generate-sources</phase>
                <goals>
                    <goal>delombok</goal>
                </goals>
            </execution>
        </executions>
        <configuration>
            <sourceDirectory>src/main/java</sourceDirectory>
            <outputDirectory>${project.build.directory}/delombok</outputDirectory>
            <addOutputDirectory>false</addOutputDirectory>
            <encoding>UTF-8</encoding>
        </configuration>
    </plugin>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-resources-plugin</artifactId>
        <version>3.1.0</version>
        <executions>
            <execution>
                <id>copy-to-lombok-build</id>
                <phase>process-resources</phase>
                <goals>
                    <goal>copy-resources</goal>
                </goals>
                <configuration>
                    <resources>
                        <resource>
                            <directory>${project.basedir}/src/main/resources</directory>
                        </resource>
                    </resources>
                    <outputDirectory>${project.build.directory}/delombok</outputDirectory>
                </configuration>
            </execution>
        </executions>
    </plugin>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-antrun-plugin</artifactId>
        <version>1.8</version>
        <executions>
            <execution>
                <id>generate-delomboked-sources-jar</id>
                <phase>package</phase>
                <goals>
                    <goal>run</goal>
                </goals>
                <configuration>
                    <target>
                        <jar destfile="${project.build.directory}/${project.build.finalName}-sources.jar"
                             basedir="${project.build.directory}/delombok"/>
                    </target>
                </configuration>
            </execution>
        </executions>
    </plugin>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-install-plugin</artifactId>
        <version>2.5.2</version>
        <executions>
            <execution>
                <id>install-source-jar</id>
                <goals>
                    <goal>install-file</goal>
                </goals>
                <phase>install</phase>
                <configuration>
                    <file>${project.build.directory}/${project.build.finalName}-sources.jar</file>
                    <groupId>${project.groupId}</groupId>
                    <artifactId>${project.artifactId}</artifactId>
                    <version>${project.version}</version>
                    <classifier>sources</classifier>
                    <generatePom>true</generatePom>
                    <pomFile>${project.basedir}/pom.xml</pomFile>
                </configuration>
            </execution>
        </executions>
    </plugin>
    </plugins>
    </build>
    </project>
    

    Explanation

    lombok-maven-plugin will enable you to delombok the source code (${project.basedir}/src/main/java) and place it in the target directory (${project.build.directory}/delombok). Usually this will place the code in the ${project.build.directory}/generated-sources/delombok folder, but because Intellij automatically considers this additional source-code, duplicate code errors will occur when developing your library, in order to stop this, just specify a non-default target directory (in this case just outside of the generated-sources dir).

    maven-resources-plugin is necessary in order to also copy resources from the standard ${project.basedir}/src/main/resources directory. If there are any other non-standard resource directories in your project, you should configure them in the resources section for this plugin.

    maven-antrun-plugin is used instead of the maven-source-plugin because you cannot specify a custom source directory in the latter. The jar task points to our custom "generated-sources" and produces the standard-named sources jar.

    maven-install-plugin install-file goal is used because you cannot attach jars using the install goal. We can hack a solution by manually installing a file using the install-file goal with a classifier of sources.

    I hope this helps others who are on struggle street like I was with this problem.