From fcd00ab517ee2d5cba1a48c2c402634384306cba Mon Sep 17 00:00:00 2001 From: Asbestosstar Date: Sun, 2 Apr 2023 04:03:17 -0600 Subject: [PATCH 1/6] Fixed some stuff, made a few small changes, removed Java 16 code Before it was not working because of multiple issues with the Classloader which I have fixed. Its not perfect, but it at least boots into the game which it could not before. I have also removed some of the Java 16 and newer specific code to work on Java 8 and 11. This updated version was able to Launch on TL with my RHEL9 system. It even said modded (which for some reason it did not on Vanilla FC despite having similar JSON). Anyhow I hope this works for you. --- .../java/xyz/spruceloader/trunk/Trunk.java | 19 ++++++++++++++-- .../spruceloader/trunk/TrunkClassLoader.java | 22 ++++++++++++++++--- .../trunk/api/TransformerManager.java | 7 ++++-- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/main/java/xyz/spruceloader/trunk/Trunk.java b/src/main/java/xyz/spruceloader/trunk/Trunk.java index 70b5bca..4a00804 100644 --- a/src/main/java/xyz/spruceloader/trunk/Trunk.java +++ b/src/main/java/xyz/spruceloader/trunk/Trunk.java @@ -11,6 +11,7 @@ import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; +import java.net.MalformedURLException; import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; @@ -29,17 +30,31 @@ public class Trunk { public Trunk() { setupClassPath(); - classLoader = new TrunkClassLoader(this, classPath.stream().map(path -> { + classLoader = new TrunkClassLoader(this, convertObjectsToURLs(classPath.stream().map(path -> { try { return path.toUri().toURL(); } catch (Throwable t) { return null; } - }).filter(Objects::nonNull).collect(Collectors.toList()).toArray(URL[]::new), getClass().getClassLoader()); + }).filter(Objects::nonNull).collect(Collectors.toList()).toArray()), getClass().getClassLoader()); + transformerManager = new TransformerManager(); Thread.currentThread().setContextClassLoader(classLoader); GLOBAL_PROPERTIES.put("trunk.development", DEVELOPMENT); } + // For Java 8 + public static URL[] convertObjectsToURLs(Object[] objects) { + URL[] urls = new URL[objects.length]; + for (int i = 0; i < objects.length; i++) { + try { + urls[i] = new URL(objects[i].toString()); + } catch (MalformedURLException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + return urls; + } public void initialize(ArgumentMap argMap, EnvSide env) { LOGGER.info("Launching Minecraft with Spruce Trunk"); diff --git a/src/main/java/xyz/spruceloader/trunk/TrunkClassLoader.java b/src/main/java/xyz/spruceloader/trunk/TrunkClassLoader.java index 55bd620..7fb577e 100644 --- a/src/main/java/xyz/spruceloader/trunk/TrunkClassLoader.java +++ b/src/main/java/xyz/spruceloader/trunk/TrunkClassLoader.java @@ -15,6 +15,7 @@ public class TrunkClassLoader extends URLClassLoader { private final List> filters = new ArrayList<>(); private final List> transformerFilters = new ArrayList<>(); private final ClassLoader fallback; + public String[] forbiddenPackages = {"java.", "jdk.", "javax.", "com.sun.","org.apache.logging.log4j.","com.fasterxml.jackson.","sun.", "javax.servlet."}; //denylisted packages, most required by Java, had to look to the LegacyLaunch ClassWrapper to seee that you needed you needed to use parent but then i realised the filter here does that with fallback but does not work, may add more later(like for other JDKs or denylisted files) some like com.sun (as a whole), Jakara, Jackson, and Log4j public TrunkClassLoader(Trunk trunk, URL[] urls, ClassLoader fallback) { super(urls, null); @@ -102,9 +103,23 @@ public Class loadClass(String name) throws ClassNotFoundException { } } + + /** + * Filters a class out from being transformed. + * + * @param className the class name. + */ + public boolean usesForbiddenPackage(String className) { + for (String packageName : forbiddenPackages) { +if (className.startsWith(packageName)) {return true;} + } +return false; + } + @Override protected Class findClass(String name) throws ClassNotFoundException { - try { +if (usesForbiddenPackage(name)) {return fallback.loadClass(name);} + try { byte[] data = transformClassBytes(name); if (data == null) throw new ClassNotFoundException(name); @@ -116,7 +131,8 @@ protected Class findClass(String name) throws ClassNotFoundException { } private byte[] transformClassBytes(String name) throws IOException { - return transformClassBytes(name, getClassBytes(name)); + // if(getClassBytes(name) != null) {System.out.println("getClassBytes is ok");}else {System.out.println("getClassBytes is nil"+name);} For testing + return transformClassBytes(name, getClassBytes(name)); } private byte[] transformClassBytes(String name, byte[] bytes) { @@ -130,7 +146,7 @@ private byte[] transformClassBytes(String name, byte[] bytes) { } private byte[] getClassBytes(String name) throws IOException { - try (InputStream in = getResourceAsStream(name)) { + try (InputStream in = getResourceAsStream(name.replace(".", "/").concat(".class"))) { //What you had before did not work and i had to take influence from Javas if (in == null) return null; diff --git a/src/main/java/xyz/spruceloader/trunk/api/TransformerManager.java b/src/main/java/xyz/spruceloader/trunk/api/TransformerManager.java index 304aae7..498f495 100644 --- a/src/main/java/xyz/spruceloader/trunk/api/TransformerManager.java +++ b/src/main/java/xyz/spruceloader/trunk/api/TransformerManager.java @@ -9,6 +9,7 @@ import java.util.Iterator; import java.util.List; import java.util.Objects; +import java.util.stream.Collectors; public class TransformerManager implements Iterable { @@ -44,9 +45,11 @@ private void handleFromNamespaces(ArgumentMap argMap, String argName, String pro argValues.forEach(name -> transformers.add(fromName(name))); String prop = System.getProperty(propName); + + + if (prop != null) { - List propValues = Arrays.stream(prop.split("/")).toList(); - if (!propValues.isEmpty()) + List propValues = Arrays.stream(prop.split("/")).collect(Collectors.toList()); if (!propValues.isEmpty()) propValues.forEach(name -> transformers.add(fromName(name))); } From e8a0c5fd27eb46676a367196700d4cae760d73e4 Mon Sep 17 00:00:00 2001 From: Asbestosstar Date: Sun, 2 Apr 2023 04:17:32 -0600 Subject: [PATCH 2/6] Update TrunkClassLoader.java --- src/main/java/xyz/spruceloader/trunk/TrunkClassLoader.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/xyz/spruceloader/trunk/TrunkClassLoader.java b/src/main/java/xyz/spruceloader/trunk/TrunkClassLoader.java index 7fb577e..79acd1b 100644 --- a/src/main/java/xyz/spruceloader/trunk/TrunkClassLoader.java +++ b/src/main/java/xyz/spruceloader/trunk/TrunkClassLoader.java @@ -15,7 +15,7 @@ public class TrunkClassLoader extends URLClassLoader { private final List> filters = new ArrayList<>(); private final List> transformerFilters = new ArrayList<>(); private final ClassLoader fallback; - public String[] forbiddenPackages = {"java.", "jdk.", "javax.", "com.sun.","org.apache.logging.log4j.","com.fasterxml.jackson.","sun.", "javax.servlet."}; //denylisted packages, most required by Java, had to look to the LegacyLaunch ClassWrapper to seee that you needed you needed to use parent but then i realised the filter here does that with fallback but does not work, may add more later(like for other JDKs or denylisted files) some like com.sun (as a whole), Jakara, Jackson, and Log4j + public String[] forbiddenPackages = {"java.", "jdk.", "javax.", "com.sun.","org.apache.logging.log4j.","com.fasterxml.jackson.","sun.", "javax.servlet."};//Re-evaluate if issues arrise public TrunkClassLoader(Trunk trunk, URL[] urls, ClassLoader fallback) { super(urls, null); @@ -131,7 +131,6 @@ protected Class findClass(String name) throws ClassNotFoundException { } private byte[] transformClassBytes(String name) throws IOException { - // if(getClassBytes(name) != null) {System.out.println("getClassBytes is ok");}else {System.out.println("getClassBytes is nil"+name);} For testing return transformClassBytes(name, getClassBytes(name)); } @@ -146,7 +145,7 @@ private byte[] transformClassBytes(String name, byte[] bytes) { } private byte[] getClassBytes(String name) throws IOException { - try (InputStream in = getResourceAsStream(name.replace(".", "/").concat(".class"))) { //What you had before did not work and i had to take influence from Javas + try (InputStream in = getResourceAsStream(name.replace(".", "/").concat(".class"))) { if (in == null) return null; From ec77d317d02a39a8fc1481530db2ed086aff2ff9 Mon Sep 17 00:00:00 2001 From: Asbestosstar Date: Sun, 2 Apr 2023 04:32:15 -0600 Subject: [PATCH 3/6] Update Trunk.java --- .../java/xyz/spruceloader/trunk/Trunk.java | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/src/main/java/xyz/spruceloader/trunk/Trunk.java b/src/main/java/xyz/spruceloader/trunk/Trunk.java index 4a00804..dbf41f3 100644 --- a/src/main/java/xyz/spruceloader/trunk/Trunk.java +++ b/src/main/java/xyz/spruceloader/trunk/Trunk.java @@ -30,31 +30,18 @@ public class Trunk { public Trunk() { setupClassPath(); - classLoader = new TrunkClassLoader(this, convertObjectsToURLs(classPath.stream().map(path -> { + classLoader = new TrunkClassLoader(this, classPath.stream().map(path -> { try { return path.toUri().toURL(); } catch (Throwable t) { return null; } - }).filter(Objects::nonNull).collect(Collectors.toList()).toArray()), getClass().getClassLoader()); - + }).filter(Objects::nonNull).collect(Collectors.toList()).toArray(new URL[0]), getClass().getClassLoader()); transformerManager = new TransformerManager(); Thread.currentThread().setContextClassLoader(classLoader); GLOBAL_PROPERTIES.put("trunk.development", DEVELOPMENT); } - // For Java 8 - public static URL[] convertObjectsToURLs(Object[] objects) { - URL[] urls = new URL[objects.length]; - for (int i = 0; i < objects.length; i++) { - try { - urls[i] = new URL(objects[i].toString()); - } catch (MalformedURLException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - return urls; - } + public void initialize(ArgumentMap argMap, EnvSide env) { LOGGER.info("Launching Minecraft with Spruce Trunk"); From 08918db33fd5350431ffe8d71be71ce86056256e Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sun, 2 Apr 2023 12:57:43 +0100 Subject: [PATCH 4/6] Use existing api, reformat --- .../spruceloader/trunk/TrunkClassLoader.java | 29 ++++++++----------- .../trunk/api/TransformerManager.java | 7 ++--- 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/src/main/java/xyz/spruceloader/trunk/TrunkClassLoader.java b/src/main/java/xyz/spruceloader/trunk/TrunkClassLoader.java index 79acd1b..f74c114 100644 --- a/src/main/java/xyz/spruceloader/trunk/TrunkClassLoader.java +++ b/src/main/java/xyz/spruceloader/trunk/TrunkClassLoader.java @@ -15,7 +15,16 @@ public class TrunkClassLoader extends URLClassLoader { private final List> filters = new ArrayList<>(); private final List> transformerFilters = new ArrayList<>(); private final ClassLoader fallback; - public String[] forbiddenPackages = {"java.", "jdk.", "javax.", "com.sun.","org.apache.logging.log4j.","com.fasterxml.jackson.","sun.", "javax.servlet."};//Re-evaluate if issues arrise + + { + addPackageLoadingFilter("java"); + addPackageLoadingFilter("jdk"); + addPackageLoadingFilter("javax"); + addPackageLoadingFilter("sun"); + addPackageLoadingFilter("com.sun"); + addPackageLoadingFilter("org.apache.logging.log4j"); + addPackageLoadingFilter("org.slf4j"); + } public TrunkClassLoader(Trunk trunk, URL[] urls, ClassLoader fallback) { super(urls, null); @@ -102,23 +111,9 @@ public Class loadClass(String name) throws ClassNotFoundException { return result; } } - - - /** - * Filters a class out from being transformed. - * - * @param className the class name. - */ - public boolean usesForbiddenPackage(String className) { - for (String packageName : forbiddenPackages) { -if (className.startsWith(packageName)) {return true;} - } -return false; - } @Override protected Class findClass(String name) throws ClassNotFoundException { -if (usesForbiddenPackage(name)) {return fallback.loadClass(name);} try { byte[] data = transformClassBytes(name); if (data == null) @@ -131,7 +126,7 @@ protected Class findClass(String name) throws ClassNotFoundException { } private byte[] transformClassBytes(String name) throws IOException { - return transformClassBytes(name, getClassBytes(name)); + return transformClassBytes(name, getClassBytes(name)); } private byte[] transformClassBytes(String name, byte[] bytes) { @@ -145,7 +140,7 @@ private byte[] transformClassBytes(String name, byte[] bytes) { } private byte[] getClassBytes(String name) throws IOException { - try (InputStream in = getResourceAsStream(name.replace(".", "/").concat(".class"))) { + try (InputStream in = getResourceAsStream(name.replace(".", "/").concat(".class"))) { if (in == null) return null; diff --git a/src/main/java/xyz/spruceloader/trunk/api/TransformerManager.java b/src/main/java/xyz/spruceloader/trunk/api/TransformerManager.java index 498f495..046d7f8 100644 --- a/src/main/java/xyz/spruceloader/trunk/api/TransformerManager.java +++ b/src/main/java/xyz/spruceloader/trunk/api/TransformerManager.java @@ -45,11 +45,10 @@ private void handleFromNamespaces(ArgumentMap argMap, String argName, String pro argValues.forEach(name -> transformers.add(fromName(name))); String prop = System.getProperty(propName); - - - + if (prop != null) { - List propValues = Arrays.stream(prop.split("/")).collect(Collectors.toList()); if (!propValues.isEmpty()) + List propValues = Arrays.stream(prop.split("/")).collect(Collectors.toList()); + if (!propValues.isEmpty()) propValues.forEach(name -> transformers.add(fromName(name))); } From 8d72e7d74109d6beb388270469d561ceb594124f Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sun, 2 Apr 2023 13:01:28 +0100 Subject: [PATCH 5/6] Use new `addDefaultLoadingFilters` --- .../xyz/spruceloader/trunk/MainClient.java | 5 +++- .../xyz/spruceloader/trunk/MainServer.java | 5 +++- .../spruceloader/trunk/TrunkClassLoader.java | 23 +++++++++++-------- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/main/java/xyz/spruceloader/trunk/MainClient.java b/src/main/java/xyz/spruceloader/trunk/MainClient.java index ace89ae..49a1a53 100644 --- a/src/main/java/xyz/spruceloader/trunk/MainClient.java +++ b/src/main/java/xyz/spruceloader/trunk/MainClient.java @@ -11,6 +11,9 @@ public static void main(String[] args) { argMap.putIfAbsent("accessToken", "None"); argMap.putIfAbsent("version", "Unknown"); argMap.putIfAbsent("gameDir", Paths.get(".").normalize().toString()); - new Trunk().initialize(argMap, EnvSide.CLIENT); + + Trunk trunk = new Trunk(); + trunk.initialize(argMap, EnvSide.CLIENT); + trunk.getClassLoader().addDefaultLoadingFilters(); } } diff --git a/src/main/java/xyz/spruceloader/trunk/MainServer.java b/src/main/java/xyz/spruceloader/trunk/MainServer.java index d2003b6..6ab3ff5 100644 --- a/src/main/java/xyz/spruceloader/trunk/MainServer.java +++ b/src/main/java/xyz/spruceloader/trunk/MainServer.java @@ -9,6 +9,9 @@ public static void main(String[] args) { argMap.remove("version"); argMap.remove("gameDir"); argMap.remove("assetsDir"); - new Trunk().initialize(argMap, EnvSide.SERVER); + + Trunk trunk = new Trunk(); + trunk.initialize(argMap, EnvSide.SERVER); + trunk.getClassLoader().addDefaultLoadingFilters(); } } diff --git a/src/main/java/xyz/spruceloader/trunk/TrunkClassLoader.java b/src/main/java/xyz/spruceloader/trunk/TrunkClassLoader.java index f74c114..00aaa26 100644 --- a/src/main/java/xyz/spruceloader/trunk/TrunkClassLoader.java +++ b/src/main/java/xyz/spruceloader/trunk/TrunkClassLoader.java @@ -16,16 +16,6 @@ public class TrunkClassLoader extends URLClassLoader { private final List> transformerFilters = new ArrayList<>(); private final ClassLoader fallback; - { - addPackageLoadingFilter("java"); - addPackageLoadingFilter("jdk"); - addPackageLoadingFilter("javax"); - addPackageLoadingFilter("sun"); - addPackageLoadingFilter("com.sun"); - addPackageLoadingFilter("org.apache.logging.log4j"); - addPackageLoadingFilter("org.slf4j"); - } - public TrunkClassLoader(Trunk trunk, URL[] urls, ClassLoader fallback) { super(urls, null); this.trunk = trunk; @@ -40,6 +30,19 @@ public void addPath(Path path) { } } + /** + * Adds the default loading filters. This is subject to change! + */ + public void addDefaultLoadingFilters() { + addPackageLoadingFilter("java"); + addPackageLoadingFilter("jdk"); + addPackageLoadingFilter("javax"); + addPackageLoadingFilter("sun"); + addPackageLoadingFilter("com.sun"); + addPackageLoadingFilter("org.apache.logging.log4j"); + addPackageLoadingFilter("org.slf4j"); + } + /** * Adds a loading filter - returns true to filter the class. * From eb9434dbcd9ee4588714bb6464e203b4f368fb5b Mon Sep 17 00:00:00 2001 From: TheKodeToad Date: Sun, 2 Apr 2023 13:02:26 +0100 Subject: [PATCH 6/6] Smol reformat --- src/main/java/xyz/spruceloader/trunk/TrunkClassLoader.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/xyz/spruceloader/trunk/TrunkClassLoader.java b/src/main/java/xyz/spruceloader/trunk/TrunkClassLoader.java index 00aaa26..f3c6652 100644 --- a/src/main/java/xyz/spruceloader/trunk/TrunkClassLoader.java +++ b/src/main/java/xyz/spruceloader/trunk/TrunkClassLoader.java @@ -114,10 +114,10 @@ public Class loadClass(String name) throws ClassNotFoundException { return result; } } - + @Override protected Class findClass(String name) throws ClassNotFoundException { - try { + try { byte[] data = transformClassBytes(name); if (data == null) throw new ClassNotFoundException(name);