Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Aggregate Javadoc for Android project with multiple library modules

I've gone through almost entire Internet in search of a way how to aggregate Javadocs in the project consisting of separate library modules into single Javadoc.

There is a plugin that apparently allows to do that: https://github.com/nebula-plugins/gradle-aggregate-javadocs-plugin

However, if I run the command specified by the plugin Gradle finds the task and executes it but no output directory is generated.

Any help how to build single Javadoc from multiple modules much appreciated.

like image 691
dawid gdanski Avatar asked Jul 16 '15 12:07

dawid gdanski


1 Answers

I managed to get it working some time ago, apologies for a late response. The solution for aggregatable Javadoc creation is the following:

  1. In each of the subprojects maintained within the project create a task generating the Javadoc:

    android.libraryVariants.all { variant ->
    
    task("generate${variant.name.capitalize()}Javadoc", type: Javadoc) {
        destinationDir = project.file("$project.projectDir/javadoc/$project.PROJECT_NAME") //Project name in the Project's gradle.properties
        title = "A title of my project - $project.PROJECT_VERSION_NAME" //Project version name in the Project's gradle.properties
        description "Generates Javadoc for $variant.name."
        source = variant.javaCompile.source
        ext.androidJar ="${android.sdkDirectory}/platforms/${android.compileSdkVersion}/android.jar"
        classpath = files(variant.javaCompile.classpath.files) + files(ext.androidJar) + project.files(android.getBootClasspath().join(File.pathSeparator))
        options {
            memberLevel = org.gradle.external.javadoc.JavadocMemberLevel.PUBLIC //change the modifier according to your needs
            links "http://docs.oracle.com/javase/8/docs/api/"
            linksOffline "http://d.android.com/reference", "${android.sdkDirectory}/docs/reference"
        }
        exclude '**/BuildConfig.java'
        exclude '**/R.java'
    }
    
      task("bundle${variant.name.capitalize()}Javadoc", type: Jar) {
        baseName = "Compass API - ($version)"
        description "Bundles Javadoc into zip for $variant.name."
        classifier = "javadoc"
        from tasks["generate${variant.name.capitalize()}Javadoc"]
      }
    }
    

The configuration above adds a Javadoc generation task for each buildVariant of your subproject. At this point you can you can generate Javadoc for each module separately by typing

gradle :myRootProject:mySubproject:generateDebugJavadoc
gradle :myRootProject:mySubproject:generateReleaseJavadoc
gradle :myRootProject:mySubproject:generateMyFancyFlavourDebugJavadoc
gradle :myRootProject:mySubproject:generateMyFancyFlavourReleaseJavadoc

If you use JRE 8 the following configuration disables errors raised by doclint during the Javadoc build (explanation in greater detail here)

   if (JavaVersion.current().isJava8Compatible()) {
     tasks.withType(Javadoc) {
         // disable the crazy super-strict doclint tool in Java 8
         //noinspection SpellCheckingInspection
         options.addStringOption('Xdoclint:none', '-quiet')
     }
    }
  1. To aggregate Javadocs of each submodules into a single one create a Plugin in to build.gradle which will add a task to the submodule a partial Javadoc generation of which you are interested in:

     class JavadocAggregationPlugin implements Plugin<Project> {
     static final String AGGREGATE_JAVADOCS_TASK_NAME = 'aggregateJavadocs'
    
     @Override
     void apply(Project project) {
         Project rootProject = project.rootProject
         rootProject.gradle.projectsEvaluated {
            Set<Project> librarySubprojects = getLibraryProjects(rootProject)
             if (!librarySubprojects.isEmpty()) {
                rootProject.task(AGGREGATE_JAVADOCS_TASK_NAME, type: Javadoc) {
                     description = 'Aggregates Javadoc API documentation of all subprojects.'
                     group = JavaBasePlugin.DOCUMENTATION_GROUP
                     dependsOn librarySubprojects.generateReleaseJavadoc //please note that generateReleaseJavadoc is the name of the separate Javadoc generation task in each library module
    
                     source librarySubprojects.generateReleaseJavadoc.source
                     destinationDir rootProject.file("$rootProject.buildDir/docs/javadoc") //Javadoc destination directory
                     classpath = rootProject.files(librarySubprojects.generateReleaseJavadoc.classpath)
                 }
             }
         }
     }
    
    private Set<Project> getLibraryProjects(Project rootProject) {
        rootProject.subprojects.findAll { subproject -> subproject.plugins.findPlugin("com.android.library") } //In this case every library module is selected
    }
    }
    

Finally, include your plugin to the gradle configuration in the Project's build.gradle below your plugin definition.

apply plugin: JavadocAggregationPlugin
  1. By doing this and rebuilding gradle's configuration you should be able to create aggregated Javadoc in specified directory by typing the following command via cli:

    gradle aggregateJavadocs
    

Hope that helps somehow.

Helpful link: Android Gradle DSL

like image 124
dawid gdanski Avatar answered Sep 18 '22 12:09

dawid gdanski