After upgrading to gradle 4.7, my previously warning-free build now emits this warning:
The following annotation processors were detected on the compile classpath: 'lombok.launch.AnnotationProcessorHider$AnnotationProcessor' and 'lombok.launch.AnnotationProcessorHider$ClaimingProcessor'. Detecting annotation processors on the compile classpath is deprecated and Gradle 5.0 will ignore them. Please add them to the annotation processor path instead. If you did not intend to use annotation processors, you can use the '-proc:none' compiler argument to ignore them.
It seems that annotation processors are deprecated and gradle version 5.0 will not support annotation processors.
My project uses lombok, which requries annotation processors, so using -proc:none is not an option. Neither is stopping using Gradle when verison 5.0 is released.
How do I:
stop the warnings, and
ensure my project will continue to build with future Gradle releases?
Change the lombok dependency type from compile to annotationProcessor, so your dependencies section in your build.gradle file should look like:
dependencies {
compileOnly('org.projectlombok:lombok:1.16.20')
annotationProcessor 'org.projectlombok:lombok:1.16.20'
// compile 'org.projectlombok:lombok:1.16.20' <-- this no longer works!
// other dependencies...
}
If your project contains tests then you'll need the following configuration to completely rid yourself of the gradle warning:
dependencies {
compileOnly "org.projectlombok:lombok:1.18.2"
testCompileOnly "org.projectlombok:lombok:1.18.2"
annotationProcessor "org.projectlombok:lombok:1.18.2"
testAnnotationProcessor "org.projectlombok:lombok:1.18.2"
}
Adjust the lombok version to suit.
Gradle added annotationProcessor in 4.6 and Lombok is an annotation processor even though their documentation is not really clear about this when using Gradle they are also aware of it as they recommend it when using Android Studio.
So short answer is to use:
dependencies {
compileOnly('org.projectlombok:lombok:1.18.0')
annotationProcessor('org.projectlombok:lombok:1.18.0')
}
Related
I tried to add 3rd party dependencies in gradle.properties as below
dependencies {
pmd fileTree(dir: "${lib}/aspectj-1.9.4", includes: ['*.jar'])
// OR below
// pmd 'org.aspectj:aspectjtools:1.9.4'
// OR even below also causes same problem.
// pmdAux 'org.aspectj:aspectjtools:1.9.4'
}
It causes error as java.lang.ClassNotFoundException: net.sourceforge.pmd.PMD what can be issue here? how to overcome?
Ref:
https://stackoverflow.com/a/17179486/1665592
https://stackoverflow.com/a/71147569/1665592
It seems that all the dependencies in configuration pmd are replaced once you manually configure the dependency as in your example.
In https://stackoverflow.com/a/71147569/1169968 is explained, that the gradle pmd plugin adds two dependencies configurations: pmd and pmdAux.
pmd defines the classpath that is used to run PMD. It is by default setup by the plugin automatically, dependending on the toolVersion property (see PmdPlugin.java#L194-L201 and PmdPlugin.java#L145-L152).
The gradle documentation about Declaring Dependencies explains, that "Many Gradle plugins add pre-defined configurations to your project". It also seems, that pmd is a default configuration, that is registered/created by AbstractCodeQualityPlugin.java#L98-L116. The configuration name is getToolName().toLowerCase() - so all code-quality plugins define a configuration with the same name as themselves.
When declaring now a dependency like above, it seems that the previously configured dependencies are removed - or in other words: the configuration is replaced.
I don't know, whether this is correct behavior or whether this is a bug. But it seems, once you start declaring such tool dependencies manually, you take over responsibility to declare the complete classpath for PMD. That makes sense, because then the "whole truth" is in your build.gradle/gradle.properties file.
However, since the plugin also has the toolVersion property, this behavior is surprising: The toolVersion property is being ignored, once you declare the dependencies manually.
To fix this, you just need to declare additionally the pmd dependency. So, the following works:
dependencies {
// first define the main PMD dependency
pmd 'net.sourceforge.pmd:pmd-java:6.54.0'
// then declare additional dependencies, e.g. to include your custom rule
pmd 'com.example:myrule:1.0.0'
// or
pmd fileTree(dir: "${lib}/aspectj-1.9.4", includes: ['*.jar'])
// OR below
// pmd 'org.aspectj:aspectjtools:1.9.4'
}
Using toolVersion doesn't work anymore then. In order to use a different PMD version, you just need to update the version in the dependency then.
Btw. I can't reproduce your problem with pmdAux - if the dependency is added to pmdAux, PMD is executed. However, it might not run correctly, as probably the same happens: the automatically calculated auxiliary classpath is thrown away and only your declared dependencies are used. That might result in false-positives/false-negatives due to type resolution not working correctly.
Having a gradle project.
When i'm trying to build project.
buildscript {
ext {
springBootVersion = '2.2.4.RELEASE'
}
repositories {
mavenCentral()
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath "gradle.plugin.org.hidetake:gradle-swagger-generator-plugin:2.9.0"
classpath "net.ltgt.gradle:gradle-apt-plugin:0.21"
}
}
plugins {
id "net.ltgt.apt-eclipse" version "0.21"
id "net.ltgt.apt-idea" version "0.15"
id "net.ltgt.apt" version "0.15"
}
I have error which is connected with plugins
Plugin [id: 'net.ltgt.apt-eclipse', version: '0.15'] was not found in any of the following sources:
How to fix it?
I was facing the same issue. In build.gradle, the paths provided for the dependencies weren't matching the folders specified. Placing the folders in the mentioned path shown in the build.gradle solved it. After that I was able to build the project without errors.
TL;DR: If you are using a current gradle version, it's fine to just drop all of the net.ltgt.apt dependencies. You will not need it anymore because, it's features are now available natively in Gradle.
More details:
From the plugin README.md (https://github.com/tbroyer/gradle-apt-plugin#readme)
The goal of this plugin was to eventually no longer be needed, being superseded by built-in features. This has become a reality with Gradle 5.2 and IntelliJ IDEA 2019.1. tl;dr: this plugin is obsolete, don't use it. If you're using Eclipse though, continue reading.
It originally did a few things to make it easier/safer to use Java annotation processors in a Gradle build. Those things are now available natively in Gradle, so what's this plugin about?
If you use older versions of Gradle (pre-4.6), you can still benefit from those features:
it ensures the presence of configurations for your compile-time only dependencies (annotations, generally) and annotation processors, consistently across all supported Gradle versions;
automatically configures the corresponding JavaCompile and GroovyCompile tasks to make use of these configurations, when the java or groovy plugin is applied.
With recent versions of Gradle (between 4.6 and 5.1), this plugin will actually only:
add some DSL to configure annotation processors; it is however recommended to directly configure the tasks' options.compilerArgs;
backport the sourceSet.output.generatedSourcesDirs Gradle 5.2 API;
configure JavaCompile and GroovyCompile tasks' options.annotationProcessorGeneratedSourcesDirectory with a sane default value so you can see the generated sources in your IDE and for debugging, and avoid shipping them in your JARs.
I have build.gradle in front of me and there are some dependencies declared as provided but in documentation I do not see this dependency scope.
dependencies {
compile("org.springframework.boot:spring-boot-starter-web:1.2.4.RELEASE")
....
provided 'backport-util-concurrent:backport-util-concurrent:3.1'
provided 'org.javolution:javolution:5.5.1#jar
....
}
Is this provided by a plugin? If so how do I found out which plugin this belongs to?
What is the difference between provided and runtime dependency scope in Gradle?
What is provided scope?
Suppose that a jar is needed to compile your code, but the jar is present in the production environment library collection. Then you don't need to package the jar with your project archives. To support this requirement, Maven has a scope named provided. If you declare any jar dependency as provided, then this jar will be present in your classpath during compilation but will not be packaged with your project archive.
provided scope is very useful, particularly in web applications. For example, servlet-api.jar is needed to be present in your classpath to compile your project, but you don't need this to package servlet-api.jar file with your war. With provided scope one can achieve this requirement.
There is no Scope defined in Gradle java plugin named provided. Also not in war or android plugins. If you want to use provided scope in your project, then you have to define it in your build.gradle file. Following is the code snippet to declare provided scope in gradle:
configurations {
provided
}
sourceSets {
main { compileClasspath += configurations.provided }
}
Now, your second question:
What is the difference between provided and runtime dependency scope in Gradle?
To answer this question first I will define compile dependency. compile dependencies are dependencies, those are necessary to compile your code. Now imagine that if your code uses a library named X then you must declare X as your compile-time dependency. Also imagine that X uses another library Y internally, and you declared Y as your runtime dependency.
During compilation, Gradle will add X into your classpath but will not add Y. Since, Y is not required for compilation. But it will package both X and Y with your project archive since both X and Y are necessary to run your project archive in the production environment. Generally, all the dependencies needed in the production environment are known as runtime dependency.
In Gradle official documentation, it says that runtime dependency are "the dependencies required by the production classes at runtime. By default, also includes the compile time dependencies.".
Now, if you've read this far, then you already know that provided is a compile dependency that we don't want to be present in the runtime dependency (basically, we don't want it to package with the project archive).
Following is an illustration of provided and runtime scope. Here, compile refers to the dependencies that are required to compile the project and non-compile refers to the dependencies that are not required for project compilation.
As from Gradle 2.12, you can use the compileOnly option.
See
https://blog.gradle.org/introducing-compile-only-dependencies
For further clarification, as of the latest version, Gradle 5.5 has compileOnly (same as provided) and runtimeOnly options. The new default "compile and runtime" option is implementation.
Updating the answer as per the latest gradle versions.
From gradle's official documentation at below link:
https://docs.gradle.org/current/userguide/upgrading_version_5.html
Deprecations
Dependencies should no longer be declared using the compile and runtime configurations. The usage of the compile and runtime
configurations in the Java ecosystem plugins has been discouraged
since Gradle 3.4.
The implementation, api, compileOnly and runtimeOnly configurations should be used to declare dependencies and the compileClasspath and
runtimeClasspath configurations to resolve dependencies.
More so, the compile dependency configuration has been removed in the recently released Gradle 7.0 version.
If you try to use compile in your Gradle 3.4+ project you’ll get a warning like this:
Deprecated Gradle features were used in this build, making it
incompatible with Gradle 7.0. Use ‘–warning-mode all’ to show the
individual deprecation warnings.
You should always use implementation rather than compile for dependencies, and use runtimeOnly instead of runtime.
War plugin
The War plugin extends the Java plugin to add support for assembling web application WAR files. It disables the default JAR archive
generation of the Java plugin and adds a default WAR archive task.
The War plugin adds two dependency configurations:
providedCompile
providedRuntime
Adding an entry to providedCompile or providedRuntime will cause that dependency to be excluded from the war file.
Use providedCompile if you have source that relies on some classes
for compiling.
Use providedRuntime if you use it for testing and not
compiling.
Example:
providedCompile 'org.springframework.boot:spring-boot-starter-tomcat:1.1.6.RELEASE'
The above JAR and its transitive dependency will only be available at compile time but it will not be available at runtime. It means, those JAR will not be included in war archive.
I would like to know if in an Android project mixing Java and Kotlin files we must use annotationProcessor or kapt, or both ?
In my understanding annotationProcessor must be used for Java files using annotations for code generation, and kapt must be used for Kotlin files using annotations for code generation.
I have a project mixing both languages, and I just have replaced all the annotationProcessor dependencies in the build.gradle by kapt.
Surprisingly it builds and seems to run correctly but I do not understand why kapt works well even with Java files...
Can someone explain to me ?
Thank you
First of all, the Kotlin Annotation processing tool (kapt) uses the Java compiler to run annotation processors. If your project contains any Java classes, kapt takes care of them by design. Kotlinlang recommends using kapt incase you used annotationProcessor from the Android Support before.
JetBrains has a nice article about how kapt works in more detail, its from 2015 but UP-TO-DATE.
In Java you can specify annotationProcessor (or apt) dependency like below:
dependencies {
...
annotationProcessor "com.google.dagger:dagger-compiler:$dagger-version"
}
In Kotlin you have to add the kotlin-kapt plugin to enable kapt, and then replace annotationProcessor with kapt:
apply plugin: 'kotlin-kapt' //Must include
dependencies {
...
kapt "com.google.dagger:dagger-compiler:$dagger-version"
}
That's all! Note that kapt takes care of your Java files as well as kotlin file, so you don't need to keep the annotationProcessor dependency.
For more details: link
What would be the easiest way to tell Gradle the following:
Retrieve 'junit' dependency and take its latest 'release' version.
Managing Maven and Ivy repositories is sort of new to me. I tried the following steps and they result in Could not resolve dependency ... error:
Write compile "junit:junit:latest.release" with repositories set to only mavenCentral() (however, it works if I say "junit:junit:4.10").
Write compile "junit:junit:latest.release" with repository set the following way:
ivy {
// I also tried 'http://maven.org' and other possible variants.
url "http://repo1.maven.org"
layout "maven"
}
Attempted to use Spring Source Ivy repository:
ivy {
artifactPattern "http://repository.springsource.com/ivy/libraries/release/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]"
ivyPattern "http://repository.springsource.com/ivy/libraries/release/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]"
}
Maybe I misunderstand something. Why would getting the latest version of the dependency be such a hard task?
It can be quite useful sometimes to get the latest release - if for example you release often your own dependencies.
You can get the latest version like
compile "junit:junit:+"
or better specify at least the major version like
compile "junit:junit:4.+"
Gradle currently does not support Maven's RELEASE (which is rarely used and deprecated) but it does support Ivy's latest.release (and for snapshots latest.integration). However, the general recommendation is to build against exact versions. Otherwise, the build can become a lottery.
Check out the Gradle-Versions-Plugin. It does exactly what you want: https://github.com/ben-manes/gradle-versions-plugin
For the installation, see the github page. Basically you need to add these two lines to your build.gradle - project file:
apply plugin: 'com.github.ben-manes.versions'
buildscript {
[...]
dependencies {
classpath 'com.github.ben-manes:gradle-versions-plugin:0.8'
[...]
}
}
[...]
Then you can use the plugin, by running this command in terminal in your project dir:
./gradlew dependencyUpdates -Drevision=release
And it will show you which dependencies are outdated!
Latest Gradle User Guide mentions and explains plus sign in versions:
From 7.2. Declaring your dependencies:
dependencies {
compile group: 'org.hibernate', name: 'hibernate-core', version: '3.6.7.Final'
testCompile group: 'junit', name: 'junit', version: '4.+'
}
... The build script also states that any junit >= 4.0 is required to compile the project's tests.
From 23.7. How dependency resolution works:
If the dependency is declared as a dynamic version (like 1.+), Gradle will resolve this to the newest available static version (like 1.2) in the repository. For Maven repositories, this is done using the maven-metadata.xml file, while for Ivy repositories this is done by directory listing.
In Android Studio:
If you're using + for the version, and want to know which version is actually being used, select Project in the sidebar, and then under External Libraries you will see the actual version number in use.
Another similar notation for Kotlin DSL (build.gradle.kts):
dependencies {
implementation("or.jsoup", "jsoup") {
version {
require("1.14.+")
}
}
// OR simply
// implementation("or.jsoup:jsoup:1.14.+")
}
Read more about this in Gradle documentations.
An excerpt from the docs:
A dynamic version can be either a version range (e.g. 2.+) or it can be a placeholder for the latest version available e.g. latest.integration.