From 85af170b8a6a72233efa15192317f4b6e819dec6 Mon Sep 17 00:00:00 2001 From: Jendrik Johannes Date: Thu, 25 Jun 2026 21:11:41 +0200 Subject: [PATCH] Handle classifiers in FilePathToModuleCoordinates (fixed) --- CHANGELOG.md | 4 +- README.md | 6 ++- .../FilePathToModuleCoordinates.java | 4 +- .../javamodule/moduleinfo/IdValidator.java | 2 +- .../javamodule/moduleinfo/ModuleSpec.java | 5 ++- .../FilePathToModuleCoordinatesTest.groovy | 6 ++- .../test/ClassifiedJarsFunctionalTest.groovy | 37 ++++++++++++++++++- .../test/EdgeCasesFunctionalTest.groovy | 2 +- 8 files changed, 53 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 11e9f5b..732f3eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,10 @@ # Extra Java Module Info Gradle Plugin - Changelog +## Version 1.14.2 +* [Fixed] [#246](https://github.com/gradlex-org/extra-java-module-info/issues/246) - More correct classifier handling (fixed) + ## Version 1.14.1 * [Fixed] [#246](https://github.com/gradlex-org/extra-java-module-info/issues/246) - More correct classifier handling (Thanks to [Geolykt](https://github.com/Geolykt) for reporting) - * ⚠️ For matching a Jar with classifier, the _identifier_ now needs to be included - e.g. `org.dojotoolkit:dojo|distribution` instead of `org.dojotoolkit:dojo` ## Version 1.14 * [New] [#207](https://github.com/gradlex-org/extra-java-module-info/issues/207) - Add 'exportAllPackagesExcept("org.exception", ...)' (Thanks [Tim Hurman](https://github.com/timhamoni) for contributing) diff --git a/README.md b/README.md index cb4ae46..b5c07b1 100644 --- a/README.md +++ b/README.md @@ -104,8 +104,10 @@ extraJavaModuleInfo { // when the Jar has a classifier - 'linux-x86_64' in this example: module("io.netty:netty-transport-native-epoll|linux-x86_64", - "io.netty.transport.epoll.linux.x86_64") - // when you somehow cannot address a Jar via coordinates, you may use the Jar name: + "io.netty.transport.epoll.linux.x86_64") + // when there are multiple Jars and you only want to match the one without classifier + module("org.lwjgl:lwjgl-glfw|", "org.lwjgl.glfw") + // when you cannot address a Jar via coordinates, you may use the Jar name: module("commons-logging-1.2.jar", "org.apache.commons.loggin") } ``` diff --git a/src/main/java/org/gradlex/javamodule/moduleinfo/FilePathToModuleCoordinates.java b/src/main/java/org/gradlex/javamodule/moduleinfo/FilePathToModuleCoordinates.java index 39b4d51..3cbd348 100644 --- a/src/main/java/org/gradlex/javamodule/moduleinfo/FilePathToModuleCoordinates.java +++ b/src/main/java/org/gradlex/javamodule/moduleinfo/FilePathToModuleCoordinates.java @@ -45,7 +45,7 @@ static boolean gaCoordinatesFromFilePathMatch(Path path, String ga, @Nullable St String classifierFromGradleCache = isInGradleCache(path); if (classifierFromGradleCache != null) { - if (classifierFromGradleCache.isEmpty()) { + if (classifier == null) { return coordinatesFromPath.equals(ga); } return coordinatesFromPath.equals(ga) && classifierFromGradleCache.equals(classifier); @@ -53,7 +53,7 @@ static boolean gaCoordinatesFromFilePathMatch(Path path, String ga, @Nullable St String classifierFromM2Cache = isInM2Cache(path); if (classifierFromM2Cache != null) { - if (classifierFromM2Cache.isEmpty()) { + if (classifier == null) { return coordinatesFromPath.endsWith(ga); } return coordinatesFromPath.endsWith(ga) && classifierFromM2Cache.equals(classifier); diff --git a/src/main/java/org/gradlex/javamodule/moduleinfo/IdValidator.java b/src/main/java/org/gradlex/javamodule/moduleinfo/IdValidator.java index 94aa761..fa2102d 100644 --- a/src/main/java/org/gradlex/javamodule/moduleinfo/IdValidator.java +++ b/src/main/java/org/gradlex/javamodule/moduleinfo/IdValidator.java @@ -5,7 +5,7 @@ @NullMarked class IdValidator { - private static final String COORDINATES_PATTERN = "^[a-zA-Z0-9._-]+:[a-zA-Z0-9._-]+(\\|[a-zA-Z0-9._-]+)?$"; + private static final String COORDINATES_PATTERN = "^[a-zA-Z0-9._-]+:[a-zA-Z0-9._-]+(\\|[a-zA-Z0-9._-]*)?$"; private static final String FILE_NAME_PATTERN = "^[a-zA-Z0-9._-]+\\.(jar|zip)$"; static void validateIdentifier(String identifier) { diff --git a/src/main/java/org/gradlex/javamodule/moduleinfo/ModuleSpec.java b/src/main/java/org/gradlex/javamodule/moduleinfo/ModuleSpec.java index e90abb2..ce0706d 100644 --- a/src/main/java/org/gradlex/javamodule/moduleinfo/ModuleSpec.java +++ b/src/main/java/org/gradlex/javamodule/moduleinfo/ModuleSpec.java @@ -33,8 +33,9 @@ protected ModuleSpec(String identifier, String moduleName) { validateIdentifier(identifier); validateModuleName(moduleName); if (identifier.contains("|")) { - this.identifier = identifier.split("\\|")[0]; - this.classifier = identifier.split("\\|")[1]; + String[] split = identifier.split("\\|"); + this.identifier = split[0]; + this.classifier = split.length > 1 ? split[1] : ""; } else { this.identifier = identifier; this.classifier = null; diff --git a/src/test/groovy/org/gradlex/javamodule/moduleinfo/FilePathToModuleCoordinatesTest.groovy b/src/test/groovy/org/gradlex/javamodule/moduleinfo/FilePathToModuleCoordinatesTest.groovy index a12e494..02e8e23 100644 --- a/src/test/groovy/org/gradlex/javamodule/moduleinfo/FilePathToModuleCoordinatesTest.groovy +++ b/src/test/groovy/org/gradlex/javamodule/moduleinfo/FilePathToModuleCoordinatesTest.groovy @@ -46,7 +46,8 @@ class FilePathToModuleCoordinatesTest extends Specification { def path = path('/Users/jendrik/.gradle/caches/modules-2/files-2.1/org.lwjgl/lwjgl-glfw/3.3.6/399b42b491c5dfa6595ae6fd79dcba61b93538a7/lwjgl-glfw-3.3.6-natives-macos-arm64.jar') expect: - !gaCoordinatesFromFilePathMatch(path, "org.lwjgl:lwjgl-glfw", null) + !gaCoordinatesFromFilePathMatch(path, "org.lwjgl:lwjgl-glfw", "") + gaCoordinatesFromFilePathMatch(path, "org.lwjgl:lwjgl-glfw", null) // matches all classifiers gaCoordinatesFromFilePathMatch(path, "org.lwjgl:lwjgl-glfw", "natives-macos-arm64") } @@ -95,7 +96,8 @@ class FilePathToModuleCoordinatesTest extends Specification { def path = path('/Users/someone/.m2/repository/org/lwjgl/lwjgl-glfw/3.3.6/lwjgl-glfw-3.3.6-natives-macos-arm64.jar') expect: - !gaCoordinatesFromFilePathMatch(path, "org.lwjgl:lwjgl-glfw", null) + !gaCoordinatesFromFilePathMatch(path, "org.lwjgl:lwjgl-glfw", "") + gaCoordinatesFromFilePathMatch(path, "org.lwjgl:lwjgl-glfw", null) // matches all classifiers gaCoordinatesFromFilePathMatch(path, "org.lwjgl:lwjgl-glfw", "natives-macos-arm64") } diff --git a/src/test/groovy/org/gradlex/javamodule/moduleinfo/test/ClassifiedJarsFunctionalTest.groovy b/src/test/groovy/org/gradlex/javamodule/moduleinfo/test/ClassifiedJarsFunctionalTest.groovy index 13dc3ed..cec77dd 100644 --- a/src/test/groovy/org/gradlex/javamodule/moduleinfo/test/ClassifiedJarsFunctionalTest.groovy +++ b/src/test/groovy/org/gradlex/javamodule/moduleinfo/test/ClassifiedJarsFunctionalTest.groovy @@ -63,6 +63,39 @@ class ClassifiedJarsFunctionalTest extends Specification { build().task(':compileJava').outcome == TaskOutcome.SUCCESS } + def "patches classified Jar if no classifier is specified"() { + given: + file("src/main/java/org/gradle/sample/app/Main.java") << """ + package org.gradle.sample.app; + public class Main { + public static void main(String[] args) { + com.sun.javafx.scene.control.ContextMenuContent menu; + } + } + """ + file("src/main/java/module-info.java") << """ + module org.gradle.sample.app { + requires javafx.controls; + } + """ + buildFile << """ + dependencies { + implementation("org.openjfx:javafx-controls:11:linux") + implementation("org.openjfx:javafx-graphics:11:linux") + implementation("org.openjfx:javafx-base:11:linux") + } + extraJavaModuleInfo { + module("org.openjfx:javafx-controls", "javafx.controls") { + preserveExisting() + exports("com.sun.javafx.scene.control") + } + } + """ + + expect: + build().task(':compileJava').outcome == TaskOutcome.SUCCESS + } + def "does not accidentally patch classified Jar"() { given: file("src/main/java/org/gradle/sample/app/Main.java") << """ @@ -85,11 +118,11 @@ class ClassifiedJarsFunctionalTest extends Specification { implementation("org.lwjgl:lwjgl:3.2.2:natives-macos") } extraJavaModuleInfo { - module("org.lwjgl:lwjgl", "org.lwjgl") { + module("org.lwjgl:lwjgl|", "org.lwjgl") { preserveExisting() requiresStatic("org.lwjgl.natives") } - module("org.lwjgl:lwjgl-glfw", "org.lwjgl.glfw") { + module("org.lwjgl:lwjgl-glfw|", "org.lwjgl.glfw") { preserveExisting() requiresStatic("org.lwjgl.glfw.natives") } diff --git a/src/test/groovy/org/gradlex/javamodule/moduleinfo/test/EdgeCasesFunctionalTest.groovy b/src/test/groovy/org/gradlex/javamodule/moduleinfo/test/EdgeCasesFunctionalTest.groovy index 9f5eb62..6b12338 100644 --- a/src/test/groovy/org/gradlex/javamodule/moduleinfo/test/EdgeCasesFunctionalTest.groovy +++ b/src/test/groovy/org/gradlex/javamodule/moduleinfo/test/EdgeCasesFunctionalTest.groovy @@ -74,7 +74,7 @@ class EdgeCasesFunctionalTest extends Specification { failOnMissingModuleInfo.set(false) automaticModule("org.apache.qpid:qpid-broker-core", "org.apache.qpid.broker") { mergeJar("org.apache.qpid:qpid-broker-plugins-management-http") - mergeJar("org.dojotoolkit:dojo|distribution") // This is a Zip, selected by 'distribution' classifier in dependencies of 'qpid-broker-plugins-management-http' + mergeJar("org.dojotoolkit:dojo") // This is a Zip, selected by 'distribution' classifier in dependencies of 'qpid-broker-plugins-management-http' mergeJar("org.webjars.bower:dgrid") mergeJar("org.webjars.bower:dstore") }