I have a gradle project with the following dependencies declaration.
dependencies{
implementation 'com.github.gwtmaterialdesign:gwt-material:2.1'
implementation 'com.github.gwtmaterialdesign:gwt-material-addins:2.1'
implementation 'com.github.gwtmaterialdesign:gwt-material-themes:2.1'
implementation 'com.github.gwtmaterialdesign:gwt-material-table:2.1'
}
However, gwt-material-2.1 depends on gwt-user-2.8.2 and gwt-dev-2.8.2.
In turn they have numerous dependencies which are not required by my project.
I can disable transitive dependencies completely and manually add gwt-user and gwt-dev. However, I would like it to happen automatically but still fetch only 1st level dependencies.
Related
I have a gradle project with several modules in it. In the main module I have id "io.spring.dependency-management" plugin. In the adapters module I have dependency on the main one implementation project(":main") with runtimeOnly 'io.r2dbc:r2dbc-postgresql in dependency block, which pulls 0.8.12.RELEASE version of the r2dc-postgresql driver.
Now I want to use 0.8.13.RELEASE verision of the driver, so I simply added runtimeOnly 'io.r2dbc:r2dbc-postgresql:0.8.13.RELEASE to the dependency declaration, but now I have two versions of this library in external libraries section (0.8.12.RELEASE and 0.8.13.RELEASE), but ./gradlew adapters:dependencies displays only 0.8.13.RELEASE version.
How to find out where 0.8.12.RELEASE is coming from now and remove it?
I tried
exlude(group = 'io.r2dbc', module = 'r2dbc-postgresql')
but it didn't work
have you had a look at e.g.:
https://docs.gradle.org/current/userguide/resolution_rules.html
or
How to exclude library from all dependencies in Kotlin DSL build.gradle?
or
What does this "all*.exclude" means in Gradle transitive dependency?
I have a dependency in one of my project
implementation (group: 'com.ibm.cloud', name: 'ibmcloudsql-jdbc', version: '2.5.34')
I want to specifically exclude a package from this jar, i.e
com.ibm.cloud.sdk.core.http
Is there a way? I already tried this but did not work.
implementation (group: 'com.ibm.cloud', name: 'ibmcloudsql-jdbc', version: '2.5.34'){
exclude module: 'com.ibm.cloud.sdk.core.http'
}
You can't use dependency management to remove part of a dependency - with dependency management it's either the complete dependency or no dependency (and this is not limited to gradle - other dependency managers / build systems like maven or ivy also don't have this feature).
The exclude module can only be used to prevent inclusion of transitive dependencies (i.e. you need dependency com.xy:A and com.xy:A declares that it also needs com.xy:B - with exclude module you can prevent the inclusion com.xy:B)
It might be possible to create your own version of that dependency by manually removing the package com.ibm.cloud.sdk.core.http from the jar itself and adding that modified jar file to your project.
I am trying to get Gradle to select different dependencies in my multiproject build based on whether I am building for desktop or for Android. I have a common subproject (a library) I am trying to reuse. However, I cannot get Gradle to correctly switch dependency configurations.
My main settings.gradle simply includes all the dependencies:
// /settings.gradle
rootProject.name = 'myProject'
include 'androidUI'
include 'reusableLibrary'
include 'desktopUI'
Now both androidUI and desktopUI specify reusableLibrary as a dependency:
// /androidUI/build.gradle and /desktopUI/build.gradle
apply plugin: 'java'
dependencies {
compile project(path: ':reusableLibrary', configuration: 'desktop')
}
reusableLibrary itself specifies two configurations, because its dependencies are different whether it's building on desktop or Android:
// /reusableLibrary/build.gradle
apply plugin: 'java'
configurations {
desktop {
extendsFrom compile
}
android {
extendsFrom compile
}
}
dependencies {
// Just examples, the real list is longer.
// The point is that h2database is only included on desktop,
// and ormlite is only included on Android.
android 'com.j256.ormlite:ormlite-jdbc:5.0'
desktop 'com.h2database:h2:1.4.192'
}
This looks fine to me. But when I compile either desktopUI or androidUI, I can see that although the dependencies of reusableLibrary are being included on the classpath in the manner I desire, the actual JAR provided by reusableLibrary itself is not included. This of course causes the build to fail. I suspect I'm not setting up reusableLibrary correctly; I'm not clear on what the configurations {} blocks do.
Why aren't the compiled items in reusableLibrary being included on the classpaths of the UI projects? And what is the canonical way to include platform-specific dependencies in this manner?
The original configuration is pretty close to right. The key is to understand this dependency graph from the Gradle Java plugin's documentation:
This is a visualization of the Java plugin's various dependency configurations, which is Gradle-ese for "list of dependencies." When you add compile lines to a dependencies {...} block, you're adding Dependency elements to the compile dependency list.
The default dependency configuration is special; it is the one included by a compile project("path") line unless a different one is chosen with the configuration: argument. This means that when you build the library, the runtime dependency list (which includes the compiled jar from the library itself) is added to the classpath of the client project.
The original configuration creates two new nodes, desktop and android in this graph, and couples them both to compile by using extendsFrom. They are not otherwise connected to the graph! Now the problem with the original configuration is apparent: by switching the upstream project to either of these, it is missing the compiled code from runtime. This explains the classpath omission.
The solution is a bit more subtle than just aiming desktop and android at runtime. In order to ensure that everything is correctly decoupled when we add tests, we need one extra layer of dependency configurations to keep testCompile from indirectly depending on runtime. Additionally, the library's source code itself may need things on its classpath just to typecheck; we can use compileOnly for this. The end solution looks like this:
configurations {
desktopCompile
androidCompile
compileOnly.extendsFrom desktopCompile
testCompile.extendsFrom desktopCompile // Assuming tests run on the desktop
desktop {
extendsFrom desktopCompile
extendsFrom runtime
}
android {
extendsFrom androidCompile
extendsFrom runtime
}
}
dependencies {
androidCompile "some.android:dependency"
desktopCompile "other.desktop:dependency"
}
I have an Android project and I plan to make one of its components a library. This will be a Java library (jar), as the android dependencies are not needed there.
The problem is that this library depends on RxJava. But I would like it to be dependent on the RxJava version which the library client will use, no to be explicitly provided by me in the library's build.gradle.
I thought that maybe Gradle Default dependencies would be the way to go, but it doesn't provide the RxJava dependency at all and the library module doesn't build.
My build.gradle:
apply plugin: 'java'
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
}
configurations.all {
pluginTool {
defaultDependencies { dependencies ->
dependencies.add(this.project.dependencies.create("io.reactivex:rxjava:1.1.0"))
}
}
}
sourceCompatibility = "1.7"
targetCompatibility = "1.7"
The problem is that this library depends on RxJava. But I would like it to be dependent on the RxJava version which the library client will use, no to be explicitly provided by me in the library's build.gradle.
I don't know if that's possible because that's not the way dependencies work. Maven Transitive Dependencies explains this issue a little.
For example, you made a library and used a given version of RxJava, say, vn. It implictly means that your lib uses some features of vn that are not present in vn-1 and hopefully won't be deprecated in vn+1 and later. If a lib client were able to choose any RxJava version, it could arbitrarily pick vn-1 and your code would not work. You have a hard dependency on vn and anyone who uses your library should be aware of it.
There's no problem in providing an explicit dependency in your lib's build.gradle. In fact, listing the dependencies will help Gradle resolve the dependency graph, handle conflicts and everything. Here's a bit of what Gradle does: https://docs.gradle.org/current/dsl/org.gradle.api.artifacts.ResolutionStrategy.html
Finally, even if you find a way to achieve the dependency delegation to the lib client, the application can crash during runtime.
Given a gradle project A having a dependency on project B (no common parent)
compile project('B'){
exclude group: 'org.slf4j'
}
how do we exclude transitive dependency group from a project we depend upon? (this piece of script will fail as there is no exclude for compile projet(..))
and more general question : is there an elegant way to exclude a particular group from all dependancies except if its a first level dependency?
for example we may have a bunch of libraries, and each may declare its logging environment, but by excluding all known groups of slf4j, its implementations and declaring specific version, we would ensure we don't have any version conflicts and would control version on module level.
Here is an example from the Gradle documentation of how to exclude a transitive dependency (I guess that is what you meant by "except if its a first level dependency") on project level:
configurations {
compile.exclude module: 'commons'
all*.exclude group: 'org.gradle.test.excludes', module: 'reports'
}
See 52.4.7. Excluding transitive dependencies here
You can either specify the dependency directly with the desired version or use a forced version resolution strategy