From 6252c0502dd4948f440bc928155c90da5314a792 Mon Sep 17 00:00:00 2001 From: yushijinhun Date: Sun, 20 Jan 2019 18:35:38 +0800 Subject: [PATCH] Refactor agentmain --- .../authlibinjector/AuthlibInjector.java | 38 ++++++++++- .../javaagent/AuthlibInjectorPremain.java | 64 ++----------------- .../yushi/authlibinjector/util/Logging.java | 3 +- 3 files changed, 44 insertions(+), 61 deletions(-) diff --git a/src/main/java/moe/yushi/authlibinjector/AuthlibInjector.java b/src/main/java/moe/yushi/authlibinjector/AuthlibInjector.java index 545e2bd..46a33b4 100644 --- a/src/main/java/moe/yushi/authlibinjector/AuthlibInjector.java +++ b/src/main/java/moe/yushi/authlibinjector/AuthlibInjector.java @@ -377,7 +377,7 @@ public final class AuthlibInjector { Set classNamesSet = new HashSet<>(Arrays.asList(classNames)); Class[] classes = Stream.of(instrumentation.getAllLoadedClasses()) .filter(clazz -> classNamesSet.contains(clazz.getName())) - .filter(instrumentation::isModifiableClass) + .filter(AuthlibInjector::canRetransformClass) .toArray(Class[]::new); if (classes.length > 0) { Logging.TRANSFORM.info("Attempt to retransform classes: " + Arrays.toString(classes)); @@ -389,6 +389,42 @@ public final class AuthlibInjector { } } + public static void retransformAllClasses() { + if (!retransformSupported) { + return; + } + Logging.TRANSFORM.info("Attempt to retransform all classes"); + long t0 = System.currentTimeMillis(); + + Class[] classes = Stream.of(instrumentation.getAllLoadedClasses()) + .filter(AuthlibInjector::canRetransformClass) + .toArray(Class[]::new); + if (classes.length > 0) { + try { + instrumentation.retransformClasses(classes); + } catch (Throwable e) { + Logging.TRANSFORM.log(Level.WARNING, "Failed to retransform", e); + return; + } + } + + long t1 = System.currentTimeMillis(); + Logging.TRANSFORM.info("Retransformed " + classes.length + " classes in " + (t1 - t0) + "ms"); + } + + private static boolean canRetransformClass(Class clazz) { + if (!instrumentation.isModifiableClass(clazz)) { + return false; + } + String name = clazz.getName(); + for (String prefix : nonTransformablePackages) { + if (name.startsWith(prefix)) { + return false; + } + } + return true; + } + public static ClassTransformer getClassTransformer() { return classTransformer; } diff --git a/src/main/java/moe/yushi/authlibinjector/javaagent/AuthlibInjectorPremain.java b/src/main/java/moe/yushi/authlibinjector/javaagent/AuthlibInjectorPremain.java index 7327b9c..8086aa8 100644 --- a/src/main/java/moe/yushi/authlibinjector/javaagent/AuthlibInjectorPremain.java +++ b/src/main/java/moe/yushi/authlibinjector/javaagent/AuthlibInjectorPremain.java @@ -16,22 +16,15 @@ */ package moe.yushi.authlibinjector.javaagent; -import static moe.yushi.authlibinjector.AuthlibInjector.PROP_API_ROOT; -import static moe.yushi.authlibinjector.AuthlibInjector.bootstrap; -import static moe.yushi.authlibinjector.AuthlibInjector.nonTransformablePackages; import java.lang.instrument.Instrumentation; -import java.util.Arrays; import java.util.logging.Level; +import moe.yushi.authlibinjector.AuthlibInjector; import moe.yushi.authlibinjector.InjectorInitializationException; import moe.yushi.authlibinjector.util.Logging; public class AuthlibInjectorPremain { - static { - Logging.init(); - } - public static void premain(String arg, Instrumentation instrumentation) { try { initInjector(arg, instrumentation, false); @@ -55,63 +48,18 @@ public class AuthlibInjectorPremain { } } - public static void initInjector(String arg, Instrumentation instrumentation, boolean needsRetransform) { + public static void initInjector(String arg, Instrumentation instrumentation, boolean retransform) { setupConfig(arg); + AuthlibInjector.bootstrap(instrumentation); - boolean retransformSupported = instrumentation.isRetransformClassesSupported(); - boolean retransformEnabled = retransformSupported && needsRetransform; - bootstrap(instrumentation); - - if (needsRetransform) { - if (retransformSupported) { - Logging.TRANSFORM.info("Start retransforming"); - doRetransform(instrumentation); - } else { - Logging.TRANSFORM.warning("Retransform is not supported"); - } + if (retransform) { + AuthlibInjector.retransformAllClasses(); } } private static void setupConfig(String arg) { if (arg != null && !arg.isEmpty()) { - System.setProperty(PROP_API_ROOT, arg); + System.setProperty(AuthlibInjector.PROP_API_ROOT, arg); } } - - private static void doRetransform(Instrumentation instrumentation) { - try { - long t0 = System.currentTimeMillis(); - Class[] classToRetransform = getClassesToRetransform(instrumentation); - if (classToRetransform.length > 0) { - instrumentation.retransformClasses(classToRetransform); - } - long t1 = System.currentTimeMillis(); - Logging.TRANSFORM.info("Retransform finished in " + (t1 - t0) + "ms"); - } catch (Throwable e) { - Logging.TRANSFORM.log(Level.SEVERE, "Failed to retransform", e); - } - } - - private static Class[] getClassesToRetransform(Instrumentation instrumentation) { - Class[] loadedClasses = instrumentation.getAllLoadedClasses(); - Class[] dest = new Class[loadedClasses.length]; - int idx = 0; - for (Class clazz : loadedClasses) { - if (instrumentation.isModifiableClass(clazz)) { - boolean toRetransform = true; - for (String nonTransformablePackage : nonTransformablePackages) { - if (clazz.getName().startsWith(nonTransformablePackage)) { - toRetransform = false; - break; - } - } - if (toRetransform) { - dest[idx++] = clazz; - } - } - } - Logging.TRANSFORM.fine("Loaded " + loadedClasses.length + " classes, " + idx + " to retransform"); - return Arrays.copyOf(dest, idx); - } - } diff --git a/src/main/java/moe/yushi/authlibinjector/util/Logging.java b/src/main/java/moe/yushi/authlibinjector/util/Logging.java index 856e297..3e0bc7e 100644 --- a/src/main/java/moe/yushi/authlibinjector/util/Logging.java +++ b/src/main/java/moe/yushi/authlibinjector/util/Logging.java @@ -43,9 +43,8 @@ public final class Logging { private static Predicate debugLoggerNamePredicate; - public static void init() { + static { debugLoggerNamePredicate = createDebugLoggerNamePredicate(); - initRootLogger(); }