From f97039358f2e195a6acec93b1493c876446a3cf3 Mon Sep 17 00:00:00 2001 From: shartte Date: Thu, 30 May 2024 19:37:17 +0200 Subject: [PATCH] Always load UnionURLStreamHandler even in non-modular environments (#74) The use case for this is the use of SJH inside of FML unit tests where SJH itself was not loaded as a module. It is perfectly capable of being used, but fails due to the `union` protocol handler not being loaded. This change makes SJH always load its own protocol handler regardless of layer and supports the extension point in non modular environments too. As an aside: The extension point does not seem to be used by anyone else according to a GH search and can likely be deprecated/removed at some point. --- .../java/cpw/mods/cl/ModularURLHandler.java | 24 +++++++++++++++---- src/main/java/module-info.java | 2 -- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/main/java/cpw/mods/cl/ModularURLHandler.java b/src/main/java/cpw/mods/cl/ModularURLHandler.java index e365a11..bdc5293 100644 --- a/src/main/java/cpw/mods/cl/ModularURLHandler.java +++ b/src/main/java/cpw/mods/cl/ModularURLHandler.java @@ -1,5 +1,7 @@ package cpw.mods.cl; +import org.jetbrains.annotations.Nullable; + import java.io.IOException; import java.io.InputStream; import java.io.UncheckedIOException; @@ -7,24 +9,36 @@ import java.net.URLConnection; import java.net.URLStreamHandler; import java.net.URLStreamHandlerFactory; +import java.util.HashMap; import java.util.Map; import java.util.ServiceLoader; import java.util.function.Function; -import java.util.stream.Collectors; public class ModularURLHandler implements URLStreamHandlerFactory { public static final ModularURLHandler INSTANCE = new ModularURLHandler(); private Map handlers; - public static void initFrom(ModuleLayer layer) { + public static void initFrom(@Nullable ModuleLayer layer) { + var handlers = new HashMap(); + + // This handler is required for SJH to work. + var unionHandler = new UnionURLStreamHandler(); + handlers.put(unionHandler.protocol(), unionHandler); + if (layer == null) { - INSTANCE.handlers = null; + // Support non-modular environment for testing purposes + ServiceLoader.load(IURLProvider.class).stream() + .map(ServiceLoader.Provider::get) + .forEach(handler -> handlers.putIfAbsent(handler.protocol(), handler)); } else { - INSTANCE.handlers = ServiceLoader.load(layer, IURLProvider.class).stream() + ServiceLoader.load(layer, IURLProvider.class).stream() .map(ServiceLoader.Provider::get) - .collect(Collectors.toMap(IURLProvider::protocol, Function.identity())); + .forEach(handler -> handlers.putIfAbsent(handler.protocol(), handler)); } + + INSTANCE.handlers = Map.copyOf(handlers); } + @Override public URLStreamHandler createURLStreamHandler(final String protocol) { if (handlers == null) return null; diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 6ad8598..0c1bb31 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -1,5 +1,4 @@ import cpw.mods.cl.ModularURLHandler; -import cpw.mods.cl.UnionURLStreamHandler; import cpw.mods.niofs.union.UnionFileSystemProvider; module cpw.mods.securejarhandler { @@ -14,5 +13,4 @@ requires static org.jetbrains.annotations; provides java.nio.file.spi.FileSystemProvider with UnionFileSystemProvider; uses cpw.mods.cl.ModularURLHandler.IURLProvider; - provides ModularURLHandler.IURLProvider with UnionURLStreamHandler; }