Skip to content

Commit

Permalink
replace multiRelease and moduleInfoCompatibility with multiReleaseVer…
Browse files Browse the repository at this point in the history
…sion
  • Loading branch information
siordache committed Oct 30, 2021
1 parent e19d553 commit 60c2e36
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 45 deletions.
35 changes: 12 additions & 23 deletions README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ To use the plugin, include the following in your build script:
----
plugins {
id 'java'
id 'org.beryx.jar' version '2.0.0-rc-3'
id 'org.beryx.jar' version '2.0.0-rc-4'
}
----

Expand All @@ -51,8 +51,7 @@ The plugin uses an extension named `moduleConfig`. The sample below shows a few
----
moduleConfig {
moduleInfoPath = 'src/main/module/module-info.java'
multiRelease = true
moduleInfoCompatibility = 9
multiReleaseVersion = 9
version = project.version
}
----
Expand All @@ -69,41 +68,28 @@ Therefore, you should use a Java 9+ toolchain whenever it's possible.

The properties provided by the `moduleConfig` extension are described below.

==== _multiRelease_ : enable/disable Multi-release JAR
[purple]##default value: ## `true`
==== _multiReleaseVersion_: create a Multi-release JAR with a specific version
[purple]##default value: ## `-1` (the module-info.class is put in the root of the jar)

Typically, a https://openjdk.java.net/projects/jigsaw/spec/sotms/#module-artifacts[modular jar]
includes the `module-info.class` file in its root directory.
This causes problems for some older tools, which incorrectly process the module descriptor as if it were a normal Java class.
To provide the best backward compatibility, the plugin creates by default a
This may cause problems with some older tools, which incorrectly process the module descriptor as if it were a normal Java class.
To avoid this, you can create a
https://openjdk.java.net/jeps/238#Modular-multi-release-JAR-files[modular multi-release jar]
with the `module-info.class` file located in `META-INF/versions/9`, as shown below.
with the `module-info.class` file located in `META-INF/versions/<number>`, as shown below.

image:https://raw.githubusercontent.com/beryx/badass-jar-plugin/master/doc/multi-release-jar.png[multi-release-jar,548,200]

You can prevent the creation of a multi-release jar by setting the `multiRelease` property to `false` in the `moduleConfig` extension:
By setting the `multiReleaseVersion` property to a value greater than 0, the plugin will create a multi-release jar:

[source,groovy]
----
moduleConfig {
multiRelease = false
multiReleaseVersion = 9
...
}
----

==== _moduleInfoCompatibility_: configure module descriptor location
[purple]##default value: ## `9`

When creating a multi-release jar, the plugin puts by default the `module-info.class` file in the `META-INF/versions/9` folder, which means that any JVM with version >= 9 will handle this jar as modular. You can change this by setting the `moduleInfoCompatibility` property in the `moduleConfig` extension. For example, the code below instructs the plugin to put the module descriptor in the `META-INF/versions/11` folder.

[source,groovy]
----
moduleConfig {
moduleInfoCompatibility = 11
}
----


==== _moduleInfoPath_: configure module-info.java location
[purple]##default value: ## `src/main/java/module-info.java`

Expand Down Expand Up @@ -142,6 +128,9 @@ The following projects illustrate how to use this plugin to create modular jars
- https://github.com/beryx-gist/badass-jar-example-nqueens[badass-jar-example-nqueens]: a Java library for solving the N-Queens problem.
- https://github.com/beryx-gist/badass-jar-example-nqueens-kotlin[badass-jar-example-nqueens-kotlin]: a Kotlin library for solving the N-Queens problem.

=== Projects using badass-jar-plugin
See https://github.com/beryx/badass-jar-plugin/wiki/Projects-using-badass-jar-plugin[this Wiki page].

=== Acknowledgements

This plugin was heavily inspired by and includes code from
Expand Down
17 changes: 7 additions & 10 deletions src/main/groovy/org/beryx/jar/JarTaskConfigurer.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ class JarTaskConfigurer {
this.javaPluginExtension = project.extensions.getByType(JavaPluginExtension)
this.mainSourceSet = javaPluginExtension.sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME)
def targetBaseDir = mainSourceSet.java.destinationDirectory.asFile.get()
this.moduleInfoTargetDir = moduleData.multiRelease
? new File(targetBaseDir, "META-INF/versions/$moduleData.moduleInfoCompatibility")
this.moduleInfoTargetDir = (moduleData.multiReleaseVersion > 0)
? new File(targetBaseDir, "META-INF/versions/$moduleData.multiReleaseVersion")
: targetBaseDir
this.moduleInfoJava = findModuleInfoJava()
}
Expand Down Expand Up @@ -107,7 +107,7 @@ class JarTaskConfigurer {

compileJava.include("**/module-info.java")
compileJava.getDestinationDirectory().set(moduleInfoTargetDir)
compileJava.options.release.set(moduleData.moduleInfoCompatibility)
compileJava.options.release.set(moduleData.multiReleaseVersion > 0 ? moduleData.multiReleaseVersion : 9)

LOGGER.debug("mainSourceSet: $mainSourceSet.java.srcDirs")
LOGGER.debug("compileJava release: ${compileJava.options.release.getOrNull()}")
Expand All @@ -124,11 +124,8 @@ class JarTaskConfigurer {
def classesTask = project.tasks.getByName(JavaPlugin.CLASSES_TASK_NAME)
classesTask.dependsOn(compileNonJpms)
} else {
if(moduleConfigExtension.multiRelease.isPresent() && moduleData.multiRelease) {
LOGGER.info("multiRelease ignored because classes are compiled using Java $sourceCompatibilityJavaVersion")
}
if(moduleConfigExtension.moduleInfoCompatibility.isPresent() && JavaVersion.toVersion(moduleData.moduleInfoCompatibility) != sourceCompatibilityJavaVersion) {
LOGGER.info("moduleInfoCompatibility ignored because classes are compiled using Java $sourceCompatibilityJavaVersion")
if((moduleData.multiReleaseVersion > 0) && JavaVersion.toVersion(moduleData.multiReleaseVersion) != sourceCompatibilityJavaVersion) {
LOGGER.info("multiReleaseVersion ignored because classes are compiled using Java $sourceCompatibilityJavaVersion")
}
}
}
Expand Down Expand Up @@ -177,8 +174,8 @@ class JarTaskConfigurer {
LOGGER.debug "Setting module version to $moduleData.version"
byte[] clazz = ModuleInfoCompiler.compileModuleInfo( module, null, moduleData.version)
LOGGER.debug "Module info compiled: $clazz.length bytes"
LOGGER.debug "multiRelease = $moduleData.multiRelease"
if(moduleData.multiRelease) {
LOGGER.debug "multiReleaseVersion = $moduleData.multiReleaseVersion"
if(moduleData.multiReleaseVersion > 0) {
jarTask.manifest.attributes('Multi-Release': true)
}
def moduleDescriptor = new File(moduleInfoTargetDir, 'module-info.class')
Expand Down
19 changes: 7 additions & 12 deletions src/main/groovy/org/beryx/jar/ModuleConfigExtension.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,21 @@ import org.gradle.api.provider.Property
class ModuleConfigExtension {
private final Project project
final Property<String> moduleInfoPath
final Property<Boolean> multiRelease
final Property<String> version
final Property<Integer> moduleInfoCompatibility
final Property<Integer> multiReleaseVersion
final Property<Boolean> neverCompileModuleInfo

static class ModuleData {
final String moduleInfoPath
final boolean multiRelease
final String version
final int moduleInfoCompatibility
final int multiReleaseVersion
final boolean neverCompileModuleInfo

ModuleData(String moduleInfoPath, boolean multiRelease,
String version, int moduleInfoCompatibility, boolean neverCompileModuleInfo) {
ModuleData(String moduleInfoPath, String version,
int multiReleaseVersion, boolean neverCompileModuleInfo) {
this.moduleInfoPath = moduleInfoPath
this.multiRelease = multiRelease
this.version = version
this.moduleInfoCompatibility = moduleInfoCompatibility
this.multiReleaseVersion = multiReleaseVersion
this.neverCompileModuleInfo = neverCompileModuleInfo
}
}
Expand All @@ -49,18 +46,16 @@ class ModuleConfigExtension {
this.project = project

this.moduleInfoPath = project.objects.property(String)
this.multiRelease = project.objects.property(Boolean)
this.version = project.objects.property(String)
this.moduleInfoCompatibility = project.objects.property(Integer)
this.multiReleaseVersion = project.objects.property(Integer)
this.neverCompileModuleInfo = project.objects.property(Boolean)
}

ModuleData getData() {
new ModuleData(
moduleInfoPath.getOrElse(''),
multiRelease.getOrElse(true),
version.getOrElse(''),
moduleInfoCompatibility.getOrElse(9),
multiReleaseVersion.getOrElse(-1),
neverCompileModuleInfo.getOrElse(false)
)
}
Expand Down

0 comments on commit 60c2e36

Please sign in to comment.