How do I setup the dependencies of the modules in an Android Gradle project, where the modules have dependencies on each other, such that I can deploy a build of a new snapshot or release version of all modules in one go?
I have a project that consists of 2 modules: lib-core and lib-help, with lib-help depending on lib-core. I want to publish lib-core and lib-help seperately to Maven Central, such that the pom file of lib-help specifies the dependency on lib-core with the correct version.
The project is structured as follows:
/my-project-name
|
|--/lib-core
| |-- build.gradle
| |-- gradle.properties
|
|--/lib-help
| |-- build.gradle
| |-- gradle.properties
|
|-- build.gradle
|-- gradle.properties
|-- settings.gradle
|-- gradle-mvn-push.gradle
The project configuration files are as follows, showing only the relevant parts (by my judgement):
settings.gradle:
include ':lib-core', ':lib-help'
gradle.properties:
GROUP=com.company
VERSION=5.0.0-SNAPSHOT
gradle-mvn-push.gradle:
apply plugin: 'maven'
afterEvaluate { project ->
uploadArchives {
repositories {
mavenDeployer {
// GROUP is defined in <root>/gradle.properties
pom.groupId = GROUP
// ARTIFACT is defined in <root>/<module>/gradle.properties
pom.artifactId = ARTIFACT
// VERSION is defined in <root>/gradle.properties
pom.version = VERSION
}
}
}
}
// Contains a lot more to fill in other meta-data like project name,
// developer name, github url, javadoc, signing of the artifacts, etc, etc..
lib-core/gradle.properties:
ARTIFACT=my-lib-core
lib-core/build.gradle:
apply plugin: 'com.android.library'
// Contains more code to configure the android stuff, not relevant for this question
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
}
apply from: rootProject.file('gradle-mvn-push.gradle')
lib-help/gradle.properties:
ARTIFACT=my-lib-help
lib-help/build.gradle:
apply plugin: 'com.android.library'
// Contains more code to configure the android stuff, not relevant for this question
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile project(':lib-core')
}
apply from: rootProject.file('gradle-mvn-push.gradle')
When I run gradlew clean :lib-core:uploadArchives :lib-help:uploadArchives
, everything compiles nicely and uploads are being pushed to the correct repository. In the Nexus Repository Manager I can see the artifacts for both modules with the correct name, version, signing, etc., but the dependency of lib-help on lib-core in the generated pom.xml is wrong. It uses the project name as groupId, the module name as the artifactId and an unspecified version name:
<dependency>
<groupId>my-project-name</groupId>
<artifactId>lib-core</artifactId>
<version>unspecified</version>
<scope>compile</scope>
</dependency>
Consequently, projects using lib-help as a dependency can't resolve the lib-core dependency. The correct values that should have been in lib-help's pom.xml are groupId=com.company, artifactId=my-lib-core and version=5.0.0-SNAPSHOT.
To fix this, I thought I'd use a maven dependency in lib-help, instead of a module dependency, like this:
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.company:my-lib-core:' + VERSION
}
Naturally, this version does not exist before the uploadArchives command of lib-core has been executed, but gradle wants to resolve the dependencies of all modules before starting execution of any of the given commands. Thus, it can't resolve this dependency and quits with an error while configuring the gradle projects. Now, I can work around this by temporarily setting the dependency of lib-help to project(':lib-core')
, then release lib-core, then adjust the dependency of lib-help to 'com.company:my-lib-core:5.0.0-SNAPSHOT'
, then release lib-help, but that just doesn't seem the right way. It invites human mistakes (what if I accidentally increase the version number between the to uploadArchives commands?) and it takes several manual, strictly ordered steps.
How do I setup the dependencies of the modules in an Android Gradle project, where the modules have dependencies on each other, such that I can deploy a build of a new snapshot or release version of all modules in one go? (e.g., but not necessarily, with the command gradlew clean :lib-core:uploadArchives :lib-help:uploadArchives
)
Simply open the gradle tab (can be located on the right) and right-click on the parent in the list (should be called "Android"), then select "Refresh dependencies". This should resolve your issue.
Gradle declares dependencies on JAR files inside your project's module_name /libs/ directory (because Gradle reads paths relative to the build.gradle file). This declares a dependency on version 12.3 of the "app-magic" library, inside the "com.example.android" namespace group.
It's possible to keep the local project dependencies (compile project(':core')
), if you rewrite the POM before uploading:
afterEvaluate { project ->
uploadArchives {
repositories {
mavenDeployer {
// ... other config here ...
pom.whenConfigured { pom ->
pom.dependencies.forEach { dep ->
if (dep.getVersion() == "unspecified") {
dep.setGroupId(GROUP)
dep.setVersion(VERSION_NAME)
}
}
}
}
}
}
}
Here's an example of a working project: https://github.com/hannesstruss/WindFish
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With