From 33e3c394b9dfbfae0f3e5bd6db903fa3d8609cc8 Mon Sep 17 00:00:00 2001 From: syeyoung Date: Sat, 19 Nov 2022 18:48:43 +0900 Subject: - Inject classes into LaunchClassLoader so that mod class could be used at other places. Signed-off-by: syeyoung --- .../launcher/coremod/EventBusTransformer.java | 2 +- .../launcher/loader/DGClassLoader.java | 23 +++++++++++++++++++++- .../dungeonsguide/launcher/loader/JarLoader.java | 6 ++++-- .../dungeonsguide/launcher/loader/LocalLoader.java | 6 ++++-- .../launcher/loader/RemoteLoader.java | 6 ++++-- 5 files changed, 35 insertions(+), 8 deletions(-) (limited to 'loader/src/main/java') diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/coremod/EventBusTransformer.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/coremod/EventBusTransformer.java index bcfa0cef..f0e9a91b 100644 --- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/coremod/EventBusTransformer.java +++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/coremod/EventBusTransformer.java @@ -7,8 +7,8 @@ import org.objectweb.asm.tree.*; import java.util.Iterator; +// I still need this with classloader injection, because of the cache in ASMEventHandler. public class EventBusTransformer implements IClassTransformer { - @Override public byte[] transform(String name, String transformedName, byte[] basicClass) { if (name.equals("net.minecraftforge.fml.common.eventhandler.EventBus")) { diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/DGClassLoader.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/DGClassLoader.java index a2f1a784..4a902d8d 100644 --- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/DGClassLoader.java +++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/DGClassLoader.java @@ -1,16 +1,26 @@ package kr.syeyoung.dungeonsguide.launcher.loader; import kr.syeyoung.dungeonsguide.launcher.events.DGAwareEventSubscriptionTransformer; +import net.minecraft.launchwrapper.LaunchClassLoader; +import net.minecraftforge.fml.relauncher.ReflectionHelper; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; public abstract class DGClassLoader extends ClassLoader implements ByteStreamURLHandler.InputStreamGenerator{ DGAwareEventSubscriptionTransformer eventSubscriptionTransformer = new DGAwareEventSubscriptionTransformer(this); - public DGClassLoader(ClassLoader parent) { + + private Map> launchClassLoaderCacheMap; + private Set classesILoaded= new HashSet<>(); + public DGClassLoader(LaunchClassLoader parent) { super(parent); + + this.launchClassLoaderCacheMap = ReflectionHelper.getPrivateValue(LaunchClassLoader.class, parent, "cachedClasses"); } public Class loadClass(String name, boolean resolve) @@ -25,6 +35,11 @@ public abstract class DGClassLoader extends ClassLoader implements ByteStreamURL long t0 = System.nanoTime(); c = findClass(name); + if (c != null) { + launchClassLoaderCacheMap.put(name, c); + classesILoaded.add(name); + } + sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t0); sun.misc.PerfCounter.getFindClasses().increment(); } @@ -46,6 +61,12 @@ public abstract class DGClassLoader extends ClassLoader implements ByteStreamURL } } + public void cleanup() { + for (String s : classesILoaded) { + launchClassLoaderCacheMap.remove(s); + } + } + @Override protected Class findClass(String name) throws ClassNotFoundException { byte[] res; diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/JarLoader.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/JarLoader.java index df450af6..608238a1 100644 --- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/JarLoader.java +++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/JarLoader.java @@ -21,6 +21,7 @@ package kr.syeyoung.dungeonsguide.launcher.loader; import kr.syeyoung.dungeonsguide.launcher.DGInterface; import kr.syeyoung.dungeonsguide.launcher.exceptions.DungeonsGuideLoadingException; import kr.syeyoung.dungeonsguide.launcher.exceptions.DungeonsGuideUnloadingException; +import net.minecraft.launchwrapper.LaunchClassLoader; import org.apache.commons.io.IOUtils; import java.io.ByteArrayInputStream; @@ -41,7 +42,7 @@ public class JarLoader implements IDGLoader { private boolean loaded; public static class JarClassLoader extends DGClassLoader { - public JarClassLoader(ClassLoader parent, ZipInputStream zipInputStream) throws IOException { + public JarClassLoader(LaunchClassLoader parent, ZipInputStream zipInputStream) throws IOException { super(parent); ZipEntry zipEntry; @@ -72,7 +73,7 @@ public class JarLoader implements IDGLoader { if (dgInterface != null) throw new IllegalStateException("Already loaded"); try { - classLoader = new JarClassLoader(this.getClass().getClassLoader(), new ZipInputStream(JarLoader.class.getResourceAsStream("/mod.jar"))); + classLoader = new JarClassLoader((LaunchClassLoader) this.getClass().getClassLoader(), new ZipInputStream(JarLoader.class.getResourceAsStream("/mod.jar"))); dgInterface = (DGInterface) classLoader.loadClass("kr.syeyoung.dungeonsguide.mod.DungeonsGuide", true).newInstance(); phantomReference = new PhantomReference<>(classLoader, refQueue); @@ -94,6 +95,7 @@ public class JarLoader implements IDGLoader { } catch (Exception e) { throw new DungeonsGuideUnloadingException(e); } + classLoader.cleanup(); classLoader = null; dgInterface = null; System.gc();// pls do diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/LocalLoader.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/LocalLoader.java index 005a6005..1264c7ee 100644 --- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/LocalLoader.java +++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/LocalLoader.java @@ -21,6 +21,7 @@ package kr.syeyoung.dungeonsguide.launcher.loader; import kr.syeyoung.dungeonsguide.launcher.DGInterface; import kr.syeyoung.dungeonsguide.launcher.exceptions.DungeonsGuideLoadingException; import kr.syeyoung.dungeonsguide.launcher.exceptions.DungeonsGuideUnloadingException; +import net.minecraft.launchwrapper.LaunchClassLoader; import org.apache.commons.io.IOUtils; import java.io.BufferedInputStream; @@ -39,7 +40,7 @@ public class LocalLoader implements IDGLoader { private boolean loaded; public static class LocalClassLoader extends DGClassLoader { - public LocalClassLoader(ClassLoader parent) throws IOException { + public LocalClassLoader(LaunchClassLoader parent) throws IOException { super(parent); } @Override @@ -64,7 +65,7 @@ public class LocalLoader implements IDGLoader { if (dgInterface != null) throw new IllegalStateException("Already loaded"); try { - classLoader = new LocalClassLoader(this.getClass().getClassLoader()); + classLoader = new LocalClassLoader((LaunchClassLoader) this.getClass().getClassLoader()); dgInterface = (DGInterface) classLoader.loadClass("kr.syeyoung.dungeonsguide.mod.DungeonsGuide", true).newInstance(); phantomReference = new PhantomReference<>(classLoader, refQueue); @@ -86,6 +87,7 @@ public class LocalLoader implements IDGLoader { } catch (Exception e) { throw new DungeonsGuideUnloadingException(e); } + classLoader.cleanup(); classLoader = null; dgInterface = null; System.gc();// pls do diff --git a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/RemoteLoader.java b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/RemoteLoader.java index 575a31b3..b3e1a77e 100644 --- a/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/RemoteLoader.java +++ b/loader/src/main/java/kr/syeyoung/dungeonsguide/launcher/loader/RemoteLoader.java @@ -25,6 +25,7 @@ import kr.syeyoung.dungeonsguide.launcher.exceptions.DungeonsGuideLoadingExcepti import kr.syeyoung.dungeonsguide.launcher.exceptions.InvalidSignatureException; import kr.syeyoung.dungeonsguide.launcher.exceptions.NoVersionFoundException; import kr.syeyoung.dungeonsguide.launcher.exceptions.DungeonsGuideUnloadingException; +import net.minecraft.launchwrapper.LaunchClassLoader; import org.apache.commons.io.IOUtils; import java.io.ByteArrayInputStream; @@ -52,7 +53,7 @@ public class RemoteLoader implements IDGLoader { public static class JarClassLoader extends DGClassLoader { - public JarClassLoader(ClassLoader parent, ZipInputStream zipInputStream) throws IOException { + public JarClassLoader(LaunchClassLoader parent, ZipInputStream zipInputStream) throws IOException { super(parent); ZipEntry zipEntry; @@ -105,7 +106,7 @@ public class RemoteLoader implements IDGLoader { throw new InvalidSignatureException(target, "Invalid Signature Version: " + version); } - classLoader = new JarClassLoader(this.getClass().getClassLoader(), new ZipInputStream(new ByteArrayInputStream(mod))); + classLoader = new JarClassLoader((LaunchClassLoader) this.getClass().getClassLoader(), new ZipInputStream(new ByteArrayInputStream(mod))); dgInterface = (DGInterface) classLoader.loadClass("kr.syeyoung.dungeonsguide.mod.DungeonsGuide", true).newInstance(); phantomReference = new PhantomReference<>(classLoader, refQueue); @@ -127,6 +128,7 @@ public class RemoteLoader implements IDGLoader { } catch (Exception e) { throw new DungeonsGuideUnloadingException(e); } + classLoader.cleanup(); classLoader = null; dgInterface = null; -- cgit