gradle, is there side effect with exclude on a transitive dependency - gradle

In an android lib (my_lib) which has dependency on other lib (other_lib), the other lib has dependency on okhttp:3.10.0.
Now my lib would like to use okhttp:4.9.3
the other_lib has
api "com.squareup.okhttp3:okhttp:3.10.0"
so my_lib changed from:
api "com.mobile.xxx:other_lib:2.0.0"
to:
implementation("com.mobile.xxx:other_lib:2.0.0") {
exclude group: 'com.squareup.okhttp3', module: 'okhttp'
}
api "com.squareup.okhttp3:okhttp:4.9.3"
so that my_lib will still use other_lib, but all okhttp will be from okhttp:4.9.3. And make it still transitive so that the client of my_lib will get okhttp:4.9.3.
Question:
does it need the exclude group: 'com.squareup.okhttp3', module: 'okhttp'? without it the okhttp will still be using okhttp:4.9.3 since it's the newer version specified in my_lib with the
api "com.squareup.okhttp3:okhttp:4.9.3"
What is the difference with/or without the exclude here?
with specifying a newer version of the dependency (here api "com.squareup.okhttp3:okhttp:4.9.3"), will it bring in some side effect to the other_lib at runtime? i.e. what if the other_lib is using some old interface/method within the okhttp:3.10.0 but that has been removed/altered in okhttp:4.9.3, will the other_lib still function correctly?

Related

Gradle bundle import to module

I am trying to import base to a project, but I get an error.
settings.gradle
enableFeaturePreview('VERSION_CATALOGS')
dependencyResolutionManagement {
versionCatalogs {
libs {
// https://mvnrepository.com/artifact/org.springframework/spring-core
version('spring', '5.3.14')
// https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter
version('spring-boot', '2.6.2')
alias('spring-core').to('org.springframework', 'spring-core').versionRef('spring')
alias('spring-context').to('org.springframework', 'spring-context').versionRef('spring')
alias('spring-boot').to('org.springframework.boot', 'spring-boot-starter').versionRef('spring-boot')
bundle('base', ['spring-core', 'spring-context'])
}
}
}
module's build.gradle
dependencies {
implementation(libs.base)
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
}
refreshing gradle will produce the following error
Could not get unknown property 'base' for extension 'libs' of type org.gradle.accessors.dm.LibrariesForLibs.
How to import libs.base correctly?
The correct way of referencing a bundle from a version catalog is
libs.bundles.base
Similarly for plugins use:
libs.plugins.yourplugin
It is also possible to reference versions, but this works slightly different. For example:
implementation group: "org.springframework.boot", name: "spring-boot-starter-web-services", version: libs.versions.spring.boot.get()
This assumes a version definition in your catalog which looks like:
version('spring-boot', '2.6.7')
Note that bundles, versions and plugins are all spelled as plural.
Also note that as of Gradle 7 version catalogs are no longer a feature preview. They are available by default. Also, the notation for libraries has changed slightly. You have to use library instead of alias.
See Gradle's support site for more information.

import dependencies from another module

I think I am missing some point in how dependencies management works in gradle.
Let's say I have the following project structure:
project
---api
------api-commons
------api-v1
------api-v2
------api-v3
where all api* directories are modules. All api-v* need a particular dependency (let's say common-dependency).
My aim would be to import it in api-commons build.gradle file:
dependencies {
implementation 'common-dependency'
}
while in the build.gradle files of the other modules api-v* put:
dependencies{
implementation project(':api:api-commons')
}
I would expect this to work but it doesn't. The code in the api-v* modules simply acts like the dependency is not declared. Indeed, if I import the dependency in the single modules, the code works as expected.
Am I doing a wrong assumption? Doesn't the dependency inheritance work like that?
Declaring a dependency in the implementation configuration conceptually means it is internal to the module (it is used in the implementation but not part of the public API). Such a dependency will not be exposed to the compile classpath of consumers, though it will still be on the runtime classpath.
An advantage of this way of modelling dependencies is that you do not need to recompile consuming projects if an implementation dependency changes. Another is that by encapsulating them, it is less likely that a consumer will start depending on them directly and then breaking if you change them.
If you want to expose the dependency to consumers, you have to declare it as part of the API for the module. You do that by applying the java-library plugin and using the api configuration.
Example:
// api-commons/build.gradle
plugins {
id 'java-library'
}
dependencies {
api 'common-dependency'
}
Read more about it in the Gradle user guide
Let say, I have to moved below common code(*.java files) from below 2 service/modules to sharedprocessing-data which is present inside shared-libraries service/modules :
abc-service
xyz-servcie
Address.java
Employee.java
Department.java
Vaccation.java
Name.java
City.java
Order.java
Steps0:
In shared- service/modules folder create additional module inside existing shared-libraries module
Name it as sharedprocessing-data
Steps1:
Move(refactor) common code inside this module
Steps2:
In parent folder (root) update settings.gradle file
rootProject.name = "root"
include 'abc-service'
include 'xyz-service'
include 'shared-libraries:sharedprocessing-data'
Step3:
In each of abc-service and xyz-flow service modules, update build.gradle file
dependencies
{
implementation project(':shared-libraries:sharedprocessing-data')
}

How to use current version in configurations in gradle

Situation: In my build.gradle file I have 2 separate configurations for pulling in specific dependencies.
One is called configJars where I pull down jars to unpack and get specific json files from.
My question is, is there a way to call out the versions that are already being resolved in the compile/transitive dependencies.
com.example:common:2.0.0-SNAPSHOT -> 2.0.1-SNAPSHOT
I attempted to use "+" but this only pulls the latest version that is available in the repo which is not what I require.
configJars(group: "com.example", name: "common", version: "+")
+--- com.example:common:+ -> 3.2.18-SNAPSHOT
I need to use the version that is being used by a specific dependency that gets updated by a different team.
I ended up adding the library that was doing the update to my other libraries and removed the other libraries from the build file. SO they get pulled in transitively and explicitly exclude the libraries I don't need from the transitive pull.
I had to change the configuration to transitive = true and change all the dependency declarations to { transitive = false}.
A bit messy but it worked out.

Spring boot, exclude dependencies from test in Gradle 5

I want to exclude two jars from test and only use them when the application is actually running.
dependencies {
runtimeOnly('org.springframework.cloud:spring-cloud-starter-netflix-eureka-client')
runtimeOnly('org.springframework.cloud:spring-cloud-starter-config')
}
How do I explicitly tell Gradle 5 not to load these jars during the running of tests? I have already disabled their use but they keep getting loaded anyway. I was hoping for something simple like below, but I've been unable to find a conclusive answer.
test.exclude {
group 'org.springframework.cloud'
}
EDIT
Copy paste solution
configurations.testCompile.exclude(group: 'org.springframework.cloud', module: 'spring-cloud-starter-netflix-eureka-client')
configurations.testCompile.exclude(group: 'org.springframework.cloud', module: 'spring-cloud-starter-config')
Inside your dependencies block, you can do something like:
configurations.testCompile.exclude(group: 'the-group', module: 'the-module')
Hope this helps!

Gradle build error with Simpleframework

I upload my library module to jcenter and I use this module with my application project.
I try to build my application it returns an error.
I searched this issue and This issue is due to be aware of what simpleframework.
I have to use this library both My library module and application module.
How can I solve this problem?
Gradle error msg is below
trouble processing "javax/xml/stream/events/StartElement.class":
Ill-advised or mistaken usage of a core class (java.* or javax.*) when
not building a core library. This is often due to inadvertently
including a core library file in your application's project, when
using an IDE (such as Eclipse). If you are sure you're not
intentionally defining a core class, then this is the most likely
explanation of what's going on. However, you might actually be trying
to define a class in a core namespace, the source of which you may
have taken, for example, from a non-Android virtual machine project.
This will most assuredly not work. At a minimum, it jeopardizes the
compatibility of your app with future versions of the platform. It is
also often of questionable legality. If you really intend to build a
core library -- which is only appropriate as part of creating a full
virtual machine distribution, as opposed to compiling an application
-- then use the "--core-library" option to suppress this error message. If you go ahead and use "--core-library" but are in fact
building an application, then be forewarned that your application will
still fail to build or run, at some point. Please be prepared for
angry customers who find, for example, that your application ceases to
function once they upgrade their operating system. You will be to
blame for this problem. If you are legitimately using some code that
happens to be in a core package, then the easiest safe alternative you
have is to repackage that code. That is, move the classes in question
into your own package namespace. This means that they will never be in
conflict with core system classes. JarJar is a tool that may help you
in this endeavor. If you find that you cannot do this, then that is an
indication that the path you are on will ultimately lead to pain,
suffering, grief, and lamentation. 1 error; aborting Error:Execution
failed for task ':app:preDexDebug'.
com.android.ide.common.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command
'C:\jdk1.7.0\bin\java.exe'' finished with non-zero exit value 1
My library build.gradle dependencies are below.
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.mcxiaoke.volley:library:1.0.+'
compile 'com.google.code.gson:gson:2.2.4'
compile ('org.simpleframework:simple-xml:2.7.+') {
exclude module: 'stax'
exclude module: 'stax-api'
exclude module: 'xpp3'
}
}
My Application dependencies are below :
dependencies {
compile 'com.android.support:support-v4:19.+'
compile 'com.google.android.gms:play-services:5.+'
compile 'com.jakewharton:butterknife:5.1.2'
compile 'com.jakewharton.timber:timber:3.1.0'
compile 'commons-io:commons-io:2.4'
compile 'commons-net:commons-net:3.3'
compile 'org.apache.httpcomponents:httpmime:4.2.5'
/*compile 'com.mcxiaoke.volley:library:1.0.+'
compile 'com.google.code.gson:gson:2.2.4'
compile('org.simpleframework:simple-xml:2.7.+') {
exclude module: 'stax'
exclude module: 'stax-api'
exclude module: 'xpp3'
}*/
compile 'org.jsoup:jsoup:1.7.2+'
compile 'com.effectivelife:cokcok-support:1.0.0'
}
I solved this problem.
I add a configurations to my application project.
So my application build.gradle file is below.
configurations {
compile.exclude module: 'stax'
compile.exclude module: 'stax-api'
compile.exclude module: 'xpp3'
}
dependencies {
compile 'com.android.support:support-v4:19.+'
compile 'com.google.android.gms:play-services:5.+'
compile 'com.jakewharton:butterknife:5.1.2'
compile 'com.jakewharton.timber:timber:3.1.0'
compile 'commons-io:commons-io:2.4'
compile 'commons-net:commons-net:3.3'
compile 'org.apache.httpcomponents:httpmime:4.2.5'
compile 'org.jsoup:jsoup:1.7.2+'
compile 'com.effectivelife:cokcok-support:1.0.1'
}

Resources