Refactor agentmain

This commit is contained in:
yushijinhun 2019-01-20 18:35:38 +08:00
parent 8bd0f3b803
commit 6252c0502d
No known key found for this signature in database
GPG key ID: 5BC167F73EA558E4
3 changed files with 44 additions and 61 deletions

View file

@ -377,7 +377,7 @@ public final class AuthlibInjector {
Set<String> classNamesSet = new HashSet<>(Arrays.asList(classNames)); Set<String> classNamesSet = new HashSet<>(Arrays.asList(classNames));
Class<?>[] classes = Stream.of(instrumentation.getAllLoadedClasses()) Class<?>[] classes = Stream.of(instrumentation.getAllLoadedClasses())
.filter(clazz -> classNamesSet.contains(clazz.getName())) .filter(clazz -> classNamesSet.contains(clazz.getName()))
.filter(instrumentation::isModifiableClass) .filter(AuthlibInjector::canRetransformClass)
.toArray(Class[]::new); .toArray(Class[]::new);
if (classes.length > 0) { if (classes.length > 0) {
Logging.TRANSFORM.info("Attempt to retransform classes: " + Arrays.toString(classes)); 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() { public static ClassTransformer getClassTransformer() {
return classTransformer; return classTransformer;
} }

View file

@ -16,22 +16,15 @@
*/ */
package moe.yushi.authlibinjector.javaagent; 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.lang.instrument.Instrumentation;
import java.util.Arrays;
import java.util.logging.Level; import java.util.logging.Level;
import moe.yushi.authlibinjector.AuthlibInjector;
import moe.yushi.authlibinjector.InjectorInitializationException; import moe.yushi.authlibinjector.InjectorInitializationException;
import moe.yushi.authlibinjector.util.Logging; import moe.yushi.authlibinjector.util.Logging;
public class AuthlibInjectorPremain { public class AuthlibInjectorPremain {
static {
Logging.init();
}
public static void premain(String arg, Instrumentation instrumentation) { public static void premain(String arg, Instrumentation instrumentation) {
try { try {
initInjector(arg, instrumentation, false); 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); setupConfig(arg);
AuthlibInjector.bootstrap(instrumentation);
boolean retransformSupported = instrumentation.isRetransformClassesSupported(); if (retransform) {
boolean retransformEnabled = retransformSupported && needsRetransform; AuthlibInjector.retransformAllClasses();
bootstrap(instrumentation);
if (needsRetransform) {
if (retransformSupported) {
Logging.TRANSFORM.info("Start retransforming");
doRetransform(instrumentation);
} else {
Logging.TRANSFORM.warning("Retransform is not supported");
}
} }
} }
private static void setupConfig(String arg) { private static void setupConfig(String arg) {
if (arg != null && !arg.isEmpty()) { 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);
}
} }

View file

@ -43,9 +43,8 @@ public final class Logging {
private static Predicate<String> debugLoggerNamePredicate; private static Predicate<String> debugLoggerNamePredicate;
public static void init() { static {
debugLoggerNamePredicate = createDebugLoggerNamePredicate(); debugLoggerNamePredicate = createDebugLoggerNamePredicate();
initRootLogger(); initRootLogger();
} }