Multi project gradle dependencies


(eilon shai) #1

Hi,

I have a multi project with the following structure:
app–
|–commons
|–core

the app dependencies are:

dependencies {
compile project(':core')
compile project(':commons')

}

the core dependencies are just:

dependencies {
compile project(':commons')

}

and the commons module has a lot of other third party dependencies

when I create a new project that depends on the app project, the build is trying to load jar for the commons module. how can I create one jar for all sub modules and let it be the only one that loaded when I add the app project as dependency?

Thanks,
Eilon


(Pierre) #2

Hello,

What you try to achieve looks like more or less nodejs module dependency management in my mind: each dependency should come with its own dependencies bundled.
Due to the JVM classloader, things work differently with Java, you may experience weird issues if several dependencies bring into the classpath different versions of a same third party lib. To avoid these issues, most developers use – and expect that the third parties they depend on also use – conflict resolution strategies to select the best version of a common dependency.

Nevertheless, if you still want to navigate that way, here is how I did it within the app project:

app/build.gradle

plugins {
	id("java")
}

repositories {
	mavenCentral()
}

dependencies {
	implementation project(":core")
        // consumes only commons.jar and nothing else
	implementation project(":commons"), {
		transitive = false
	}
}

app/core/build.gradle

plugins {
	id("java")
}

repositories {
	mavenCentral()
}

dependencies {
        // consumes only commons.jar and nothing else
	implementation project(":commons"), {
		transitive = false
	}
}

app/core/build.gradle

plugins {
	id("java")
}

repositories {
	mavenCentral()
}

dependencies {
	implementation "junit:junit:4.12" // just an example
}

// jar with dependencies
jar {
	from sourceSets.main.output
	from {
        configurations.runtimeClasspath.findAll { it.name.endsWith('jar') }.collect { zipTree(it) }
    }
}

Note that the example is incomplete as the commons module should publish pom.xml (or ivy descriptor) that makes no mention of the third parties to make sure that gradle will not download these pom in any cases. Few links on the doc:
how to build an jar with dependencies: https://docs.gradle.org/current/userguide/working_with_files.html#sec:creating_uber_jar_example
disabling transitive dependencies: https://docs.gradle.org/current/userguide/managing_transitive_dependencies.html#sub:disabling_resolution_transitive_dependencies