Fetch runtime dependency during deployment in gradle mentioned in POM file

I am working on one script wherer I have two task

Add runtime dependency in POM file during gradle build and then create the artifact and upload it to the artifactory.Now my artifact is having POM file and the zip file.Zip file consist of lib folder and jar file.lib folder is having lots of other jar files which I put during my build.But there are two dependency which I don’t want to include in lib folder but wants to add it in the POM file which I am able to do it sucessfully.

Now my task is while I will deploy this artifact which is basically a zip file then my logic will read the POM file and it will fetch the runtime dependency during deployment.from the artifactory and will unzip it.I am not sure how to get the runtime dependency during deployment.

apply plugin: 'java’
apply plugin: 'jacoco’
apply plugin: 'findbugs’
apply plugin: 'pmd’
apply plugin: 'checkstyle’
apply plugin: ‘maven’

//-- set the group for publishing
group = ‘c.tr.ana’

/**

  • Initializing GAVC settings
    */
    def buildProperties = new Properties()
    file(“version.properties”).withInputStream {
    stream -> buildProperties.load(stream)
    }
    //add the jenkins build version to the version
    def env = System.getenv()
    if (env[“BUILD_NUMBER”]) buildProperties.analyticsengineBuildVersion += ".${env[“BUILD_NUMBER”]}"
    version = buildProperties.analyticsengineBuildVersion
    println “${version}”

//name is set in the settings.gradle file
group = "c.tr.ana"
version = buildProperties.analyticsengineBuildVersion
println “Building ${project.group}:${project.name}:${project.version}”

sourceCompatibility = 1.7
compileJava.options.encoding = ‘UTF-8’

repositories {

 maven { url "http://cm.t.t.co:8/aactory/filease-local" }

}
dependencies {
compile group: ‘c.tr.ana’, name: ‘common’, version:'4.0.0.100’
compile group: ‘c.tr.ana’, name: ‘LicenseVerifier’, version:'4.0.0.90’
compile group: ‘c.tr.ana’, name: ‘AnalyticsLib’, version: '4.0.0.137’
compile group: ‘c.tr.ana’, name: ‘Integration’, version: '4.0.0.97’
compile group: ‘c.operasolutions’, name: ‘RiskAnalytics’, version:'1.1’
compile group: ‘commons-configuration’, name: ‘commons-configuration’, version:'1.10’
compile group: ‘com.jamonapi’, name: ‘jamon’, version:'2.4’
compile group: ‘ch.qos.logback’, name: ‘logback-classic’, version:'1.1.1’
compile group: ‘ch.qos.logback’, name: ‘logback-core’, version:'1.1.1’
compile group: ‘org.slf4j’, name: ‘slf4j-api’, version:'1.7.6’
compile group: ‘net.sf.supercsv’, name: ‘super-csv-dozer’, version:'2.1.0’
compile group: ‘net.sf.supercsv’, name: ‘super-csv’, version:'2.1.0’
compile group: ‘org.codehaus.mojo’, name: ‘properties-maven-plugin’, version:'1.0-alpha-2’
compile group: ‘args4j’, name: ‘args4j’, version:'2.0.28’
compile group: ‘org.codehaus.jackson’, name: ‘jackson-mapper-asl’, version:'1.9.5’
testCompile group: ‘junit’, name: ‘junit’, version:'4.11’
testCompile group: ‘org.mockito’, name: ‘mockito-all’, version:‘1.9.5’

}
dependencies {
runtime group: ‘c.tr.ana’, name: ‘ae-libs’, version: ‘0.0.5’, classifier: ‘linux’, ext: 'zip’
runtime group: ‘c.tr.ana’, name: ‘reference-files’, version: ‘0.0.3’, classifier: ‘linux’, ext: ‘zip’
}

jacoco {
toolVersion = “0.7.1.201405082137”
}
test {
jacoco {
append = false
destinationFile = file("$buildDir/jacoco/jacocoTest.exec")
classDumpFile = file("$buildDir/jacoco/classpathdumps")
}
}

jacocoTestReport {
group = "Reporting"
description = "Generate Jacoco coverage reports after running tests."
executionData = fileTree(dir: ‘build/jacoco’, include: ‘**/*.exec’)

reports {
    xml{
        enabled true
        //Following value is a file
        destination "${buildDir}/reports/jacoco/xml/jacoco.xml"
    }
    csv.enabled false
 html{
   enabled true
   //Following value is a folder
   destination "${buildDir}/reports/jacoco/html"
 }
}

}

findbugs {
ignoreFailures = true
//sourceSets = [sourceSets.main]
}

pmd {
ruleSets = [“java-basic”, “java-braces”, “java-design”]
ignoreFailures = true
//sourceSets = [sourceSets.main]
}

checkstyle {
configFile = new File(rootDir, “config/checkstyle.xml”)
ignoreFailures = true
//sourceSets = [sourceSets.main]
}

// adding test report to taskGraph
build.dependsOn jacocoTestReport

def pomFile = file("${buildDir}/libs/${archivesBaseName.toLowerCase()}-${version}.pom")
task newPom << {
pom {
project {
groupId project.group
artifactId project.name
version project.version
description = “Configuration Management Gradle Plugin”
}
}.writeTo(pomFile)
}
// adding pom generation to taskGraph
build.dependsOn newPom

//disabling the install task since we’re not using maven for real
install.enabled = false

//for publishing to artifactory via jenkins
if(project.hasProperty(‘artifactoryPublish’)) {
artifactoryPublish {
mavenDescriptor pomFile
}
}
jar {
// Keep jar clean:
exclude ‘META-INF/.SF’, 'META-INF/.DSA’, ‘META-INF/.RSA’, 'META-INF/.MF’
manifest {
attributes ‘Manifest-Version’: ‘1.0’,
‘Implementation-Title’: ‘CLI’,
‘Implementation-Vendor-Id’: ‘c.tr.ana’,
‘Build-Jdk’: ‘1.7.0_45’,
‘Main-Class’: ‘c.tr.ana.cli.App’,
‘Class-Path’: configurations.compile.files.collect { “lib/$it.name” }.join(’ ')
}
}
task buildreportZip( type: Zip, overwrite:true ) {
//Delete zip if already exist.
delete “build/libs/CLI-${project.version}-CLI.zip”

archiveName "CLI-${project.version}-CLI.zip"
def dirName = "build/libs"
def dirDest = new File ( dirName )
dirDest.mkdirs()

destinationDir dirDest

into ("") {
  from "build/libs"
  include "*${project.name}-${project.version}.jar"
}

into ( "lib" ) {
  from configurations.compile
//  exclude '*.zip'

}

}

// adding test report to taskGraph
//build.dependsOn buildreportZip
project.buildreportZip.dependsOn jar
//task artifact(type: DefaultTask, dependsOn: [‘buildreportZip’]) {}
// ------ Publish the jar file to artifactory ------
artifacts {
archives buildreportZip
}

Here My issue is

  1. Read the POM file of the artifact

  2. The depdency whose scope is runtime fetch it from artifactory.

  3. Put those depdency(zip/jar) to destination directory

    apply plugin: ‘java’

    // ------ Tell the script to get dependencies from artifactory ------
    buildscript {
    repositories {
    maven {
    url “http://cmrt.tsh.thon.com:80/artifactory/libs-snapshot
    }
    }

     // ------ Tell the script to get dependencies from artifactory ------
     dependencies {
     classpath ([ "com.truven.cm:cmgradleplugin:1.2.147" ])
    

    }
    }

    apply plugin: ‘com.truven.cm.cmgradleplugin’

    /**

    • The folloing -D parameters are required to run this task
      • deployLayer = one of acceptance, latest, production, test
        */
        //------------------------------------------------------------------------------------------
        // Read the properties file and take the value as per the enviornment.
        //
        //------------------------------------------------------------------------------------------
        if(!System.properties.deployLayer) throw new Exception (“deployLayer must be set”)
        def thePropFile = file(“config/${System.properties.deployLayer}.properties”)
        if(!thePropFile.exists()) throw new Exception(“Cannot load the specified environment properties from ${thePropFile}”)
        println “Deploying ${System.properties.jobName}.${System.properties.buildNumber} to ${System.properties.deployLayer}”

    // load the deploy properties from the file
    def deployProperties = new Properties()
    thePropFile.withInputStream {
    stream -> deployProperties.load(stream)
    }
    // set them in the build environment
    project.ext {
    deployProps = deployProperties
    deployRoot = deployProperties["${System.properties.jobName}.deployroot"]
    deploydir = deployProperties["${System.properties.jobName}.deploydir"]
    deployFolder = deployProperties["${System.properties.jobName}.foldername"]
    deployPostInstallSteps = deployProperties["${System.properties.jobName}.postInstallSteps"]
    }

    task deleteGraphicsAssets(type: Delete, dependsOn: deploy) {
    def dirName = "${deployRoot}"
    delete dirName

     doLast {
         file(dirName).mkdirs()
     }
    

    }

    task downloaddependecies(dependsOn: deleteGraphicsAssets) << {
    def pomFile = file("${buildDir}/artifacts").listFiles().find { it.name.endsWith(’.pom’) }
    def pomXml = new XmlSlurper().parse(‘build/artifacts/pomFile’)
    def pomDependencies = pomXml.dependencies.dependency
    pomDependencies.each { dependency ->
    def dependencySpec = "${dependency.groupId}:${dependency.artifactId}:${dependency.version}:${dependency.classifier}:${dependency.type}"
    Configuration configuration = project.configurations.detachedConfiguration(dependency).setTransitive(false)
    if(dependency.scope == ‘runtime’) {
    dependencies.add ‘compile’, dependencySpec
    }
    doLast {
    from configurations.resolve
    into ( “${buildDir}/artifacts” )
    }
    }
    }

    task copyartifactZip << {
    copy {
    from "${deployRoot}"
    into “${deploydir}/”
    }
    }

    task copyLicenseZip << {
    copy {
    from "${deployRoot}"
    into “${deploydir}/${deployFolder}”
    }
    }

    task myCustomTask(dependsOn: downloaddependecies) << {
    copy {
    from ‘deploymentfiles’
    into “${deployRoot}”
    }
    }
    task unzipArtifact(dependsOn: myCustomTask) << {
    def theZip = file("${buildDir}/artifacts").listFiles().find { it.name.endsWith(’.zip’) }
    println "Unzipping ${theZip} the artifact to: ${deployRoot}"
    ant.unzip(src: theZip, dest: “${deployRoot}”, overwrite: true)
    }

    task setPerms(type:Exec, dependsOn: unzipArtifact) {
    workingDir "${deployRoot}"
    executable "bash"
    args “-c”, “chmod -fR 755 *”

    }
    def dirName = "${deploydir}/${deployFolder}"
    task zipDeployment(type: GradleBuild, dependsOn: setPerms) { GradleBuild gBuild ->
    def env = System.getenv()
    def jobName=env[‘jobName’]
    if (jobName.equals(“LicenseGenerator”)) {
    delete dirName
    file(dirName).mkdirs()
    gBuild.tasks = [‘copyLicenseZip’]
    } else {
    gBuild.tasks = [‘copyartifactZip’]
    }
    }

    task deployAll(dependsOn: zipDeployment){}

Can you elaborate on your use case a bit? I don’t fully understand why you’d need to manually read and modify a POM file. I am sure you can solve this with just a Configuration. Basic idea would be to assign the dependencies you need for a Configuration. Then you can take the configuration which includes the transitive dependencies declared in its POM file and stick it into a new artifacts. As you are building the artifact you can filter certain files.

The problem is during deployment we deploy two more artifacts and we can’t include those artifacts as a dependency in the CLI(my project name) artifact because they hardly change and if we add in CLI artifact then the size of the artifact will be big and it will consume more space in the artifactory.So we decided just add these two artifacts in the CLI artifact POM as a runtime dependecy and during deployment {will write a piece of code which} will read the CLI POM file and the dependecy whose scope is runtime will fetch it from the artifactory and put it into the destination directory.Afterwards we can easily put those zip files into the target location.

I tried to wrote the below task but no luck

**task downloaddependecies(dependsOn: deleteGraphicsAssets) << {**
**def pomFile = file("${buildDir}/artifacts").listFiles().find { it.name.endsWith('.pom') }**
**def pomXml = new XmlSlurper().parse('build/artifacts/pomFile')**
**def pomDependencies = pomXml.dependencies.dependency**
    **pomDependencies.each { dependency ->**
     **def dependencySpec = "${dependency.groupId}:${dependency.artifactId}:${dependency.version}:${dependency.classifier}:${dependency.type}"**
	 **Configuration configuration = project.configurations.detachedConfiguration(dependency).setTransitive(false)**
     **if(dependency.scope == 'runtime') {**
	 **dependencies.add 'compile', dependencySpec**
	 **}**
	**doLast {**
	 **from configurations.resolve**
     **into ( "${buildDir}/artifacts" )**
           **}**
        **}** 
    **}**

Hi

I modified my code but still facing some issue I saw the below error in the logs

cannot resolve external dependency com.truv.analyticsengine:ae-libs:0.0.5 because no repositories are defined.
Required by:

apply plugin: 'java'

// ------ Tell the script to get dependencies from artifactory ------
buildscript {
	repositories {
	  maven {
	    url "http://cmt.tsh.th.com:80/artifactory/files-release-local"
	    url "http://cmt.tsh.th.com:80/artifactory/libs-snapshot"
		 }
	}
	
	// ------ Tell the script to get dependencies from artifactory ------
	dependencies {
    classpath ([ "com.ten.cm:cmgradle:1.2.147" ])
  }
}

apply plugin: 'com.ten.cm.cmgradle'


/**
 * The folloing -D parameters are required to run this task
 *  - deployLayer = one of acceptance, latest, production, test
 */
//------------------------------------------------------------------------------------------
// Read the properties file and take the value as per the enviornment.
// 
//------------------------------------------------------------------------------------------
if(!System.properties.deployLayer) throw new Exception ("deployLayer must be set")
def thePropFile = file("config/${System.properties.deployLayer}.properties")
if(!thePropFile.exists()) throw new Exception("Cannot load the specified environment properties from ${thePropFile}")
println "Deploying ${System.properties.jobName}.${System.properties.buildNumber} to ${System.properties.deployLayer}"

// load the deploy properties from the file
def deployProperties = new Properties()
thePropFile.withInputStream { 
	stream -> deployProperties.load(stream) 
} 
// set them in the build environment
project.ext {
  deployProps = deployProperties
  deployRoot = deployProperties["${System.properties.jobName}.deployroot"]
  deploydir = deployProperties["${System.properties.jobName}.deploydir"]
  deployFolder = deployProperties["${System.properties.jobName}.foldername"]
  deployPostInstallSteps = deployProperties["${System.properties.jobName}.postInstallSteps"]
}

task deleteGraphicsAssets(type: Delete, dependsOn: deploy) {
    def dirName = "${deployRoot}"
    delete dirName

    doLast {
        file(dirName).mkdirs()
    }
}

task downloaddependecies(dependsOn: deleteGraphicsAssets) << {
  def pomFile = file("${buildDir}/artifacts").listFiles().find { it.name.endsWith 'pom' }
  def pomXml = new XmlSlurper().parse(pomFile.absolutePath)
  def pomDependencies = pomXml.dependencies.dependency
  Configuration configuration = project.configurations.detachedConfiguration()
  configuration.transitive = false
  pomDependencies.each { dependency ->
    if(dependency.scope == 'runtime') {
    def dependencySpec = dependencies.create("${dependency.groupId}:${dependency.artifactId}:${dependency.version}")
      println "Found Runtime Dependency: ${dependencySpec}"
      configuration.dependencies.add(dependencySpec)
                  }
                }
                println "RESOLVED THE FOLLOWING"
                configuration.resolvedConfiguration.firstLevelModuleDependencies.each { println it }
                copy {
                  from configuration
    into ( "${buildDir}/artifacts" )
                }
}


task copyartifactZip << {
    copy {
        from "${deployRoot}"
        into "${deploydir}/"
    }
}

task copyLicenseZip << {
    copy {
        from "${deployRoot}"
        into "${deploydir}/${deployFolder}"
    }
}

task myCustomTask(dependsOn: downloaddependecies) << {
    copy {
        from 'deploymentfiles'
        into "${deployRoot}"
    }
}
task unzipArtifact(dependsOn: myCustomTask) << {
  def theZip = file("${buildDir}/artifacts").listFiles().find { it.name.endsWith('.zip') }
  println "Unzipping ${theZip} the artifact to: ${deployRoot}"
  ant.unzip(src: theZip, dest: "${deployRoot}", overwrite: true)
}

task setPerms(type:Exec, dependsOn: unzipArtifact) {
  workingDir "${deployRoot}"
  executable "bash"
  args "-c", "chmod -fR 755 *"
  
  }
def dirName = "${deploydir}/${deployFolder}"
task zipDeployment(type: GradleBuild, dependsOn: setPerms) { GradleBuild gBuild ->
    def env = System.getenv()
	def jobName=env['jobName']
if (jobName.equals("LicenseGenerator")) {
	delete dirName
	file(dirName).mkdirs()
	gBuild.tasks = ['copyLicenseZip']
    } else {
   gBuild.tasks = ['copyartifactZip']
}
}

task deployAll(dependsOn: zipDeployment){}

As stated by the error message, you don’t seem to declare a repository. The repository needs to be declared outside of the buildscript block.