Search code examples
mavengradlenexusbuild-dependencies

Gradle: Publish a pre-built jar to a Maven repository with dependencies


There are already questions on Stackoverflow about publishing pre built jars to Maven from Gradle. However, this is slightly different: how do I publish a pre-built Jar to a Maven repo and at the same time provide the dependencies to include in the pom.xml file?

I have a jar that is being pre-built external to this script. I need to publish this jar to our Maven repo (Nexus) and specify dependencies in the pom.xml. I have been able to get a pre built jar published to a Maven repo using the artifacts closure but it ignores the dependencies closure. If I add the java plugin then Maven plugin creates a pom with the dependencies but will upload a zero byte jar file. I guess this is because the Java plugin expects to compile and package source in the src dir, which does not exist in this project.

Is there a way I can 'inject' a pre-built Jar into the Java plugin process so that I can the jar uploaded along with the dependencies? Or am I missing something else that's obvious?

Of course the best thing would be for the pre-built Jar's build process to outline its dependencies and upload to Maven but unfortunately it's a 3rd party piece of software and we have no control.

Below script publishes a zero kb jar file...

apply plugin: 'java'
apply plugin: 'maven'
jar = file(projectHome + '/build/lib').listFiles()[0]
configurations {
    archives
    runtime
}
dependencies {
    runtime 'org.apache.tika:tika-app:1.3'
}
artifacts {
    archives jar
}
uploadArchives {
    repositories {
        mavenDeployer {
            repository(url: "http://build.com/nexus/content/repositories/releases/")
            pom.version = tag
            pom.artifactId = "artifact"
            pom.groupId = "group"
        }
    }
} 

Many thanks! Rob


Solution

  • We can publish a pre-built jar into a Maven repo using Gradle by using java plugin and maven-publish plugin. maven-publish has a feature to inject dependencies into generated pom using pom.withXml block.

    Hereby I'm giving a sample build.gradle file which generates a pom.xml of the pre-built artifact with its specified dependencies. You can try this suggestion as shown below.

    apply plugin: "maven-publish"
    apply plugin: "java"
    
    
    
    dependencies {
        compile "dependency:antlr:2.7.7"
        compile "dependency:commons-beanutils:1.9.3"
        compile "dependency:dom4j:1.6.1"
        compile "dependency:jettison:1.3.8"
    }
    
    publishing {
    
        repositories {
            maven {
                url "$mavenUrl"
                credentials {
                    username = "$mavenUser"
                    password = "$mavenPwd"
    
            }
            }
        }
        publications {
            maven(MavenPublication) {
                groupId "test"
                artifactId "myArtifact"
                version "1.0"
                artifact ("/scratch/test/jars/myArtifact.jar")
                pom.withXml {
                    def dependencies  = asNode().appendNode("dependencies")
                    configurations.compile.allDependencies.each {  dep ->
                        def depNode  = dependencies.appendNode("dependency")
                        depNode.appendNode("groupId", dep.group)
                        depNode.appendNode("artifactId", dep.name)
                        depNode.appendNode("version", dep.version)
                    }       
                }
            }
        }
    }
    

    The generated pom will look like as shown below.

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <modelVersion>4.0.0</modelVersion>
      <groupId>test</groupId>
      <artifactId>myArtifact</artifactId>
      <version>1.0</version>
      <dependencies>
        <dependency>
          <groupId>dependency</groupId>
          <artifactId>antlr</artifactId>
          <version>2.7.7</version>
        </dependency>
        <dependency>
          <groupId>dependency</groupId>
          <artifactId>commons-beanutils</artifactId>
          <version>1.9.3</version>
        </dependency>
        <dependency>
          <groupId>dependency</groupId>
          <artifactId>dom4j</artifactId>
          <version>1.6.1</version>
        </dependency>
        <dependency>
          <groupId>dependency</groupId>
          <artifactId>jettison</artifactId>
          <version>1.3.8</version>
        </dependency>
      </dependencies>
    </project>
    

    I guess this might answer your question