Dependency resolution for classes with same package structure in Gradle - java

Say I have a project ProjectA with a compile dependency on core. And core depends on deepcore. Thus, ProjectA has a transitive dependency on deepcore.
So, build script for ProjectA has this
dependencies {
compile "com.something:core:1.0.0"
}
And build script for core has this
dependencies {
compile "com.something:deep-core:1.0.0"
}
Now, there is a class CoreService defined in both core and deepcore with the same package structure. And I am using that class from my ProjectA, which implementation will it use? How do configure my dependency so that I am using the version from core?

This should do what you are looking for.
dependencies {
compile "com.something:deep-core:1.0.0" {
exclude group: 'com.unwanted', module: 'unwanted'
}
}

Related

How to exclude transitive dependency from liberty-server build.gradle file

I got 2 java projects and 1 server all three having build.gradle file defining and configuring the dependencies I need in my project.
Code snippet of Liberty server build.gradle is as follows:
configuration{
project1
project2
oracle
extrasecuritystuff
}
dependencies{
project1: "fskfksd"
project2: "sdfd"
extrasecuritystuff 1."fsfd"
2."ewrwer"
}
doTask{....
My question is how do I exclude a transitive dependency present in 2."ewrwer". What is the groovy/gradle syntax for doing so?
Based on the gradle docs I tried something like this but did not work out, once I triggered the Jenkins build It was still pulling in the transitive dependency jars.
configurations {
project1
project2
extrasecuritystuff {
exclude group: 'javax.jms', module: 'jms'
exclude group: 'com.sun.jdmk', module: 'jmxtools'
}
}
dependencies {
project1 'org.javax.etc'
project2 'org.blah.blah'
extrasecuritystuff 'log4j:log4j:1.2.15'
}
I'm assuming here that you are using some plugin like the 'application' plugin to generate a .zip file of your project, and that your goal is to exclude the transitive dependency from the .zip file. The reason could be that the transitive dependency has an undesirable license, or is too large, and your code is never actually calling functions that need the transitive dependency. (Make absolutely 100% double sure of this, or your application will crash.) Or, the target system already has that dependency installed. (Likewise.)
You had a few syntax issues in your example code, but I've interpreted the question according to my understanding. In the example, my dependency ewrwer is pulling in lib-foo which I don't want.
configuration{
project1
project2
extrasecuritystuff
}
dependencies{
project1 ( [...] )
project2 ( [...] )
extrasecuritystuff ('org.blah:fsfd:1.0.1')
extrasecuritystuff ('org.bloop:ewrwer:2.12') {
exclude group: 'org.bleep', module: 'lib-foo'
}
}
For more about managing transitive dependencies, as always refer to the official Gradle docs.

Gradle multiproject multiple dependencies

I have a gradle project like this:
root
|
|---- projectA
|
|---- projectB
...
My root build.gradle contains dependencies which are needed for projectA and projectB. I have defined them like this:
subprojects {
repositories {
jcenter()
mavenCentral()
mavenLocal()
}
dependencies {
compile 'com.google.guava:guava:23.0'
compile group: 'com.google.code.gson', name: 'gson', version: '2.8.2'
Now I am trying to add a dependency on projectA from projectB so my projectB build.gradle looks like this:
dependencies {
implementation project(':projectA')
}
and projectB settings.gradle:
include ':projectA'
project(':projectA').projectDir = new File(settingsDir, '../projectA')
This is currently failing, as projectA and B do not depend on root to get their needed dependencies.
Can I add another dependency from projectA on root or what is the default gradle approach to share same dependencies from one root project?
Specifying dependencies with the "compile" keyword is being deprecated. The new keyword to use is "implementation". (See this SO question for an example of explanation.) The difference between "compile" and "implementation" as it relates to your case, is that "compile" propagates the dependency to all connected modules, while "implementation" is single-level. So, if you have
root
module A
module B
and module B has a depandency brought in with "compile", then root has access to that dependency.
But if you now change B to bring the dependency in with "implementation", then you'll still need to add the dependency to the root project's build.gradle.
Why is this relevant? Because a child module isn't allowed to know who its parent is. So, while A and B both see the dependencies you brought into root, they really shouldn't -- seeing those dependencies is a quirk of how Studio works. This is also why the answer to "Can I add another dependency from projectA on root" is "no, you're out of luck there, it'd create a circular dependency and that's not allowed".
The dependencies I'd try are:
In both module A and module B:
dependencies {
implementation 'com.google.guava:guava:23.0'
implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.2'
Then in Module B, you do:
implementation project(':projectA')
Then in root, you depend on both A and B.
Your modules (A and B) are not correctly setup as child modules of the root project.
In your base folder, create if necessary the settings.gradle file, and add the child modules definition:
root/settings.gradle
include 'projectA', 'projectB'
The build.gradle file of projectB is ok as it is, then you need to remove the root/projectB/settings.gradle file; child-modules and their locations are specified in the parent build file.

How to exclude transitive jar dependency in Gradle?

My project depends on dependency A and dependency B.
Dependency A also depends on dependency B, but a different version of it.
The problem is in project A's build.gradle dependency B is included as a jar directly using the file and fileTree methods:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile files('libs/B.jar')
}
My project's build.gradle looks like this:
dependencies {
compile 'com.B:B:myvesion'
compile('com.A:A:theirversion') {
exclude module: 'B'
}
}
But my build fails with this exception:
Execution failed for task ':myproject:transformDexArchiveWithDexMergerForDebug'.
> com.android.build.api.transform.TransformException: com.android.dex.DexException: Multiple dex files define Lcom/B/someclass;
I want to exclude the jar version of B from my project and use my version. How do I do this? Seems like the exclude instruction doesn't work in my case.
You can't do it for the jar files.
You can exclude transitive dependencies (described in the pom file). The jar file is not a transitive dependency.

Multiproject build: dependency to tests jar

I'm restructuring/refactoring build process for a big(ish) project. Currently it contains over a dozen separate modules built with standalone build scripts each. I want to integrate them all into a single multiproject build in Gradle.
After I integrated all sources into a single tree, fixed build.gradles, I came upon the following problem. Dependencies for many modules contain something like:
dependencies {
compile group: 'com.company', name: 'Module', version: '1.2.3'
// ...
testCompile group: 'com.company', name: 'Module', version: '1.2.3', classifier: 'tests'
}
I want the build to use jars from the subproject, not from a repository. I replaced compile ... with compile project(':Module') and it works fine. However, I cannot find the way to pass 'tests' specifier to the testCompile project... dependency.
Is there a way to pick up the tests jar as a dependency to testCompile?
In the producing project you will need to declare the "Test" JAR as outgoing artifact.
configurations {
testUtils
}
task testUtilsJar(type: Jar) {
...
}
artifacts {
testUtils testUtilsJar
}
In the consuming project you depend on it as such:
dependencies {
testCompile project(path: ':Module', configuration: 'testUtils')
}

How to add a local jar dependency to another dependency in gradle?

The jar amazon-kinesis-connectors is using amazon-kinesis-client. I want to change this dependency to a local custom jar:
dependencies {
compile ('com.amazonaws:amazon-kinesis-connectors:1.2.0'){
exclude group: "com.amazonaws", module: "amazon-kinesis-client"
}
compile files('libs/amazon-kinesis-client-1.6.3.jar')
//...
}
It compiles ok, but when I'm running the code I get java.lang.NoClassDefFoundError: com/amazonaws/services/kinesis/clientlibrary/interfaces/IRecordProcessorFactory. Is there a way to do this dependency management in gradle?
As environment I'm using:
gradle 2.13
intellij idea CE 2006.1
java 1.8
Edit:
dependency graph in intellij:
Running using a gradle task:
task run_app(type:JavaExec) {
main = 'org.main.RunApp'
classpath = sourceSets.main.runtimeClasspath
}
try below gradle configuration
dependencies {
compile ('com.amazonaws:amazon-kinesis-connectors:1.2.0'){
exclude group: "com.amazonaws", module: "amazon-kinesis-client"
}
compile files('libs/amazon-kinesis-client-1.6.3.jar')
runtime files('libs/amazon-kinesis-client-1.6.3.jar')
//...
}
or you can use application plugin to create executable jar
https://docs.gradle.org/current/userguide/userguide_single.html#application_plugin

Categories

Resources