Exclude transitive dependency of Gradle plugin - java

Excluding a transitive dependency in Gradle is pretty straightforward:
compile('com.example.m:m:1.0') {
exclude group: 'org.unwanted', module: 'x'
}
How would we go around he situation in which we use a plugin:
apply: "somePlugin"
And when getting the dependencies we realize that the plugin is bringing some transitive dependencies of its own?

You can remove dependencies after the plugin is applied, (from a single configuration, or to all configurations) using eg. compile.exclude. Note that compile resolves to a "Configuration"; see the javadocs at Configuration.exclude .
edit
Be aware that excluding dependecies could fail, if the configuration has already been resolved.
Sample script
apply plugin: 'java-library'
repositories {
jcenter()
}
dependencies {
compile 'junit:junit:4.12'
compile 'ant:ant:1.6'
compile 'org.apache.commons:commons-lang3:3.8'
}
// remove dependencies
configurations.all {
exclude group:'junit', module:'junit'
}
configurations.compile {
exclude group:'org.apache.commons', module: 'commons-lang3'
}
println 'compile deps:\n' + configurations.compile.asPath

You can manipulate the classpath of the buildscript itself through:
buildscript {
configurations {
classpath {
exclude group: 'org', module: 'foo' // For a global exclude
}
}
dependencies {
classpath('org:bar:1.0') {
exclude group: 'org', module: 'baz' // For excluding baz from bar but not if brought elsewhere
}
}
}

Here is another way to enforce your project to strictly use a specific version for the build.gradle.kts
val grpcVersion = "1.45.1"
implementation("io.grpc:grpc-stub") {
version {
strictly(grpcVersion)
}
}
More info can be found at the gradle documentation: https://docs.gradle.org/current/userguide/dependency_downgrade_and_exclude.html

Related

how to exclude a folder from checkstyle of Gradle on Intellij

I am new for IntelliJ and Gradle, but I have enough experience on Java and Eclipse. I generated some java classes from wsdl file. I put them under src/main/resources with a folder name - "generatedsources".
I try to prevent checkstyle for this folder and its subfolders like src/main/resources/generatedsources/* with gradle on IntelliJ.
I tried some lines such;
task checkstyle(type: Checkstyle) {
source 'src'
// include '**/*.java'
// exclude '**/gen/**'
// exclude '**/R.java'
// exclude '**/BuildConfig.java'
exclude 'src/main/resources/generatedsources/**'
}
But I'm failed again.
build.gradle;
apply plugin: 'war'
apply plugin: 'jetty'
apply plugin: 'checkstyle'
apply plugin: 'java'
apply plugin: 'no.nils.wsdl2java'
sourceCompatibility = 1.7
version = '1.0'
...
buildscript{
repositories{
jcenter()
mavenCentral()
}
dependencies {
classpath 'no.nils:wsdl2java:0.10'
}
}
task checkstyle(type: Checkstyle) {
source 'src'
// include '**/*.java'
// exclude '**/gen/**'
// exclude '**/R.java'
// exclude '**/BuildConfig.java'
exclude 'src/main/resources/generatedsources/**'
}
EDIT - After recommendations(but still failed!):
apply plugin: 'war'
apply plugin: 'jetty'
apply plugin: 'checkstyle'
apply plugin: 'java'
apply plugin: 'no.nils.wsdl2java'
sourceCompatibility = 1.7
version = '1.0'
description = """BLABLABLA_application"""
war.archiveName = "BLABLABLA.war"
configurations{
deployerJars
}
repositories {
mavenCentral()
}
dependencies {
compile group: 'org.codehaus.jackson', name: 'jackson-core-asl', version: '1.9.3'
compile group: 'org.codehaus.jackson', name: 'jackson-mapper-asl', version: '1.9.3'
compile group: 'org.springframework', name: 'spring-core', version:'4.0.0.RELEASE'
compile group: 'org.springframework', name: 'spring-web', version:'4.0.0.RELEASE'
compile 'log4j:log4j:1.2.17'
compile 'com.sun.xml.ws:jaxws-rt:2.2.8'
compile 'org.jvnet.jax-ws-commons.spring:jaxws-spring:1.9'
compile group: 'org.springframework', name: 'spring-webmvc', version:'4.0.0.RELEASE'
providedCompile group: 'javax.servlet', name: 'servlet-api', version:'2.5'
testCompile group: 'junit', name: 'junit', version: '4.11'
deployerJars "org.apache.maven.wagon:wagon-http:2.2"
}
jar {
manifest {
attributes 'Implementation-Title': 'BLABLABLA', 'Implementation-Version': version
}
}
uploadArchives {
repositories {
flatDir {
dirs 'repos'
}
}
}
buildscript{
repositories{
jcenter()
mavenCentral()
}
dependencies {
classpath 'no.nils:wsdl2java:0.10'
}
}
wsdl2java{
wsdlsToGenerate = [
["$projectDir/src/main/resources/BLABLABLA.wsdl"]
]
generatedWsdlDir = file("$projectDir/src/gen/java")
wsdlDir = file("$projectDir/src/main/resources")
}
wsdl2javaExt {
cxfVersion = "2.5.1"
}
tasks.withType(Checkstyle) {
exclude '**/your/generated/package/goes/here**'
}
checkstyleMain.exclude '**/your/generated/package/goes/here**'
"exclude" in tasks.withType and "checkstyleMain" causes an error such as "cannot resolve symbol"!
When checkstyle plugin is applied custom tasks are delivered along with it (see here), so instead of adding custom task with type Checkstyle configure the shipped one. This is how it should be done:
tasks.withType(Checkstyle) {
exclude '**/your/generated/package/goes/here**'
}
You can also configure a particular task, not all:
checkstyleMain.exclude '**/your/generated/package/goes/here**'
Also this is not good practice to put generated sources under src/main/resources. Typically such files goes to e.g. src/gen/java
I followed some comments and make it work add this in file build.gradle
checkstyle {
config = rootProject.resources.text.fromFile("${project.projectDir}/checkstyle-8.34_google_checks.xml")
toolVersion = '8.34'
ignoreFailures = false
maxWarnings = 0
}
checkstyleMain
.exclude('com/examples/gen/api/*.java')
.exclude('com/examples/gen/model/*.java')
.exclude('com/examples/gen/auth/*.java')
You can only exclude a folder that is in the source set. That is something that had not been mentioned and it caused me to struggle since I am using Intellij. The generated files are in the build/ folder which is on the same level as src/. I tried excluding the build folder for a while but there was no effect. The only solution was to specify the source folder. Since the build folder is not under src (the source folder), it worked immediately.
checkstyleMain.source = "src/main/java"
I found the solution here: Specify excludes to Checkstyle task
I had lots of issues with checkStyle & pmd + QueryDSL
A final solution for me was not to exclude generated sources, but clean them after assemble task: no sources - nothing to analyze! :)
assemble {
finalizedBy cleanQuerydslSourcesDir
}
For kotlin dsl use
tasks.withType<Checkstyle>() {
exclude("**/com/generated/*.java")
}

compile() error while trying to pass dependencies to subprojects in gradle.build file

I'm trying to generalize a dependency to all subprojects in my gradle project. Reading this question: https://discuss.gradle.org/t/inheriting-common-dependencies-from-parent-project-in-child-projects/5493/2
I tried it out:
subprojects{
dependencies {
compile group: 'com.xetra11.toolbox', name: 'toolbox-commons', version: "0.0.1"
}
}
I failed with the following error:
1. Error:(60, 0) Could not find method compile() for arguments
[{group=com.xetra11.toolbox, name=toolbox-commons, version=0.0.1}] on
object of type
org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.
<a
href="openFile:C:\Development\Testzone\toolbox-backend\build.gradle">Open
File</a>
Also using allprojects closure did not succeeded. Did I understood the answers of this above mentioned question wrong or what is the issue here?
That's because your subprojects do not have compile configuration yet. In other words, you have to first apply Java plugin and then declare the dependencies. Three ways how you can achieve that:
1) change the code to apply the plugin from root project
subprojects{
apply plugin: 'java'
dependencies {
compile group: 'com.xetra11.toolbox', name: 'toolbox-commons', version: "0.0.1"
}
}
2) call the configuration after buildscript evaluation of each project is done
subprojects{
afterEvaluate {
dependencies {
compile group: 'com.xetra11.toolbox', name: 'toolbox-commons', version: "0.0.1"
}
}
}
3) or, add the configuration as soon as the Java plugin is added in subprojects
subprojects{
plugins.whenPluginAdded { plugin ->
if (plugin instanceof JavaPlugin) {
dependencies {
compile group: 'com.xetra11.toolbox', name: 'toolbox-commons', version: "0.0.1"
}
}
}
}

gradle circular dependency with external project

I have a fairly simple setup, that does not work and I cannot work out why:
the folder structure is as follows:
/dependency
/build.gradle
/settings.gradle
/src/main/...
/Mainproject
/build.gradle
/settings.gradle
/Subproject_1
/build.gradle
/src/main...
/Subproject_2
/build.gradle
/src/main...
I want the Subproject to depend on "dependency" locally for quick testing.
so I stuck to the manual and did:
/Mainproject/settings.gradle:
include "Subproject_1", "Subproject_2", "dependency"
project(":dependency").projectDir = file('../dependency')
/Mainproject/build.gradle:
allprojects {
apply plugin: 'java'
dependencies {
compile project(path: ':dependency')
}
}
dependencies {
compile project(':Subproject_1')
compile project(':Subproject_2')
}
/dependency/build.gradle:
version '1.0'
apply plugin: 'java'
repositories {
maven {
url "http://...."
}
}
dependencies {
compile group: 'commons-lang', name: 'commons-lang', version: '2.6'
compile group: 'javax', name: 'javaee-api', version: '7.0'
}
jar {
manifest {
attributes 'Implementation-Title': 'Archive delegation dispatcher classes',
'Implementation-Version': project.version
}
}
The build.gradle files of Subproject_1 and _2 are empty.
The settings.gradle file of dependency is empty.
When i gradle build MainProject i get:
Circular dependency between the following tasks:
:dependency:classes
\--- :dependency:compileJava
\--- :dependency:jar
\--- :dependency:classes (*)
(*) - details omitted (listed previously)
And I cannot get my head around why that would be.
Any hints?
When you include "dependency" in your Mainproject's settings.gradle file, you are making the "dependency" project a subproject of "Mainproject".
Then this block in your Mainproject's build.gradle file defines "dependency" as a compile dependency of all subprojects.
allProjects {
dependencies {
compile project(path: ':dependency')
}
}
Since the "dependency" project is also a subproject, you have a circular dependency defined where the "dependency" project depends on itself.
Instead, try creating a settings.gradle file for each of the subprojects with the following:
include "dependency"
project(":dependency").projectDir = file('../dependency')
Then modify your settings.gradle file for the Mainproject to look like this:
include "Subproject_1", "Subproject_2"
You've stated that allProjects have a dependency on the project dependency as seen here:
allprojects {
apply plugin: 'java'
dependencies {
compile project(path: ':dependency')
}
}
You need this to only apply to your projects that aren't dependency. You can do that by excluding it when applying dependencies, like this
subprojects { project ->
if (project.name != "dependency") {
apply plugin: 'java'
dependencies {
compile project(path: ':dependency')
}
}
}
Because dependencies itself.
Move it must be OK.
Turning off Instant run worked for me, could work for someone else too. I had some changes related to gradle and my application appeared not to work after it.
build.gradle (:shared)
This is because you are trying to include a module inside of yourself.
From:
dependencies {
implementation project(':shared')
...
}
To:
dependencies {
...
}
GL
Source

Is there any way of making IntelliJ IDEA recognizing Dagger 2 generated classes in a Java project?

Context
I have started a personal project in java with Gradle as the build system and I want to use Dagger 2 as a DI. The main reason of doing that is to get used to that library and be able to use it easily in bigger projects.
What have I tried
I've managed to make the Google sample runs on IntelliJ IDEA
Problem
IntelliJ IDEA keeps telling me that it cannot resolve the generated class (in this case DaggerCoffeeApp_Coffee). It's a bit annoying not to know if the written code is correct (specially when you are learning to use Dagger 2).
All java classes are the same as the Google sample. Here is my build.gradle file:
apply plugin: 'java'
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile 'com.google.dagger:dagger:2.0.1'
compile 'com.google.dagger:dagger-compiler:2.0.1'
}
Question
Is there any way to make IntelliJ IDEA recognize DaggerCoffeeApp_Coffee as a generated class (and so make it possible to go to its implementation by `ctrl + left click)?
Simplest way I found:
Add idea plugin and add Dagger2 dependency like below:
plugins {
id "net.ltgt.apt" version "0.10"
}
apply plugin: 'java'
apply plugin: 'idea'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile 'com.google.dagger:dagger:2.11'
apt 'com.google.dagger:dagger-compiler:2.11'
}
Turn on Annotation Processing for IntelliJ: Go to Settings and search for Annotation Processors, check Enable annotation processing like below image:
Finally I made it!
I had to add the apt and the idea plugin so right now my build.gradle file look like this:
buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "net.ltgt.gradle:gradle-apt-plugin:0.4"
}
}
apply plugin: "net.ltgt.apt"
apply plugin: 'java'
apply plugin: 'idea'
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile 'com.google.dagger:dagger:2.0.1'
apt 'com.google.dagger:dagger-compiler:2.0.1'
}
you must manually enable the annotation processing in IntelliJ.
From: Settings --> Build, Execution, Deployment --> Compiler --> Annotation Processors --> Enable annotation processing and Obtain processors from project classpath
then rebuild the project and you will find the generated classes in the project.
Please note that I have used this solution in a (java) android project.
I'm using version 2017.3.3 of IntelliJ IDEA, version 0.14 of the net.ltgt.apt plugin and version 2.14.1 of Dagger and as well as applying the idea plugin in the build.gradle file (as in Pelocho's answer) I found I also had to tell IntelliJ where it can find the sources generated by Dagger, as follows:
apply plugin: 'idea'
idea {
module {
sourceDirs += file("$buildDir/generated/source/apt/main")
testSourceDirs += file("$buildDir/generated/source/apt/test")
}
}
This is what I had to do in order to get Idea to work with Dagger2 and gradle.
Turn on annotation processing as shown in the answers above.
Add the following to the build.gradle file in order for Idea to see the generated classes as sources.
sourceDirs += file("$projectDir/out/production/classes/generated/")
Here's the full listing of my build.gradle
plugins {
id 'java'
id 'idea'
id "net.ltgt.apt" version "0.10"
}
idea {
module {
sourceDirs += file("$projectDir/out/production/classes/generated/")
}
}
repositories {
mavenCentral()
}
dependencies {
compile 'com.google.dagger:dagger:2.16'
apt 'com.google.dagger:dagger-compiler:2.16'
}
sourceCompatibility = 1.8
Also, I had to add the following gradle task (to my build.gradle file) to clear out my out directory. When I moved some files around and Dagger2 regenerated the source files, the out directory wasn't being cleared out :(. I also included this task in my run configuration, so that it gets triggered before I rebuild my project.
task clearOutFolder(type: Delete) {
delete 'out'
}
Here's the solution that worked for me:
File -> Project Structure -> (select your project under list of modules) -> Open 'Dependencies' tab
Then, click on green '+' sign, select 'JARs or directory' and select 'build/classes/main' folder.
Another solution would be to link folder with build class files using 'dependencies' block inside build.gradle:
https://stackoverflow.com/a/22769015/5761849
Using IntelliJ IDEA 2019.1 and Gradle 5.4.1, this seems to be enough:
plugins {
id 'java'
}
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testImplementation group: 'junit', name: 'junit', version: '4.12'
implementation 'com.google.dagger:dagger:2.23.1'
annotationProcessor 'com.google.dagger:dagger-compiler:2.23.1'
}
I don't know the minimal versions for which this solution works, though.
I had a similar problem, I could not find out the cause for a long time.
Just launched and the result surprised me.
Intellij Idea 2018.3.6 -
build.gradle:
plugins {
id "java"
}
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile 'com.google.dagger:dagger:2.11'
apt 'com.google.dagger:dagger-compiler:2.11'
}
The following worked for me on IntelliJ 2021.3.3 (UE)
plugins {
id 'java'
id 'idea'
id("com.github.johnrengelman.shadow") version "7.1.2"
}
idea {
module {
sourceDirs += file("$projectDir/build/generated/sources/annotationProcessor/java/main")
testSourceDirs += file("$projectDir/build/generated/sources/annotationProcessor/java/test")
}
}
group 'com.codigomorsa'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
annotationProcessor 'com.google.dagger:dagger-compiler:2.44'
implementation 'com.google.code.gson:gson:2.9.1'
implementation 'com.google.dagger:dagger:2.44'
testAnnotationProcessor 'com.google.dagger:dagger-compiler:2.44'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0'
}
test {
useJUnitPlatform()
}

How do I exclude all instances of a transitive dependency when using Gradle?

My gradle project uses the application plugin to build a jar file. As part of the runtime transitive dependencies, I end up pulling in org.slf4j:slf4j-log4j12. (It's referenced as a sub-transitive dependency in at least 5 or 6 other transitive dependencies - this project is using spring and hadoop, so everything but the kitchen sink is getting pulled in... no wait... that's there too :) ).
I want to globally exclude the slf4j-log4j12 jar from my built jar. So I've tried this:
configurations {
runtime.exclude group: "org.slf4j", name: "slf4j-log4j12"
}
However, this seems to exclude all org.slf4j artifacts including slf4j-api. When running under debug mode I see lines such as:
org.slf4j#slf4j-api is excluded from com.pivotal.gfxd:gfxd-demo-mapreduce:1.0(runtime).
org.slf4j#slf4j-simple is excluded from com.pivotal.gfxd:gfxd-demo-mapreduce:1.0(runtime).
org.slf4j#slf4j-log4j12 is excluded from org.apache.hadoop:hadoop-common:2.2.0(runtime).
I do not want to have to look up the source of each slf4j-log4j12 transitive dependency and then have individual compile foo { exclude slf4j... } statements in my dependencies block.
Update:
I did also try this:
configurations {
runtime.exclude name: "slf4j-log4j12"
}
Which ends up excluding everything from the build! As though I specified group: "*".
Update 2:
I'm using Gradle version 1.10 for this.
Ah, the following works and does what I want:
configurations {
runtime.exclude group: "org.slf4j", module: "slf4j-log4j12"
}
It seems that an Exclude Rule only has two attributes - group and module.
Hence for excluding from only an individual dependency, we can do something like:
dependencies {
compile ('org.springframework.data:spring-data-hadoop-core:2.0.0.M4-hadoop22') {
exclude group: "org.slf4j", module: "slf4j-log4j12"
}
}
However, the above syntax doesn't prevent you from specifying any arbitrary property as a predicate. When trying to exclude from an individual dependency you cannot specify arbitrary properties. For example, this fails:
dependencies {
compile ('org.springframework.data:spring-data-hadoop-core:2.0.0.M4-hadoop22') {
exclude group: "org.slf4j", name: "slf4j-log4j12"
}
}
with
No such property: name for class: org.gradle.api.internal.artifacts.DefaultExcludeRule
So even though you can specify a dependency with a group: and name: you can't specify an exclusion with a name:!?!
Perhaps a separate question, but what exactly is a module then? I can understand the Maven notion of groupId:artifactId:version, which I understand translates to group:name:version in Gradle. But then, how do I know what module (in gradle-speak) a particular Maven artifact belongs to?
For excluding one or more library globally add the following to your build.gradle
configurations.all {
exclude group:"org.apache.geronimo.specs", module: "geronimo-servlet_2.5_spec"
exclude group:"ch.qos.logback", module:"logback-core"
}
Now the exclude block has two properties group and module. For those of you coming from maven background, group is same as groupId and module is same as artifactId.
Example: To exclude com.mchange:c3p0:0.9.2.1 following should be exclude block
exclude group:"com.mchange", module:"c3p0"
Your approach is correct. (Depending on the circumstances, you might want to use configurations.all { exclude ... }.) If these excludes really exclude more than a single dependency (I haven't ever noticed that when using them), please file a bug at http://forums.gradle.org, ideally with a reproducible example.
in the example below I exclude
spring-boot-starter-tomcat
compile("org.springframework.boot:spring-boot-starter-web") {
//by both name and group
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
}
I was using spring boot 1.5.10 and tries to exclude logback, the given solution above did not work well, I use configurations instead
configurations.all {
exclude group: "org.springframework.boot", module:"spring-boot-starter-logging"
}
In addition to what #berguiga-mohamed-amine stated, I just found that a wildcard requires leaving the module argument the empty string:
compile ("com.github.jsonld-java:jsonld-java:$jsonldJavaVersion") {
exclude group: 'org.apache.httpcomponents', module: ''
exclude group: 'org.slf4j', module: ''
}
compile is deprecated and it was replaced by implementation. Therefore, the solution for those running newer versions of gradle:
implementation("org.springframework.boot:spring-boot-starter-web") {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
}
This is for Kotlin DSL (build.gradle.kts) which prevents you from using wrong properties.
Exclude the library from all configrations (implementation, runtimeOnly, etc.):
configurations.all {
exclude(group = "ir.mahozad.android", module = "pie-chart")
// OR exclude("ir.mahozad.android", "pie-chart")
}
// Another notation:
// configurations {
// all {
// exclude(group = "ir.mahozad.android", module = "pie-chart")
// }
// }
Exclude the library from a single configuration (like implementation):
configurations.implementation {
exclude(group = "ir.mahozad.android", module = "pie-chart")
}
// Another notation:
// configurations {
// implementation {
// exclude(group = "ir.mahozad.android", module = "pie-chart")
// }
// }
Exclude the library for a single dependency:
dependencies {
// ...
implementation("ir.mahozad.android:charts:1.2.3") {
exclude(group = "ir.mahozad.android", module = "pie-chart")
}
}

Categories

Resources