import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ConstantDynamic; import org.objectweb.asm.Handle; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import java.io.FileOutputStream; import java.io.IOException; /** * This class was created by ASM-ifying a class generated by Byte Buddy. * Its purpose it to create a class CondyCallable making use of * dynamic class-file constants, a Java 11 feature introduced by JEP 309. * * @see https://openjdk.java.net/jeps/309 */ public class Generator implements Opcodes { private static final String CLASS_FILE = "CondyCallable.class"; public static void main(String[] args) throws IOException { try (FileOutputStream fos = new FileOutputStream(CLASS_FILE)) { fos.write(getClassBytes()); } System.out.println(CLASS_FILE + " generated successfully"); } private static byte[] getClassBytes() { ClassWriter classWriter = new ClassWriter(0); classWriter.visit(V11, ACC_PUBLIC | ACC_SUPER, "CondyCallable", null, "java/lang/Object", new String[] { "java/util/concurrent/Callable" }); createDefaultConstructor(classWriter); createMethod_call(classWriter); classWriter.visitEnd(); return classWriter.toByteArray(); } private static void createDefaultConstructor(ClassWriter classWriter) { MethodVisitor methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "", "()V", null, null); methodVisitor.visitCode(); methodVisitor.visitVarInsn(ALOAD, 0); methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false); methodVisitor.visitInsn(RETURN); methodVisitor.visitMaxs(1, 1); methodVisitor.visitEnd(); } private static void createMethod_call(ClassWriter classWriter) { MethodVisitor methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "call", "()Ljava/lang/Object;", null, new String[] { "java/lang/Exception" }); methodVisitor.visitCode(); methodVisitor.visitLdcInsn( // Create constant-dynamic instruction new ConstantDynamic( // Dummy name "_", // Constant type "LApplication;", // Bootstrap method: ConstantBootstraps::invoke, dispatching to an existing method/constructor new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/ConstantBootstraps", "invoke", "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/invoke/MethodHandle;[Ljava/lang/Object;)Ljava/lang/Object;", false), // Bootstrap method arguments: here we simply dispatch to the constructor of class Application new Handle(Opcodes.H_NEWINVOKESPECIAL, "Application", "", "()V", false)) ); methodVisitor.visitInsn(ARETURN); methodVisitor.visitMaxs(1, 1); methodVisitor.visitEnd(); } }