projectlombok / lombok

Very spicy additions to the Java programming language.
https://projectlombok.org/
Other
12.9k stars 2.39k forks source link

Deprecated Gradle features were used in this build #1602

Open eximius313 opened 6 years ago

eximius313 commented 6 years ago

When I use Lombok in Gradle:

compile (
   [group: 'org.projectlombok', name: 'lombok', version: '1.16.20']
)

I get warning message:

Deprecated Gradle features were used in this build, making it incompatible with Gradle 5.0.
See https://docs.gradle.org/4.6/userguide/command_line_interface.html#sec:command_line_warnings
kavinvin commented 6 years ago

I got this too.

mszabo-wikia commented 6 years ago

Try to make use of the new dedicated annotationProcessor dependency configuration instead of using compile to declare your lombok dependency:

annotationProcessor "org.projectlombok:lombok:$lombokVersion"
compileOnly "org.projectlombok:lombok:$lombokVersion"

// unlike testCompile, these configurations do not inherit from their compile counterparts
// so if your tests depend on lombok, make sure you have specified these:
testAnnotationProcessor "org.projectlombok:lombok:$lombokVersion"
testCompileOnly "org.projectlombok:lombok:$lombokVersion"
kavinvin commented 6 years ago

Mine already use compileOnly, which still produce the warning. Adding annotationProcessor doesn't help too.

victorwss commented 6 years ago

Running it with gradle --warning-mode=all build will produce this:

Putting annotation processors on the compile classpath has been deprecated and is scheduled to be removed in Gradle 5.0. Please add them to the processor path instead. If these processors were unintentionally leaked on the compile classpath, use the -proc:none compiler option to ignore them..

But, since lombok.jar is monolythical, I don't see any way around that other than manually repackaging lombok, which is something too far errorprone to be acceptable.

See #1611

larisa-pozhilova commented 6 years ago

I had the same issue and adding annotationProcessor and compileOnly resolved the issue.

jabrena commented 6 years ago

For me this configuration solve the issue:

dependencies {
    annotationProcessor("org.projectlombok:lombok:1.16.20")
    compileOnly("org.projectlombok:lombok:1.16.20")
}
victorwss commented 6 years ago

@lorochka @jabrena For me, Gradle 4.6 produces this error:

Could not find method annotationPocessor() for arguments [{group=org.projectlombok, name=lombok, version=1.16.20}] on object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.

😩

mszabo-wikia commented 6 years ago

@victorwss that looks like a typo, since your pasted error message says annotationPocessor()instead of annotationProcessor().

victorwss commented 6 years ago

@mszabo-wikia Oh, thanks. I can't understand how could I commit such silly mistake.

andrepintorj commented 6 years ago

@mszabo-wikia suggestion seems to solve the warning when the build contains: testCompile 'org.springframework.boot:spring-boot-starter-test'

daggerok commented 6 years ago

@jabrena solution is working fine for me with gradle 4.7


Maksim

jabrena commented 6 years ago

I will review again and I will show my Gradle. Give me one day to check everything.

philippeboyd commented 6 years ago

Project doesn't compile when using

dependencies {
    annotationProcessor("org.projectlombok:lombok:1.16.20")
    compileOnly("org.projectlombok:lombok:1.16.20")
}
................ error: package lombok does not exist
import lombok.ToString;
             ^

Am I missing something?

daggerok commented 6 years ago

@philippeboyd , if it's failing during test phase, probably you might try use test configurations as well

dependencies {
    annotationProcessor("org.projectlombok:lombok:$lombokVersion")
    compileOnly("org.projectlombok:lombok:$lombokVersion")
    testAnnotationProcessor("org.projectlombok:lombok:$lombokVersion")
    testCompileOnly("org.projectlombok:lombok:$lombokVersion")
}

Regards,

philippeboyd commented 6 years ago

@daggerok but I executed without tests...

./gradlew clean build -x test
daggerok commented 6 years ago

it's really hard to guess can you show us some github repo with gradle build which could be reproduced?

nsiniakevich commented 6 years ago

@daggerok take mine

https://github.com/nsiniakevich/gradle-lombok-issue

It's clearly reproduces.

To be honest, @oehme could, please, verify, that I'm using correct way to add lombok in my repo?

mszabo-wikia commented 6 years ago

@nsiniakevich have you tried with compileOnly instead of implementation?

nsiniakevich commented 6 years ago

@mszabo-wikia please, check documentation. I'm doing it right https://docs.gradle.org/current/userguide/java_plugin.html?#sec:java_compile_avoidance

mszabo-wikia commented 6 years ago

@nsiniakevich Dagger is a different beast—its annotation processor components are a separate dependency in dagger-library, while the dagger dependency itself does not include such artifacts.

Since Lombok does not offer such separation and there's also no need for Lombok after compilation, here compileOnly needs to be used.

oehme commented 6 years ago

Put it in the annotationProcessor configuration like the warning says. If you are using it for tests, you'll also need testAnnotationProcessor.

To make the Lombok annotations visible to your code, you shouldn't put it on compile/implementation, but compileOnly so you don't leak the dependency to downstream projects.

Dagger has a separate runtime library, which is why it is on the implementation classpath. Lombok does not have such a library, it's only needed at compile time.

oehme commented 6 years ago

It seems a lot of the confusion stems from leaking Lombok into the test compile classpath. I'll consider making testAnnotationProcessor extend from annotationProcessor to make this behave more symmetric.

nsiniakevich commented 6 years ago

@oehme I got it. But I think it should be covered in Gradle documentation.

jabrena commented 6 years ago

For me, it is working:

https://github.com/ev3dev-lang-java/ev3dev-lang-java/blob/feature/%23498/build.gradle

dependencies {
    annotationProcessor("org.projectlombok:lombok:1.16.20")
    testCompile("org.projectlombok:lombok:1.16.20")
}
jabrena commented 6 years ago

I would like to know how to generate the classes compiled with lombok but not include the dependency as part of fatjar

mszabo-wikia commented 6 years ago

@jabrena try compileOnly rather than compile

oehme commented 6 years ago

We can't cover every processor in the docs. The processors should document how they should be used instead.

nsiniakevich commented 6 years ago

@oehme understood

@rzwitserloot I'd like to create PR to resolve this issue

I'll just update this file https://github.com/rzwitserloot/lombok/blob/master/website/templates/setup/gradle.html

From Gradle 4.6 it should be:

dependencies {
    annotationProcessor("org.projectlombok:$lombokVersion")
    compileOnly("org.projectlombok:lombok:$lombokVersion")
}

Also if lombok is used in tests:

dependencies {
    annotationProcessor("org.projectlombok:$lombokVersion")
    compileOnly("org.projectlombok:lombok:$lombokVersion")
    testAnnotationProcessor("org.projectlombok:lombok:$lombokVersion")
    testCompileOnly("org.projectlombok:lombok:$lombokVersion")
}
jabrena commented 6 years ago

hi @mszabo-wikia,

I have just tested. It is amazing. I next release, will add a direct dependency. I removed it because for embedded libraries it could be optional but now with compileOnly, the fatJar doesn´t include any Lombok class.

Many thanks.

Cheers

Juan Antonio

eximius313 commented 6 years ago

I can confirm that @nsiniakevich comment (https://github.com/rzwitserloot/lombok/issues/1602#issuecomment-389179459) is correct.

Maybe since Gradle deprecated compile, this should be described in documentation?

eximius313 commented 6 years ago

@rzwitserloot this is another example: https://github.com/rzwitserloot/lombok/issues/1580#issuecomment-394487868 which shows that putting @nsiniakevich comment in documentation is vital

daggerok commented 6 years ago

Today my simple spring-boot app from http://start.spring.io doesn't compiled with gradle unless I add lombok dependency as compile configuration or ugly combination with four of them compileOnly + testCompileOnly + annotationProcessor + testAnnotationProcessor...

So my solution was gradle-lombok plugin:

plugins {
  id 'io.franzbecker.gradle-lombok' version '1.14' apply false
}

allprojects {
  buildscript {
    ext {
      lombokVersion = '1.16.20'
    }
  }

  apply plugin: 'java'
  apply plugin: 'io.franzbecker.gradle-lombok'

  lombok {
    version = project.lombokVersion
  }

  dependencies {
    compileOnly("org.projectlombok:lombok:$lombokVersion")
    testCompileOnly("org.projectlombok:lombok:$lombokVersion")
  }
}

// ...

for me now at the moment it has more sense then doing something like so:

  dependencies {
    // why???
    compileOnly("org.projectlombok:lombok:$lombokVersion")
    testCompileOnly("org.projectlombok:lombok:$lombokVersion")
    annotationProcessor("org.projectlombok:lombok:$lombokVersion")
    testAnnotationProcessor("org.projectlombok:lombok:$lombokVersion")
  }

Regards, Maksim

jabrena commented 6 years ago

Hi @daggerok,

Why you add the plugin:

plugins {
  id 'io.franzbecker.gradle-lombok' version '1.14' apply false
}

In my case, I don´t use it: https://github.com/ev3dev-lang-java/ev3dev-lang-java/blob/develop/build.gradle

Juan Antonio

oehme commented 6 years ago

dependencies { // why??? compileOnly("org.projectlombok:lombok:$lombokVersion") testCompileOnly("org.projectlombok:lombok:$lombokVersion") annotationProcessor("org.projectlombok:lombok:$lombokVersion") testAnnotationProcessor("org.projectlombok:lombok:$lombokVersion") }

Because lombok needs to be both on the compile classpath (for the annotations) and the processor path (for the processor). And you need to do so for each sourcSet where you want to use it. We don't want to automatically leak it into tests, since that would mean a slowdown even for people who don't to use lombok in their tests.

The plugin by Franz Becker automates the case where you want lombok both for main and test code (you don't need any dependency declarations if you use it). So if that's what you want, please go ahead and use it :)

jabrena commented 6 years ago

Hi @oehme,

So, the plugin is an alternative to the usage of Intellij lombok plugin? Sorry, I didn't use in the past.

oehme commented 6 years ago

No, it's a Gradle plugin, not an IntelliJ plugin. It just automates the dependency declarations for the main and test sourceSet.

eximius313 commented 6 years ago

This looks ugly, because Lombok is "all-in-one" jar. Look at the Mapstruct for example - here is clear what is what. There was an issue (https://github.com/rzwitserloot/lombok/issues/1611) for splitting Lombok, but it was declined :(

By the way: using Lombok in tests I'd treat as a bad smell

Maaartinus commented 6 years ago

@oehme

The plugin by Franz Becker automates the case where you want lombok both for main and test code

So you mean, all I need is to use the plugin like described here. But there I see no place where to specify the lombok version.


@eximius313

By the way: using Lombok in tests I'd treat as a bad smell

Why? val is handy, and so are some trivial @Value or @Data classes.

oehme commented 6 years ago

@Maaartinus Please look at the plugin's readme.

eximius313 commented 6 years ago

@Maaartinus because you shouldn't create/modify domain code for test purposes. If you have Lombok annotations in domain object in and only use object in tests, you don't need lombok jar in tests.

daggerok commented 6 years ago

HI @jabrena

I need it because I want apply cinfiguration to allprojects closure, not root only. (In my case it was multi-project build)


Regards, Maksim

daggerok commented 6 years ago

Thanks for explanation, @oehme

But I just have build fat jars in using: 1) gradle lombok plugin 2) with 4 dependencies declarations

as result they are have same content - no lombok inside


Regards, Maksim

daggerok commented 6 years ago

Hi all,

according to this discussion here I have prepared a repository with proofs HOWTO in README to demonstrate that gradle lombok plugin doesn't include in your distribution lombok jar dependency...

So, as @oehme mention, if you need lombok also for tests, then simplest gradle config could be achieved by using gradle-lombok plugin, otherwise ...you probably not needed all these four configurations in dependencies closure, but of course you can also use all of them, like so


Regards, Maksim

eximius313 commented 6 years ago

@daggerok , @nsiniakevich in your comments https://github.com/rzwitserloot/lombok/issues/1602#issuecomment-389179459 and https://github.com/rzwitserloot/lombok/issues/1602#issuecomment-388225705 you have org.projectlombok:$lombokVersion while it should be org.projectlombok:lombok:$lombokVersion

daggerok commented 6 years ago

@eximius313 well, github issue thread not best tool for coding :) PS: Fixed