Using Dagger2 with Lombok

2020-06-09 04:38发布

问题:

Has anyone used Lombok 1.16 with Dagger2?

My current code looks like:

@AllArgsConstructor(onConstructor = @__(@Inject))
public class JuiceMaker {
    private final Apple apple;

The error is:

JuiceMaker cannot be provided without an @Inject constructor or from an @Provides-annotated method.

Without the Lombok annotation this actually works, so:

public class JuiceMaker {
    private final Apple apple;
    @Inject
    public JuiceMaker(Apple apple){
        this.apple = apple
    }
}

works

回答1:

This is a copy paste version of my answer here:

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

But you still have to list lombok as provided dependency ;)



回答2:

The issue is that, by the time the dagger annotation processor looks for @Inject constructors, they have not been generated by lombok. One solution might be to delombok the source and then compile it. But I personally haven't done that.



回答3:

I'm trying to solve it but, unfortunately, I still have not managed to do it.

What I had progressed so far is the following (in Gradle): using the Ant task as a function and generate the sources into some build folder in which the dagger processor may find afterwards. But I admit this way might be totally awkward.

The following code snippet tries to use the ant task currently in lombok.jar in a project-agnostic approach.

final def generateJava = { ->
  ant.taskdef(
    name: 'delombok',
    classname: 'lombok.delombok.ant.Tasks$Delombok',
    classpath: configurations.annotationProcessor
      .filter { (it.name =~ 'lombok') }.asPath
  )
  ant.mkdir(dir: sourceSets.main.output.classesDirs.asPath)
  ant.delombok(
    verbose: true,
    encoding: StandardCharsets.UTF_8,
    from: sourceSets.main.java.sourceDirectories.asPath,
    to: sourceSets.main.output.classesDirs.asPath,
    modulepath: sourceSets.main.runtimeClasspath.asPath
  )
}

and, finally try to append the generated code in somewhere else Dagger can scan for.

sourceSets.main.java.srcDirs = sourceSets.main.output.classesDirs

I'm currently using Gradle version 6.0.1 and lombok 1.18.10. I'm not sure if it is backwards-compatible.