docs: @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);
          }
  
      }