From 664c6108a5d0dadfc530aeeca9f478393b1e00d4 Mon Sep 17 00:00:00 2001 From: fszimnau Date: Wed, 19 Nov 2025 13:57:28 +0100 Subject: [PATCH] Learn to work when run via jar instead of via .class file directly --- .../java/de/szimnau/zeitlaeufer/Main.java | 47 +++++++++++++------ 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/src/main/java/de/szimnau/zeitlaeufer/Main.java b/src/main/java/de/szimnau/zeitlaeufer/Main.java index 85d1f01..0d78920 100644 --- a/src/main/java/de/szimnau/zeitlaeufer/Main.java +++ b/src/main/java/de/szimnau/zeitlaeufer/Main.java @@ -2,13 +2,17 @@ package de.szimnau.zeitlaeufer; import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStream; import java.io.InputStreamReader; import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLDecoder; import java.nio.charset.StandardCharsets; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; import java.util.stream.Collectors; import static de.szimnau.zeitlaeufer.tools.CommonTools.print; @@ -27,26 +31,41 @@ public class Main { private static void askParametersAndRun() throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { var br = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8)); - Map> classes = getAllrelevantClasses(); + SortedMap> classes = getAllrelevantClasses(); String printedClasses = classes.entrySet().stream() .map(e -> e.getKey() + ": " + e.getValue().getCanonicalName().substring(e.getValue().getCanonicalName().lastIndexOf('.') + 1)) .reduce("", (a, b) -> a + "\n" + b); print("Welcher Zeitläufer soll verwendet werden? " + printedClasses + "\n: "); var num = Integer.parseInt(br.readLine()); Class selectedClass = classes.get(num); - var mainMethod = selectedClass.getMethod("main", String[].class); + Method mainMethod = selectedClass.getMethod("main", String[].class); mainMethod.invoke(null, (Object) new String[0]); } - private static Map> getAllrelevantClasses() { - InputStream stream = ClassLoader.getSystemClassLoader() - .getResourceAsStream("de/szimnau/zeitlaeufer"); - var br = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8)); + private static SortedMap> getAllrelevantClasses() { + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + List fileNames = new ArrayList<>(); + URL jarUrl = classLoader.getResource("de/szimnau/zeitlaeufer"); + String path = jarUrl.getPath().split(":", 2)[1]; + String cleanPath = path.substring(0, path.lastIndexOf('!')); + Enumeration entries; + try (var jarFile = new JarFile(URLDecoder.decode(cleanPath, StandardCharsets.UTF_8))) { + entries = jarFile.entries(); + } catch (IOException e) { + throw new RuntimeException(e); + } + while (entries.hasMoreElements()) { + JarEntry entry = entries.nextElement(); + if (entry.isDirectory()) { + continue; + } + fileNames.add(entry.getName()); + } var increment = new AtomicInteger(); return Collections.unmodifiableSortedMap(new TreeMap<>( - br.lines() - .filter(line -> line.endsWith(".class") && !"Main.class".equals(line)) + fileNames.stream() + .filter(line -> line.endsWith(".class") && !line.endsWith("module-info.class") && !line.endsWith("Main.class")) .sorted() .map(Main::getClass) .filter(Objects::nonNull) @@ -61,23 +80,23 @@ public class Main { private static Class getClass(String className) { - return getClassForName(className.substring(0, className.lastIndexOf('.'))); + String classWithPath = className.replace("/", "."); + return getClassForName(classWithPath.substring(0, className.lastIndexOf('.'))); } private static Class getClassForName(String className) { - String fqnClassName = "de.szimnau.zeitlaeufer." + className; try { - return Class.forName(fqnClassName); + return Class.forName(className); } catch (ClassNotFoundException cnfe) { - println("ERROR: could not find Class for Name: de.szimnau.zeitlaeufer." + fqnClassName); + println("ERROR: could not find Class for Name: de.szimnau.zeitlaeufer." + className); } return null; } private static void parseParametersAndRun(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { - Class selectedClass = getClassForName(args[0]); + Class selectedClass = getClassForName("de.szimnau.zeitlaeufer." + args[0]); if (selectedClass == null) { System.exit(1); }