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));
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;
}

View file

@ -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);
}
}

View file

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