Example usage for org.objectweb.asm.commons GeneratorAdapter GeneratorAdapter

List of usage examples for org.objectweb.asm.commons GeneratorAdapter GeneratorAdapter

Introduction

In this page you can find the example usage for org.objectweb.asm.commons GeneratorAdapter GeneratorAdapter.

Prototype

public GeneratorAdapter(final int access, final Method method, final String signature, final Type[] exceptions,
        final ClassVisitor classVisitor) 

Source Link

Document

Constructs a new GeneratorAdapter .

Usage

From source file:co.cask.cdap.internal.app.runtime.batch.distributed.ContainerLauncherGenerator.java

License:Apache License

/**
 * Generates the bytecode for a main class and writes to the given {@link JarOutputStream}.
 * The generated class looks like this://w  w  w . java  2  s  .  c  om
 *
 * <pre>{@code
 * class className {
 *   public static void main(String[] args) {
 *     MapReduceContainerLauncher.launch(launcherClassPath, classLoaderName, className, args);
 *   }
 * }
 * }
 * </pre>
 *
 * The {@code launcherClassPath}, {@code classLoaderName} and {@code className} are represented as
 * string literals in the generated class.
 */
private static void generateLauncherClass(String launcherClassPath, String classLoaderName, String className,
        JarOutputStream output) throws IOException {
    String internalName = className.replace('.', '/');

    ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
    classWriter.visit(Opcodes.V1_7, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, internalName, null,
            Type.getInternalName(Object.class), null);

    Method constructor = Methods.getMethod(void.class, "<init>");

    // Constructor
    // MRAppMaster()
    GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, constructor, null, null, classWriter);

    mg.loadThis();
    mg.invokeConstructor(Type.getType(Object.class), constructor);
    mg.returnValue();
    mg.endMethod();

    // Main method.
    // public static void main(String[] args) {
    //   MapReduceContainerLauncher.launch(launcherClassPath, classLoaderName, className, args);
    // }
    Method mainMethod = Methods.getMethod(void.class, "main", String[].class);
    mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, mainMethod, null,
            new Type[] { Type.getType(Exception.class) }, classWriter);

    mg.getStatic(Type.getType(System.class), "out", Type.getType(PrintStream.class));
    mg.visitLdcInsn("Launch class " + className);
    mg.invokeVirtual(Type.getType(PrintStream.class), Methods.getMethod(void.class, "println", String.class));

    // The Launcher classpath, classloader name and main classname are stored as string literal in the generated class
    mg.visitLdcInsn(launcherClassPath);
    mg.visitLdcInsn(classLoaderName);
    mg.visitLdcInsn(className);
    mg.loadArg(0);
    mg.invokeStatic(Type.getType(MapReduceContainerLauncher.class),
            Methods.getMethod(void.class, "launch", String.class, String.class, String.class, String[].class));
    mg.returnValue();
    mg.endMethod();

    classWriter.visitEnd();

    output.putNextEntry(new JarEntry(internalName + ".class"));
    output.write(classWriter.toByteArray());
}

From source file:co.cask.cdap.internal.app.runtime.batch.distributed.ContainerLauncherGenerator.java

License:Apache License

/**
 * Generates a class that has a static main method which delegates the call to a static method in the given delegator
 * class with method signature {@code public static void launch(String className, String[] args)}
 *
 * @param className the classname of the generated class
 * @param mainDelegator the class to delegate the main call to
 * @param output for writing the generated bytes
 */// ww  w .j  a va 2  s.com
private static void generateMainClass(String className, Type mainDelegator, JarOutputStream output)
        throws IOException {
    String internalName = className.replace('.', '/');

    ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
    classWriter.visit(Opcodes.V1_7, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, internalName, null,
            Type.getInternalName(Object.class), null);

    // Generate the default constructor, which just call super()
    Method constructor = Methods.getMethod(void.class, "<init>");
    GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, constructor, null, null, classWriter);
    mg.loadThis();
    mg.invokeConstructor(Type.getType(Object.class), constructor);
    mg.returnValue();
    mg.endMethod();

    // Generate the main method
    // public static void main(String[] args) {
    //   System.out.println("Launch class .....");
    //   <MainDelegator>.launch(<className>, args);
    // }
    Method mainMethod = Methods.getMethod(void.class, "main", String[].class);
    mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, mainMethod, null,
            new Type[] { Type.getType(Exception.class) }, classWriter);

    mg.getStatic(Type.getType(System.class), "out", Type.getType(PrintStream.class));
    mg.visitLdcInsn("Launch class " + className + " by calling " + mainDelegator.getClassName() + ".launch");
    mg.invokeVirtual(Type.getType(PrintStream.class), Methods.getMethod(void.class, "println", String.class));

    // The main classname is stored as string literal in the generated class
    mg.visitLdcInsn(className);
    mg.loadArg(0);
    mg.invokeStatic(mainDelegator, Methods.getMethod(void.class, "launch", String.class, String[].class));
    mg.returnValue();
    mg.endMethod();

    classWriter.visitEnd();

    output.putNextEntry(new JarEntry(internalName + ".class"));
    output.write(classWriter.toByteArray());
}

From source file:co.cask.cdap.internal.app.runtime.service.http.HttpHandlerGenerator.java

License:Apache License

/**
 * Generates the constructor. The constructor generated has signature {@code (DelegatorContext, MetricsContext)}.
 *///from   w w  w.  j av a2 s.  c  o  m
private void generateConstructor(TypeToken<? extends HttpServiceHandler> delegateType,
        ClassWriter classWriter) {
    Method constructor = Methods.getMethod(void.class, "<init>", DelegatorContext.class, MetricsContext.class);
    String signature = Signatures.getMethodSignature(constructor, getContextType(delegateType),
            TypeToken.of(MetricsContext.class));

    // Constructor(DelegatorContext, MetricsContext)
    GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, constructor, signature, null, classWriter);

    // super(context, metricsContext);
    mg.loadThis();
    mg.loadArg(0);
    mg.loadArg(1);
    mg.invokeConstructor(Type.getType(AbstractHttpHandlerDelegator.class),
            Methods.getMethod(void.class, "<init>", DelegatorContext.class, MetricsContext.class));
    mg.returnValue();
    mg.endMethod();
}

From source file:co.cask.cdap.internal.app.runtime.service.http.HttpHandlerGenerator.java

License:Apache License

/**
 * Generates a static Logger field for logging and a static initialization block to initialize the logger.
 *//*from   w ww  .  j ava2s. c o  m*/
private void generateLogger(Type classType, ClassWriter classWriter) {
    // private static final Logger LOG = LoggerFactory.getLogger(classType);
    classWriter.visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL, "LOG",
            Type.getType(Logger.class).getDescriptor(), null, null);
    Method init = Methods.getMethod(void.class, "<clinit>");
    GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_STATIC, init, null, null, classWriter);
    mg.visitLdcInsn(classType);
    mg.invokeStatic(Type.getType(LoggerFactory.class),
            Methods.getMethod(Logger.class, "getLogger", Class.class));
    mg.putStatic(classType, "LOG", Type.getType(Logger.class));
    mg.returnValue();
    mg.endMethod();
}

From source file:co.cask.cdap.internal.io.DatumWriterGenerator.java

License:Apache License

/**
 * Generates the constructor. The constructor generated has signature {@code (Schema, FieldAccessorFactory)}.
 *//*w  ww .j a  v a 2 s.  co m*/
private void generateConstructor() {
    Method constructor = getMethod(void.class, "<init>", Schema.class, FieldAccessorFactory.class);

    // Constructor(Schema schema, FieldAccessorFactory accessorFactory)
    GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, constructor, null, null, classWriter);

    // super(); // Calling Object constructor
    mg.loadThis();
    mg.invokeConstructor(Type.getType(Object.class), getMethod(void.class, "<init>"));

    // if (!SCHEMA_HASH.equals(schema.getSchemaHash().toString())) { throw IllegalArgumentException }
    mg.getStatic(classType, "SCHEMA_HASH", Type.getType(String.class));
    mg.loadArg(0);
    mg.invokeVirtual(Type.getType(Schema.class), getMethod(SchemaHash.class, "getSchemaHash"));
    mg.invokeVirtual(Type.getType(SchemaHash.class), getMethod(String.class, "toString"));
    mg.invokeVirtual(Type.getType(String.class), getMethod(boolean.class, "equals", Object.class));
    Label hashEquals = mg.newLabel();
    mg.ifZCmp(GeneratorAdapter.NE, hashEquals);
    mg.throwException(Type.getType(IllegalArgumentException.class), "Schema not match.");
    mg.mark(hashEquals);

    // this.schema = schema;
    mg.loadThis();
    mg.loadArg(0);
    mg.putField(classType, "schema", Type.getType(Schema.class));

    // For each record field that needs an accessor, get the accessor and store it in field.
    for (Map.Entry<TypeToken<?>, String> entry : fieldAccessorRequests.entries()) {
        String fieldAccessorName = getFieldAccessorName(entry.getKey(), entry.getValue());

        classWriter.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL, fieldAccessorName,
                Type.getDescriptor(FieldAccessor.class), null, null);
        // this.fieldAccessorName
        //  = accessorFactory.getFieldAccessor(TypeToken.of(Class.forName("className")), "fieldName");
        mg.loadThis();
        mg.loadArg(1);
        mg.push(entry.getKey().getRawType().getName());
        mg.invokeStatic(Type.getType(Class.class), getMethod(Class.class, "forName", String.class));
        mg.invokeStatic(Type.getType(TypeToken.class), getMethod(TypeToken.class, "of", Class.class));
        mg.push(entry.getValue());
        mg.invokeInterface(Type.getType(FieldAccessorFactory.class),
                getMethod(FieldAccessor.class, "getFieldAccessor", TypeToken.class, String.class));
        mg.putField(classType, fieldAccessorName, Type.getType(FieldAccessor.class));
    }

    mg.returnValue();
    mg.endMethod();
}

From source file:co.cask.cdap.internal.io.DatumWriterGenerator.java

License:Apache License

/**
 * Generates the {@link DatumWriter#encode(Object, co.cask.cdap.common.io.Encoder)} method.
 * @param outputType Type information of the data type for output
 * @param schema Schema to use for output.
 *///from   ww w .j  ava2s .c o  m
private void generateEncode(TypeToken<?> outputType, Schema schema) {
    TypeToken<?> callOutputType = getCallTypeToken(outputType, schema);

    Method encodeMethod = getMethod(void.class, "encode", callOutputType.getRawType(), Encoder.class);

    if (!Object.class.equals(callOutputType.getRawType())) {
        // Generate the synthetic method for the bridging
        Method method = getMethod(void.class, "encode", Object.class, Encoder.class);
        GeneratorAdapter mg = new GeneratorAdapter(
                Opcodes.ACC_PUBLIC + Opcodes.ACC_BRIDGE + Opcodes.ACC_SYNTHETIC, method, null,
                new Type[] { Type.getType(IOException.class) }, classWriter);

        mg.loadThis();
        mg.loadArg(0);
        mg.checkCast(Type.getType(callOutputType.getRawType()));
        mg.loadArg(1);
        mg.invokeVirtual(classType, encodeMethod);
        mg.returnValue();
        mg.endMethod();
    }

    // Generate the top level public encode method
    String methodSignature = null;
    if (callOutputType.getType() instanceof ParameterizedType) {
        methodSignature = Signatures.getMethodSignature(encodeMethod, callOutputType, null);
    }
    GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, encodeMethod, methodSignature,
            new Type[] { Type.getType(IOException.class) }, classWriter);

    // Delegate to the actual encode method(value, encoder, schema, Sets.newIdentityHashSet());
    mg.loadThis();
    mg.loadArg(0);
    mg.loadArg(1);
    mg.loadThis();
    mg.getField(classType, "schema", Type.getType(Schema.class));
    // seenRefs Set
    mg.invokeStatic(Type.getType(Sets.class), getMethod(Set.class, "newIdentityHashSet"));
    mg.invokeVirtual(classType, getEncodeMethod(outputType, schema));
    mg.returnValue();
    mg.endMethod();
}

From source file:co.cask.cdap.internal.io.DatumWriterGenerator.java

License:Apache License

/**
 * Returns the encode method for the given type and schema. The same method will be returned if the same
 * type and schema has been passed to the method before.
 *
 * @param outputType Type information of the data type for output
 * @param schema Schema to use for output.
 * @return A method for encoding the given output type and schema.
 *///from  ww w . j  av  a 2  s.c o m
private Method getEncodeMethod(TypeToken<?> outputType, Schema schema) {
    String key = String.format("%s%s", normalizeTypeName(outputType), schema.getSchemaHash());

    Method method = encodeMethods.get(key);
    if (method != null) {
        return method;
    }

    // Generate the encode method (value, encoder, schema, set)
    TypeToken<?> callOutputType = getCallTypeToken(outputType, schema);
    String methodName = String.format("encode%s", key);
    method = getMethod(void.class, methodName, callOutputType.getRawType(), Encoder.class, Schema.class,
            Set.class);

    // Put the method into map first before generating the body in order to support recursive data type.
    encodeMethods.put(key, method);

    String methodSignature = Signatures.getMethodSignature(method, callOutputType, null, null,
            new TypeToken<Set<Object>>() {
            });
    GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PRIVATE, method, methodSignature,
            new Type[] { Type.getType(IOException.class) }, classWriter);

    generateEncodeBody(mg, schema, outputType, 0, 1, 2, 3);
    mg.returnValue();
    mg.endMethod();

    return method;
}

From source file:co.cask.cdap.internal.io.FieldAccessorGenerator.java

License:Apache License

private void generateConstructor(Field field) {
    if (isPrivate) {
        classWriter.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_FINAL, "field",
                Type.getDescriptor(Field.class), null, null).visitEnd();
    }//from w w  w . j av a 2  s.c  o m

    // Constructor(Type classType)
    Method constructor = getMethod(void.class, "<init>", java.lang.reflect.Type.class);
    GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, constructor, null, new Type[0], classWriter);
    mg.loadThis();
    mg.loadArg(0);
    mg.invokeConstructor(Type.getType(AbstractFieldAccessor.class), constructor);
    if (isPrivate) {
        initializeReflectionField(mg, field);
    }

    mg.returnValue();
    mg.endMethod();
}

From source file:co.cask.cdap.internal.io.FieldAccessorGenerator.java

License:Apache License

/**
 * Generates the try-catch block that wrap around the given reflection method call.
 * @param method The method to be called within the try-catch block.
 *///  ww w  . j  a v  a 2s.  c  om
private void invokeReflection(Method method, String signature) {
    GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, method, signature, new Type[0], classWriter);
    /**
     * try {
     *   // Call method
     * } catch (IllegalAccessException e) {
     *   throw Throwables.propagate(e);
     * }
     */
    Label beginTry = mg.newLabel();
    Label endTry = mg.newLabel();
    Label catchHandle = mg.newLabel();
    mg.visitTryCatchBlock(beginTry, endTry, catchHandle, Type.getInternalName(IllegalAccessException.class));
    mg.mark(beginTry);
    mg.loadThis();
    mg.getField(Type.getObjectType(className), "field", Type.getType(Field.class));
    mg.loadArgs();
    mg.invokeVirtual(Type.getType(Field.class), method);
    mg.mark(endTry);
    mg.returnValue();
    mg.mark(catchHandle);
    int exception = mg.newLocal(Type.getType(IllegalAccessException.class));
    mg.storeLocal(exception);
    mg.loadLocal(exception);
    mg.invokeStatic(Type.getType(Throwables.class),
            getMethod(RuntimeException.class, "propagate", Throwable.class));
    mg.throwException();
    mg.endMethod();

}

From source file:co.cask.cdap.internal.io.FieldAccessorGenerator.java

License:Apache License

/**
 * Generates a getter that get the value by directly accessing the class field.
 * @param field The reflection field object.
 *///from w w w  . j a  v  a  2 s. co  m
private void directGetter(Field field) {
    GeneratorAdapter mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC, getMethod(Object.class, "get", Object.class),
            getterSignature(), new Type[0], classWriter);
    // Simply access by field
    // return ((classType)object).fieldName;
    mg.loadArg(0);
    mg.checkCast(Type.getType(field.getDeclaringClass()));
    mg.getField(Type.getType(field.getDeclaringClass()), field.getName(), Type.getType(field.getType()));
    if (field.getType().isPrimitive()) {
        mg.valueOf(Type.getType(field.getType()));
    }
    mg.returnValue();
    mg.endMethod();
}