Gradle issue #10046 — reported by @chrisdennis a few weeks ago — sparked an idea for a plugin. Earlier today I published the mrJar plugin that fulfills the main requirement requested in that issue. Plus it partially supports parts of the others:
…
support for:
- Compiling the needed class-files.
- …
- Executing unit tests across [some of the] JDK versions.
…
The plugin’s implementation of @chrisdennis’ list of requirements is still not 100% feature complete. Yet. I’d say it’s maybe %70-80% right now. The same thing goes for the level of my Gradle knowledge at this point (with my Gradle knowledge numbers being a lot lower ). But I intend to fill the gaps in both eventually.
I have established, nevertheless, that the mrJar plugin is satisfactorily usable even at this early v0.0.1
stage. During development of the plugin, I applied the plugin to its own project. It had no problem turning itself into a modular MRJAR-assembled plugin. It was as easy as:
plugins{
...
id 'com.lingocoder.mrjar' version '0.0.1'
id 'java'
id 'groovy' /* I used Groovy in my project; But you don't have to in yours */
...
}
...
dependencies {
/* <mrjar plugin project's dependencies> */
}
...
mrjar {
/* The releases property is mandatory. The values must be Gradle's version enum types */
releases [JavaVersion.VERSION_1_9, JavaVersion.VERSION_12, ]
}
...
What the mrjar
extension does is tell the plugin which Java releases your artifact will support. With that in your build script, you just simply need to run the one single task that the plugin exports:
$ ./gradlew :mrinit
In my example the plugin’s lone :mrinit
task created source directories src/main/java9
and src/main/java12
in my project directory.
I then simply added my release-specific source code to the respective release’s source folder. That source code could, optionally, include a module-info.java
source file.
Just an aside: My particular use case called for modularity. Your own use case might not necessarily need to support Java 9+ modules. It is a valid use case to support just a Multi-Release Jar that has no module-info.java
descriptors. The mrJar plugin can do that for you.
TL;DR: As an end user of the mrJar plugin, there were only two extra steps I needed to do to have Gradle assemble my project as a modular MRJAR artifact:
- fill in the properties of
mrjar
extension - execute
./gradlew :mrinit
After that, I simply carried on the normal steps of the typical test/develop/build cycle. Then when I was eventually ready to publish the plugin to Gradles Plugins Portal, I just did it the same way I normally do it:
./gradlew publishPlugins
Et viola! Who knew dog food was so tastey? I share more detailed usage examples on the project’s site.
Naturally, there will be things that during development of the mrJar plugin I might have either overlooked, incorrectly assumed or just plain had no clue about. To fill those gaps sooner, I’m reaching out to the community to get feedback on usage of the plugin.
Before I started development of the plugin, I did some analysis/research to establish what was feasible. From that, I learned that these guys know more than a thing or two about MRJARS and/or Java 9 modules:
So I’m requesting a favor from you all (and the Gradle community in general): Please give the usage of the mrJar plugin the once over? Apply the mrJar plugin in your project, see if it works for you, and share your feedback and suggestions? Please? TIA.