下面列出了org.objectweb.asm.ClassWriter#COMPUTE_MAXS 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private static void loadAdaptedClass(File file,
Map<String, String> typeMappnigs, Map<Class<?>, byte[]> result)
throws IOException, ClassNotFoundException {
ClassWriter writer = new ClassWriter(
ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
TestClassAdapter adapter = new TestClassAdapter(writer, typeMappnigs);
InputStream in = new FileInputStream(file);
try {
new ClassReader(in).accept(adapter, ClassReader.EXPAND_FRAMES);
} finally {
try {
in.close();
} catch (IOException e) {
// Ignore.
}
}
byte[] bytes = writer.toByteArray();
String className = adapter.getClassName().replace('/', '.');
result.put(Class.forName(className), bytes); // FIXME: ClassLoader...
}
@Override
public byte[] transform(String s, String s1, byte[] bytes) {
LogUtil.startClass("GuiIngameForge (%s)", Names.guiIngameForge.getName());
ClassReader reader = new ClassReader(bytes);
ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS);
ClassPatcher visitor = new ClassPatcher(writer);
reader.accept(visitor, 0);
LogUtil.endClass();
return writer.toByteArray();
}
@Override
public byte[] transform(String s, String s1, byte[] bytes) {
LogUtil.startClass("GuiEditSign (%s)", Names.guiEditSign.getName());
ClassReader reader = new ClassReader(bytes);
ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS);
ClassPatcher visitor = new ClassPatcher(writer);
reader.accept(visitor, 0);
LogUtil.endClass();
return writer.toByteArray();
}
@Override
public byte[] transform(String s, String s1, byte[] bytes) {
LogUtil.startClass("Minecraft (%s)", Names.minecraft.getName());
ClassReader reader = new ClassReader(bytes);
ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS);
ClassPatcher visitor = new ClassPatcher(writer);
reader.accept(visitor, 0);
LogUtil.endClass();
return writer.toByteArray();
}
@Override
public byte[] transform(String s, String s1, byte[] bytes) {
LogUtil.startClass("GuiTextfield (%s)", Names.guiTextfield.getName());
ClassReader reader = new ClassReader(bytes);
ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS);
ClassPatcher visitor = new ClassPatcher(writer);
reader.accept(visitor, 0);
LogUtil.endClass();
return writer.toByteArray();
}
@Override
public byte[] transform(String s, String s1, byte[] bytes) {
LogUtil.startClass("Minecraft (%s)", Names.minecraft.getName());
ClassReader reader = new ClassReader(bytes);
ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS);
ClassPatcher visitor = new ClassPatcher(writer);
reader.accept(visitor, 0);
LogUtil.endClass();
return writer.toByteArray();
}
@Override
public byte[] transform(String s, String s1, byte[] bytes) {
LogUtil.startClass("GuiIngameForge (%s)", Names.guiIngameForge.getName());
ClassReader reader = new ClassReader(bytes);
ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
ClassPatcher visitor = new ClassPatcher(writer);
reader.accept(visitor, 0);
LogUtil.endClass();
return writer.toByteArray();
}
@Override
public byte[] transform(String s, String s1, byte[] bytes) {
LogUtil.startClass("GuiEditSign (%s)", Names.guiEditSign.getName());
ClassReader reader = new ClassReader(bytes);
ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS);
ClassPatcher visitor = new ClassPatcher(writer);
reader.accept(visitor, 0);
LogUtil.endClass();
return writer.toByteArray();
}
@Override
public byte[] transform(String s, String s1, byte[] bytes) {
LogUtil.startClass("GuiDisconnected (%s)", Names.guiDisconnected.getName());
ClassReader reader = new ClassReader(bytes);
ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
ClassPatcher visitor = new ClassPatcher(writer);
reader.accept(visitor, 0);
LogUtil.endClass();
return writer.toByteArray();
}
@Override
public byte[] transform(String s, String s1, byte[] bytes) {
LogUtil.startClass("GuiGameOver (%s)", Names.guiGameOver.getName());
ClassReader reader = new ClassReader(bytes);
ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS);
ClassPatcher visitor = new ClassPatcher(writer);
reader.accept(visitor, 0);
LogUtil.endClass();
return writer.toByteArray();
}
@Override
public byte[] transform(String s, String s1, byte[] bytes) {
LogUtil.startClass("GuiTextfield (%s)", Names.guiTextfield.getName());
ClassReader reader = new ClassReader(bytes);
ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
ClassPatcher visitor = new ClassPatcher(writer);
reader.accept(visitor, 0);
LogUtil.endClass();
return writer.toByteArray();
}
private LazyDefinedClass generate() {
LazyDefinedClass methodMetaClass = null;
if (methodMetaInternalName != null) {
methodMetaClass = generateMethodMetaClass(config);
}
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
String[] interfaces = null;
if (!config.enabledProperty().isEmpty() || !config.traceEntryEnabledProperty().isEmpty()) {
interfaces = new String[] {"org/glowroot/agent/plugin/api/config/ConfigListener"};
}
cw.visit(V1_5, ACC_PUBLIC + ACC_SUPER, adviceInternalName, null, "java/lang/Object",
interfaces);
addClassAnnotation(cw);
addStaticFields(cw);
addStaticInitializer(cw);
boolean checkNotInTransaction = config.isTransaction()
&& config.alreadyInTransactionBehavior() == AlreadyInTransactionBehavior.DO_NOTHING;
boolean checkPropertyNotEnabled = pluginId != null && !config.enabledProperty().isEmpty();
addIsEnabledMethodIfNeeded(cw, checkNotInTransaction, checkPropertyNotEnabled);
if (config.isTraceEntryOrGreater()) {
// methodMetaInternalName is non-null when entry or greater
checkNotNull(methodMetaInternalName);
addOnBeforeMethod(cw);
addOnThrowMethod(cw);
addOnReturnMethod(cw);
} else if (config.captureKind() == CaptureKind.TIMER) {
addOnBeforeMethodTimerOnly(cw);
addOnAfterMethodTimerOnly(cw);
} else {
addOnBeforeMethodOther(cw);
}
cw.visitEnd();
ImmutableLazyDefinedClass.Builder builder = ImmutableLazyDefinedClass.builder()
.type(Type.getObjectType(adviceInternalName))
.bytes(cw.toByteArray());
if (methodMetaClass != null) {
builder.addDependencies(methodMetaClass);
}
return builder.build();
}
default byte[] transform(byte[] input, String classname, BuildContext context) {
ClassReader reader = new ClassReader(input);
ClassNode cn = new ClassNode();
reader.accept(cn, 0);
transform(cn, classname, context);
SafeClassWriter writer = new SafeClassWriter(context.task.reader, ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
cn.accept(writer);
return writer.toByteArray();
}
@Override
public byte[] transform(String s, String s1, byte[] bytes) {
LogUtil.startClass("GuiOptions (%s)", Names.guiOptions.getName());
ClassReader reader = new ClassReader(bytes);
ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS);
ClassPatcher visitor = new ClassPatcher(writer);
reader.accept(visitor, 0);
LogUtil.endClass();
return writer.toByteArray();
}
@Override
public byte[] transform(String s, String s1, byte[] bytes) {
LogUtil.startClass("GuiOptions (%s)", Names.guiOptions.getName());
ClassReader reader = new ClassReader(bytes);
ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS);
ClassPatcher visitor = new ClassPatcher(writer);
reader.accept(visitor, 0);
LogUtil.endClass();
return writer.toByteArray();
}
@Override
public byte[] transform(String s, String s1, byte[] bytes) {
LogUtil.startClass("GuiIngameForge (%s)", Names.guiIngameForge.getName());
ClassReader reader = new ClassReader(bytes);
ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS);
ClassPatcher visitor = new ClassPatcher(writer);
reader.accept(visitor, 0);
LogUtil.endClass();
return writer.toByteArray();
}
@Override
public byte[] transform(String s, String s1, byte[] bytes) {
LogUtil.startClass("GuiEditSign (%s)", Names.guiEditSign.getName());
ClassReader reader = new ClassReader(bytes);
ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS);
ClassPatcher visitor = new ClassPatcher(writer);
reader.accept(visitor, 0);
LogUtil.endClass();
return writer.toByteArray();
}
@Override
public byte[] transform(String s, String s1, byte[] bytes) {
LogUtil.startClass("GuiEditSign (%s)", Names.guiEditSign.getName());
ClassReader reader = new ClassReader(bytes);
ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
ClassPatcher visitor = new ClassPatcher(writer);
reader.accept(visitor, 0);
LogUtil.endClass();
return writer.toByteArray();
}
@Test
public void test() throws Throwable {
ClassReader cr = new ClassReader(Config.class.getName());
ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_MAXS);
ClassVisitor cv = new MethodChangeClassAdapter(cw);
cr.accept(cv, Opcodes.ASM5);
//Add a new method
MethodVisitor mw = cw.visitMethod(ACC_PUBLIC + ACC_STATIC,
"add",
"([Ljava/lang/String;)V",
null,
null);
// pushes the 'out' field (of type PrintStream) of the System class
mw.visitFieldInsn(GETSTATIC,
"java/lang/System",
"out",
"Ljava/io/PrintStream;");
// pushes the "Hello World!" String constant
mw.visitLdcInsn("this is add method print!");
// invokes the 'println' method (defined in the PrintStream class)
mw.visitMethodInsn(INVOKEVIRTUAL,
"java/io/PrintStream",
"println",
"(Ljava/lang/String;)V");
mw.visitInsn(RETURN);
// this code uses a maximum of two stack elements and two local
// variables
mw.visitMaxs(0, 0);
mw.visitEnd();
//Type.getDescriptor(AdviceFlowOuterHolder.class)
FieldVisitor fv = cw.visitField(ACC_PUBLIC + ACC_STATIC + ACC_FINAL,
"age",
Type.INT_TYPE.toString(),
null,
1);
fv.visitEnd();
FieldVisitor fv2 = cw.visitField(ACC_PUBLIC + ACC_STATIC + ACC_FINAL,
"name2",
Type.getDescriptor(String.class),
null,
"name2");
fv2.visitEnd();
ModifyClassVisiter cv2 = new ModifyClassVisiter(Opcodes.ASM5);
cv2.addRemoveField("name");
cr.accept(cv2, Opcodes.ASM5);
FieldVisitor fv3 = cw.visitField(ACC_PUBLIC + ACC_STATIC + ACC_FINAL,
"name",
Type.getDescriptor(String.class),
null,
"name");
fv3.visitEnd();
byte[] code = cw.toByteArray();
File file = new File("Config.class");
System.out.println(file.getAbsolutePath());
FileOutputStream fos = new FileOutputStream(file);
fos.write(code);
fos.close();
}
@Override
public int mergeWriter(int flags)
{
return flags | ClassWriter.COMPUTE_MAXS;
}