Create jars in doLast of a task


(Matthew Rusinak) #1

I’m trying to create multiple jar’s in a task, but as of yet I can’t seem to get it to work.

The premise is that I have a bunch of individual JARs used as a thirdparty libraries, but a single source zip for all of the code (ie, the project produced a bunch of modules, but the source was one big dump). I’m trying to write a gradle script that will produce individual source jar’s for each jar I have.

def libraryJars = [ "moduleA.jar", "moduleB.jar", "moduleC.jar" ]
task extractSrc {
  ext.SrcDir = file("build/srcs")
  // Copies all of the *.java files out of the source zip into a folder, all collapsed and merged into package heirarchy. ie,
  // build/srcs
  //
        '-- org
  //
               '-- company
  //
                       +-- package
  //
                        ...
}
task createSrcPackages (dependsOn: extractSrc) {
 ext.jarDirectory = "build/thirdparty" // contains a bunch of stuff, and at some area underneath, the jars we care about
    doLast {
  libraryJars.each { jarName ->
   def jarFile = fileTree(jarDirectory).include('*/' + <some-extra-path-stuff> + jarName).singleFile
   def jarSources = []
     // Inspect the contents of the jar, finding all the .class files that we have source for.
   // Cut it down to package-path level, then add it to the list
    zipTree(jarFile).each { clazz ->
    def ourClazz = clazz.absolutePath.replaceFirst(".*[\\/]com[\\/]mcafee", "com/mcafee")
          if ( !ourClazz.equals(clazz.absolutePath) ) {
     jarSources.add( extractSrc.SrcDir.absolutePath + "/" + ourClazz.replaceFirst("\.class", ".java") )
    }
   }
      //jarSources now contains a list of strings to files in the sources directory
   jar {
    baseName jarFile.name.replaceFirst("\.jar", "-sources")
    from files(jarSources)
    destinationDir buildDir
   }
  }
 }
}

Executing the task, it takes time and completes successfully, but no jars are produced at all.


(Peter Niederwieser) #2

A task cannot call other tasks, and there is no ‘jar’ method.

I’d try to approach this differently, namely be adding a (source) ‘Jar’ task for each library Jar that includes the relevant files.


(Matthew Rusinak) #3

Thanks for the help.

Just to have this out there for anyone else like me: I rewrote it to dynamically create a Jar-type task for each jar, and add them as dependencies to the main target:

task run {
 // Does some final stuff
}
libraryJars.each { jarName ->
 run.dependsOn tasks.add(name: "createSrcFor_${jarName}", type: Jar, dependsOn: extractSrc) {
  doFirst {
   def jarPath = basePath + jarName
   def jarFile = fileTree(packageDir).include(jarPath).singleFile
     zipTree(jarFile).each { clazz ->
    def ourClazz = clazz.absolutePath.replaceFirst(".*[\/]org[\/]company", "org/company")
          if ( !ourClazz.equals(clazz.absolutePath) ) {
     include ourClazz.replaceFirst("\.class", ".java")
    }
   }
  }
    baseName jarName.replaceFirst("\.jar", "-sources")
  includeEmptyDirs false
      from extractSrc.SrcDir.absolutePath
  destinationDir buildDir
 }
}

Personally I wish there were jar and zip methods, but this came out looking a lot cleaner than I was expecting it to.