How to exclude library from dependencies? - java

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?

Related

Gradle dependencies: package does not exist

I know this has been asked multiple times but the questions have multiple answers.
I'm trying to use a Java package that's a dependency of my dependency. Let's say I've built this gradle project called "ee_tools". And that has a dependency called "my_models", which has a package called "com.mycompany.my_models.db". So in the ee_tools project build.gradle, I've got
dependencies {
// My stuff
implementation group: "com.mycompany", name: "my_models", version: "1.0.0"
}
Then in my current project, I've got
dependencies {
// My stuff
implementation group: "com.mycompany", name: "ee_tools", version: "1.0.0"
Shouldn't this mean that the public classes in my_models are accessible through ee_tools to my current project? Gradle was able to find both in my artifactory instance. And the gradle dependencies command shows ee_tools under the compileClasspath, implementation, and testCompileClasspath trees, but not with its children dependencies. It also shows up in the runtimeClasspath and testRuntimeClasspath trees with its children dependencies, including my_models.
I am also able to see that package inside the jar on the left side of IntelliJ, under the "External Libraries" tree, along with some classes.
But when I try to use the my_models package in my current project, IntelliJ can't find it and it fails a gradle build with the error
error: package com.company.my_models.db does not exist
It can't find any package in that dependency. What gives? Am I declaring the dependencies incorrectly? Or is this a gap between the gradle binary in my command line vs IntellJ and gradlew?
If ee_tools depends on my_models, then your gradle file in ee_tools should be like
implementation project(path: ":path:to:my_models", configuration: 'default')
:path:to:my_models is defined in settings.gradle in project root path like this:
include ':path:to:my_models'

Excluding a specific package from a dependency in Gradle

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.

What does the configuration "provided" in build.gradle do? [duplicate]

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.

Gradle dependency resolution - fetch only direct dependencies

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.

Creating Java library - add Gradle dependency for testing, but don't include it in compiled library (or make it overridable)

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.

Categories