List of usage examples for org.objectweb.asm Type getClassName
public String getClassName()
From source file:ca.weblite.mirah.ant.mirrors.ASMTests.java
@Test public void testGetObjectType() { Type map = Type.getObjectType("java/util/Map"); assertTrue("Failed to find java/util/Map", map != null); assertEquals("Binary name of Map wrong", "java.util.Map", map.getClassName()); Type entry = Type.getObjectType("java/util/Map$Entry"); assertTrue("Failed to find java/util/Map$Entry", entry != null); assertEquals("Binary name of Entry wrong", "java.util.Map$Entry2", entry.getClassName()); }
From source file:ca.weblite.mirah.ant.mirrors.ASMTests.java
@Test public void testClassWriter() { ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); /*writer.visit(/*from ww w. j a va 2 s . com*/ 1, Opcodes.ACC_PUBLIC, "ca/weblite/test/TestClass", null, "java/util/ArrayList", null ); */ Type cls = Type.getObjectType("ca/weblite/test/TestClass"); assertTrue("Failed to retrieve TestClass", cls != null); assertEquals("Internal name of TestClass is wrong", "ca/weblite/test/TestClass", cls.getInternalName()); assertEquals("Binary name of TestClass is wrong", "ca.weblite.test.TestClass", cls.getClassName()); }
From source file:ch.sourcepond.utils.podescoin.internal.SerializableClassVisitor.java
License:Apache License
/** * Determines whether the current method is the readObject method with * following signature://w w w. j a v a 2s . com * * <pre> * private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException * </pre> * * See {@link Serializable} for further information. * * @param access * the method's access flags (see {@link Opcodes}). This * parameter also indicates if the method is synthetic and/or * deprecated. * @param name * the method's name. * @param desc * the method's descriptor (see {@link Type}). * @param exceptions * the internal names of the method's exception classes (see * {@link Type#getInternalName()} ). May be null. * @return {@code true} if the method specified is the readObject method as * described by {@link Serializable}, {@code false} otherwise */ public static boolean isReadObjectMethod(final int access, final String name, final String desc, final String[] exceptions) { if (ACC_PRIVATE == access && READ_OBJECT_METHOD_NAME.equals(name) && exceptions != null && exceptions.length == 2) { if (IO_EXCEPTION_INTERNAL_NAME.equals(exceptions[0]) && CLASS_NOT_FOUND_EXCEPTION_INTERNAL_NAME.equals(exceptions[1]) || IO_EXCEPTION_INTERNAL_NAME.equals(exceptions[1]) && CLASS_NOT_FOUND_EXCEPTION_INTERNAL_NAME.equals(exceptions[0])) { final Type returnType = getReturnType(desc); if (VOID_NAME.equals(returnType.getClassName())) { final Type[] argumentTypes = getArgumentTypes(desc); // We need this information later when we generate the // concrete // injection method. return argumentTypes.length == 1 && OBJECT_INPUT_STREAM_NAME.equals(argumentTypes[0].getClassName()); } } } return false; }
From source file:ch.sourcepond.utils.podescoin.internal.SerializableClassVisitor.java
License:Apache License
/** * Determines whether the current method is the writeObject method with * following signature:/*from w w w. j a v a2 s. c om*/ * * <pre> * private void writeObject(java.io.ObjectOutputStream out) throws IOException * </pre> * * See {@link Serializable} for further information. * * @param access * the method's access flags (see {@link Opcodes}). This * parameter also indicates if the method is synthetic and/or * deprecated. * @param name * the method's name. * @param desc * the method's descriptor (see {@link Type}). * @param exceptions * the internal names of the method's exception classes (see * {@link Type#getInternalName()} ). May be null. * @return {@code true} if the method specified is the writeObject method as * described by {@link Serializable}, {@code false} otherwise */ public static boolean isWriteObjectMethod(final int access, final String name, final String desc, final String[] exceptions) { if (ACC_PRIVATE == access && WRITE_OBJECT_METHOD_NAME.equals(name) && exceptions != null && exceptions.length == 1) { if (IO_EXCEPTION_INTERNAL_NAME.equals(exceptions[0])) { final Type returnType = getReturnType(desc); if (VOID_NAME.equals(returnType.getClassName())) { final Type[] argumentTypes = getArgumentTypes(desc); // We need this information later when we generate the // concrete // injection method. return argumentTypes.length == 1 && OBJECT_OUTPUT_STREAM_NAME.equals(argumentTypes[0].getClassName()); } } } return false; }
From source file:cl.inria.stiq.db.structure.impl.StructureDatabase.java
License:Open Source License
public static ITypeInfo getType(IMutableStructureDatabase aStructureDatabase, String aName, boolean aCreateIfAbsent, boolean aFailIfAbsent) { aName = transformClassName(aName);/*from ww w . j av a 2s. c om*/ Type theType = Type.getType(aName); switch (theType.getSort()) { case Type.OBJECT: { String theClassName = theType.getClassName(); return aCreateIfAbsent ? aStructureDatabase.getNewClass(theClassName) : aStructureDatabase.getClass(theClassName, aFailIfAbsent); } case Type.ARRAY: { ITypeInfo theElementType = getType(aStructureDatabase, theType.getElementType().getDescriptor(), aCreateIfAbsent, aFailIfAbsent); int theDimensions = theType.getDimensions(); return new ArrayTypeInfo(null, // That should be safe... if there is a problem we'll see what we do theElementType, theDimensions); } case Type.VOID: return PrimitiveTypeInfo.VOID; case Type.BOOLEAN: return PrimitiveTypeInfo.BOOLEAN; case Type.BYTE: return PrimitiveTypeInfo.BYTE; case Type.CHAR: return PrimitiveTypeInfo.CHAR; case Type.DOUBLE: return PrimitiveTypeInfo.DOUBLE; case Type.FLOAT: return PrimitiveTypeInfo.FLOAT; case Type.INT: return PrimitiveTypeInfo.INT; case Type.LONG: return PrimitiveTypeInfo.LONG; case Type.SHORT: return PrimitiveTypeInfo.SHORT; default: // This is not a "normal" failure, so always throw exception throw new RuntimeException("Not handled: " + theType); } }
From source file:cn.annoreg.asm.DelegateGenerator.java
License:Open Source License
public static MethodVisitor generateStaticMethod(ClassVisitor parentClass, MethodVisitor parent, String className, String methodName, String desc, final Side side) { //This method is a little bit complicated. //We need to generate a delegate class implementing NetworkCallDelegate and a redirect //the code that originally generated here in parent, into the delegate class, //by returning a MethodVisitor under the ClassVisitor of the delegate class. //Besides, we should generate a call to NetworkCallManager into parent. //Above is the original method. Now it has a little bit change. To allow private call in //here, we need to generate the delegate method in this class instead of in a delegate class. //We make the delegate method public so that the delegate class can call it. //delegateName is a string used by both sides to identify a network-call delegate. final String delegateName = className + ":" + methodName + ":" + desc; final Type[] args = Type.getArgumentTypes(desc); final Type ret = Type.getReturnType(desc); //Check types for (Type t : args) { //TODO support these types if (!t.getDescriptor().startsWith("L") && !t.getDescriptor().startsWith("[")) { throw new RuntimeException("Unsupported argument type in network call. in method " + methodName + ", " + t.getDescriptor()); }/*from ww w . j ava2s. c om*/ } if (!ret.equals(Type.VOID_TYPE)) { throw new RuntimeException( "Unsupported return value type in network call. " + "Only void is supported."); } //Generate call to NetworkCallManager in parent. parent.visitCode(); //First parameter parent.visitLdcInsn(delegateName); //Second parameter: object array pushIntegerConst(parent, args.length); //array size parent.visitTypeInsn(Opcodes.ANEWARRAY, Type.getInternalName(Object.class)); for (int i = 0; i < args.length; ++i) { parent.visitInsn(Opcodes.DUP); pushIntegerConst(parent, i); parent.visitVarInsn(Opcodes.ALOAD, i); parent.visitInsn(Opcodes.AASTORE); } //Call cn.annoreg.mc.network.NetworkCallManager.onNetworkCall parent.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(NetworkCallManager.class), "onNetworkCall", Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(String.class), Type.getType(Object[].class))); parent.visitInsn(Opcodes.RETURN); parent.visitMaxs(5, args.length); parent.visitEnd(); //Create delegate object. final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); final String delegateId = Integer.toString(delegateNextID++); final Type delegateClassType = Type.getType("cn/annoreg/asm/NetworkCallDelegate_" + delegateId); cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, delegateClassType.getInternalName(), null, Type.getInternalName(Object.class), new String[] { Type.getInternalName(NetworkCallDelegate.class) }); //package cn.annoreg.asm; //class NetworkCallDelegate_? implements NetworkCallDelegate { { MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), "<init>", "()V"); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } //public NetworkCallDelegate_?() {} final String delegateFunctionName = methodName + "_delegate_" + delegateId; { MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "invoke", Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(Object[].class)), null, null); mv.visitCode(); for (int i = 0; i < args.length; ++i) { mv.visitVarInsn(Opcodes.ALOAD, 1); //0 is this pushIntegerConst(mv, i); mv.visitInsn(Opcodes.AALOAD); mv.visitTypeInsn(Opcodes.CHECKCAST, args[i].getInternalName()); } mv.visitMethodInsn(Opcodes.INVOKESTATIC, //delegateClassType.getInternalName(), //changed to original class className.replace('.', '/'), delegateFunctionName, desc); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(args.length + 2, 2); mv.visitEnd(); } //@Override public void invoke(Object[] args) { // xxxx.xxxx_delegated_xxx((Type0) args[0], (Type1) args[1], ...); //} //The returned MethodVisitor will visit the original version of the method, //including its annotation, where we can get StorageOptions. return new MethodVisitor(Opcodes.ASM4, parentClass.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, delegateFunctionName, desc, null, null)) { //Remember storage options for each argument StorageOption.Option[] options = new StorageOption.Option[args.length]; int targetIndex = -1; StorageOption.Target.RangeOption range = StorageOption.Target.RangeOption.SINGLE; double sendRange = -1; { for (int i = 0; i < options.length; ++i) { options[i] = StorageOption.Option.NULL; //set default value } } @Override public AnnotationVisitor visitParameterAnnotation(final int parameter, String desc, boolean visible) { Type type = Type.getType(desc); if (type.equals(Type.getType(StorageOption.Data.class))) { options[parameter] = StorageOption.Option.DATA; } else if (type.equals(Type.getType(StorageOption.Instance.class))) { //INSTANCE as defualt options[parameter] = StorageOption.Option.INSTANCE; //Change to NULLABLE_INSTANCE if nullable set to true return new AnnotationVisitor(this.api, super.visitParameterAnnotation(parameter, desc, visible)) { @Override public void visit(String name, Object value) { if (name.equals("nullable")) { if ((Boolean) value == true) { options[parameter] = StorageOption.Option.NULLABLE_INSTANCE; } } super.visit(name, value); } }; } else if (type.equals(Type.getType(StorageOption.Update.class))) { options[parameter] = StorageOption.Option.UPDATE; } else if (type.equals(Type.getType(StorageOption.Null.class))) { options[parameter] = StorageOption.Option.NULL; } else if (type.equals(Type.getType(StorageOption.Target.class))) { if (!args[parameter].equals(Type.getType(EntityPlayer.class))) { throw new RuntimeException("Target annotation can only be used on EntityPlayer."); } if (targetIndex != -1) { throw new RuntimeException("You can not specify multiple targets."); } options[parameter] = StorageOption.Option.INSTANCE; targetIndex = parameter; return new AnnotationVisitor(this.api, super.visitParameterAnnotation(parameter, desc, visible)) { @Override public void visitEnum(String name, String desc, String value) { super.visitEnum(name, desc, value); range = StorageOption.Target.RangeOption.valueOf(value); } }; } else if (type.equals(Type.getType(StorageOption.RangedTarget.class))) { if (targetIndex != -1) { throw new RuntimeException("You can not specify multiple targets."); } range = null; targetIndex = parameter; return new AnnotationVisitor(this.api, super.visitParameterAnnotation(parameter, desc, visible)) { @Override public void visit(String name, Object value) { super.visit(name, value); sendRange = (double) value; } }; } return super.visitParameterAnnotation(parameter, desc, visible); } @Override public void visitEnd() { super.visitEnd(); //This is the last method in the delegate class. //Finish the class and do the registration. cw.visitEnd(); try { Class<?> clazz = classLoader.defineClass(delegateClassType.getClassName(), cw.toByteArray()); NetworkCallDelegate delegateObj = (NetworkCallDelegate) clazz.newInstance(); if (side == Side.CLIENT) { NetworkCallManager.registerClientDelegateClass(delegateName, delegateObj, options, targetIndex, range, sendRange); } else { NetworkCallManager.registerServerDelegateClass(delegateName, delegateObj, options); } } catch (Throwable e) { throw new RuntimeException("Can not create delegate for network call.", e); } } }; //public static void delegated(Type0 arg0, Type1, arg1, ...) { // //Code generated by caller. //} //} }
From source file:cn.annoreg.asm.DelegateGenerator.java
License:Open Source License
public static MethodVisitor generateNonStaticMethod(ClassVisitor parentClass, MethodVisitor parent, String className, String methodName, String desc, final Side side) { //convert desc to a non-static method form String nonstaticDesc;/* www .j a va2 s . co m*/ { Type staticType = Type.getMethodType(desc); Type retType = staticType.getReturnType(); Type[] argsType = staticType.getArgumentTypes(); Type[] argsTypeWithThis = new Type[argsType.length + 1]; argsTypeWithThis[0] = Type.getType('L' + className.replace('.', '/') + ';'); System.arraycopy(argsType, 0, argsTypeWithThis, 1, argsType.length); nonstaticDesc = Type.getMethodDescriptor(retType, argsTypeWithThis); } //delegateName is a string used by both sides to identify a network-call delegate. final String delegateName = className + ":" + methodName + ":" + desc; final Type[] args = Type.getArgumentTypes(nonstaticDesc); final Type ret = Type.getReturnType(nonstaticDesc); //Check types for (Type t : args) { //TODO support these types if (!t.getDescriptor().startsWith("L") && !t.getDescriptor().startsWith("[")) { throw new RuntimeException("Unsupported argument type in network call. "); } } if (!ret.equals(Type.VOID_TYPE)) { throw new RuntimeException( "Unsupported return value type in network call. " + "Only void is supported."); } //Generate call to NetworkCallManager in parent. parent.visitCode(); //First parameter parent.visitLdcInsn(delegateName); //Second parameter: object array pushIntegerConst(parent, args.length); //this (0) has been included parent.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object"); for (int i = 0; i < args.length; ++i) { parent.visitInsn(Opcodes.DUP); pushIntegerConst(parent, i); parent.visitVarInsn(Opcodes.ALOAD, i); parent.visitInsn(Opcodes.AASTORE); } //Call cn.annoreg.mc.network.NetworkCallManager.onNetworkCall parent.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(NetworkCallManager.class), "onNetworkCall", "(Ljava/lang/String;[Ljava/lang/Object;)V"); parent.visitInsn(Opcodes.RETURN); parent.visitMaxs(5, args.length); parent.visitEnd(); //Create delegate object. final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); final String delegateId = Integer.toString(delegateNextID++); final Type delegateClassType = Type.getType("cn/annoreg/asm/NetworkCallDelegate_" + delegateId); cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, delegateClassType.getInternalName(), null, Type.getInternalName(Object.class), new String[] { Type.getInternalName(NetworkCallDelegate.class) }); //package cn.annoreg.asm; //class NetworkCallDelegate_? implements NetworkCallDelegate { { MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), "<init>", "()V"); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } //public NetworkCallDelegate_?() {} final String delegateMethodName = methodName + "_delegate_" + delegateId; { MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "invoke", Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(Object[].class)), null, null); mv.visitCode(); //check if this is null mv.visitVarInsn(Opcodes.ALOAD, 1); //0 is this pushIntegerConst(mv, 0); mv.visitInsn(Opcodes.AALOAD); Label lblEnd = new Label(); mv.visitJumpInsn(Opcodes.IFNULL, lblEnd); for (int i = 0; i < args.length; ++i) { mv.visitVarInsn(Opcodes.ALOAD, 1); //0 is this pushIntegerConst(mv, i); mv.visitInsn(Opcodes.AALOAD); mv.visitTypeInsn(Opcodes.CHECKCAST, args[i].getInternalName()); } mv.visitMethodInsn(Opcodes.INVOKESTATIC, //delegateClassType.getInternalName(), className.replace('.', '/'), delegateMethodName, nonstaticDesc); mv.visitLabel(lblEnd); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(args.length + 2, 2); mv.visitEnd(); } //@Override public void invoke(Object[] args) { // delegated((Type0) args[0], (Type1) args[1], ...); //} //The returned MethodVisitor will visit the original version of the method, //including its annotation, where we can get StorageOptions. return new MethodVisitor(Opcodes.ASM4, parentClass.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, delegateMethodName, nonstaticDesc, null, null)) { //Remember storage options for each argument StorageOption.Option[] options = new StorageOption.Option[args.length]; int targetIndex = -1; double sendRange = -1; StorageOption.Target.RangeOption range = StorageOption.Target.RangeOption.SINGLE; { for (int i = 0; i < options.length; ++i) { options[i] = StorageOption.Option.NULL; //set default value } options[0] = StorageOption.Option.INSTANCE; } @Override public AnnotationVisitor visitParameterAnnotation(int parameter_in_func, String desc, boolean visible) { final int parameter = parameter_in_func + 1; //skip this Type type = Type.getType(desc); if (type.equals(Type.getType(StorageOption.Data.class))) { options[parameter] = StorageOption.Option.DATA; } else if (type.equals(Type.getType(StorageOption.Instance.class))) { //INSTANCE as defualt options[parameter] = StorageOption.Option.INSTANCE; //Change to NULLABLE_INSTANCE if nullable set to true return new AnnotationVisitor(this.api, super.visitParameterAnnotation(parameter, desc, visible)) { @Override public void visit(String name, Object value) { if (name.equals("nullable")) { if ((Boolean) value == true) { options[parameter] = StorageOption.Option.NULLABLE_INSTANCE; } } super.visit(name, value); } }; } else if (type.equals(Type.getType(StorageOption.Update.class))) { options[parameter] = StorageOption.Option.UPDATE; } else if (type.equals(Type.getType(StorageOption.Null.class))) { options[parameter] = StorageOption.Option.NULL; } else if (type.equals(Type.getType(StorageOption.Target.class))) { if (!args[parameter].equals(Type.getType(EntityPlayer.class))) { throw new RuntimeException("Target annotation can only be used on EntityPlayer."); } if (targetIndex != -1) { throw new RuntimeException("You can not specify multiple targets."); } options[parameter] = StorageOption.Option.INSTANCE; targetIndex = parameter; return new AnnotationVisitor(this.api, super.visitParameterAnnotation(parameter, desc, visible)) { @Override public void visitEnum(String name, String desc, String value) { super.visitEnum(name, desc, value); range = StorageOption.Target.RangeOption.valueOf(value); } }; } else if (type.equals(Type.getType(StorageOption.RangedTarget.class))) { if (targetIndex != -1) { throw new RuntimeException("You can not specify multiple targets."); } targetIndex = parameter; range = null; return new AnnotationVisitor(this.api, super.visitParameterAnnotation(parameter, desc, visible)) { @Override public void visit(String name, Object value) { super.visit(name, value); sendRange = (double) value; } }; } return super.visitParameterAnnotation(parameter, desc, visible); } //TODO this option (from annotation) @Override public void visitEnd() { super.visitEnd(); //This is the last method in the delegate class. //Finish the class and do the registration. cw.visitEnd(); try { Class<?> clazz = classLoader.defineClass(delegateClassType.getClassName(), cw.toByteArray()); NetworkCallDelegate delegateObj = (NetworkCallDelegate) clazz.newInstance(); if (side == Side.CLIENT) { NetworkCallManager.registerClientDelegateClass(delegateName, delegateObj, options, targetIndex, range, sendRange); } else { NetworkCallManager.registerServerDelegateClass(delegateName, delegateObj, options); } } catch (Throwable e) { throw new RuntimeException("Can not create delegate for network call.", e); } } }; //public static void delegated(Type0 arg0, Type1, arg1, ...) { // //Code generated by caller. //} //} }
From source file:co.cask.cdap.app.runtime.spark.SparkRunnerClassLoader.java
License:Apache License
/** * Defines the DStreamGraph class by rewriting calls to parallel array with a call to * SparkRuntimeUtils#setTaskSupport(ParArray). *//* w ww.j av a 2s . co m*/ private Class<?> defineDStreamGraph(String name, InputStream byteCodeStream) throws IOException { ClassReader cr = new ClassReader(byteCodeStream); ClassWriter cw = new ClassWriter(0); cr.accept(new ClassVisitor(Opcodes.ASM5, cw) { @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); return new MethodVisitor(Opcodes.ASM5, mv) { @Override public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { super.visitMethodInsn(opcode, owner, name, desc, itf); // If detected call to ArrayBuffer.par(), set the TaskSupport to avoid thread leak. //INVOKEVIRTUAL scala/collection/mutable/ ArrayBuffer.par ()Lscala/collection/parallel/mutable/ParArray; Type returnType = Type.getReturnType(desc); if (opcode == Opcodes.INVOKEVIRTUAL && name.equals("par") && owner.equals("scala/collection/mutable/ArrayBuffer") && returnType.getClassName().equals("scala.collection.parallel.mutable.ParArray")) { super.visitMethodInsn(Opcodes.INVOKESTATIC, SPARK_RUNTIME_UTILS_TYPE.getInternalName(), "setTaskSupport", Type.getMethodDescriptor(returnType, returnType), false); } } }; } }, ClassReader.EXPAND_FRAMES); byte[] byteCode = cw.toByteArray(); return defineClass(name, byteCode, 0, byteCode.length); }
From source file:co.cask.cdap.app.runtime.spark.SparkRunnerClassLoader.java
License:Apache License
/** * Rewrites the constructors who don't delegate to other constructor with the given {@link ConstructorRewriter} * and define the class./*from w w w . j a v a 2s. c o m*/ * * @param classType type of the class to be defined * @param byteCodeStream {@link InputStream} for reading the original bytecode of the class * @param rewriter a {@link ConstructorRewriter} for rewriting the constructor * @return a defined Class */ private Class<?> rewriteConstructorAndDefineClass(final Type classType, InputStream byteCodeStream, final ConstructorRewriter rewriter) throws IOException { ClassReader cr = new ClassReader(byteCodeStream); ClassWriter cw = new ClassWriter(0); cr.accept(new ClassVisitor(Opcodes.ASM5, cw) { @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { // Call super so that the method signature is registered with the ClassWriter (parent) MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); // We only attempt to rewrite constructor if (!"<init>".equals(name)) { return mv; } return new AdviceAdapter(Opcodes.ASM5, mv, access, name, desc) { boolean calledThis; @Override public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { // See if in this constructor it is calling other constructor (this(..)). calledThis = calledThis || (opcode == Opcodes.INVOKESPECIAL && Type.getObjectType(owner).equals(classType) && name.equals("<init>") && Type.getReturnType(desc).equals(Type.VOID_TYPE)); super.visitMethodInsn(opcode, owner, name, desc, itf); } @Override protected void onMethodExit(int opcode) { if (calledThis) { // For constructors that call this(), we don't need to generate a call to SparkContextCache return; } // Add a call to SparkContextCache.setContext() for the normal method return path if (opcode == RETURN) { rewriter.onMethodExit(this); } } }; } }, ClassReader.EXPAND_FRAMES); byte[] byteCode = cw.toByteArray(); return defineClass(classType.getClassName(), byteCode, 0, byteCode.length); }
From source file:co.cask.cdap.app.runtime.spark.SparkRunnerClassLoader.java
License:Apache License
/** * Find the return type of the ActorSystem.dispatcher() method. It is ExecutionContextExecutor in * Akka 2.3 (Spark 1.2+) and ExecutionContext in Akka 2.2 (Spark < 1.2, which CDAP doesn't support, * however the Spark 1.5 in CDH 5.6. still has Akka 2.2, instead of 2.3). * * @return the return type of the ActorSystem.dispatcher() method or {@code null} if no such method */// ww w .j a v a 2 s.c o m @Nullable private Type determineAkkaDispatcherReturnType() { try (InputStream is = openResource("akka/actor/ActorSystem.class")) { if (is == null) { return null; } final AtomicReference<Type> result = new AtomicReference<>(); ClassReader cr = new ClassReader(is); cr.accept(new ClassVisitor(Opcodes.ASM5) { @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { if (name.equals("dispatcher") && Type.getArgumentTypes(desc).length == 0) { // Expected to be either ExecutionContext (akka 2.2, only in CDH spark) // or ExecutionContextExecutor (akka 2.3, for open source, HDP spark). Type returnType = Type.getReturnType(desc); if (returnType.equals(EXECUTION_CONTEXT_TYPE) || returnType.equals(EXECUTION_CONTEXT_EXECUTOR_TYPE)) { result.set(returnType); } else { LOG.warn("Unsupported return type of ActorSystem.dispatcher(): {}", returnType.getClassName()); } } return super.visitMethod(access, name, desc, signature, exceptions); } }, ClassReader.SKIP_DEBUG | ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES); return result.get(); } catch (IOException e) { LOG.warn("Failed to determine ActorSystem dispatcher() return type.", e); return null; } }