On 6/02/10 10:42 AM, merscwog wrote:
I have an alljavadoc task that attempts to aggregate information from the
sources from all subprojects into a full project javadoc task.

task alljavadoc(type: Javadoc) {}

def depTasks = []
subprojects.each
{
   Project subproject ->

   depTasks.add(subproject.classes)
}

alljavadoc.dependsOn depTasks

alljavadoc.doFirst()
{
   Task task ->

   task.project.subprojects.each
   {
     Project subproject ->
     task.source = task.source + subproject.javadoc.source

     // NOTE: All java plugin projects have "compile"
     if (subproject.configurations.findByName('compile') != null)
     {
       subDeps = subproject.configurations.compile.getDependencies()
       task.project.configurations.compile.getDependencies().addAll(subDeps)
     }

I think the above is what's causing the dependencies to go missing.

Configurations cache the resolved files when they are first requested, and return the cached result from then on. In Gradle 0.8 (and earlier 0.9 snapshots), for your build, the 'compile' configuration will be resolved when the main javadoc action executes, which is after the doFirst() action above. Which means that the modifications that the action makes to the 'compile' configuration will be picked up.

In later 0.9 snapshots, the configuration will be resolved just before the actions of the Javadoc task are executed, when Gradle does the up-to-date check. This happens before the doFirst() action. Which means that the modifications to the 'compile' configuration will not be picked up. And hence the javadoc generation fails.

The configuration implementation is supposed to throw an exception when you modify it after it has been resolved. We missed the case where you add dependencies directly to the result of Configuration.getDependencies(). I think I'll change this so the collections returned by Configuration are unmodifiable.

To fix the problem, you could move the doFirst() action to a stand-alone task:

task javadocClasspath << {
   subprojects { ... do stuff to configurations.compile ... }
}

task alljavadoc(type: Javadoc, dependsOn: javadocClasspath) {
    ....
}

Or you could build the dependencies on demand in the javadoc task (this has the advantage that the task dependencies are automatically wired up for you):

task alljavadoc(type: Javadoc) {
    classpath = files {
        subprojects.inject([]) { classpath, subproject ->
            if ( subproject.configurations.findByName('compile') ) {
                classpath << subproject.configurations.compile
            }
// don't need to worry about providedCompile - it will be included in compile.
            classpath
        }
    }
}


     // NOTE: All java war plugin projects have "providedCompile"
     if (subproject.configurations.findByName('providedCompile') != null)
     {
       subDeps = subproject.configurations.providedCompile.getDependencies()
       task.project.configurations.compile.getDependencies().addAll(subDeps)
     }
   }
}

This definitely works fine in 0.8, and it also worked in older 0.9 snapshots
(don't know exactly when it started failing.

The stack trace is:
         at
org.gradle.api.internal.file.CompositeFileTree.getSourceCollections(CompositeFileTree.java:30)
         at
org.gradle.api.internal.file.CompositeFileTree$FilteredFileTree.addSourceCollections(CompositeFileTree.java:90)
         at
org.gradle.api.internal.file.CompositeFileCollection.getSourceCollections(CompositeFileCollection.java:149)
         at
org.gradle.api.internal.file.CompositeFileTree.getSourceCollections(CompositeFileTree.java:30)
         at
org.gradle.api.internal.file.CompositeFileTree$FilteredFileTree.addSourceCollections(CompositeFileTree.java:90)
         at
org.gradle.api.internal.file.CompositeFileCollection.getSourceCollections(CompositeFileCollection.java:149)
(until StackOverflow occurs)

Obviously there is an infinite recursion happening.

There is probably a much better way to do what I've done in 0.9, but that's
what worked for me in 0.8.

I'll gladly accept suggestions on how to do the equivalent of what I've
defined in 0.9 without the failure, but since it worked in 0.8 and earlier
0.9 snapshots, I'm kind of curious as to what fundamentally changed to allow
this cycle to occur.

-Spencer

--
Adam Murdoch
Gradle Developer
http://www.gradle.org


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

   http://xircles.codehaus.org/manage_email


Reply via email to