Jar task fails quietly absent a destinationDir

I ran into this problem when upgrading from 1.6 to 1.8

I have a jar task to create a source jar for a project. This source jar task did not have destinationDir set, as it was not needed as part of the local project build. However, I had supplied it to a source configuration that was used by a downstream project. Previously, this worked fine: The jar was built, and the downstream configuration picks up the jar to use. Now however, it appears that the source jar is not built, and the downstream configuration misses the jar.

Project base-code

getConfigurations().create("source");
Jar sourceJarTask = project.tasks.create("sourceJar", Jar.class);
sourceJar.baseName
'sources'
sourceJar.from 'src'
// This line was not needed previously
sourceJar.destinationDir project.buildDir
artifacts { source sourceJar }

Aggregator Code:

configurations {
sources
}
dependencies {
sources project(path: ":base-code", configuration: "source")
}

Now I know you should be able to do this without specifying a destinationDir. I actually have another source jar task elsewhere in my build that works without destinationDir (That task is located in a gradle project, and uses project.sourceSets to set its sources, as opposed to this task which is in a wrapped ant project and uses the relative path ‘src’ to set its sources). Those jars are built into build/lib, which i expect is right. However, with just the minimal code above, it seems to be not working without destinationDir

I feel like I’m missing something very obvious in what I am not setting that destinationDir enforces, perhaps the fact that since this is a wrapped ant task, it does not have a default jar task that was doing some common setup?

This shouldn’t be happening.

Is it possible to create a small sample project that exhibits the problem and share it? 1.9 is close to finalisation so the sooner the better.

The code above will work (I just verified it). Simply add it to a project with a single file source tree

mkdir jarTest
cd jarTest
edit build.gradle # Use favorite editor
mkdir src
touch src/somefile.java

build.gradle

getConfigurations().create("source");
     Jar sourceJar = project.tasks.create("sourceJar", Jar.class);
sourceJar.baseName = 'sources'
sourceJar.from 'src'
//sourceJar.destinationDir project.buildDir
     artifacts { source sourceJar }

This will produce a sources.jar if you uncomment the line (when running gradle sourceJar), if you leave the line commented out it produces no jar in the build folder (it does produce a manifest file though).

Testing the consume case would also be rather trivial if needed, you just need to have a seperate project depend on it and then a task that resolves the configuration and tries to use the file (so a copy task from the dependency or something :slight_smile: )

Edit: I feel silly now, sources.jar is being built by default to project.projectDir instead of project.buildDir, so I just didn’t see the default artifact. Let me try a quick test for the multi-project use case.

I did a test case of a simple multi-project build and it works. Phoohy.

I think this is related to the fact that the Jar task outputs to the top-level projects projectDir directory (not the child’s projectDir or buildDir), and my build is large and complex enough that putting things to the root project could cause some kind of conflict. I’ll keep looking at my build and see if I can find what is causing this

I am able to reliably reproduce the problem now.

If you run the attached script, it will produce a sources.jar at the root level (not in the producer project). if you delete this sources.jar, the jar will not be recreated on a clean assemble and the downstream projects will not get any artifacts. The only way to force the jar to be recreated is to force remove .gradle folder

I do not know if this issue was happening before I updated or I just happened to delete the random sources.jar I found at my root when updating and thus showing the issue.

(Note that the jar task is scheduled to run. I do not know why deleting the output would cause the task to be skipped, I would of thought it would of been the opposite…)

apply plugin: 'base'
project(":producer") {
      //This does not come from base plugin because you cannot apply
     //base plugin easily to an ant project that already has a clean
    task clean(type: Delete) {
        delete 'build'
    }
      getConfigurations().create("source");
          Jar sourceJar = project.tasks.create("sourceJar", Jar.class);
    sourceJar.baseName = 'sources'
    sourceJar.from 'src'
    //sourceJar.destinationDir project.buildDir
          artifacts { source sourceJar }
}
  project(":consumer"){
    apply plugin: 'base'
    configurations {
        sources
    }
    dependencies {
        sources project(path: ":producer", configuration:"source")
    }
      task copySrcJar(type:Copy){
       dependsOn configurations.sources
       from configurations.sources
       into new File(project.buildDir, "copyTarget")
   }
     assemble.dependsOn(copySrcJar)
}