I have a Gradle project I'm using the maven-publisher plugin to install my android library to maven local and a maven repo.
That works, but the generated pom.xml does not include any dependency information. Is there a workaround to include that information, or am I forced to go back to the maven plugin and do all the manual configuration that requires?
Researching I realized that I'm not telling the publication where the dependencies are, I'm only specifying the output/artifact, so I need a way to link this MavenPublication
to the dependencies, but I have not yet found how to do that in the documentation.
------------------------------------------------------------ Gradle 1.10 ------------------------------------------------------------ Build time: 2013-12-17 09:28:15 UTC Build number: none Revision: 36ced393628875ff15575fa03d16c1349ffe8bb6 Groovy: 1.8.6 Ant: Apache Ant(TM) version 1.9.2 compiled on July 8 2013 Ivy: 2.2.0 JVM: 1.7.0_60 (Oracle Corporation 24.60-b09) OS: Mac OS X 10.9.2 x86_64
Relevant build.gradle sections
//...
apply plugin: 'android-library'
apply plugin: 'robolectric'
apply plugin: 'maven-publish'
//...
repositories {
mavenLocal()
maven {
name "myNexus"
url myNexusUrl
}
mavenCentral()
}
//...
android.libraryVariants
publishing {
publications {
sdk(MavenPublication) {
artifactId 'my-android-sdk'
artifact "${project.buildDir}/outputs/aar/${project.name}-${project.version}.aar"
}
}
repositories {
maven {
name "myNexus"
url myNexusUrl
credentials {
username myNexusUsername
password myNexusPassword
}
}
}
}
Generated pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example.android</groupId>
<artifactId>my-android-sdk</artifactId>
<version>gradle-SNAPSHOT</version>
<packaging>aar</packaging>
</project>
I was able to work around this by having the script add the dependencies to the pom directly using pom.withXml
.
//The publication doesn't know about our dependencies, so we have to manually add them to the pom
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
//Iterate over the compile dependencies (we don't want the test ones), adding a <dependency> node for each
configurations.compile.allDependencies.each {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', it.group)
dependencyNode.appendNode('artifactId', it.name)
dependencyNode.appendNode('version', it.version)
}
}
This works for my project, it may have unforeseen consequences in others.
I'm upgraded C.Ross solution. This example will generate pom.xml with dependecies from compile configuration and also with special build type dependecies, for example if you use different dependencies for release or debug version (debugCompile and releaseCompile). And also it adding exlusions
publishing {
publications {
// Create different publications for every build types (debug and release)
android.buildTypes.all { variant ->
// Dynamically creating publications name
"${variant.name}Aar"(MavenPublication) {
def manifest = new XmlSlurper().parse(project.android.sourceSets.main.manifest.srcFile);
def libVersion = manifest['@android:versionName'].text()
def artifactName = project.getName()
// Artifact properties
groupId GROUP_ID
version = libVersion
artifactId variant.name == 'debug' ? artifactName + '-dev' : artifactName
// Tell maven to prepare the generated "*.aar" file for publishing
artifact("$buildDir/outputs/aar/${project.getName()}-${variant.name}.aar")
pom.withXml {
//Creating additional node for dependencies
def dependenciesNode = asNode().appendNode('dependencies')
//Defining configuration names from which dependencies will be taken (debugCompile or releaseCompile and compile)
def configurationNames = ["${variant.name}Compile", 'compile']
configurationNames.each { configurationName ->
configurations[configurationName].allDependencies.each {
if (it.group != null && it.name != null) {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', it.group)
dependencyNode.appendNode('artifactId', it.name)
dependencyNode.appendNode('version', it.version)
//If there are any exclusions in dependency
if (it.excludeRules.size() > 0) {
def exclusionsNode = dependencyNode.appendNode('exclusions')
it.excludeRules.each { rule ->
def exclusionNode = exclusionsNode.appendNode('exclusion')
exclusionNode.appendNode('groupId', rule.group)
exclusionNode.appendNode('artifactId', rule.module)
}
}
}
}
}
}
}
}
}
}
uploadArchives
task it appears to be missing the scope
attribute. Is there a way to easily include that to your code above?
def configurationNames = ["${variant.name}Compile", 'compile']
debugCompile and releaseCompile shoulb be skipped, but configuration name compile is that you need in scope attribute. To make pom with dependensies of all scopes you need to add all of them (runtime, etc.) in that array. And in loop just check if it's not debugCompile or releaseCompile append node scope. exclusionNode.appendNode('scope', configurationName)
With gradle 3 implemention
was introduced. Replace compile
with implementation
. Use this instead.
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
configurations.implementation.allDependencies.each {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', it.group)
dependencyNode.appendNode('artifactId', it.name)
dependencyNode.appendNode('version', it.version)
}
}
Kotlin DSL version of the accepted answer:
create<MavenPublication>("maven") {
groupId = "com.example"
artifactId = "sdk"
version = Versions.sdkVersionName
artifact("$buildDir/outputs/aar/Example-release.aar")
pom.withXml {
val dependenciesNode = asNode().appendNode("dependencies")
val configurationNames = arrayOf("implementation", "api")
configurationNames.forEach { configurationName ->
configurations[configurationName].allDependencies.forEach {
if (it.group != null) {
val dependencyNode = dependenciesNode.appendNode("dependency")
dependencyNode.appendNode("groupId", it.group)
dependencyNode.appendNode("artifactId", it.name)
dependencyNode.appendNode("version", it.version)
}
}
}
}
}
I guess it has something to do with the from components.java
directive, as seen in the guide. I had a similar setup and it made the difference to add the line into the publication block:
publications {
mavenJar(MavenPublication) {
artifactId 'rest-security'
artifact jar
from components.java
}
}
.jar
output but not for aar
afaik. Apparently its broken for aar at present (gradle plugin 1.2.2)
aar
and a need to remove md5/sha files because of overwritten pom
build.gradle
file, you'll see this error message when trying to parse the file: "Could not find property 'java' on SoftwareComponentInternal set."
2.1.0
also doesn't work for aar
s. Is there a work around?
I was using the maven-publish
plugin for publishing my aar
dependency and actually I could not use the maven
task in my case. So I used the mavenJava
task provided by the maven-publish
plugin and used that as follows.
apply plugin 'maven-publish'
publications {
mavenAar(MavenPublication) {
from components.android
}
mavenJava(MavenPublication) {
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
// Iterate over the api dependencies (we don't want the test ones), adding a <dependency> node for each
configurations.api.allDependencies.each {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', it.group)
dependencyNode.appendNode('artifactId', it.name)
dependencyNode.appendNode('version', it.version)
}
}
}
}
I hope that it helps someone who is looking for help on how to publish the aar
along with pom
file using the maven-publish
plugin.
now that compile is deprecated we have to use implementation.
pom.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
configurations.implementation.allDependencies.each {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', it.group)
dependencyNode.appendNode('artifactId', it.name)
dependencyNode.appendNode('version', it.version)
}
Success story sharing
*(MavenPublication)
block and all my dependencies are now in my aar's pom. Many thxit.group
,it.name
not being null or unspecified so that it skips the default dependency on lib directory in android studio. Without it gradle generates an invalid POM file and crashes.