plantuml has 2 main variants, a slim standard version, and one which allows to generate pdf. the pdf variant includes additional libraries, which can be used when on the classpath. i included this - but that seems not enough to get it built:
> gradle outgoingVariants | grep -i pdf
Variant pdfApiElements
Description = API elements for feature pdf
- net.sourceforge.plantuml:plantuml-pdf:1.2022.1-SNAPSHOT
Variant pdfRuntimeElements
Description = Runtime elements for feature pdf
- net.sourceforge.plantuml:plantuml-pdf:1.2022.1-SNAPSHOT
there is no task though, and doing a normal build or assemble creates the fat jar unconditionally, including the feature dependencies:
> gradle tasks | grep -i pdf
> gradle assemble
> ls -l build/libs/
total 73324
-rw-r--r-- 1 rt rt 24987267 12. Feb 11:32 plantuml-1.2022.1-SNAPSHOT.jar
-rw-r--r-- 1 rt rt 26353195 12. Feb 11:32 plantuml-1.2022.1-SNAPSHOT-javadoc.jar
-rw-r--r-- 1 rt rt 23737102 12. Feb 11:32 plantuml-1.2022.1-SNAPSHOT-sources.jar
you set source encoding for JavaCompile tasks to UTF-8, but you don’t do so for the JavaDoc tasks, they also need the correct source encoding or you might get encoding problems in the generated documentation
you don’t allow publishing to maven local without signing configured, that’s imho bad practice, if someone wants to publish to maven local, he should be able to do without needing to set up signing
your sources jar cannot be built because there are duplicate entries
the pdf feature you define is also for source set main, so the respective dependencies are also on the runtimeClasspath for source set main that you pack into your jar
In the POM the dependencies will be marked as optional, in the Gradle module metadata file they will only be present on the pdfRuntimeElements variant.
imho you shouldn’t build a fat jar, especially if you publish to a Maven repository and especially as the default jar and even worse with still having the dependencies declared in the metadata (well, you don’t have dependencies except for the pdf variant, but as soon as you add one you will have it), if someone depends on your artifact, he will get your artifact and additionally the declared dependencies and thus has the classes twice in the class path. And even if you leave out the dependencies from the metadata, if someone depends on your artifact and also adds one of the packaged dependencies separately or as transitive dependencies of another dependency he will also have the classes twice on the classpath and maybe in different versions which can generate big headaches. If you really want to publish fat jars to a Maven repository, then at least do it as a separate variant with proper attributes set that define that the dependencies are packaged within the jar. From Maven view this is then an artifact with a classifier for Gradle it is a separate variant one can explicitly request by requesting via attribute that he wants the version with packaged dependencies.
And one more, don’t use tasks.withType<Javadoc> { ... } it is eager and defeats task configuration avoidance efforts, better use tasks.withType<Javadoc>().configureEach { ... }
impressive list, thank you! i saw now optional dependencies, and i like how this can be stated in gradle.
the goal was not to publish a fat jar into the maven repo, but generate both, the jar for maven, and the fat jar. maybe publish the fat jar on github to make peoples live easier so they do not need to download the jars when they run it on command line to generate pdf’s. in maven, with the current pom, one can generate a jar with dependencies.
i understood your last remark, to create a variant, with proper attributes set to denote dependencies are in the jar. i guess this is what i tried to reach and hoped the 4 lines “registerFeature” would do it.
> gradle publishMavenPublicationToMavenLocal
Maven publication 'maven' pom metadata warnings (silence with 'suppressPomMetadataWarningsFor(variant)'):
- Variant pdfApiElements:
- Declares capability net.sourceforge.plantuml:plantuml-pdf:1.2022.1-SNAPSHOT which cannot be mapped to Maven
- Variant pdfRuntimeElements:
- Declares capability net.sourceforge.plantuml:plantuml-pdf:1.2022.1-SNAPSHOT which cannot be mapped to Maven
These issues indicate information that is lost in the published 'pom' metadata file, which may be an issue if the published library is consumed by an old Gradle version or Apache Maven.
The 'module' metadata file, which is used by Gradle 6+ is not affected.
> Task :publishMavenPublicationToMavenLocal FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':publishMavenPublicationToMavenLocal'.
> Failed to publish publication 'maven' to repository 'mavenLocal'
> Invalid publication 'maven': multiple artifacts with the identical extension and classifier ('jar', 'null').
there is:
am not sure - currently i downgraded to shadowJar 5.2.0 to not publish the fat jar. but it does not sign the artifact for a github upload as well. hmm.
task("pdfJar") creates an eager (not using task configuration avoidance) instance of an ad-hoc task named pdfJar. You then give this task of type DefaultTask to the sign method and so it of course is not an archive task.
Now if you consider task-configuration avoidance, you want to use register instead of create and then need to use the closure variant of sign to not trigger task realization early as it does not accept a TaskProvider:
thank you, changed it like you suggested, and replaced the gpg part with the gradle in memory signing, with if for local. the “sing” task now got a new names, signMavenPublication and signPdfJar and gradle help does not list them. is this a bug in the sign plugin, as it does not list “sign” in gradle tasks as well?
The Sign tasks are usually not called by an end-user manually so they don’t get a category assigned and tasks without category are not shown by gradlew tasks. They are shown by gradlew tasks --all though under the “Other” category.