Feature request: allow excluding thirdPartyCompatibility from GMM

This is a follow up per @Vampire recommendation based on a Slack Conversation.

In summary, I would like to have the ability to do at least do the following:

tasks.withType(GenerateModuleMetadata) {
    thirdPartyCompatibility = false
}

To explain, lets consider the following build.gradle file for a typical OSS JavaFX library package:

plugins {
    id 'java'
    id 'java-library'
    id 'application'
    id 'maven-publish'
    id 'org.openjfx.javafxplugin' version '0.0.14'
}

group = 'org.example'
version = '1.0-SNAPSHOT'
description = 'An example JFX app'

repositories {
    mavenCentral()
}

application {
    mainModule = 'org.example'
    mainClass = 'org.example.Launcher'
}

java {
    sourceCompatibility = JavaVersion.VERSION_17
    targetCompatibility = JavaVersion.VERSION_17
    modularity.inferModulePath.set(true)
}

javafx {
    version = '20.0.2' 
    modules = ['javafx.controls', 'javafx.graphics']
}

publishing {
    publications {
        mavenCustom(MavenPublication) {
            artifactId = 'example'
            group = project.group
            version = project.version
            from components.java

            pom.withXml {
                def root = asNode()
                root.dependencies.'*'
                        .findAll() { it.groupId.text() == 'org.openjfx' }
                        .each { it.remove(it.classifier) }
            }

            pom {
                name = 'Example'
                description = project.description
            }
        }
    }

}

When publishing this package, it yields the proper pom.xml, but the module.json is a bit problematic.

The pom.xml:

...
<dependency>
  <groupId>org.openjfx</groupId>
  <artifactId>javafx-base</artifactId>
  <version>20.0.2</version>
  <scope>runtime</scope>
</dependency>
...

The module.json:

...
{
  "group": "org.openjfx",
  "module": "javafx-base",
  "version": {
    "requires": "20.0.2"
  },
  "thirdPartyCompatibility": {
    "artifactSelector": {
      "name": "javafx-base",
      "type": "jar",
      "extension": "jar",
      "classifier": "linux"
    }
  }
}
...

This can cause issues to downstream consumers such as this JLink error Error: Two versions of module javafx.base found in /path/to/build/jlinkbase/jlinkjars (javafx-base-20.0.2-mac-aarch64.jar and javafx-base-20.0.2-linux.jar) since the published .module file will have the classifier entry.

I’m looking for an option that I can prevent this from happening and yield the following module.json:

...
{
  "group": "org.openjfx",
  "module": "javafx-base",
  "version": {
    "requires": "20.0.2"
  }
}
...

which behaves as expected to downstream consumers when we publish our JavaFX libraries.

Currently, I’m resorting to the following code to modify the module.json before publishing:

tasks.withType(GenerateModuleMetadata).configureEach {
    doLast { _ ->
        def gmmFile = it.outputFile.get().asFile
        def inJson = new JsonSlurper().parseText(gmmFile.text)
        def filteredVariant = inJson.variants.findAll { it.name == configurations.runtimeElements.name }
        // remove "thirdPartyCompatibility" from GMM
        filteredVariant.dependencies.first().each {
            if (it.group == 'org.openjfx') {
                it.remove('thirdPartyCompatibility')
            }
        }
        def outJson = JsonOutput.toJson(inJson)
        gmmFile.write(JsonOutput.prettyPrint(outJson))
    }
}

Here’s an example from a published library before and after the fix above:

This is a community forum, much like the Slack, just in forum form. If you want to post an official feature request, you need to open it as issue on GitHub. :wink:

1 Like