freefair / gradle-plugins

Gradle Plugin Collection
https://docs.freefair.io/gradle-plugins/current/reference/
MIT License
215 stars 32 forks source link

io.freefair.aggregate-javadoc JDK 17 too many modules #409

Open tlf30 opened 2 years ago

tlf30 commented 2 years ago

Hello, I'm migrating a project to java modules, and am getting a too many modules error when aggregating javadocs with JDK 17.

> Task :aggregateJavadoc
C:\<project/submodule1>\src\main\java\module-info.java:1: error: too many module declarations found
module <censored> {
^
C:\<project/submodule2>\src\main\java\module-info.java:1: error: too many module declarations found
module <censored> {
^
C:\<project/submodule3>\src\main\java\module-info.java:1: error: too many module declarations found
module <censored> {
^
C:\<project/submodule4>\src\main\java\module-info.java:1: error: too many module declarations found
module <censored> {
^
4 errors
tlf30 commented 2 years ago

For anyone getting this, I hacked together my own solution without this plugin. Perhaps this can be used to fix this plugin by someone who knows how to do so.

task assembleJavadocArgs() {
    group = "Build"
    File mspFile = new File(rootProject.buildDir, "/tmp/modulesourcepath.args")
    outputs.file(mspFile)

    doLast {
        mspFile.delete()

        //Add module source path
        mspFile << "--module-source-path\n"
        mspFile << rootProject.projectDir.path + '/modules/*/src/main/java'
        mspFile << "\n"

        //Add reads all-unnamed
        javaProjects.collect {
            mspFile << "--add-reads " + project(it).name + "=ALL-UNNAMED\n"
        }
    }
}

task aggregateJavadoc(type: Javadoc, dependsOn: assembleJavadocArgs) {
    group = "Basic"
    def projectsToDocument = javaProjects.collect { project(it) }
    dependsOn(projectsToDocument.collect { project -> project.getTasksByName("classes", true) })
    source(projectsToDocument.collect({
        [it.sourceSets.main.java]
    }))
    setDestinationDir(new File(buildDir, 'docs/aggregateJavadoc'))

    classpath = files(projectsToDocument.collect({
        it.configurations.runtimeClasspath.files //configurations.runtimeClasspath.files
    }))

    options.locale("en")
    options.addBooleanOption("XDignore.symbol.file").setValue(true)
    options.addBooleanOption("html5").setValue(true)
    options.addBooleanOption("javafx").setValue(true)
    options.addBooleanOption("use").setValue(true)
    //options.verbose()

    // Suppress generating overridden methods with no additional documentation
    // The leading '-' is necessary, since this option starts with '--' and gradle adds '-' when passing an option to javadoc
    options.addBooleanOption("-override-methods=summary").setValue(true)

    options.setOptionFiles([
            new File(rootProject.buildDir, "/tmp/modulesourcepath.args")
    ])
}

To configure this, you will need an array of projects called javaProjects to tell it which projects to use. i.e.:

ext {
    javaProjects = [":modules:project0, ":modules:project1", ":modules:project2",
                    ":modules:project3", ":modules:project4"]
}

Your projects need to be in a common folder, here I used ./modules/<project0...4> The project folder name MUST match the name of the module, this is a requirement by the javadoc command in the jdk, I have not yet found a way around this yet.

It will put the javadocs in the folder build/docs/aggregateJavadoc

This was inspired by how jfx generates their javadocs: https://github.com/openjdk/jfx/blob/master/build.gradle