use of act.asm.ClassWriter in project actframework by actframework.
the class AppClassLoader method asmEnhance.
private byte[] asmEnhance(String className, byte[] bytecode) {
if (!enhanceEligible(className))
return bytecode;
$.Var<ClassWriter> cw = $.var(null);
ByteCodeVisitor enhancer = Act.enhancerManager().appEnhancer(app, className, cw);
if (null == enhancer) {
return bytecode;
}
EnvMatcher matcher = new EnvMatcher();
matcher.setDownstream(enhancer);
cw.set(new ClassWriter(ClassWriter.COMPUTE_FRAMES));
enhancer.commitDownstream();
ClassReader r = new ClassReader(bytecode);
try {
r.accept(matcher, ClassReader.EXPAND_FRAMES);
} catch (EnvNotMatchException e) {
return bytecode;
} catch (AsmException e) {
logger.error(e, "error enhancing bytecode at %s", e.context());
throw ActErrorResult.enhancingError(e);
}
return cw.get().toByteArray();
}
use of act.asm.ClassWriter in project actframework by actframework.
the class HelloWorld method main.
public static void main(final String[] args) throws Exception {
// Generates the bytecode corresponding to the following Java class:
//
// public class Example {
// public static void main (String[] args) {
// System.out.println("Hello world!");
// }
// }
// creates a ClassWriter for the Example public class,
// which inherits from Object
ClassWriter cw = new ClassWriter(0);
cw.visit(V1_1, ACC_PUBLIC, "Example", null, "java/lang/Object", null);
// creates a MethodWriter for the (implicit) constructor
MethodVisitor mw = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
// pushes the 'this' variable
mw.visitVarInsn(ALOAD, 0);
// invokes the super class constructor
mw.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
mw.visitInsn(RETURN);
// this code uses a maximum of one stack element and one local variable
mw.visitMaxs(1, 1);
mw.visitEnd();
// creates a MethodWriter for the 'main' method
mw = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main", "([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("Hello world!");
// invokes the 'println' method (defined in the PrintStream class)
mw.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
mw.visitInsn(RETURN);
// this code uses a maximum of two stack elements and two local
// variables
mw.visitMaxs(2, 2);
mw.visitEnd();
// gets the bytecode of the Example class, and loads it dynamically
byte[] code = cw.toByteArray();
FileOutputStream fos = new FileOutputStream("Example.class");
fos.write(code);
fos.close();
HelloWorld loader = new HelloWorld();
Class<?> exampleClass = loader.defineClass("Example", code, 0, code.length);
// uses the dynamically generated class to print 'HelloWorld'
exampleClass.getMethods()[0].invoke(null, new Object[] { null });
// ------------------------------------------------------------------------
// Same example with a GeneratorAdapter (more convenient but slower)
// ------------------------------------------------------------------------
cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
cw.visit(V1_1, ACC_PUBLIC, "Example", null, "java/lang/Object", null);
// creates a GeneratorAdapter for the (implicit) constructor
Method m = Method.getMethod("void <init> ()");
GeneratorAdapter mg = new GeneratorAdapter(ACC_PUBLIC, m, null, null, cw);
mg.loadThis();
mg.invokeConstructor(Type.getType(Object.class), m);
mg.returnValue();
mg.endMethod();
// creates a GeneratorAdapter for the 'main' method
m = Method.getMethod("void main (String[])");
mg = new GeneratorAdapter(ACC_PUBLIC + ACC_STATIC, m, null, null, cw);
mg.getStatic(Type.getType(System.class), "out", Type.getType(PrintStream.class));
mg.push("Hello world!");
mg.invokeVirtual(Type.getType(PrintStream.class), Method.getMethod("void println (String)"));
mg.returnValue();
mg.endMethod();
cw.visitEnd();
code = cw.toByteArray();
loader = new HelloWorld();
exampleClass = loader.defineClass("Example", code, 0, code.length);
// uses the dynamically generated class to print 'HelloWorld'
exampleClass.getMethods()[0].invoke(null, new Object[] { null });
}
use of act.asm.ClassWriter in project actframework by actframework.
the class ServerBootstrapClassLoader method loadActClass.
protected Class<?> loadActClass(String name, boolean resolve, boolean pluginOnly) {
boolean fromPlugin = false;
byte[] ba = pluginBC.remove(name);
if (null == ba) {
if (!pluginOnly) {
ba = libBC.remove(name);
}
} else {
fromPlugin = true;
}
if (null == ba) {
ba = tryLoadResource(name);
}
if (null == ba) {
if (pluginOnly) {
return findLoadedClass(name);
}
return null;
}
Class<?> c = null;
if (!name.startsWith(ACT_PKG) || name.startsWith(ASM_PKG)) {
// skip bytecode enhancement for asm classes or non Act classes
c = super.defineClass(name, ba, 0, ba.length, DOMAIN);
}
if (null == c) {
$.Var<ClassWriter> cw = $.val(null);
ByteCodeVisitor enhancer = Act.enhancerManager().generalEnhancer(name, cw);
if (null == enhancer) {
c = super.defineClass(name, ba, 0, ba.length, DOMAIN);
} else {
ClassWriter w = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
cw.set(w);
enhancer.commitDownstream();
ClassReader r;
r = new ClassReader(ba);
try {
r.accept(enhancer, 0);
byte[] baNew = w.toByteArray();
c = super.defineClass(name, baNew, 0, baNew.length, DOMAIN);
} catch (RuntimeException e) {
throw e;
} catch (Error e) {
throw e;
} catch (Exception e) {
throw E.unexpected("Error processing class " + name);
}
}
}
if (resolve) {
super.resolveClass(c);
}
return c;
}
use of act.asm.ClassWriter in project actframework by actframework.
the class BootstrapClassLoader method defineClass.
protected Class<?> defineClass(String name, byte[] ba) {
Class<?> c = null;
$.Var<ClassWriter> cw = $.val(null);
ByteCodeVisitor enhancer = enhancerManager.generalEnhancer(name, cw);
if (null == enhancer) {
c = defineClassX(name, ba, 0, ba.length, DOMAIN);
} else {
Exception exception = null;
ClassWriter w = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
cw.set(w);
enhancer.commitDownstream();
ClassReader r;
r = new ClassReader(ba);
try {
r.accept(enhancer, 0);
byte[] baNew = w.toByteArray();
c = defineClassX(name, baNew, 0, baNew.length, DOMAIN);
} catch (Error e) {
throw e;
} catch (Exception e) {
exception = e;
}
if (null != exception) {
logger.error(exception, "Error enhancing class %s", name);
throw E.unexpected(exception);
}
}
return c;
}
Aggregations