A WIP gradle plugin with the intention of implementing jvmDowngrader in a gradle environment in a way that is extensible and following the design paradigms set here at stianloader.
This plugin is currently in the "is the idea even good?" phase and as such the documentation is currently still to be drafted. As such consider not using the plugin for the time being until we can verify that the plugin can be used as-is without further issues.
The plugin is available under our maven repository: https://stianloader.org/maven
Beware that we use a not-so-traditional versioning scheme, so ensure you are using the proper version.
Note that at this point in time all examples make use of groovy gradle. This is largely caused by groovy being the golden standard here in stianloader as it is the most widely supported gradle DSL for IDEs.
build.gradle:
plugins {
// [...]
id 'org.stianloader.interjava' version '0.1.0-a20240512'
}
settings.gradle:
pluginManagement {
repositories {
gradlePluginPortal()
mavenCentral()
// [...]
maven {
name = 'stianloader-maven'
url = 'https://stianloader.org/maven/'
}
maven {
name = "wagyourtail"
url = "https://maven.wagyourtail.xyz/releases"
}
}
}
repositories {
// [...]
maven {
name = 'wagyourtail'
url = 'https://maven.wagyourtail.xyz/releases'
}
}
configurations {
jvmDowngraderJavaApi
}
dependencies {
// [...]
// Java 8 APIs required by jvmDowngrader
jvmDowngraderJavaApi (group: 'xyz.wagyourtail.jvmdowngrader', name: 'jvmdowngrader-java-api', version: '0.1.2', classifier: 'downgraded-8')
}
// Note: DowngradedArchiveTask is an AbstractArchiveTask and as such has all the methods and properties AbstractArchiveTasks normally have
task downgradedJar(type: org.stianloader.interjava.DowngradedArchiveTask, dependsOn: jar) {
from(zipTree(jar.archiveFile))
archiveVersion = jar.archiveVersion
archiveBaseName = jar.archiveBaseName
targetVersion = 8
// The following is only required to recompute frames. So all direct compile-time dependencies need to be present.
sourceSets.main.compileClasspath.each { classpathEntry ->
compileClassPath.from(zipTree(classpathEntry))
}
}
build {
dependsOn(downgradedJar)
}
Note that jvmDowngraderJavaApi
could also be runtime
, in which case you don't need to
include the configurations
block. However, using a dedicated configuration to store the
jvmdowngrader-java-api artifact will be useful when making use of variant publishing.
Defining the downgraded configuration that needs to be published:
configurations {
downgradedJar {
canBeConsumed = true
canBeResolved = false
attributes {
attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category, Category.LIBRARY))
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, Usage.JAVA_RUNTIME))
attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling, Bundling.EXTERNAL))
attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 8)
attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements, 'jar'))
}
artifacts {
downgradedJar
}
outgoing {
artifact tasks['downgradedJar']
}
extendsFrom configurations['implementation']
extendsFrom configurations['jvmDowngraderJavaApi']
}
}
Tip: The order of blocks matter: This configuration block needs to be below
the downgradedJar
task definition, which needs to be below the dependencies
definition which
in turn needs to be below the configurations
block defining jvmDowngraderJavaApi
.
Thankfully, we can have two configurations
blocks.
Defining the downgraded configuration as a variant (needs to be after the second configurations
block):
components {
java {
addVariantsFromConfiguration(configurations['downgradedJar']) {
mapToMavenScope("runtime")
}
}
}
Actually publishing the variant (should be after the components
block):
publishing {
publications {
plugin(MavenPublication) { publication ->
// [...]
from components['java']
}
}
// [...]
}
publish {
dependsOn(downgradedJar)
}
Note that from components['java']
will cause all other variants associated
with the java
component to be published. Unfortunately, one cannot create components
out of thin air in the buildscript without using a plugin for it.
See: https://docs.gradle.org/current/userguide/publishing_customization.html#sec:publishing-custom-components
repositories {
// [...]
maven {
name = 'wagyourtail'
url = 'https://maven.wagyourtail.xyz/releases'
}
}
dependencies {
implementation (group: 'org.stianloader', name: 'jlsl', version: '1.0.0', classifier: 'j8')
}
There isn't really anything special here to be honest. The above code should be familiar enough if you have ever worked with classifiers before.
The only thing you need to be aware of is that you cannot remove the transitive
dependency on jvmdowngrader-java-api
, which is why it is important to define
the repository of jvmdowngrader.
While it is planned on supporting the ability to shade jvmdowngrader-java-api
into the produced jar, the ability to do so has not yet been added.
The performance of this plugin is likely going to be pretty bad with larger jars. It might be worse than jvmDowngrader's official plugin for any jar in any environment in fact.
However, performance is only rarely our selling point when reinventing the wheel. What else did you expect.