gradlegradle-eclipse

Get JavaDoc jars for dependencies in Gradle


I am working on a Gradle task to create a project for an IDE based on Eclipse. This requires to generate both a .project and a .classpath file. This part is absolutely no problem and I can use the Gradle Eclipse Plugin via apply plugin: 'eclipse', to let my task depend on eclipseProject and eclipseClasspath with altered configurations. But an additional requirement says, that the whole project must be portable (even to environments without Gradle), so it is not possible to just define the external dependencies, because the classpath will reference to the cache. I solved this problem by using a main project defining the dependencies:

// Define configurations
configurations {
    libs
}

// Define repositories
repositories {                                                              
    mavenCentral()
}

// Include dependencies via 'groupID:artifactID:version[:classifier]'
dependencies {
     libs 'junit:junit:4.12'
}

These dependencies will be downloaded to the cache, and a simple Copy task copies them to my project 'lib' folder:

// Copies the dependencies to project 'lib' folder
task copyLibs(type: Copy) {
     from configurations.libs
     into "$projectDir/$projectName/lib"
}

A subproject now uses those copied libraries as dependencies, simply using:

dependencies {
    compile fileTree(dir: 'lib', include: ['*.jar'])
}

An additional task in the subproject relativizes the paths, so I can move my project and call gradle build anywhere I want. This is how the classpath looks:

<classpath>
     <classpathentry path="bin" kind="output"/>
     <classpathentry kind="src" path="src"/>
     <classpathentry kind="lib" path="lib\hamcrest-core-1.3.jar"/>
     <classpathentry kind="lib" path="lib\junit-4.12.jar"/>
</classpath>

Now I want to include the javadoc-jars of the dependencies. Before using the local copies, I could simply use this Eclipse plugin feature:

eclipse {
    classpath {
         downloadJavadoc = true
         downloadSources = true
    }
}

But now my project uses files as dependencies, so the Eclipse plugin can't just simply request the Javadoc files, too. How can I request the download of the javadoc-jars without adding a second dependency everytime with the :javadoc classifier suffix? Once it gets downloaded, I can search it in the cache myself and also add it to the .classpath in the intended way:

<classpathentry kind="lib" path="lib\junit-4.12.jar">
  <attributes>
    <attribute name="javadoc_location" value="jar:platform:/path/to/javadoc/junit-4.12-javadoc.jar"/>
  </attributes>
</classpathentry>

But at the moment, the javadoc-jars are only downloaded, if a) the dependency with the :javadoc classifier suffix is defined just like the regular dependency or b) the dependencies are not copied, but directly referenced by a project with the Eclipse plugin (with downloadJavadoc = true).


Solution

  • Even if I think, that I need to change the structure of my build file, I found a solution for this specific case, so I want to provide it for others who might stumble upon the same problem.

    I found the ArtifactResolutionQuery, which can resolve additional required JARs (Javadoc and sources), so I wrote a task to copy those JARs, too.

    // Copies the javadoc files to project 'lib/javadoc' folder
    task copyJavadocs(type: Copy) {
        from {
            dependencies.createArtifactResolutionQuery()
                .forComponents(
                     configurations.compile.incoming.resolutionResult
                         .allDependencies.collect { it.selected.id }
                )
                .withArtifacts(JvmLibrary, JavadocArtifact)
                .execute()
                .resolvedComponents
                .collectMany {
                    it.artifactResults
                        .collect { it.file.path }
                }
        }
        into "$projectDir/$sunriseProjectName/lib/javadoc"
    }