Compare commits

...

4 Commits

Author SHA1 Message Date
fszimnau
dc690f3350 - enable running project 'quck' - run the jar in the dist directory directly
- enable running any class directly without needing a jar in the first place
2025-12-03 15:13:16 +01:00
fszimnau
8be9cf81d7 work with jar file before closing it 2025-11-25 09:21:53 +01:00
fszimnau
7df22a2d1f improved/ added error messages 2025-11-20 09:07:29 +01:00
fszimnau
664c6108a5 Learn to work when run via jar instead of via .class file directly 2025-11-19 13:57:28 +01:00
2 changed files with 79 additions and 21 deletions

View File

@@ -2,13 +2,25 @@
set -uo pipefail
# when executed as executable file in "git for windows" bash some things won't work, so always run with prefixed command
originDir=$(pwd);
cd /g/zeitlaeufer/;
tmpDir="/tmp/zeitlaeufer_$RANDOM";
mkdir $tmpDir;
cp dist/zeitlaeufer.jar $tmpDir;
cd $originDir;
jarDir=/g/zeitlaeufer/dist/;
if [[ $# == 0 || ($1 != -quick && $1 != -class) ]]; then
tmpDir=/tmp/zeitlaeufer_$RANDOM;
mkdir $tmpDir;
cp ${jarDir}zeitlaeufer.jar $tmpDir;
jarDir=$tmpDir;
elif [[ $1 == -quick ]]; then
shift;
elif [[ $1 == -class ]]; then
originDir=$(pwd);
cd /g/zeitlaeufer/target/;
java de.szimnau.zeitlaeufer.$2;
exitCode=$?;
cd originDir;
return $exitCode;
fi
# java -jar $tmpDir/zeitlaeufer.jar $@;
# -p <=> --module-path | -m <=> --module
java --module-path $tmpDir/zeitlaeufer.jar --module zeitlaeufer $@;
rm -r $tmpDir;
java --module-path $jarDir/zeitlaeufer.jar --module zeitlaeufer $@;
if [[ -n $tmpDir && -d $tmpDir ]]; then
rm -r $tmpDir;
fi

View File

@@ -5,10 +5,15 @@ 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 +32,34 @@ public class Main {
private static void askParametersAndRun() throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
var br = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8));
Map<Integer, Class<?>> classes = getAllrelevantClasses();
SortedMap<Integer, Class<?>> 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<Integer, Class<?>> getAllrelevantClasses() {
InputStream stream = ClassLoader.getSystemClassLoader()
.getResourceAsStream("de/szimnau/zeitlaeufer");
var br = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8));
private static SortedMap<Integer, Class<?>> getAllrelevantClasses() {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
URL resourceUrl = classLoader.getResource("de/szimnau/zeitlaeufer");
if (resourceUrl == null) {
throw new RuntimeException("Kann ausführbare Klassen nicht eruieren, da keine Ressource \"de/szimnau/zeitlaeufer\" verfügbar.");
}
Set<String> fileNames;
if (resourceUrl.getPath().contains(".jar")) {
fileNames = getFileNamesStreamFromJar(resourceUrl);
} else {
fileNames = getFileNamesStreamFromPackage(resourceUrl);
}
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)
@@ -60,24 +73,57 @@ public class Main {
}
private static Set<String> getFileNamesStreamFromJar(URL resourceUrl) {
Set<String> fileNames = new HashSet<>();
String path = resourceUrl.getPath().split(":", 2)[1];
String cleanPath = path.substring(0, path.lastIndexOf('!'));
Enumeration<JarEntry> entries;
try (var jarFile = new JarFile(URLDecoder.decode(cleanPath, StandardCharsets.UTF_8))) {
entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
if (entry.isDirectory()) {
continue;
}
fileNames.add(entry.getName());
}
} catch (IOException e) {
throw new RuntimeException("Kann JAR-Datei zwecks Reflection nicht öffnen:", e);
}
return fileNames;
}
private static Set<String> getFileNamesStreamFromPackage(URL resourceUrl) {
try (InputStream stream = resourceUrl.openStream();
var br = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) {
return br.lines()
.map(line -> "de/szimnau/zeitlaeufer." + line)
.collect(Collectors.toSet());
} catch (IOException e) {
throw new RuntimeException("ausführbare Klassen nicht eruieren, da Ressource " + resourceUrl + " nicht auslesbar.", e);
}
}
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);
}