How to exclude transitive dependency


(priyanka_bhopali) #1

Hello ,

I am working on converting a maven based build system to gradle based build. I am having issues with following :

Issue# 1) Transitive Dependency :

I have dependency tree like this in maven pom.xml

<dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>jcl-over-slf4j</artifactId>
   <version>1.6.2</version>
  </dependency>
  <dependency>
   <groupId>ch.qos.logback</groupId>
   <artifactId>logback-core</artifactId>
   <version>1.0.0</version>
  </dependency>
  <dependency>
   <groupId>ch.qos.logback</groupId>
   <artifactId>logback-classic</artifactId>
   <version>1.0.0</version>
   <exclusions>
    <exclusion>
     <groupId>org.slf4j</groupId>
     <artifactId>slf4j-api</artifactId>
    </exclusion>
   </exclusions>
  </dependency>

Here is my build.gradle

dependencies {
 compile (
        [group: 'org.slf4j', name: 'jcl-over-slf4j', version: '1.6.2'],
   [group: 'ch.qos.logback', name: 'logback-core', version: '1.0.0'],
   [group: 'ch.qos.logback', name: 'logback-classic', version: '1.0.0']
   /*
   [group: 'ch.qos.logback', name: 'logback-classic', version: '1.0.0']{
    exclude(group: 'org.slf4j', name: 'slf4j-api', version: '1.6.2')
   }*/
        )

Please suggest how to remove transitive dependency in situation like this.

Issue#2 ) my settings.gradle look like this :

includeFlat('dns-core', 'dns-model','dns-web','dns-target-rest')

I would like to get project built in that order .

When I do gradle clean

Here is what I see:

:clean UP-TO-DATE
:dns-core:clean UP-TO-DATE
:dns-model:clean UP-TO-DATE
:dns-target-rest:clean UP-TO-DATE
:dns-web:clean UP-TO-DATE
  BUILD SUCCESSFUL

why is dns-target-rest cleaned before dns-web ?

Thanks in advance.

Please suggest. I am writing a poc to suggest gradle is better than maven.


(crotwell) #2

This should help http://gradle.org/docs/current/dsl/org.gradle.api.artifacts.dsl.DependencyHandler.html

http://gradle.org/docs/current/javadoc/org/gradle/api/artifacts/ModuleDependency.html#exclude(java.util.Map)

and here is the example given in the above:

apply plugin: ‘java’ //so that I can declare ‘compile’ dependencies

dependencies {

compile(‘org.hibernate:hibernate:3.1’) {

//excluding a particular transitive dependency:

exclude module: ‘cglib’ //by artifact name

exclude group: ‘org.jmock’ //by group

exclude group: ‘org.unwanted’, module: ‘iAmBuggy’ //by both name and group

}

} </code

Philip


(priyanka_bhopali) #3

Thanks it worked.

Here is my working example if anyone is interested .

dependencies {
 compile (
   [group: 'org.slf4j', name: 'jcl-over-slf4j', version: '1.6.2'],
   [group: 'ch.qos.logback', name: 'logback-core', version: '1.0.0']
     )
   compile('ch.qos.logback:logback-classic:1.0.0') {
  exclude group: 'org.slf4j', module: 'slf4j-api' //by both name and group
 }
}

so we will have two compile block.


(priyanka_bhopali) #4

Any pointers on issue #2. Why is it build dns-web after dns-target-rest ?


(Peter Niederwieser) #5

In Gradle, execution dependencies are between tasks, not between projects. What is it that you hope to gain from a strict project order?


(priyanka_bhopali) #6

May be it is my lack of understanding . Well I am coming from ant background . When we define a projectB dependent on projectA .project A is built before projectB. I was trying to do similar stuff with Gradle . So when I gave dns-web before dns-target-rest I was hoping that it would be built in that order.

I have added following to dns-target-rest and project compiles.

dependencies {
 compile project(':dns-web')
}

I see following output in console:

:dns-web:compileJava UP-TO-DATE
:dns-web:processResources UP-TO-DATE
:dns-web:classes UP-TO-DATE
:dns-web:jar UP-TO-DATE
:dns-target-rest:compileJava UP-TO-DATE
:dns-target-rest:processResources UP-TO-DATE
:dns-target-rest:classes UP-TO-DATE
:dns-target-rest:war UP-TO-DATE
:dns-target-rest:assemble UP-TO-DATE
:dns-target-rest:compileTestJava UP-TO-DATE
:dns-target-rest:processTestResources UP-TO-DATE
:dns-target-rest:testClasses UP-TO-DATE
:dns-target-rest:test UP-TO-DATE
:dns-target-rest:check UP-TO-DATE
:dns-target-rest:build UP-TO-DATE
:dns-web:assemble UP-TO-DATE
:dns-web:compileTestJava UP-TO-DATE
:dns-web:processTestResources UP-TO-DATE
:dns-web:testClasses UP-TO-DATE
:dns-web:test UP-TO-DATE
:dns-web:check UP-TO-DATE
:dns-web:build UP-TO-DATE

I see it does :dns-web:jar first than dns-target-rest build afterwards . Why doestn’t it do dns-web all steps e.g. dns-web assemble- dns-web build before dns-target-rest.

Sorry for my lack of understanding.

Priyanka


(Peter Niederwieser) #7

As I already mentioned, execution dependencies are between tasks, not between projects. The order in which projects are included in settings.xml is irrelevant. If two particular tasks have no (direct or transitive) execution dependency, Gradle is free to execute them in any order it sees fit. In the future, this will allow Gradle to do powerful optimizations like running tasks in parallel or running quicker tasks first - even across projects. Serializing projects would severely limit these possibilities without providing any benefits.

The dependency you added will result in :dns-web:jar being executed before :dns-target-rest:compileJava. However, it isn’t necessary to execute all tasks in dns-web before any task in dns-target-rest to get to a correct result.