17

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

Jessica
  • 721
  • 1
  • 6
  • 13
  • I believe your error comes from somewhere else. Please have a look at [How to fix cannot be provided](https://stackoverflow.com/q/44912080/1837367) – David Medenjak May 16 '18 at 06:37
  • Without Lombok it works – Jessica May 16 '18 at 14:58
  • If you are running JDK8 then check this [link](https://projectlombok.org/api/lombok/RequiredArgsConstructor.html#onConstructor--) out – Shankha057 Aug 18 '18 at 12:52
  • 1
    @Jessica, did you ever get an answer to this? I'm having the same problem. Like you, it works when I manually add a constructor, but not when the constructor is generated by Lombok with `@RequiredArgsConstructor(onConstructor = @__(@Inject))` – Andrew Rose Jan 18 '19 at 17:03
  • Have a look at https://stackoverflow.com/a/50058828/1645517 – Markus Schulte Mar 29 '19 at 13:05
  • this is most likely a mvn issue, have a look at my answer [here](https://stackoverflow.com/a/50058828/4363948) – Ore Mar 29 '19 at 13:15

3 Answers3

5

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 ;)

Ore
  • 972
  • 2
  • 12
  • 24
  • 1
    Thank you so much! That's what was the reason! – Dmitry Zlykh Apr 21 '20 at 18:20
  • This doesn't seem to work for me. If I remove the class from my component interface, the lombok code does correctly generate the class to be bound with the @Inject annotation, but when I actually try to use it I get a Dagger/MissingBinding error. For me it also correctly works if I delombok @RequiredArgsConstructor(onConstructor_ = @Inject) with my IDE and then build it. – Rik Schaaf Jul 25 '21 at 19:25
  • This solves 80% of the problems. Thanks. But, as with others, I still can't get `@RequiredArgsConstructor(onConstructor = @__(@Inject))` to work. – Manu Manjunath Dec 01 '21 at 06:00
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.

Philippe
  • 1,715
  • 4
  • 25
  • 49
1

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.

dhsrocha
  • 41
  • 1
  • 5