Search in sources :

Example 1 with SncpAction

use of org.redkale.net.sncp.SncpClient.SncpAction in project redkale by redkale.

the class Sncp method createRemoteService.

/**
 * <blockquote><pre>
 * &#64;Resource(name = "")
 * &#64;SncpDyn(remote = true)
 * &#64;ResourceType(TestService.class)
 * public final class _DynRemoteTestService extends TestService{
 *
 *      private AnyValue _redkale_conf;
 *
 *      private SncpClient _redkale_client;
 *
 *      &#64;SncpDyn(remote = false, index = 0)
 *      public void _redkale_createSomeThing(boolean selfrunnable, boolean samerunnable, boolean diffrunnable, TestBean bean){
 *          _redkale_client.remote(0, selfrunnable, samerunnable, diffrunnable, bean);
 *      }
 *
 *      &#64;SncpDyn(remote = false, index = 1)
 *      public String _redkale_updateSomeThing(boolean selfrunnable, boolean samerunnable, boolean diffrunnable, String id){
 *          return _redkale_client.remote(1, selfrunnable, samerunnable, diffrunnable, id);
 *      }
 *
 *      &#64;Override
 *      public void createSomeThing(TestBean bean){
 *          _redkale_client.remote(2, bean);
 *      }
 *
 *      &#64;Override
 *      public String findSomeThing(){
 *          return _redkale_client.remote(3);
 *      }
 *
 *      &#64;Override
 *      public String updateSomeThing(String id){
 *          return  _redkale_client.remote(4, id);
 *      }
 * }
 * </pre></blockquote>
 *
 * 创建远程模式的Service实例
 *
 * @param <T>                    Service泛型
 * @param classLoader            ClassLoader
 * @param name                   资源名
 * @param serviceTypeOrImplClass Service类
 * @param transportFactory       TransportFactory
 * @param clientAddress          本地IP地址
 * @param groups0                 所有的组节点,包含自身
 * @param conf                   启动配置项
 *
 * @return Service的远程模式实例
 */
@SuppressWarnings("unchecked")
public static <T extends Service> T createRemoteService(final ClassLoader classLoader, final String name, final Class<T> serviceTypeOrImplClass, final TransportFactory transportFactory, final InetSocketAddress clientAddress, final Set<String> groups0, final AnyValue conf) {
    if (serviceTypeOrImplClass == null)
        return null;
    if (!Service.class.isAssignableFrom(serviceTypeOrImplClass))
        return null;
    Set<String> groups = groups0 == null ? new HashSet<>() : groups0;
    ResourceFactory.checkResourceName(name);
    int mod = serviceTypeOrImplClass.getModifiers();
    boolean realed = !(java.lang.reflect.Modifier.isAbstract(mod) || serviceTypeOrImplClass.isInterface());
    if (!java.lang.reflect.Modifier.isPublic(mod))
        return null;
    final String supDynName = serviceTypeOrImplClass.getName().replace('.', '/');
    final String clientName = SncpClient.class.getName().replace('.', '/');
    final String resDesc = Type.getDescriptor(Resource.class);
    final String clientDesc = Type.getDescriptor(SncpClient.class);
    final String sncpDynDesc = Type.getDescriptor(SncpDyn.class);
    final String anyValueDesc = Type.getDescriptor(AnyValue.class);
    ClassLoader loader = classLoader == null ? Thread.currentThread().getContextClassLoader() : classLoader;
    String newDynName = supDynName.substring(0, supDynName.lastIndexOf('/') + 1) + REMOTEPREFIX + serviceTypeOrImplClass.getSimpleName();
    try {
        Class newClazz = loader.loadClass(newDynName.replace('/', '.'));
        T rs = (T) newClazz.getDeclaredConstructor().newInstance();
        SncpClient client = new SncpClient(name, serviceTypeOrImplClass, rs, transportFactory, true, realed ? createLocalServiceClass(loader, name, serviceTypeOrImplClass) : serviceTypeOrImplClass, clientAddress);
        client.setRemoteGroups(groups);
        client.setRemoteGroupTransport(transportFactory.loadRemoteTransport(clientAddress, groups));
        Field c = newClazz.getDeclaredField(FIELDPREFIX + "_client");
        c.setAccessible(true);
        c.set(rs, client);
        transportFactory.addSncpService(rs);
        return rs;
    } catch (Throwable ex) {
    }
    // ------------------------------------------------------------------------------
    ClassWriter cw = new ClassWriter(COMPUTE_FRAMES);
    FieldVisitor fv;
    MethodDebugVisitor mv;
    AnnotationVisitor av0;
    cw.visit(V1_8, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, null, serviceTypeOrImplClass.isInterface() ? "java/lang/Object" : supDynName, serviceTypeOrImplClass.isInterface() ? new String[] { supDynName } : null);
    {
        av0 = cw.visitAnnotation(resDesc, true);
        av0.visit("name", name);
        av0.visitEnd();
    }
    {
        av0 = cw.visitAnnotation(Type.getDescriptor(ResourceType.class), true);
        ResourceType rty = serviceTypeOrImplClass.getAnnotation(ResourceType.class);
        av0.visit("value", Type.getType(Type.getDescriptor(rty == null ? serviceTypeOrImplClass : rty.value())));
        av0.visitEnd();
    }
    {
        av0 = cw.visitAnnotation(sncpDynDesc, true);
        av0.visit("remote", Boolean.TRUE);
        av0.visitEnd();
    }
    {
        // 给新类加上 原有的Annotation
        for (Annotation ann : serviceTypeOrImplClass.getAnnotations()) {
            if (ann instanceof Resource || ann instanceof SncpDyn || ann instanceof ResourceType)
                continue;
            visitAnnotation(cw.visitAnnotation(Type.getDescriptor(ann.annotationType()), true), ann);
        }
    }
    {
        fv = cw.visitField(ACC_PRIVATE, FIELDPREFIX + "_conf", anyValueDesc, null, null);
        fv.visitEnd();
    }
    {
        fv = cw.visitField(ACC_PRIVATE, FIELDPREFIX + "_client", clientDesc, null, null);
        fv.visitEnd();
    }
    {
        // 构造函数
        mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null));
        // mv.setDebug(true);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, serviceTypeOrImplClass.isInterface() ? "java/lang/Object" : supDynName, "<init>", "()V", false);
        mv.visitInsn(RETURN);
        mv.visitMaxs(1, 1);
        mv.visitEnd();
    }
    {
        // init
        mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "init", "(" + anyValueDesc + ")V", null, null));
        mv.visitInsn(RETURN);
        mv.visitMaxs(0, 2);
        mv.visitEnd();
    }
    {
        // destroy
        mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "destroy", "(" + anyValueDesc + ")V", null, null));
        mv.visitInsn(RETURN);
        mv.visitMaxs(0, 2);
        mv.visitEnd();
    }
    {
        // toString()
        mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null));
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, newDynName, FIELDPREFIX + "_client", clientDesc);
        Label l1 = new Label();
        mv.visitJumpInsn(IFNONNULL, l1);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getName", "()Ljava/lang/String;", false);
        Label l2 = new Label();
        mv.visitJumpInsn(GOTO, l2);
        mv.visitLabel(l1);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, newDynName, FIELDPREFIX + "_client", clientDesc);
        mv.visitMethodInsn(INVOKEVIRTUAL, clientName, "toSimpleString", "()Ljava/lang/String;", false);
        mv.visitLabel(l2);
        mv.visitInsn(ARETURN);
        mv.visitMaxs(1, 1);
        mv.visitEnd();
    }
    int i = -1;
    for (final SncpAction entry : SncpClient.getSncpActions(realed ? createLocalServiceClass(loader, name, serviceTypeOrImplClass) : serviceTypeOrImplClass)) {
        final int index = ++i;
        final java.lang.reflect.Method method = entry.method;
        {
            mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, method.getName(), Type.getMethodDescriptor(method), null, null));
            // mv.setDebug(true);
            {
                // 给参数加上 Annotation
                final Annotation[][] anns = method.getParameterAnnotations();
                for (int k = 0; k < anns.length; k++) {
                    for (Annotation ann : anns[k]) {
                        visitAnnotation(mv.visitParameterAnnotation(k, Type.getDescriptor(ann.annotationType()), true), ann);
                    }
                }
            }
            mv.visitVarInsn(ALOAD, 0);
            mv.visitFieldInsn(GETFIELD, newDynName, FIELDPREFIX + "_client", clientDesc);
            pushInt(mv, index);
            {
                // 传参数
                int paramlen = entry.paramTypes.length;
                pushInt(mv, paramlen);
                mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
                java.lang.reflect.Type[] paramtypes = entry.paramTypes;
                int insn = 0;
                for (int j = 0; j < paramtypes.length; j++) {
                    final java.lang.reflect.Type pt = paramtypes[j];
                    mv.visitInsn(DUP);
                    insn++;
                    pushInt(mv, j);
                    if (pt instanceof Class && ((Class) pt).isPrimitive()) {
                        if (pt == long.class) {
                            mv.visitVarInsn(LLOAD, insn++);
                        } else if (pt == float.class) {
                            mv.visitVarInsn(FLOAD, insn++);
                        } else if (pt == double.class) {
                            mv.visitVarInsn(DLOAD, insn++);
                        } else {
                            mv.visitVarInsn(ILOAD, insn);
                        }
                        Class bigclaz = java.lang.reflect.Array.get(java.lang.reflect.Array.newInstance((Class) pt, 1), 0).getClass();
                        mv.visitMethodInsn(INVOKESTATIC, bigclaz.getName().replace('.', '/'), "valueOf", "(" + Type.getDescriptor((Class) pt) + ")" + Type.getDescriptor(bigclaz), false);
                    } else {
                        mv.visitVarInsn(ALOAD, insn);
                    }
                    mv.visitInsn(AASTORE);
                }
            }
            mv.visitMethodInsn(INVOKEVIRTUAL, clientName, "remote", "(I[Ljava/lang/Object;)Ljava/lang/Object;", false);
            // mv.visitMethodInsn(INVOKEVIRTUAL, convertName, "convertFrom", convertFromDesc, false);
            if (method.getGenericReturnType() == void.class) {
                mv.visitInsn(POP);
                mv.visitInsn(RETURN);
            } else {
                Class returnclz = method.getReturnType();
                Class bigPrimitiveClass = returnclz.isPrimitive() ? java.lang.reflect.Array.get(java.lang.reflect.Array.newInstance(returnclz, 1), 0).getClass() : returnclz;
                mv.visitTypeInsn(CHECKCAST, (returnclz.isPrimitive() ? bigPrimitiveClass : returnclz).getName().replace('.', '/'));
                if (returnclz.isPrimitive()) {
                    String bigPrimitiveName = bigPrimitiveClass.getName().replace('.', '/');
                    try {
                        java.lang.reflect.Method pm = bigPrimitiveClass.getMethod(returnclz.getSimpleName() + "Value");
                        mv.visitMethodInsn(INVOKEVIRTUAL, bigPrimitiveName, pm.getName(), Type.getMethodDescriptor(pm), false);
                    } catch (Exception ex) {
                        // 不可能会发生
                        throw new RuntimeException(ex);
                    }
                    if (returnclz == long.class) {
                        mv.visitInsn(LRETURN);
                    } else if (returnclz == float.class) {
                        mv.visitInsn(FRETURN);
                    } else if (returnclz == double.class) {
                        mv.visitInsn(DRETURN);
                    } else {
                        mv.visitInsn(IRETURN);
                    }
                } else {
                    mv.visitInsn(ARETURN);
                }
            }
            mv.visitMaxs(20, 20);
            mv.visitEnd();
        }
    }
    cw.visitEnd();
    byte[] bytes = cw.toByteArray();
    Class<?> newClazz = new ClassLoader(loader) {

        public final Class<?> loadClass(String name, byte[] b) {
            return defineClass(name, b, 0, b.length);
        }
    }.loadClass(newDynName.replace('/', '.'), bytes);
    try {
        T rs = (T) newClazz.getDeclaredConstructor().newInstance();
        SncpClient client = new SncpClient(name, serviceTypeOrImplClass, rs, transportFactory, true, realed ? createLocalServiceClass(loader, name, serviceTypeOrImplClass) : serviceTypeOrImplClass, clientAddress);
        client.setRemoteGroups(groups);
        client.setRemoteGroupTransport(transportFactory.loadRemoteTransport(clientAddress, groups));
        {
            Field c = newClazz.getDeclaredField(FIELDPREFIX + "_client");
            c.setAccessible(true);
            c.set(rs, client);
        }
        {
            Field c = newClazz.getDeclaredField(FIELDPREFIX + "_conf");
            c.setAccessible(true);
            c.set(rs, conf);
        }
        transportFactory.addSncpService(rs);
        return rs;
    } catch (Exception ex) {
        throw new RuntimeException(ex);
    }
}
Also used : MethodDebugVisitor(org.redkale.asm.MethodDebugVisitor) java.lang.reflect(java.lang.reflect) SncpAction(org.redkale.net.sncp.SncpClient.SncpAction) Resource(javax.annotation.Resource) Annotation(java.lang.annotation.Annotation) Type(org.redkale.asm.Type)

Example 2 with SncpAction

use of org.redkale.net.sncp.SncpClient.SncpAction in project redkale by redkale.

the class Sncp method createRemoteService.

/**
 * <blockquote><pre>
 * &#64;Resource(name = "")
 * &#64;SncpDyn(remote = true)
 * &#64;ResourceType(TestService.class)
 * public final class _DynRemoteTestService extends TestService{
 *
 *      private AnyValue _redkale_conf;
 *
 *      private SncpClient _redkale_client;
 *
 *      &#64;Override
 *      public void createSomeThing(TestBean bean){
 *          _redkale_client.remote(0, bean);
 *      }
 *
 *      &#64;Override
 *      public String findSomeThing(){
 *          return _redkale_client.remote(1);
 *      }
 *
 *      &#64;Override
 *      public String updateSomeThing(String id){
 *          return  _redkale_client.remote(2, id);
 *      }
 * }
 * </pre></blockquote>
 *
 * 创建远程模式的Service实例
 *
 * @param <T>                    Service泛型
 * @param classLoader            ClassLoader
 * @param name                   资源名
 * @param serviceTypeOrImplClass Service类
 * @param messageAgent           MQ管理器
 * @param transportFactory       TransportFactory
 * @param clientAddress          本地IP地址
 * @param groups0                所有的组节点,包含自身
 * @param conf                   启动配置项
 *
 * @return Service的远程模式实例
 */
@SuppressWarnings("unchecked")
public static <T extends Service> T createRemoteService(final ClassLoader classLoader, final String name, final Class<T> serviceTypeOrImplClass, final MessageAgent messageAgent, final TransportFactory transportFactory, final InetSocketAddress clientAddress, final Set<String> groups0, final AnyValue conf) {
    if (serviceTypeOrImplClass == null)
        return null;
    if (!Service.class.isAssignableFrom(serviceTypeOrImplClass))
        return null;
    final Set<String> groups = groups0 == null ? new HashSet<>() : groups0;
    ResourceFactory.checkResourceName(name);
    final int mod = serviceTypeOrImplClass.getModifiers();
    boolean realed = !(java.lang.reflect.Modifier.isAbstract(mod) || serviceTypeOrImplClass.isInterface());
    if (!java.lang.reflect.Modifier.isPublic(mod))
        return null;
    final String supDynName = serviceTypeOrImplClass.getName().replace('.', '/');
    final String clientName = SncpClient.class.getName().replace('.', '/');
    final String resDesc = Type.getDescriptor(Resource.class);
    final String clientDesc = Type.getDescriptor(SncpClient.class);
    final String sncpDynDesc = Type.getDescriptor(SncpDyn.class);
    final String anyValueDesc = Type.getDescriptor(AnyValue.class);
    final ClassLoader loader = classLoader == null ? Thread.currentThread().getContextClassLoader() : classLoader;
    // final String newDynName = supDynName.substring(0, supDynName.lastIndexOf('/') + 1) + REMOTEPREFIX + serviceTypeOrImplClass.getSimpleName();
    final String newDynName = "org/redkaledyn/service/remote/_DynRemoteService__" + serviceTypeOrImplClass.getName().replace('.', '_').replace('$', '_');
    try {
        Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.'));
        Class newClazz = clz == null ? loader.loadClass(newDynName.replace('/', '.')) : clz;
        T service = (T) newClazz.getDeclaredConstructor().newInstance();
        SncpClient client = new SncpClient(name, serviceTypeOrImplClass, service, messageAgent, transportFactory, true, realed ? createLocalServiceClass(loader, name, serviceTypeOrImplClass) : serviceTypeOrImplClass, clientAddress);
        client.setRemoteGroups(groups);
        if (transportFactory != null)
            client.setRemoteGroupTransport(transportFactory.loadTransport(clientAddress, groups));
        {
            Field c = newClazz.getDeclaredField(FIELDPREFIX + "_client");
            c.setAccessible(true);
            c.set(service, client);
        }
        if (messageAgent != null) {
            Field c = newClazz.getDeclaredField(FIELDPREFIX + "_messageagent");
            c.setAccessible(true);
            c.set(service, messageAgent);
            if (service instanceof WebSocketNode) {
                c = WebSocketNode.class.getDeclaredField("messageAgent");
                c.setAccessible(true);
                c.set(service, messageAgent);
            }
        }
        {
            Field c = newClazz.getDeclaredField(FIELDPREFIX + "_conf");
            c.setAccessible(true);
            c.set(service, conf);
        }
        if (transportFactory != null)
            transportFactory.addSncpService(service);
        return service;
    } catch (Throwable ex) {
    }
    // ------------------------------------------------------------------------------
    ClassWriter cw = new ClassWriter(COMPUTE_FRAMES);
    FieldVisitor fv;
    MethodDebugVisitor mv;
    AnnotationVisitor av0;
    cw.visit(V11, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, null, serviceTypeOrImplClass.isInterface() ? "java/lang/Object" : supDynName, serviceTypeOrImplClass.isInterface() ? new String[] { supDynName } : null);
    {
        av0 = cw.visitAnnotation(resDesc, true);
        av0.visit("name", name);
        av0.visitEnd();
    }
    {
        av0 = cw.visitAnnotation(Type.getDescriptor(ResourceType.class), true);
        ResourceType rty = serviceTypeOrImplClass.getAnnotation(ResourceType.class);
        av0.visit("value", Type.getType(Type.getDescriptor(rty == null ? serviceTypeOrImplClass : rty.value())));
        av0.visitEnd();
    }
    {
        av0 = cw.visitAnnotation(sncpDynDesc, true);
        av0.visit("remote", Boolean.TRUE);
        av0.visitEnd();
    }
    {
        // 给新类加上 原有的Annotation
        for (Annotation ann : serviceTypeOrImplClass.getAnnotations()) {
            if (ann instanceof Resource || ann instanceof SncpDyn || ann instanceof ResourceType)
                continue;
            MethodDebugVisitor.visitAnnotation(cw.visitAnnotation(Type.getDescriptor(ann.annotationType()), true), ann);
        }
    }
    {
        fv = cw.visitField(ACC_PRIVATE, FIELDPREFIX + "_conf", anyValueDesc, null, null);
        fv.visitEnd();
    }
    {
        fv = cw.visitField(ACC_PRIVATE, FIELDPREFIX + "_client", clientDesc, null, null);
        fv.visitEnd();
    }
    {
        fv = cw.visitField(ACC_PRIVATE, FIELDPREFIX + "_messageagent", Type.getDescriptor(MessageAgent.class), null, null);
        fv.visitEnd();
    }
    {
        // 构造函数
        mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null));
        // mv.setDebug(true);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, serviceTypeOrImplClass.isInterface() ? "java/lang/Object" : supDynName, "<init>", "()V", false);
        mv.visitInsn(RETURN);
        mv.visitMaxs(1, 1);
        mv.visitEnd();
    }
    {
        // init
        mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "init", "(" + anyValueDesc + ")V", null, null));
        mv.visitInsn(RETURN);
        mv.visitMaxs(0, 2);
        mv.visitEnd();
    }
    {
        // stop
        mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "stop", "(" + anyValueDesc + ")V", null, null));
        mv.visitInsn(RETURN);
        mv.visitMaxs(0, 2);
        mv.visitEnd();
    }
    {
        // destroy
        mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "destroy", "(" + anyValueDesc + ")V", null, null));
        mv.visitInsn(RETURN);
        mv.visitMaxs(0, 2);
        mv.visitEnd();
    }
    {
        // toString()
        mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null));
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, newDynName, FIELDPREFIX + "_client", clientDesc);
        Label l1 = new Label();
        mv.visitJumpInsn(IFNONNULL, l1);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getName", "()Ljava/lang/String;", false);
        Label l2 = new Label();
        mv.visitJumpInsn(GOTO, l2);
        mv.visitLabel(l1);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, newDynName, FIELDPREFIX + "_client", clientDesc);
        mv.visitMethodInsn(INVOKEVIRTUAL, clientName, "toSimpleString", "()Ljava/lang/String;", false);
        mv.visitLabel(l2);
        mv.visitInsn(ARETURN);
        mv.visitMaxs(1, 1);
        mv.visitEnd();
    }
    int i = -1;
    for (final SncpAction entry : SncpClient.getSncpActions(realed ? createLocalServiceClass(loader, name, serviceTypeOrImplClass) : serviceTypeOrImplClass)) {
        final int index = ++i;
        final java.lang.reflect.Method method = entry.method;
        {
            mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, method.getName(), Type.getMethodDescriptor(method), null, null));
            // mv.setDebug(true);
            {
                // 给参数加上 Annotation
                final Annotation[][] anns = method.getParameterAnnotations();
                for (int k = 0; k < anns.length; k++) {
                    for (Annotation ann : anns[k]) {
                        MethodDebugVisitor.visitAnnotation(mv.visitParameterAnnotation(k, Type.getDescriptor(ann.annotationType()), true), ann);
                    }
                }
            }
            mv.visitVarInsn(ALOAD, 0);
            mv.visitFieldInsn(GETFIELD, newDynName, FIELDPREFIX + "_client", clientDesc);
            MethodDebugVisitor.pushInt(mv, index);
            {
                // 传参数
                int paramlen = entry.paramTypes.length;
                MethodDebugVisitor.pushInt(mv, paramlen);
                mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
                java.lang.reflect.Type[] paramtypes = entry.paramTypes;
                int insn = 0;
                for (int j = 0; j < paramtypes.length; j++) {
                    final java.lang.reflect.Type pt = paramtypes[j];
                    mv.visitInsn(DUP);
                    insn++;
                    MethodDebugVisitor.pushInt(mv, j);
                    if (pt instanceof Class && ((Class) pt).isPrimitive()) {
                        if (pt == long.class) {
                            mv.visitVarInsn(LLOAD, insn++);
                        } else if (pt == float.class) {
                            mv.visitVarInsn(FLOAD, insn++);
                        } else if (pt == double.class) {
                            mv.visitVarInsn(DLOAD, insn++);
                        } else {
                            mv.visitVarInsn(ILOAD, insn);
                        }
                        Class bigclaz = java.lang.reflect.Array.get(java.lang.reflect.Array.newInstance((Class) pt, 1), 0).getClass();
                        mv.visitMethodInsn(INVOKESTATIC, bigclaz.getName().replace('.', '/'), "valueOf", "(" + Type.getDescriptor((Class) pt) + ")" + Type.getDescriptor(bigclaz), false);
                    } else {
                        mv.visitVarInsn(ALOAD, insn);
                    }
                    mv.visitInsn(AASTORE);
                }
            }
            mv.visitMethodInsn(INVOKEVIRTUAL, clientName, "remote", "(I[Ljava/lang/Object;)Ljava/lang/Object;", false);
            // mv.visitMethodInsn(INVOKEVIRTUAL, convertName, "convertFrom", convertFromDesc, false);
            if (method.getGenericReturnType() == void.class) {
                mv.visitInsn(POP);
                mv.visitInsn(RETURN);
            } else {
                Class returnclz = method.getReturnType();
                Class bigPrimitiveClass = returnclz.isPrimitive() ? java.lang.reflect.Array.get(java.lang.reflect.Array.newInstance(returnclz, 1), 0).getClass() : returnclz;
                mv.visitTypeInsn(CHECKCAST, (returnclz.isPrimitive() ? bigPrimitiveClass : returnclz).getName().replace('.', '/'));
                if (returnclz.isPrimitive()) {
                    String bigPrimitiveName = bigPrimitiveClass.getName().replace('.', '/');
                    try {
                        java.lang.reflect.Method pm = bigPrimitiveClass.getMethod(returnclz.getSimpleName() + "Value");
                        mv.visitMethodInsn(INVOKEVIRTUAL, bigPrimitiveName, pm.getName(), Type.getMethodDescriptor(pm), false);
                    } catch (Exception ex) {
                        // 不可能会发生
                        throw new RuntimeException(ex);
                    }
                    if (returnclz == long.class) {
                        mv.visitInsn(LRETURN);
                    } else if (returnclz == float.class) {
                        mv.visitInsn(FRETURN);
                    } else if (returnclz == double.class) {
                        mv.visitInsn(DRETURN);
                    } else {
                        mv.visitInsn(IRETURN);
                    }
                } else {
                    mv.visitInsn(ARETURN);
                }
            }
            mv.visitMaxs(20, 20);
            mv.visitEnd();
        }
    }
    cw.visitEnd();
    byte[] bytes = cw.toByteArray();
    Class<?> newClazz = new ClassLoader(loader) {

        public final Class<?> loadClass(String name, byte[] b) {
            return defineClass(name, b, 0, b.length);
        }
    }.loadClass(newDynName.replace('/', '.'), bytes);
    RedkaleClassLoader.putDynClass(newDynName.replace('/', '.'), bytes, newClazz);
    RedkaleClassLoader.putReflectionPublicConstructors(newClazz, newDynName.replace('/', '.'));
    RedkaleClassLoader.putReflectionDeclaredConstructors(newClazz, newDynName.replace('/', '.'));
    try {
        T service = (T) newClazz.getDeclaredConstructor().newInstance();
        SncpClient client = new SncpClient(name, serviceTypeOrImplClass, service, messageAgent, transportFactory, true, realed ? createLocalServiceClass(loader, name, serviceTypeOrImplClass) : serviceTypeOrImplClass, clientAddress);
        client.setRemoteGroups(groups);
        if (transportFactory != null)
            client.setRemoteGroupTransport(transportFactory.loadTransport(clientAddress, groups));
        {
            Field c = newClazz.getDeclaredField(FIELDPREFIX + "_client");
            c.setAccessible(true);
            c.set(service, client);
            RedkaleClassLoader.putReflectionField(newDynName.replace('/', '.'), c);
        }
        if (messageAgent != null) {
            Field c = newClazz.getDeclaredField(FIELDPREFIX + "_messageagent");
            c.setAccessible(true);
            c.set(service, messageAgent);
            RedkaleClassLoader.putReflectionField(newDynName.replace('/', '.'), c);
            if (service instanceof WebSocketNode) {
                c = WebSocketNode.class.getDeclaredField("messageAgent");
                c.setAccessible(true);
                c.set(service, messageAgent);
                RedkaleClassLoader.putReflectionField(newDynName.replace('/', '.'), c);
            }
        }
        {
            Field c = newClazz.getDeclaredField(FIELDPREFIX + "_conf");
            c.setAccessible(true);
            c.set(service, conf);
            RedkaleClassLoader.putReflectionField(newDynName.replace('/', '.'), c);
        }
        if (transportFactory != null)
            transportFactory.addSncpService(service);
        return service;
    } catch (Exception ex) {
        throw new RuntimeException(ex);
    }
}
Also used : MethodDebugVisitor(org.redkale.asm.MethodDebugVisitor) java.lang.reflect(java.lang.reflect) SncpAction(org.redkale.net.sncp.SncpClient.SncpAction) Resource(javax.annotation.Resource) MessageAgent(org.redkale.mq.MessageAgent) Annotation(java.lang.annotation.Annotation) Type(org.redkale.asm.Type) WebSocketNode(org.redkale.net.http.WebSocketNode)

Aggregations

Annotation (java.lang.annotation.Annotation)2 java.lang.reflect (java.lang.reflect)2 Resource (javax.annotation.Resource)2 MethodDebugVisitor (org.redkale.asm.MethodDebugVisitor)2 Type (org.redkale.asm.Type)2 SncpAction (org.redkale.net.sncp.SncpClient.SncpAction)2 MessageAgent (org.redkale.mq.MessageAgent)1 WebSocketNode (org.redkale.net.http.WebSocketNode)1