From 6f294d4dd76017ef8d468b418b2b0d6018943eb6 Mon Sep 17 00:00:00 2001 From: Walter Oggioni Date: Mon, 27 Jun 2022 17:21:23 +0800 Subject: [PATCH] fixed bug with resource handling --- build.gradle | 5 -- .../net/woggioni/envelope/MainRunner.java | 86 ------------------- .../java => main/java11}/module-info.java | 0 .../net/woggioni/envelope/MainRunner.java | 46 ++++++---- .../main/java/envelope/test/jpms/Main.java | 10 ++- .../src/main/java/module-info.java | 1 + .../envelope/test/jpms/someResource.xml | 39 +++++++++ .../main/java/envelope/test/legacy/Main.java | 10 ++- .../envelope/test/legacy/someResource.xml | 39 +++++++++ 9 files changed, 124 insertions(+), 112 deletions(-) delete mode 100644 launcher/src/java11/java/net/woggioni/envelope/MainRunner.java rename launcher/src/{java11/java => main/java11}/module-info.java (100%) create mode 100644 src/test/resources/test-project/jpms-executable/src/main/resources/envelope/test/jpms/someResource.xml create mode 100644 src/test/resources/test-project/legacy-executable/src/main/resources/envelope/test/legacy/someResource.xml diff --git a/build.gradle b/build.gradle index a9defb6..c0fdcba 100644 --- a/build.gradle +++ b/build.gradle @@ -105,11 +105,6 @@ publishing { url = publishMavenRepositoryUrl } } - publications { - maven(MavenPublication) { - from(components["java"]) - } - } } wrapper { diff --git a/launcher/src/java11/java/net/woggioni/envelope/MainRunner.java b/launcher/src/java11/java/net/woggioni/envelope/MainRunner.java deleted file mode 100644 index 7317629..0000000 --- a/launcher/src/java11/java/net/woggioni/envelope/MainRunner.java +++ /dev/null @@ -1,86 +0,0 @@ -package net.woggioni.envelope; - -import java.util.Map; -import java.util.TreeMap; -import java.lang.module.Configuration; -import java.lang.module.ModuleFinder; -import java.lang.module.ResolvedModule; -import java.lang.module.ModuleReference; -import java.util.Collections; -import java.util.List; -import java.util.ArrayList; -import java.util.Optional; -import java.util.Enumeration; -import java.util.function.Consumer; -import java.net.URL; -import java.net.URLClassLoader; - - -import lombok.SneakyThrows; - -import net.woggioni.xclassloader.ModuleClassLoader; -import net.woggioni.xclassloader.JarFileModuleFinder; -import net.woggioni.xclassloader.jar.JarFile; -import java.util.jar.JarEntry; - -class MainRunner { - - @SneakyThrows - static void run(JarFile currentJarFile, - String mainModuleName, - String mainClassName, - String librariesFolder, - Consumer> runner) { - if(mainModuleName == null) { - List jarList = new ArrayList<>(); - Enumeration entries = currentJarFile.entries(); - while(entries.hasMoreElements()) { - JarEntry entry = entries.nextElement(); - String name = entry.getName(); - if(!entry.isDirectory() && name.startsWith(librariesFolder) && name.endsWith(".jar")) { - jarList.add(currentJarFile.getNestedJarFile(entry).getUrl()); - } - } - try (URLClassLoader cl = new URLClassLoader(jarList.toArray(new URL[0]), ClassLoader.getSystemClassLoader().getParent())) { - Thread.currentThread().setContextClassLoader(cl); - runner.accept(cl.loadClass(mainClassName)); - } - } else { - List jarList = new ArrayList<>(); - Enumeration entries = currentJarFile.entries(); - while(entries.hasMoreElements()) { - JarEntry entry = entries.nextElement(); - String name = entry.getName(); - if(!entry.isDirectory() && name.startsWith("LIB-INF") && name.endsWith(".jar")) { - jarList.add(currentJarFile.getNestedJarFile(entry)); - } - } - ModuleLayer bootLayer = ModuleLayer.boot(); - Configuration bootConfiguration = bootLayer.configuration(); - Configuration cfg = bootConfiguration.resolve(new JarFileModuleFinder(jarList), ModuleFinder.of(), Collections.singletonList(mainModuleName)); - Map packageMap = new TreeMap<>(); - ModuleLayer.Controller controller = - ModuleLayer.defineModules(cfg, Collections.singletonList(ModuleLayer.boot()), moduleName -> { - ModuleReference modRef = cfg.findModule(moduleName) - .map(ResolvedModule::reference) - .orElseThrow(); - ClassLoader cl = new ModuleClassLoader( - Collections.unmodifiableMap(packageMap), - modRef - ); - for(String packageName : modRef.descriptor().packages()) { - packageMap.put(packageName, cl); - } - return cl; - }); - ModuleLayer layer = controller.layer(); - Module mainModule = layer.findModule(mainModuleName).orElseThrow( - () -> new IllegalStateException(String.format("Main module '%s' not found", mainModuleName))); - runner.accept(Optional.ofNullable(mainClassName) - .or(() -> mainModule.getDescriptor().mainClass()) - .map(className -> Class.forName(mainModule, className)) - .orElseThrow(() -> new IllegalStateException( - String.format("Unable to determine main class name for module '%s'", mainModule.getName())))); - } - } -} diff --git a/launcher/src/java11/java/module-info.java b/launcher/src/main/java11/module-info.java similarity index 100% rename from launcher/src/java11/java/module-info.java rename to launcher/src/main/java11/module-info.java diff --git a/launcher/src/main/java11/net/woggioni/envelope/MainRunner.java b/launcher/src/main/java11/net/woggioni/envelope/MainRunner.java index 7317629..a581b06 100644 --- a/launcher/src/main/java11/net/woggioni/envelope/MainRunner.java +++ b/launcher/src/main/java11/net/woggioni/envelope/MainRunner.java @@ -12,10 +12,11 @@ import java.util.ArrayList; import java.util.Optional; import java.util.Enumeration; import java.util.function.Consumer; +import java.net.URI; import java.net.URL; +import java.net.URLStreamHandler; import java.net.URLClassLoader; - import lombok.SneakyThrows; import net.woggioni.xclassloader.ModuleClassLoader; @@ -24,6 +25,10 @@ import net.woggioni.xclassloader.jar.JarFile; import java.util.jar.JarEntry; class MainRunner { + @SneakyThrows + private static final URL uri2url(URI uri, URLStreamHandler streamHandler) { + return new URL(null, uri.toString(), streamHandler); + } @SneakyThrows static void run(JarFile currentJarFile, @@ -57,30 +62,33 @@ class MainRunner { } ModuleLayer bootLayer = ModuleLayer.boot(); Configuration bootConfiguration = bootLayer.configuration(); - Configuration cfg = bootConfiguration.resolve(new JarFileModuleFinder(jarList), ModuleFinder.of(), Collections.singletonList(mainModuleName)); + JarFileModuleFinder jarFileModuleFinder = new JarFileModuleFinder(jarList); + Configuration cfg = bootConfiguration.resolve(jarFileModuleFinder, ModuleFinder.of(), Collections.singletonList(mainModuleName)); Map packageMap = new TreeMap<>(); ModuleLayer.Controller controller = - ModuleLayer.defineModules(cfg, Collections.singletonList(ModuleLayer.boot()), moduleName -> { - ModuleReference modRef = cfg.findModule(moduleName) - .map(ResolvedModule::reference) - .orElseThrow(); - ClassLoader cl = new ModuleClassLoader( - Collections.unmodifiableMap(packageMap), - modRef - ); - for(String packageName : modRef.descriptor().packages()) { - packageMap.put(packageName, cl); - } - return cl; - }); + ModuleLayer.defineModules(cfg, Collections.singletonList(ModuleLayer.boot()), moduleName -> { + ModuleReference modRef = cfg.findModule(moduleName) + .map(ResolvedModule::reference) + .orElseThrow(); + URLStreamHandler streamHandler = jarFileModuleFinder.getStreamHandlerForModule(moduleName); + ClassLoader cl = new ModuleClassLoader( + Collections.unmodifiableMap(packageMap), + modRef, + (URI uri) -> uri2url(uri, streamHandler) + ); + for(String packageName : modRef.descriptor().packages()) { + packageMap.put(packageName, cl); + } + return cl; + }); ModuleLayer layer = controller.layer(); Module mainModule = layer.findModule(mainModuleName).orElseThrow( () -> new IllegalStateException(String.format("Main module '%s' not found", mainModuleName))); runner.accept(Optional.ofNullable(mainClassName) - .or(() -> mainModule.getDescriptor().mainClass()) - .map(className -> Class.forName(mainModule, className)) - .orElseThrow(() -> new IllegalStateException( - String.format("Unable to determine main class name for module '%s'", mainModule.getName())))); + .or(() -> mainModule.getDescriptor().mainClass()) + .map(className -> Class.forName(mainModule, className)) + .orElseThrow(() -> new IllegalStateException( + String.format("Unable to determine main class name for module '%s'", mainModule.getName())))); } } } diff --git a/src/test/resources/test-project/jpms-executable/src/main/java/envelope/test/jpms/Main.java b/src/test/resources/test-project/jpms-executable/src/main/java/envelope/test/jpms/Main.java index 0c1b6c5..8966fae 100644 --- a/src/test/resources/test-project/jpms-executable/src/main/java/envelope/test/jpms/Main.java +++ b/src/test/resources/test-project/jpms-executable/src/main/java/envelope/test/jpms/Main.java @@ -1,10 +1,18 @@ package envelope.test.jpms; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; public class Main { - public static void main(String[] args) throws MalformedURLException { + public static void main(String[] args) throws Exception { new URL("https://www.google.com"); System.out.println("Hello World!!"); + URL url = Main.class.getResource("/envelope/test/jpms/someResource.xml"); + DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + try(InputStream is = url.openStream()) { + builder.parse(is); + } } } \ No newline at end of file diff --git a/src/test/resources/test-project/jpms-executable/src/main/java/module-info.java b/src/test/resources/test-project/jpms-executable/src/main/java/module-info.java index c6fcfaa..52512c6 100644 --- a/src/test/resources/test-project/jpms-executable/src/main/java/module-info.java +++ b/src/test/resources/test-project/jpms-executable/src/main/java/module-info.java @@ -1,3 +1,4 @@ module envelope.test.jpms { + requires java.xml; exports envelope.test.jpms; } \ No newline at end of file diff --git a/src/test/resources/test-project/jpms-executable/src/main/resources/envelope/test/jpms/someResource.xml b/src/test/resources/test-project/jpms-executable/src/main/resources/envelope/test/jpms/someResource.xml new file mode 100644 index 0000000..2d28b50 --- /dev/null +++ b/src/test/resources/test-project/jpms-executable/src/main/resources/envelope/test/jpms/someResource.xml @@ -0,0 +1,39 @@ + + + + Convert number to string + Examp1.EXE + 1 + One + + + Find succeeding characters + Examp2.EXE + abc + def + + + Convert multiple numbers to strings + Examp2.EXE /Verbose + 123 + One Two Three + + + Find correlated key + Examp3.EXE + a1 + b1 + + + Count characters + FinalExamp.EXE + This is a test + 14 + + + Another Test + Examp2.EXE + Test Input + 10 + + diff --git a/src/test/resources/test-project/legacy-executable/src/main/java/envelope/test/legacy/Main.java b/src/test/resources/test-project/legacy-executable/src/main/java/envelope/test/legacy/Main.java index 1f2d1c7..0301b80 100644 --- a/src/test/resources/test-project/legacy-executable/src/main/java/envelope/test/legacy/Main.java +++ b/src/test/resources/test-project/legacy-executable/src/main/java/envelope/test/legacy/Main.java @@ -1,10 +1,18 @@ package envelope.test.legacy; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.DocumentBuilder; +import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; public class Main { - public static void main(String[] args) throws MalformedURLException { + public static void main(String[] args) throws Exception { new URL("https://www.google.com"); System.out.println("Hello World!!"); + URL url = Main.class.getResource("someResource.xml"); + DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + try(InputStream is = url.openStream()) { + builder.parse(is); + } } } \ No newline at end of file diff --git a/src/test/resources/test-project/legacy-executable/src/main/resources/envelope/test/legacy/someResource.xml b/src/test/resources/test-project/legacy-executable/src/main/resources/envelope/test/legacy/someResource.xml new file mode 100644 index 0000000..2d28b50 --- /dev/null +++ b/src/test/resources/test-project/legacy-executable/src/main/resources/envelope/test/legacy/someResource.xml @@ -0,0 +1,39 @@ + + + + Convert number to string + Examp1.EXE + 1 + One + + + Find succeeding characters + Examp2.EXE + abc + def + + + Convert multiple numbers to strings + Examp2.EXE /Verbose + 123 + One Two Three + + + Find correlated key + Examp3.EXE + a1 + b1 + + + Count characters + FinalExamp.EXE + This is a test + 14 + + + Another Test + Examp2.EXE + Test Input + 10 + +