javagradleshadowjar

How to make the gradle ShadowJar task also create sources and javadoc of its children?


I have a gradle project with 8 child projects and a configured shadowjar task to create an "all" jar. The toplevel project is setup to have dependencies to all its children, this tells shadowjar what to include:

project(':') {
    dependencies {
        compile project(':jfxtras-agenda')
        compile project(':jfxtras-common')
        compile project(':jfxtras-controls')
        compile project(':jfxtras-icalendarfx')
        compile project(':jfxtras-icalendaragenda')
        compile project(':jfxtras-menu')
        compile project(':jfxtras-gauge-linear')
        compile project(':jfxtras-font-roboto')
    }
}

shadowJar {
   classifier = null // do not append "-all", so the generated shadow jar replaces the existing jfxtras-all.jar (instead of generating jfxtras-all-all.jar)
}

This works fine, but maven central is refusing the all jar, because it does not have an associated sources and javadocs jar.

How do I tell gradle to also generate the sources and javadoc? ShadowJar's documentation says it should do this by default.


Solution

  • The shadow plugin doesn't seem to have a feature of building a fat sources/javadocs jars.

    Below, I provide a few short tasks (javadocJar and sourcesJar) that will build fat javadoc and source jars. They are linked to be always executed after shadowJar. But it has no dependency on the shadow jar plugin.

    subprojects {
        apply plugin: 'java'
    }
    
    // Must be BELOW subprojects{}
    task alljavadoc(type: Javadoc) {
        source subprojects.collect { it.sourceSets.main.allJava }
        classpath = files(subprojects.collect { it.sourceSets.main.compileClasspath })
        destinationDir = file("${buildDir}/docs/javadoc")
    }
    
    task javadocJar(type: Jar, dependsOn: alljavadoc) {
        classifier = 'javadoc'
        from alljavadoc.destinationDir
    }
    
    task sourcesJar(type: Jar) {
        classifier = 'sources'
        from subprojects.collect { it.sourceSets.main.allSource }
    }
    
    shadowJar.finalizedBy javadocJar
    shadowJar.finalizedBy sourcesJar
    

    Note, the subprojects section is required, even if you already apply the java plugin inside your subprojects.

    Also note, it doesn't include javadocs of the third party libraries your subprojects might depend on. But usually you wouldn't want to do it anyway, probably.