public Class createProxy(Class<?> clsToProxy, ClassLoader cl) { String proxyName = generateProxyName(clsToProxy.getName()); return createProxy(clsToProxy, proxyName, cl); }
/** * Gets the string to use for CHECKCAST instruction, returning the correct value for any type, including primitives and arrays * @param returnType The type to cast to with CHECKCAST * @return CHECKCAST parameter */ String getCastType(Class<?> returnType) { if (returnType.isPrimitive()) { return getWrapperType(returnType); } else { return getAsmTypeAsString(returnType, false); } }
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, method.getName(), getMethodSignatureAsString(returnType, parameterTypes), null, null); mv.visitCode(); createArrayDefinition(mv, parameterTypes.length, Class.class); pushIntOntoStack(mv, i); String wrapperType = getWrapperType(parameterType); mv.visitFieldInsn(GETSTATIC, wrapperType, "TYPE", "Ljava/lang/Class;"); } else { mv.visitLdcInsn(Type.getType(getAsmTypeAsString(parameterType, true))); createArrayDefinition(mv, parameterTypes.length, Object.class); pushIntOntoStack(mv, i); String wrapperType = getWrapperType(parameterType); mv.visitVarInsn(getVarInsn(parameterType), index); mv.visitMethodInsn(INVOKESTATIC, wrapperType, "valueOf", "(" + getPrimitiveLetter(parameterType) + ")L" + wrapperType + ";"); mv.visitInsn(AASTORE); mv.visitTypeInsn(CHECKCAST, getCastType(returnType)); mv.visitMethodInsn(INVOKEVIRTUAL, getWrapperType(returnType), getPrimitiveMethod(returnType), "()" + getPrimitiveLetter(returnType)); mv.visitInsn(getReturnInsn(returnType)); } else { mv.visitInsn(POP);
/** * Converts a class to a String suitable for ASM. * @param parameterType Class to convert * @param wrap True if a non-array object should be wrapped with L and ; - e.g. Ljava/lang/Integer; * @return String to use for ASM */ public String getAsmTypeAsString(Class<?> parameterType, boolean wrap) { if (parameterType.isArray()) { if (parameterType.getComponentType().isPrimitive()) { Class<?> componentType = parameterType.getComponentType(); return "[" + getPrimitiveLetter(componentType); } else { return "[" + getAsmTypeAsString(parameterType.getComponentType(), true); } } else { if (! parameterType.isPrimitive()) { if (wrap) { return "L" + parameterType.getCanonicalName().replaceAll("\\.", "/") + ";"; } else { return parameterType.getCanonicalName().replaceAll("\\.", "/"); } } else { return getPrimitiveLetter(parameterType); } } }
public static Object newProxyInstance(ClassLoader cl, Class interfce, java.lang.reflect.InvocationHandler h) throws IllegalArgumentException { try { Class proxyCls = new LocalBeanProxyGeneratorImpl().createProxy(interfce, cl); Constructor constructor = proxyCls.getConstructor(java.lang.reflect.InvocationHandler.class); Object object = constructor.newInstance(h); return object; } catch (NoSuchMethodException e) { throw new InternalError(e.toString()); } catch (InstantiationException e) { throw new InternalError(e.toString()); } catch (IllegalAccessException e) { throw new InternalError(e.toString()); } catch (InvocationTargetException e) { throw new InternalError(e.toString()); } }
String getMethodSignatureAsString(Class<?> returnType, Class<?>[] parameterTypes) { StringBuilder builder = new StringBuilder(); builder.append("("); for (Class<?> parameterType : parameterTypes) { builder.append(getAsmTypeAsString(parameterType, true)); } builder.append(")"); builder.append(getAsmTypeAsString(returnType, true)); return builder.toString(); }
private Class createProxy(Class<?> clsToProxy, String proxyName, ClassLoader cl) { String clsName = proxyName.replaceAll("\\.", "/"); try { return cl.loadClass(proxyName); } catch (Exception e) { } try { byte[] proxyBytes = generateProxy(clsToProxy, clsName); return (Class<?>) unsafe.defineClass(proxyName, proxyBytes, 0, proxyBytes.length, cl, this.getClass().getProtectionDomain()); } catch (ProxyGenerationException e) { throw new InternalError(e.toString()); } }