2

I am converting an existing Java library to use module-info.java. I use Lombok and generics extensively. When I run "mvn package" I get a ton of errors that follow this pattern:

[ERROR] /projects/app/src/main/java/com/whatever/app/server/handlers/HandlerCreateForumPost.java:[116,13] cannot find symbol
[ERROR]   symbol:   method <com.whatever.app.common.messages.CreateForumPostResults>builder()
[ERROR]   location: class com.whatever.app.common.Response

The statement that causes the error is:

return Response
    .<CreateForumPostResults>builder()
    .success(true)
    .requestID(context.getRequestID())
    .results(
        CreateForumPostResults
            .builder()
            .id(forumPostID)
            .build()
    )
    .build();

Line 116 reported in the error is the one that reads ".builder()".

The Response class lives in com.whatever.app.common and is defined as:

package com.whatever.app.common;

import lombok.Getter;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import lombok.extern.jackson.Jacksonized;

@SuperBuilder
@Jacksonized
@Getter
@Setter
public class Response<T extends Response.Results> {
    boolean success;
    String message;
    String requestID;
    T results;

    @SuperBuilder
    @Jacksonized
    @Getter
    @Setter
    public static class Results {

    }
}

The CreateForumPostResults class lives in com.whatever.app.common.messages and extends Response.Results:

package com.whatever.app.common.messages;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.whatever.app.common.AppResponse;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import lombok.extern.jackson.Jacksonized;

import java.util.UUID;

@SuperBuilder
@Getter
@Setter
@Jacksonized
public class AppCreateForumPostResults extends AppResponse.Results {
    @JsonProperty("id")
    UUID id;
}

My module-info.java looks like this:

module com.whatever.app.common {
    exports com.whatever.app.common;
    exports com.whatever.app.common.messages;

    requires com.fasterxml.jackson.annotation;
    requires com.fasterxml.jackson.core;
    requires com.fasterxml.jackson.databind;
    requires com.fasterxml.jackson.datatype.jsr310;
    requires com.google.common;
    requires lombok;
}

My POM is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         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>

    <parent>
        <artifactId>app</artifactId>
        <groupId>com.whatever</groupId>
        <version>0.9</version>
    </parent>

    <artifactId>app-common</artifactId>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <maven.compiler.plugin.version>3.8.1</maven.compiler.plugin.version>

        <maven.jar.plugin.version>3.2.0</maven.jar.plugin.version>

        <guava-version>23.0</guava-version>

        <jackson-version>2.13.1</jackson-version>

        <lombok-version>1.18.22</lombok-version>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.compiler.plugin.version}</version>
                <configuration>
                    <source>${maven.compiler.source}</source>
                    <target>${maven.compiler.target}</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>${maven.jar.plugin.version}</version>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${jackson-version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
            <version>${jackson-version}</version>
        </dependency>

        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>${guava-version}</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok-version}</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
</project>

I suspect that there's some magic incantation needed to make Lombok's @Builder annotation (and possibly others) work with module-info.java, or perhaps something related to generics that is causing this to break, but I haven't been able to figure out what it is.

What am I doing wrong?

Any insights are greatly appreciated.

Tim Gustafson
  • 177
  • 1
  • 11

1 Answers1

6

As is often the case, taking the time to write this question out clearly lead me to find the answer I was looking for. Short version, I needed to modify the maven-compiler-plugin configuration as follows:

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>${maven.compiler.plugin.version}</version>
            <configuration>
                <source>${maven.compiler.source}</source>
                <target>${maven.compiler.target}</target>
                <annotationProcessorPaths>
                    <annotationProcessorPath>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok</artifactId>
                        <version>${lombok-version}</version>
                    </annotationProcessorPath>
                </annotationProcessorPaths>
            </configuration>
        </plugin>
Tim Gustafson
  • 177
  • 1
  • 11
  • 2
    For some extra context – until 'module mode' compilation was around, any annotation processors on the classpath would just get applied automatically. In module mode compilation land, it's not that simple. Best to explicitly mention all APs to the compiler (which `` does). For more, see [Project Lombok's page on maven](https://projectlombok.org/setup/maven). – rzwitserloot Feb 22 '22 at 11:38
  • check https://stackoverflow.com/a/59976234/175554 for module configuration. – ozkanpakdil May 08 '23 at 20:54