From 909c7591b2676336f6c608aea606fcc8b43753c7 Mon Sep 17 00:00:00 2001
From: arimu1 <19286898+arimu1@users.noreply.github.com>
Date: Sat, 15 Aug 2026 09:48:47 +0700
Subject: [PATCH] fix(jpms): align Automatic-Module-Name with module-info names
Use each module's java.module.name property for the manifest entry so
core, okhttp, and retrofit no longer share dev.failsafe on the module path.
Fixes #386
---
.../java/dev/failsafe/ModuleManifestTest.java | 47 +++++++++++++++++++
.../failsafe/okhttp/ModuleManifestTest.java | 47 +++++++++++++++++++
.../failsafe/retrofit/ModuleManifestTest.java | 47 +++++++++++++++++++
pom.xml | 2 +-
4 files changed, 142 insertions(+), 1 deletion(-)
create mode 100644 core/src/test/java/dev/failsafe/ModuleManifestTest.java
create mode 100644 modules/okhttp/src/test/java/dev/failsafe/okhttp/ModuleManifestTest.java
create mode 100644 modules/retrofit/src/test/java/dev/failsafe/retrofit/ModuleManifestTest.java
diff --git a/core/src/test/java/dev/failsafe/ModuleManifestTest.java b/core/src/test/java/dev/failsafe/ModuleManifestTest.java
new file mode 100644
index 00000000..2f2bedd9
--- /dev/null
+++ b/core/src/test/java/dev/failsafe/ModuleManifestTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2026 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package dev.failsafe;
+
+import org.testng.annotations.Test;
+
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.jar.Manifest;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+@Test
+public class ModuleManifestTest {
+ public void shouldExposeCorrectAutomaticModuleName() throws Exception {
+ Path manifestPath = moduleManifestPath();
+ assertTrue(Files.exists(manifestPath), "Module manifest should exist at " + manifestPath);
+ try (InputStream in = Files.newInputStream(manifestPath)) {
+ Manifest manifest = new Manifest(in);
+ assertEquals(manifest.getMainAttributes().getValue("Automatic-Module-Name"), "dev.failsafe.core");
+ }
+ }
+
+ private static Path moduleManifestPath() throws Exception {
+ Path outputDirectory = Paths.get(ModuleManifestTest.class.getProtectionDomain().getCodeSource().getLocation().toURI());
+ if ("test-classes".equals(outputDirectory.getFileName().toString())) {
+ outputDirectory = outputDirectory.getParent().resolve("classes");
+ }
+ return outputDirectory.resolve("META-INF/MANIFEST.MF");
+ }
+}
diff --git a/modules/okhttp/src/test/java/dev/failsafe/okhttp/ModuleManifestTest.java b/modules/okhttp/src/test/java/dev/failsafe/okhttp/ModuleManifestTest.java
new file mode 100644
index 00000000..d46815d1
--- /dev/null
+++ b/modules/okhttp/src/test/java/dev/failsafe/okhttp/ModuleManifestTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2026 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package dev.failsafe.okhttp;
+
+import org.testng.annotations.Test;
+
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.jar.Manifest;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+@Test
+public class ModuleManifestTest {
+ public void shouldExposeCorrectAutomaticModuleName() throws Exception {
+ Path manifestPath = moduleManifestPath();
+ assertTrue(Files.exists(manifestPath), "Module manifest should exist at " + manifestPath);
+ try (InputStream in = Files.newInputStream(manifestPath)) {
+ Manifest manifest = new Manifest(in);
+ assertEquals(manifest.getMainAttributes().getValue("Automatic-Module-Name"), "dev.failsafe.okhttp");
+ }
+ }
+
+ private static Path moduleManifestPath() throws Exception {
+ Path outputDirectory = Paths.get(ModuleManifestTest.class.getProtectionDomain().getCodeSource().getLocation().toURI());
+ if ("test-classes".equals(outputDirectory.getFileName().toString())) {
+ outputDirectory = outputDirectory.getParent().resolve("classes");
+ }
+ return outputDirectory.resolve("META-INF/MANIFEST.MF");
+ }
+}
diff --git a/modules/retrofit/src/test/java/dev/failsafe/retrofit/ModuleManifestTest.java b/modules/retrofit/src/test/java/dev/failsafe/retrofit/ModuleManifestTest.java
new file mode 100644
index 00000000..dfdebe12
--- /dev/null
+++ b/modules/retrofit/src/test/java/dev/failsafe/retrofit/ModuleManifestTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2026 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package dev.failsafe.retrofit;
+
+import org.testng.annotations.Test;
+
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.jar.Manifest;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+@Test
+public class ModuleManifestTest {
+ public void shouldExposeCorrectAutomaticModuleName() throws Exception {
+ Path manifestPath = moduleManifestPath();
+ assertTrue(Files.exists(manifestPath), "Module manifest should exist at " + manifestPath);
+ try (InputStream in = Files.newInputStream(manifestPath)) {
+ Manifest manifest = new Manifest(in);
+ assertEquals(manifest.getMainAttributes().getValue("Automatic-Module-Name"), "dev.failsafe.retrofit");
+ }
+ }
+
+ private static Path moduleManifestPath() throws Exception {
+ Path outputDirectory = Paths.get(ModuleManifestTest.class.getProtectionDomain().getCodeSource().getLocation().toURI());
+ if ("test-classes".equals(outputDirectory.getFileName().toString())) {
+ outputDirectory = outputDirectory.getParent().resolve("classes");
+ }
+ return outputDirectory.resolve("META-INF/MANIFEST.MF");
+ }
+}
diff --git a/pom.xml b/pom.xml
index 9d4776d5..6fa30551 100644
--- a/pom.xml
+++ b/pom.xml
@@ -170,7 +170,7 @@
${project.version}
Failsafe
dev.failsafe
- dev.failsafe
+ ${java.module.name}
dev.failsafe*;version=1.0
*