'install' task non-deterministic for multiple 'jar' and 'proguard' artifacts

In my sample project, I generate 2 jars using the ‘jar’ task and then obfuscate those 2 jars using the ‘proguard’ plugin to generate 2 additional jars. The unobfuscated jars have the ‘debug’ classifier; the obfuscated (proguard) jars have no classifier.

My problem is that executing

./gradlew clean install --info

sometimes correctly installs the expected number of artifacts (4), but it very often installs 1 or 2 extra artifacts too (5 or 6 total).

When there are extra artifacts, sometimes the same artifact is installed twice:

[INFO] Installing /Users/echen/data/vungle/code/gradle-example/build/proguard/gradle-example-upper-1.0.0-SNAPSHOT.jar to /Users/echen/.m2/repository/example/gradle-example-upper/1.0.0-SNAPSHOT/gradle-example-upper-1.0.0-SNAPSHOT.jar
[INFO] Installing /Users/echen/data/vungle/code/gradle-example/build/proguard/gradle-example-upper-1.0.0-SNAPSHOT.jar to /Users/echen/.m2/repository/example/gradle-example-upper/1.0.0-SNAPSHOT/gradle-example-upper-1.0.0-SNAPSHOT.jar

Other times, one artifact is incorrectly installed as another artifact (the ‘lower’ artifact is being installed as the ‘upper’ artifact):

[INFO] Installing /Users/echen/data/vungle/code/gradle-example/build/proguard/gradle-example-lower-1.0.0-SNAPSHOT.jar to /Users/echen/.m2/repository/example/gradle-example-upper/1.0.0-SNAPSHOT/gradle-example-upper-1.0.0-SNAPSHOT.jar

Of note, I have 2 ‘jar’ subtasks (‘jarLower’ and ‘jarUpper’) and 2 ‘proguard’ subtasks (‘proguardLower’ and ‘proguardUpper’. I then overwrite the default ‘jar’ task to ‘dependsOn’ the 2 ‘jar’ subtasks, and similarly for a parent ‘proguard’ task.

I notice that the artifacts that are duplicated or incorrectly overwritten are always the Proguard artifacts (no ‘-debug’ classifier), but that if you remove the ‘jar’ artifacts from the ‘artifacts’ section, then the problem no longer manifests.

I have shared my sample project which illustrates my problem: https://github.com/cheneric/proguard-example/

My build script is here: https://github.com/cheneric/proguard-example/blob/master/build.gradle

Can anyone tell me if the problem is in my gradle.build or if this is an issue with Gradle?

My environment is: * Gradle 1.12 (with wrapper) * Java 1.6.0_65 * Mac OS X 10.9.4

build.gradle

import org.apache.ivy.core.module.descriptor.Artifact
import proguard.gradle.ProGuardTask
  buildscript {
 repositories {
  jcenter()
 }
 dependencies {
  classpath 'net.sf.proguard:proguard-gradle:4.11'
 }
}
  apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'distribution'
  archivesBaseName = 'gradle-example'
sourceCompatibility = JavaVersion.VERSION_1_6
targetCompatibility = JavaVersion.VERSION_1_6
final File javaRuntimeJarFile = file('/System/Library/Frameworks/JavaVM.framework/Classes/classes.jar')
  group 'example'
version = '1.0.0-SNAPSHOT'
  sourceSets {
 lower {
  java {
   srcDir 'src/lower/java'
  }
 }
 upper {
  java {
   srcDir 'src/upper/java'
  }
 }
 configure([lower, upper]) {
  java {
   final Set<File> mainSrcDirs = main.java.srcDirs
   srcDirs mainSrcDirs.toArray(new File[mainSrcDirs.size()])
  }
 }
}
  compileLowerJava {
}
  compileUpperJava {
}
  task compileJava(overwrite: true) {
 dependsOn compileLowerJava,
  compileUpperJava
}
  final String lowerAppendix = 'lower'
final String upperAppendix = 'upper'
task jarLower(type: Jar) {
 appendix lowerAppendix
 ext.jarSourceSet = sourceSets.lower
}
  task jarUpper(type: Jar) {
 appendix upperAppendix
 ext.jarSourceSet = sourceSets.upper
}
  final String debugClassifier = 'debug'
configure(tasks.withType(Jar) - jar) {
 classifier = debugClassifier
 from jarSourceSet.output
}
  task jar(overwrite: true) {
 final TaskCollection<Jar> jarSubtasks = tasks.withType(Jar)
 dependsOn jarSubtasks
 jarSubtasks.each { final Jar jarSubtask ->
  outputs.files jarSubtask.outputs.files.collect({ it })
 }
}
  task proguardLower(type: ProGuardTask) {
 ext.jarTask = jarLower
}
  task proguardUpper(type: ProGuardTask) {
 ext.jarTask = jarUpper
}
  configure(tasks.withType(ProGuardTask)) {
 dependsOn jarTask
 final File outputDirectory = new File(buildDir, 'proguard')
 injars jarTask.archivePath
 keep 'public class ** { public *; }'
 libraryjars files(configurations.compile,
  javaRuntimeJarFile)
 outjars new File(outputDirectory, "${jarTask.archiveName.replace('-debug.jar', '.jar')}")
 doFirst {
  outputDirectory.mkdirs()
 }
}
  task proguard {
 final TaskCollection<ProGuardTask> proguardSubtasks = tasks.withType(ProGuardTask)
 dependsOn proguardSubtasks
 proguardSubtasks.each { final ProGuardTask proguardSubtask ->
  outputs.files proguardSubtask.outputs.files.collect({ it })
 }
}
  artifacts {
 // remove (original) jar artifact added by Java plugin
 configurations.archives.artifacts.clear()
 [jar, proguard].each { final Task task ->
  task.outputs.files.each { final File outputFile ->
   archives(outputFile) {
    builtBy task
   }
  }
 }
}
  uploadArchives {
 dependsOn install
}
  configure([install.repositories.mavenInstaller/*, uploadArchives.repositories.mavenDeployer*/]) {
 [lowerAppendix, upperAppendix].each { final String appendix ->
  [null, debugClassifier].each { final String classifier ->
   addFilter("""${appendix}${classifier == null ? '' : "-${classifier}"}""" ) { final Artifact artifact, final File file ->
    artifact.name.contains(appendix) && artifact.getExtraAttribute('classifier') == classifier
   }
  }
 }
}

This is more of a guess, but the only time I’ve seen randomness in the build output was when I did not have a ‘classifier’ specified in ‘archives(outputFile)’ configuration, as you have above.

Thanks for the suggestion, Casey.

I tried it out:

artifacts {
 // remove (original) jar artifact added by Java plugin
 configurations.archives.artifacts.clear()
 [jar, proguard].each { final Task task ->
  task.outputs.files.each { final File outputFile ->
   archives(outputFile) {
    builtBy task
    // NEW
    // (1) either:
    classifier (task.name == 'jar' ? 'debug' : null)
    // (2) or:
    if (task.name == 'jar') {
     classifier 'debug'
    }
   }
  }
 }
}

but to no avail: same random results.

@moderators

We’d be interested in paid/priority support for this issue. I’ve tried to contact Gradleware via email on their website and by phone, but have not heard back. Could someone get in touch with me regarding this issue please?

For the benefit of anyone else who may encounter a similar issue, after working with Gary Hale @ Gradleware, it seems like this is a bug in the old Gradle Maven plugin.

Gary suggested using the new Gradle Maven Publishing plugin, and that resolved the problem for me.

I’ll update the Github example with the solution when I have time.

Thanks, Gary!

Solution code updated (moved from original URL)! https://github.com/cheneric/gradle-maven-problem