diff --git a/src/main/java/org/redkale/asm/AsmMethodBean.java b/src/main/java/org/redkale/asm/AsmMethodBean.java
index 0f6699803..6368d828e 100644
--- a/src/main/java/org/redkale/asm/AsmMethodBean.java
+++ b/src/main/java/org/redkale/asm/AsmMethodBean.java
@@ -9,7 +9,6 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.redkale.annotation.Param;
-import org.redkale.convert.json.JsonConvert;
/**
* 存放方法的字节信息
@@ -151,6 +150,7 @@ public class AsmMethodBean {
@Override
public String toString() {
- return JsonConvert.root().convertTo(this);
+ return "{params:" + params + ", access:" + access + ", name:" + name + ", desc:" + desc + ", signature:"
+ + signature + ", exceptions:" + exceptions + '}';
}
}
diff --git a/src/main/java/org/redkale/asm/AsmMethodParam.java b/src/main/java/org/redkale/asm/AsmMethodParam.java
index d5ab67c50..5790173a9 100644
--- a/src/main/java/org/redkale/asm/AsmMethodParam.java
+++ b/src/main/java/org/redkale/asm/AsmMethodParam.java
@@ -3,7 +3,6 @@
*/
package org.redkale.asm;
-import org.redkale.convert.json.JsonConvert;
import org.redkale.util.TypeToken;
/**
@@ -67,6 +66,6 @@ public class AsmMethodParam {
@Override
public String toString() {
- return JsonConvert.root().convertTo(this);
+ return "{name:" + name + ", description:" + description + ", signature:" + signature + '}';
}
}
diff --git a/src/main/java/org/redkale/net/sncp/Sncp.java b/src/main/java/org/redkale/net/sncp/Sncp.java
index 245f1c11e..e1bc96eb8 100644
--- a/src/main/java/org/redkale/net/sncp/Sncp.java
+++ b/src/main/java/org/redkale/net/sncp/Sncp.java
@@ -22,7 +22,6 @@ import org.redkale.inject.Resourcable;
import org.redkale.inject.ResourceFactory;
import org.redkale.mq.spi.MessageAgent;
import org.redkale.net.http.WebSocketNode;
-import org.redkale.net.sncp.SncpRemoteInfo.SncpRemoteAction;
import org.redkale.scheduled.Scheduled;
import org.redkale.service.*;
import org.redkale.util.AnyValue;
diff --git a/src/main/java/org/redkale/net/sncp/SncpActionServlet.java b/src/main/java/org/redkale/net/sncp/SncpActionServlet.java
new file mode 100644
index 000000000..392bbc79c
--- /dev/null
+++ b/src/main/java/org/redkale/net/sncp/SncpActionServlet.java
@@ -0,0 +1,645 @@
+/*
+ * Copyright (c) 2016-2116 Redkale
+ * All rights reserved.
+ */
+package org.redkale.net.sncp;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.nio.channels.CompletionHandler;
+import java.util.Objects;
+import java.util.concurrent.CompletionStage;
+import java.util.concurrent.Future;
+import org.redkale.annotation.ClassDepends;
+import org.redkale.annotation.NonBlocking;
+import org.redkale.asm.ClassWriter;
+import static org.redkale.asm.ClassWriter.COMPUTE_FRAMES;
+import org.redkale.asm.Label;
+import org.redkale.asm.MethodDebugVisitor;
+import static org.redkale.asm.Opcodes.*;
+import org.redkale.asm.Type;
+import org.redkale.convert.Convert;
+import org.redkale.convert.Reader;
+import org.redkale.convert.pb.ProtobufFactory;
+import org.redkale.service.Service;
+import org.redkale.util.RedkaleClassLoader;
+import org.redkale.util.TypeToken;
+import org.redkale.util.Uint128;
+
+/**
+ * 每个Service方法的SncpServlet对象
+ *
+ *
详情见: https://redkale.org
+ *
+ * @author zhangjx
+ * @since 2.8.0
+ */
+public abstract class SncpActionServlet extends SncpServlet {
+
+ protected final Method method;
+
+ protected final Uint128 actionid;
+
+ protected final boolean nonBlocking;
+
+ @ClassDepends
+ protected final java.lang.reflect.Type[] paramTypes; // 第一个元素存放返回类型return type, void的返回参数类型为null, 数组长度为:1+参数个数
+
+ @ClassDepends
+ protected final java.lang.reflect.Type paramComposeBeanType;
+
+ protected final int paramHandlerIndex; // >=0表示存在CompletionHandler参数
+
+ protected final Class extends CompletionHandler> paramHandlerClass; // CompletionHandler参数的类型
+
+ protected final java.lang.reflect.Type paramHandlerResultType; // CompletionHandler.completed第一个参数的类型
+
+ @ClassDepends
+ protected final java.lang.reflect.Type returnObjectType; // 返回结果类型 void必须设为null
+
+ @ClassDepends
+ protected final java.lang.reflect.Type returnFutureResultType; // 返回结果的CompletableFuture的结果泛型类型
+
+ @ClassDepends
+ protected SncpActionServlet(
+ String resourceName,
+ Class resourceType,
+ Service service,
+ Uint128 serviceid,
+ Uint128 actionid,
+ final Method method) {
+ super(resourceName, resourceType, service, serviceid);
+ Objects.requireNonNull(method);
+ this.actionid = actionid;
+ this.method = method;
+ this.paramComposeBeanType = SncpRemoteAction.createParamComposeBeanType(
+ Sncp.getServiceType(service),
+ method,
+ actionid,
+ method.getGenericParameterTypes(),
+ method.getParameterTypes());
+
+ int handlerFuncIndex = -1;
+ Class handlerFuncClass = null;
+ java.lang.reflect.Type handlerResultType = null;
+ try {
+ final Class[] paramClasses = method.getParameterTypes();
+ java.lang.reflect.Type[] genericParams = method.getGenericParameterTypes();
+ for (int i = 0; i < paramClasses.length; i++) { // 反序列化方法的每个参数
+ if (CompletionHandler.class.isAssignableFrom(paramClasses[i])) {
+ handlerFuncIndex = i;
+ handlerFuncClass = paramClasses[i];
+ java.lang.reflect.Type handlerType = TypeToken.getGenericType(genericParams[i], service.getClass());
+ if (handlerType instanceof Class) {
+ handlerResultType = Object.class;
+ } else if (handlerType instanceof ParameterizedType) {
+ handlerResultType = TypeToken.getGenericType(
+ ((ParameterizedType) handlerType).getActualTypeArguments()[0], handlerType);
+ } else {
+ throw new SncpException(service.getClass() + " had unknown genericType in " + method);
+ }
+ if (method.getReturnType() != void.class) {
+ throw new SncpException(
+ method + " have CompletionHandler type parameter but return type is not void");
+ }
+ break;
+ }
+ }
+ } catch (Throwable ex) {
+ // do nothing
+ }
+ java.lang.reflect.Type[] originalParamTypes =
+ TypeToken.getGenericType(method.getGenericParameterTypes(), service.getClass());
+ java.lang.reflect.Type originalReturnType =
+ TypeToken.getGenericType(method.getGenericReturnType(), service.getClass());
+ java.lang.reflect.Type[] types = new java.lang.reflect.Type[originalParamTypes.length + 1];
+ types[0] = originalReturnType;
+ System.arraycopy(originalParamTypes, 0, types, 1, originalParamTypes.length);
+ this.paramTypes = types;
+ this.paramHandlerIndex = handlerFuncIndex;
+ this.paramHandlerClass = handlerFuncClass;
+ this.paramHandlerResultType = handlerResultType;
+ this.returnObjectType =
+ originalReturnType == void.class || originalReturnType == Void.class ? null : originalReturnType;
+ if (Future.class.isAssignableFrom(method.getReturnType())) {
+ java.lang.reflect.Type futureType =
+ TypeToken.getGenericType(method.getGenericReturnType(), service.getClass());
+ java.lang.reflect.Type returnType = null;
+ if (futureType instanceof Class) {
+ returnType = Object.class;
+ } else if (futureType instanceof ParameterizedType) {
+ returnType = TypeToken.getGenericType(
+ ((ParameterizedType) futureType).getActualTypeArguments()[0], futureType);
+ } else {
+ throw new SncpException(service.getClass() + " had unknown return genericType in " + method);
+ }
+ this.returnFutureResultType = returnType;
+ } else {
+ this.returnFutureResultType = null;
+ }
+ NonBlocking non = method.getAnnotation(NonBlocking.class);
+ if (non == null) {
+ non = service.getClass().getAnnotation(NonBlocking.class);
+ }
+ // Future代替CompletionStage 不容易判断异步
+ this.nonBlocking = non == null
+ && (CompletionStage.class.isAssignableFrom(method.getReturnType()) || this.paramHandlerIndex >= 0);
+ }
+
+ @Override
+ public final void execute(SncpRequest request, SncpResponse response) throws IOException {
+ if (paramHandlerIndex > 0) {
+ response.paramAsyncHandler(paramHandlerClass, paramHandlerResultType);
+ }
+ try {
+ action(request, response);
+ } catch (IOException e) {
+ throw e;
+ } catch (Throwable t) {
+ throw new IOException(t);
+ }
+ }
+
+ protected abstract void action(SncpRequest request, SncpResponse response) throws Throwable;
+
+ public T service() {
+ return (T) service;
+ }
+
+ @Override
+ public Uint128 getServiceid() {
+ return serviceid;
+ }
+
+ public Uint128 getActionid() {
+ return actionid;
+ }
+
+ public String actionName() {
+ return method.getDeclaringClass().getSimpleName() + "." + method.getName();
+ }
+
+ /**
+ *
+ *
+ *
+ *
+ *
+ * public interface TestService extends Service {
+ *
+ * public boolean change(TestBean bean, String name, int id);
+ *
+ * public void insert(BooleanHandler handler, TestBean bean, String name, int id);
+ *
+ * public void update(long show, short v2, CompletionHandler<Boolean, TestBean> handler, TestBean bean, String name, int id);
+ *
+ * public CompletableFuture<String> changeName(TestBean bean, String name, int id);
+ *
+ * }
+ *
+ * @ResourceType(TestService.class)
+ * public class TestServiceImpl implements TestService {
+ *
+ * @Override
+ * public boolean change(TestBean bean, String name, int id) {
+ * return false;
+ * }
+ *
+ * @Override
+ * public void insert(BooleanHandler handler, TestBean bean, String name, int id) {
+ * }
+ *
+ * @Override
+ * public void update(long show, short v2, CompletionHandler<Boolean, TestBean> handler, TestBean bean, String name, int id) {
+ * }
+ *
+ * @Override
+ * public CompletableFuture<String> changeName(TestBean bean, String name, int id) {
+ * return null;
+ * }
+ * }
+ *
+ * public class BooleanHandler implements CompletionHandler<Boolean, TestBean> {
+ *
+ * @Override
+ * public void completed(Boolean result, TestBean attachment) {
+ * }
+ *
+ * @Override
+ * public void failed(Throwable exc, TestBean attachment) {
+ * }
+ *
+ * }
+ *
+ * public class DynActionTestService_change extends SncpActionServlet {
+ *
+ * public DynActionTestService_change(String resourceName, Class resourceType, Service service, Uint128 serviceid, Uint128 actionid, final Method method) {
+ * super(resourceName, resourceType, service, serviceid, actionid, method);
+ * }
+ *
+ * @Override
+ * public void action(SncpRequest request, SncpResponse response) throws Throwable {
+ * Convert<Reader, Writer> convert = request.getConvert();
+ * Reader in = request.getReader();
+ * TestBean arg1 = convert.convertFrom(paramTypes[1], in);
+ * String arg2 = convert.convertFrom(paramTypes[2], in);
+ * int arg3 = convert.convertFrom(paramTypes[3], in);
+ * TestService serviceObj = (TestService) service();
+ * Object rs = serviceObj.change(arg1, arg2, arg3);
+ * response.finish(boolean.class, rs);
+ * }
+ * }
+ *
+ * public class DynActionTestService_insert extends SncpActionServlet {
+ *
+ * public DynActionTestService_insert(String resourceName, Class resourceType, Service service, Uint128 serviceid, Uint128 actionid, final Method method) {
+ * super(resourceName, resourceType, service, serviceid, actionid, method);
+ * }
+ *
+ * @Override
+ * public void action(SncpRequest request, SncpResponse response) throws Throwable {
+ * Convert<Reader, Writer> convert = request.getConvert();
+ * Reader in = request.getReader();
+ * BooleanHandler arg0 = response.getParamAsyncHandler();
+ * convert.convertFrom(CompletionHandler.class, in);
+ * TestBean arg1 = convert.convertFrom(paramTypes[2], in);
+ * String arg2 = convert.convertFrom(paramTypes[3], in);
+ * int arg3 = convert.convertFrom(paramTypes[4], in);
+ * TestService serviceObj = (TestService) service();
+ * serviceObj.insert(arg0, arg1, arg2, arg3);
+ * response.finishVoid();
+ * }
+ * }
+ *
+ * public class DynActionTestService_update extends SncpActionServlet {
+ *
+ * public DynActionTestService_update(String resourceName, Class resourceType, Service service, Uint128 serviceid, Uint128 actionid, final Method method) {
+ * super(resourceName, resourceType, service, serviceid, actionid, method);
+ * }
+ *
+ * @Override
+ * public void action(SncpRequest request, SncpResponse response) throws Throwable {
+ * Convert<Reader, Writer> convert = request.getConvert();
+ * Reader in = request.getReader();
+ * long a1 = convert.convertFrom(paramTypes[1], in);
+ * short a2 = convert.convertFrom(paramTypes[2], in);
+ * CompletionHandler a3 = response.getParamAsyncHandler();
+ * convert.convertFrom(CompletionHandler.class, in);
+ * TestBean arg1 = convert.convertFrom(paramTypes[4], in);
+ * String arg2 = convert.convertFrom(paramTypes[5], in);
+ * int arg3 = convert.convertFrom(paramTypes[6], in);
+ * TestService serviceObj = (TestService) service();
+ * serviceObj.update(a1, a2, a3, arg1, arg2, arg3);
+ * response.finishVoid();
+ * }
+ * }
+ *
+ * public class DynActionTestService_changeName extends SncpActionServlet {
+ *
+ * public DynActionTestService_changeName(String resourceName, Class resourceType, Service service, Uint128 serviceid, Uint128 actionid, final Method method) {
+ * super(resourceName, resourceType, service, serviceid, actionid, method);
+ * }
+ *
+ * @Override
+ * public void action(SncpRequest request, SncpResponse response) throws Throwable {
+ * Convert<Reader, Writer> convert = request.getConvert();
+ * Reader in = request.getReader();
+ * TestBean arg1 = convert.convertFrom(paramTypes[1], in);
+ * String arg2 = convert.convertFrom(paramTypes[2], in);
+ * int arg3 = convert.convertFrom(paramTypes[3], in);
+ * TestService serviceObj = (TestService) service();
+ * CompletableFuture future = serviceObj.changeName(arg1, arg2, arg3);
+ * response.finishFuture(paramHandlerResultType, future);
+ * }
+ * }
+ *
+ *
+ *
+ *
+ *
+ * @param resourceName 资源名
+ * @param resourceType 资源类
+ * @param serviceImplClass Service实现类
+ * @param service Service
+ * @param serviceid 类ID
+ * @param actionid 操作ID
+ * @param method 方法
+ * @return SncpActionServlet
+ */
+ @SuppressWarnings("unchecked")
+ public static SncpActionServlet create(
+ final String resourceName,
+ final Class resourceType,
+ final Class serviceImplClass,
+ final Service service,
+ final Uint128 serviceid,
+ final Uint128 actionid,
+ final Method method) {
+
+ final Class serviceClass = service.getClass();
+ final String supDynName = SncpActionServlet.class.getName().replace('.', '/');
+ final String serviceImpTypeName = serviceImplClass.getName().replace('.', '/');
+ final String convertName = Convert.class.getName().replace('.', '/');
+ final String uint128Desc = Type.getDescriptor(Uint128.class);
+ final String convertDesc = Type.getDescriptor(Convert.class);
+ final String readerDesc = Type.getDescriptor(Reader.class);
+ final String requestName = SncpRequest.class.getName().replace('.', '/');
+ final String responseName = SncpResponse.class.getName().replace('.', '/');
+ final String requestDesc = Type.getDescriptor(SncpRequest.class);
+ final String responseDesc = Type.getDescriptor(SncpResponse.class);
+ final String serviceDesc = Type.getDescriptor(Service.class);
+ final boolean boolReturnTypeFuture = Future.class.isAssignableFrom(method.getReturnType());
+ final String newDynName = "org/redkaledyn/sncp/servlet/action/_DynSncpActionServlet__"
+ + resourceType.getSimpleName() + "_" + method.getName() + "_" + actionid;
+
+ Class> newClazz = null;
+ try {
+ Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.'));
+ newClazz = clz == null
+ ? Thread.currentThread().getContextClassLoader().loadClass(newDynName.replace('/', '.'))
+ : clz;
+ } catch (Throwable ex) {
+ // do nothing
+ }
+
+ final java.lang.reflect.Type[] originalParamTypes =
+ TypeToken.getGenericType(method.getGenericParameterTypes(), serviceClass);
+ final java.lang.reflect.Type originalReturnType =
+ TypeToken.getGenericType(method.getGenericReturnType(), serviceClass);
+
+ if (newClazz == null) {
+ // -------------------------------------------------------------
+ ClassWriter cw = new ClassWriter(COMPUTE_FRAMES);
+ MethodDebugVisitor mv;
+
+ cw.visit(V11, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, null, supDynName, null);
+ {
+ mv = new MethodDebugVisitor(cw.visitMethod(
+ ACC_PUBLIC,
+ "",
+ "(Ljava/lang/String;Ljava/lang/Class;" + serviceDesc + uint128Desc + uint128Desc
+ + "Ljava/lang/reflect/Method;)V",
+ null,
+ null));
+ Label label0 = new Label();
+ mv.visitLabel(label0);
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitVarInsn(ALOAD, 1);
+ mv.visitVarInsn(ALOAD, 2);
+ mv.visitVarInsn(ALOAD, 3);
+ mv.visitVarInsn(ALOAD, 4);
+ mv.visitVarInsn(ALOAD, 5);
+ mv.visitVarInsn(ALOAD, 6);
+ mv.visitMethodInsn(
+ INVOKESPECIAL,
+ supDynName,
+ "",
+ "(Ljava/lang/String;Ljava/lang/Class;" + serviceDesc + uint128Desc + uint128Desc
+ + "Ljava/lang/reflect/Method;)V",
+ false);
+ mv.visitInsn(RETURN);
+ Label label2 = new Label();
+ mv.visitLabel(label2);
+ mv.visitLocalVariable("this", "L" + newDynName + ";", null, label0, label2, 0);
+ mv.visitLocalVariable("resourceName", "Ljava/lang/String;", null, label0, label2, 1);
+ mv.visitLocalVariable("resourceType", "Ljava/lang/Class;", null, label0, label2, 2);
+ mv.visitLocalVariable("service", serviceDesc, null, label0, label2, 3);
+ mv.visitLocalVariable("serviceid", uint128Desc, null, label0, label2, 4);
+ mv.visitLocalVariable("actionid", uint128Desc, null, label0, label2, 5);
+ mv.visitLocalVariable("method", "Ljava/lang/reflect/Method;", null, label0, label2, 6);
+ mv.visitMaxs(7, 7);
+ mv.visitEnd();
+ }
+ String convertFromDesc = "(Ljava/lang/reflect/Type;" + readerDesc + ")Ljava/lang/Object;";
+ try {
+ convertFromDesc = Type.getMethodDescriptor(
+ Convert.class.getMethod("convertFrom", java.lang.reflect.Type.class, Reader.class));
+ } catch (Exception ex) {
+ throw new SncpException(ex); // 不可能会发生
+ }
+ { // action方法
+ mv = new MethodDebugVisitor(cw.visitMethod(
+ ACC_PUBLIC, "action", "(" + requestDesc + responseDesc + ")V", null, new String[] {
+ "java/lang/Throwable"
+ }));
+ // mv.setDebug(true);
+ { // Convert
+ mv.visitVarInsn(ALOAD, 1);
+ mv.visitMethodInsn(INVOKEVIRTUAL, requestName, "getConvert", "()" + convertDesc, false);
+ mv.visitVarInsn(ASTORE, 3);
+ }
+ { // Reader
+ mv.visitVarInsn(ALOAD, 1);
+ mv.visitMethodInsn(INVOKEVIRTUAL, requestName, "getReader", "()" + readerDesc, false);
+ mv.visitVarInsn(ASTORE, 4);
+ }
+ int iconst = ICONST_1;
+ int intconst = 1;
+ int store = 5; // action的参数个数+2
+ final Class[] paramClasses = method.getParameterTypes();
+ int[][] codes = new int[paramClasses.length][2];
+ int handlerFuncIndex = -1;
+ for (int i = 0; i < paramClasses.length; i++) { // 反序列化方法的每个参数
+ if (CompletionHandler.class.isAssignableFrom(paramClasses[i])) {
+ if (boolReturnTypeFuture) {
+ throw new SncpException(method + " have both CompletionHandler and CompletableFuture");
+ }
+ if (handlerFuncIndex >= 0) {
+ throw new SncpException(method + " have more than one CompletionHandler type parameter");
+ }
+ Sncp.checkAsyncModifier(paramClasses[i], method);
+ handlerFuncIndex = i;
+ mv.visitVarInsn(ALOAD, 2);
+ mv.visitMethodInsn(
+ INVOKEVIRTUAL,
+ responseName,
+ "getParamAsyncHandler",
+ "()Ljava/nio/channels/CompletionHandler;",
+ false);
+ mv.visitTypeInsn(CHECKCAST, paramClasses[i].getName().replace('.', '/'));
+ mv.visitVarInsn(ASTORE, store);
+ codes[i] = new int[] {ALOAD, store};
+ store++;
+ iconst++;
+ intconst++;
+ mv.visitVarInsn(ALOAD, 3);
+ mv.visitLdcInsn(Type.getType(Type.getDescriptor(CompletionHandler.class)));
+ mv.visitVarInsn(ALOAD, 4);
+ mv.visitMethodInsn(INVOKEVIRTUAL, convertName, "convertFrom", convertFromDesc, false);
+ mv.visitInsn(POP);
+ continue;
+ }
+ mv.visitVarInsn(ALOAD, 3);
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitFieldInsn(GETFIELD, newDynName, "paramTypes", "[Ljava/lang/reflect/Type;");
+
+ if (intconst < 6) {
+ mv.visitInsn(ICONST_0 + intconst);
+ } else if (iconst <= Byte.MAX_VALUE) {
+ mv.visitIntInsn(BIPUSH, intconst);
+ } else if (iconst <= Short.MAX_VALUE) {
+ mv.visitIntInsn(SIPUSH, intconst);
+ } else {
+ mv.visitLdcInsn(intconst);
+ }
+ mv.visitInsn(AALOAD);
+ mv.visitVarInsn(ALOAD, 4);
+
+ mv.visitMethodInsn(INVOKEVIRTUAL, convertName, "convertFrom", convertFromDesc, false);
+ int load = ALOAD;
+ int v = 0;
+ if (paramClasses[i].isPrimitive()) {
+ int storecode = ISTORE;
+ load = ILOAD;
+ if (paramClasses[i] == long.class) {
+ storecode = LSTORE;
+ load = LLOAD;
+ v = 1;
+ } else if (paramClasses[i] == float.class) {
+ storecode = FSTORE;
+ load = FLOAD;
+ v = 1;
+ } else if (paramClasses[i] == double.class) {
+ storecode = DSTORE;
+ load = DLOAD;
+ v = 1;
+ }
+ Class bigPrimitiveClass = TypeToken.primitiveToWrapper(paramClasses[i]);
+ String bigPrimitiveName = bigPrimitiveClass.getName().replace('.', '/');
+ try {
+ Method pm = bigPrimitiveClass.getMethod(paramClasses[i].getSimpleName() + "Value");
+ mv.visitTypeInsn(CHECKCAST, bigPrimitiveName);
+ mv.visitMethodInsn(
+ INVOKEVIRTUAL, bigPrimitiveName, pm.getName(), Type.getMethodDescriptor(pm), false);
+ } catch (Exception ex) {
+ throw new SncpException(ex); // 不可能会发生
+ }
+ mv.visitVarInsn(storecode, store);
+ } else {
+ mv.visitTypeInsn(CHECKCAST, paramClasses[i].getName().replace('.', '/'));
+ mv.visitVarInsn(ASTORE, store); //
+ }
+ codes[i] = new int[] {load, store};
+ store += v;
+ iconst++;
+ intconst++;
+ store++;
+ }
+ { // 调用service
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "service", "()" + serviceDesc, false);
+ mv.visitTypeInsn(CHECKCAST, serviceImpTypeName);
+ mv.visitVarInsn(ASTORE, store);
+
+ mv.visitVarInsn(ALOAD, store);
+ for (int[] j : codes) {
+ mv.visitVarInsn(j[0], j[1]);
+ }
+ mv.visitMethodInsn(
+ serviceImplClass.isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL,
+ serviceImpTypeName,
+ method.getName(),
+ Type.getMethodDescriptor(method),
+ serviceImplClass.isInterface());
+ store++;
+ }
+ if (method.getReturnType() != void.class) {
+ final Class returnClass = method.getReturnType();
+ if (returnClass.isPrimitive()) {
+ Class bigClass = TypeToken.primitiveToWrapper(returnClass);
+ try {
+ Method vo = bigClass.getMethod("valueOf", returnClass);
+ mv.visitMethodInsn(
+ INVOKESTATIC,
+ bigClass.getName().replace('.', '/'),
+ vo.getName(),
+ Type.getMethodDescriptor(vo),
+ false);
+ } catch (Exception ex) {
+ throw new SncpException(ex); // 不可能会发生
+ }
+ }
+ mv.visitVarInsn(ASTORE, store); // 11
+
+ if (boolReturnTypeFuture) { // 返回类型为Future
+ mv.visitVarInsn(ALOAD, 2);
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitFieldInsn(GETFIELD, newDynName, "returnFutureResultType", "Ljava/lang/reflect/Type;");
+ mv.visitVarInsn(ALOAD, store);
+ mv.visitMethodInsn(
+ INVOKEVIRTUAL,
+ responseName,
+ "finishFuture",
+ "(Ljava/lang/reflect/Type;Ljava/util/concurrent/Future;)V",
+ false);
+ } else if (handlerFuncIndex >= 0) { // 参数有CompletionHandler
+ mv.visitVarInsn(ALOAD, 2);
+ mv.visitMethodInsn(INVOKEVIRTUAL, responseName, "finishVoid", "()V", false);
+ } else { // 普通对象
+ mv.visitVarInsn(ALOAD, 2);
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitFieldInsn(GETFIELD, newDynName, "returnObjectType", "Ljava/lang/reflect/Type;");
+ mv.visitVarInsn(ALOAD, store);
+ mv.visitMethodInsn(
+ INVOKEVIRTUAL,
+ responseName,
+ "finish",
+ "(Ljava/lang/reflect/Type;Ljava/lang/Object;)V",
+ false);
+ }
+ } else { // void返回类型
+ mv.visitVarInsn(ALOAD, 2);
+ mv.visitMethodInsn(INVOKEVIRTUAL, responseName, "finishVoid", "()V", false);
+ }
+ mv.visitInsn(RETURN);
+ mv.visitMaxs(8, store);
+ mv.visitEnd();
+ }
+ cw.visitEnd();
+
+ byte[] bytes = cw.toByteArray();
+ newClazz = new ClassLoader(serviceClass.getClassLoader()) {
+ 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.putReflectionDeclaredConstructors(newClazz, newDynName.replace('/', '.'));
+ try {
+ RedkaleClassLoader.putReflectionField(newDynName.replace('/', '.'), newClazz.getField("service"));
+ } catch (Exception e) {
+ // do nothing
+ }
+ for (java.lang.reflect.Type t : originalParamTypes) {
+ if (t == java.io.Serializable.class
+ || t == java.io.Serializable[].class
+ || t.toString().startsWith("java.lang.")) {
+ continue;
+ }
+ ProtobufFactory.root().loadDecoder(t);
+ }
+ if (originalReturnType != void.class && originalReturnType != Void.class) {
+ if (boolReturnTypeFuture && method.getReturnType() != method.getGenericReturnType()) {
+ java.lang.reflect.Type t =
+ ((ParameterizedType) method.getGenericReturnType()).getActualTypeArguments()[0];
+ if (t != Void.class && t != java.lang.reflect.Type.class) {
+ ProtobufFactory.root().loadEncoder(t);
+ }
+ } else {
+ try {
+ ProtobufFactory.root().loadEncoder(originalReturnType);
+ } catch (Exception e) {
+ System.err.println(method);
+ }
+ }
+ }
+ }
+ try {
+ return (SncpActionServlet) newClazz.getConstructors()[0].newInstance(
+ resourceName, resourceType, service, serviceid, actionid, method);
+ } catch (Exception ex) {
+ throw new SncpException(ex); // 不可能会发生
+ }
+ }
+}
diff --git a/src/main/java/org/redkale/net/sncp/SncpRemoteAction.java b/src/main/java/org/redkale/net/sncp/SncpRemoteAction.java
new file mode 100644
index 000000000..fe2f03111
--- /dev/null
+++ b/src/main/java/org/redkale/net/sncp/SncpRemoteAction.java
@@ -0,0 +1,318 @@
+/*
+ * Copyright (c) 2016-2116 Redkale
+ * All rights reserved.
+ */
+package org.redkale.net.sncp;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.net.SocketAddress;
+import java.nio.channels.CompletionHandler;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Future;
+import org.redkale.asm.AnnotationVisitor;
+import org.redkale.asm.AsmMethodBean;
+import org.redkale.asm.AsmMethodBoost;
+import org.redkale.asm.AsmMethodParam;
+import org.redkale.asm.Asms;
+import org.redkale.asm.ClassWriter;
+import static org.redkale.asm.ClassWriter.COMPUTE_FRAMES;
+import org.redkale.asm.FieldVisitor;
+import org.redkale.asm.MethodDebugVisitor;
+import static org.redkale.asm.Opcodes.*;
+import org.redkale.convert.ConvertColumn;
+import org.redkale.convert.ObjectEncoder;
+import org.redkale.convert.pb.ProtobufFactory;
+import org.redkale.service.RpcAttachment;
+import org.redkale.service.RpcSourceAddress;
+import org.redkale.service.RpcTargetAddress;
+import org.redkale.service.RpcTargetTopic;
+import org.redkale.util.Creator;
+import org.redkale.util.RedkaleClassLoader;
+import org.redkale.util.TypeToken;
+import org.redkale.util.Uint128;
+
+/**
+ * 每个Service方法的相关信息对象
+ *
+ * 详情见: https://redkale.org
+ *
+ * @author zhangjx
+ * @since 2.8.0
+ */
+public final class SncpRemoteAction {
+
+ protected final Uint128 actionid;
+
+ protected final Method method;
+
+ protected final Type returnObjectType; // void必须设为null
+
+ protected final Type[] paramTypes;
+
+ protected final Class[] paramClasses;
+
+ // 参数数量为0: 值为null; 参数数量为1且参数类型为JavaBean: 值为第一个参数的类型; 其他情况: 动态生成的Object类
+ protected final Type paramComposeBeanType;
+
+ protected final int paramHandlerIndex;
+
+ protected final int paramHandlerAttachIndex;
+
+ protected final int paramAddressTargetIndex;
+
+ protected final int paramAddressSourceIndex;
+
+ protected final int paramTopicTargetIndex;
+
+ protected final Class extends CompletionHandler> paramHandlerClass; // CompletionHandler参数的类型
+
+ protected final java.lang.reflect.Type paramHandlerResultType; // CompletionHandler.completed第一个参数的类型
+
+ protected final java.lang.reflect.Type returnFutureResultType; // 返回结果的CompletableFuture的结果泛型类型
+
+ protected final Class extends Future> returnFutureClass; // 返回结果的CompletableFuture类型
+
+ protected final Creator extends CompletableFuture> returnFutureCreator; // 返回CompletableFuture类型的构建器
+
+ protected final SncpHeader header;
+
+ @SuppressWarnings("unchecked")
+ SncpRemoteAction(
+ final Class serviceImplClass,
+ Class resourceType,
+ Method method,
+ Uint128 serviceid,
+ Uint128 actionid,
+ final SncpClient sncpClient) {
+ this.actionid = actionid == null ? Sncp.actionid(method) : actionid;
+ Type rt = TypeToken.getGenericType(method.getGenericReturnType(), serviceImplClass);
+ this.returnObjectType = rt == void.class || rt == Void.class ? null : rt;
+ this.paramTypes = TypeToken.getGenericType(method.getGenericParameterTypes(), serviceImplClass);
+ this.paramClasses = method.getParameterTypes();
+ this.paramComposeBeanType =
+ createParamComposeBeanType(serviceImplClass, method, actionid, paramTypes, paramClasses);
+ this.method = method;
+ Annotation[][] anns = method.getParameterAnnotations();
+ int topicAddrIndex = -1;
+ int targetAddrIndex = -1;
+ int sourceAddrIndex = -1;
+ int handlerAttachIndex = -1;
+ int handlerFuncIndex = -1;
+ Class handlerFuncClass = null;
+ java.lang.reflect.Type handlerResultType = null;
+ Class>[] params = method.getParameterTypes();
+ Type[] genericParams = method.getGenericParameterTypes();
+ for (int i = 0; i < params.length; i++) {
+ if (CompletionHandler.class.isAssignableFrom(params[i])) {
+ if (Future.class.isAssignableFrom(method.getReturnType())) {
+ throw new SncpException(method + " have both CompletionHandler and CompletableFuture");
+ }
+ if (handlerFuncIndex >= 0) {
+ throw new SncpException(method + " have more than one CompletionHandler type parameter");
+ }
+ Sncp.checkAsyncModifier(params[i], method);
+ handlerFuncIndex = i;
+ handlerFuncClass = paramClasses[i];
+ java.lang.reflect.Type handlerType = TypeToken.getGenericType(genericParams[i], serviceImplClass);
+ if (handlerType instanceof Class) {
+ handlerResultType = Object.class;
+ } else if (handlerType instanceof ParameterizedType) {
+ handlerResultType = TypeToken.getGenericType(
+ ((ParameterizedType) handlerType).getActualTypeArguments()[0], handlerType);
+ } else {
+ throw new SncpException(serviceImplClass + " had unknown genericType in " + method);
+ }
+ if (method.getReturnType() != void.class) {
+ throw new SncpException(
+ method + " have CompletionHandler type parameter but return type is not void");
+ }
+ break;
+ }
+ }
+ if (anns.length > 0) {
+ for (int i = 0; i < anns.length; i++) {
+ if (anns[i].length > 0) {
+ for (Annotation ann : anns[i]) {
+ if (ann.annotationType() == RpcAttachment.class) {
+ if (handlerAttachIndex >= 0) {
+ throw new SncpException(method + " have more than one @RpcAttachment parameter");
+ }
+ handlerAttachIndex = i;
+ } else if (ann.annotationType() == RpcTargetAddress.class) {
+ if (SocketAddress.class.isAssignableFrom(params[i])) {
+ if (sourceAddrIndex >= 0) {
+ throw new SncpException(method + " have more than one @RpcTargetAddress parameter");
+ } else {
+ targetAddrIndex = i;
+ }
+ } else {
+ throw new SncpException(
+ method + " must be SocketAddress Type on @RpcTargetAddress parameter");
+ }
+ } else if (ann.annotationType() == RpcSourceAddress.class) {
+ if (SocketAddress.class.isAssignableFrom(params[i])) {
+ if (sourceAddrIndex >= 0) {
+ throw new SncpException(method + " have more than one @RpcSourceAddress parameter");
+ } else {
+ sourceAddrIndex = i;
+ }
+ } else {
+ throw new SncpException(
+ method + " must be SocketAddress Type on @RpcSourceAddress parameter");
+ }
+ } else if (ann.annotationType() == RpcTargetTopic.class) {
+ if (String.class.isAssignableFrom(params[i])) {
+ if (sourceAddrIndex >= 0) {
+ throw new SncpException(method + " have more than one @RpcTargetTopic parameter");
+ } else {
+ topicAddrIndex = i;
+ }
+ } else {
+ throw new SncpException(method + " must be String Type on @RpcTargetTopic parameter");
+ }
+ }
+ }
+ }
+ }
+ }
+ this.paramTopicTargetIndex = topicAddrIndex;
+ this.paramAddressTargetIndex = targetAddrIndex;
+ this.paramAddressSourceIndex = sourceAddrIndex;
+ this.paramHandlerIndex = handlerFuncIndex;
+ this.paramHandlerClass = handlerFuncClass;
+ this.paramHandlerResultType = handlerResultType;
+ this.paramHandlerAttachIndex = handlerAttachIndex;
+ this.header = SncpHeader.create(
+ sncpClient == null ? null : sncpClient.getClientSncpAddress(),
+ serviceid,
+ resourceType.getName(),
+ actionid,
+ method.getName());
+ if (this.paramHandlerIndex >= 0 && method.getReturnType() != void.class) {
+ throw new SncpException(method + " have CompletionHandler type parameter but return type is not void");
+ }
+ if (Future.class.isAssignableFrom(method.getReturnType())) {
+ java.lang.reflect.Type futureType =
+ TypeToken.getGenericType(method.getGenericReturnType(), serviceImplClass);
+ java.lang.reflect.Type returnType = null;
+ if (futureType instanceof Class) {
+ returnType = Object.class;
+ } else if (futureType instanceof ParameterizedType) {
+ returnType = TypeToken.getGenericType(
+ ((ParameterizedType) futureType).getActualTypeArguments()[0], futureType);
+ } else {
+ throw new SncpException(serviceImplClass + " had unknown return genericType in " + method);
+ }
+ this.returnFutureResultType = returnType;
+ this.returnFutureClass = method.getReturnType().isAssignableFrom(CompletableFuture.class)
+ ? CompletableFuture.class
+ : (Class) method.getReturnType();
+ if (method.getReturnType().isAssignableFrom(CompletableFuture.class)
+ || CompletableFuture.class.isAssignableFrom(method.getReturnType())) {
+ this.returnFutureCreator = (Creator) Creator.create(this.returnFutureClass);
+ } else {
+ throw new SncpException(serviceImplClass + " return must be CompletableFuture or subclass");
+ }
+ } else {
+ this.returnFutureResultType = null;
+ this.returnFutureClass = null;
+ this.returnFutureCreator = null;
+ }
+ }
+
+ public String actionName() {
+ return method.getDeclaringClass().getSimpleName() + "." + method.getName();
+ }
+
+ @Override
+ public String toString() {
+ return "{" + actionid + "," + (method == null ? "null" : method.getName()) + "}";
+ }
+
+ public static Type createParamComposeBeanType(
+ Class resourceType, Method method, Uint128 actionid, Type[] paramTypes, Class[] paramClasses) {
+ if (paramTypes == null || paramTypes.length == 0) {
+ return null;
+ }
+ if (paramTypes.length == 1 && ProtobufFactory.root().createEncoder(paramTypes[0]) instanceof ObjectEncoder) {
+ return paramTypes[0];
+ }
+
+ // 动态生成组合JavaBean类
+ final Class serviceClass = resourceType.getClass();
+ final String columnDesc = org.redkale.asm.Type.getDescriptor(ConvertColumn.class);
+ final String newDynName = "org/redkaledyn/sncp/servlet/action/_DynSncpActionParamBean__"
+ + resourceType.getSimpleName() + "_" + method.getName() + "_" + actionid;
+ try {
+ Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.'));
+ Class> newClazz = clz == null
+ ? Thread.currentThread().getContextClassLoader().loadClass(newDynName.replace('/', '.'))
+ : clz;
+ return newClazz;
+ } catch (Throwable ex) {
+ // do nothing
+ }
+
+ Map methodBeans = AsmMethodBoost.getMethodBeans(resourceType);
+ AsmMethodBean methodBean = Objects.requireNonNull(methodBeans.get(AsmMethodBoost.getMethodBeanKey(method)));
+ // -------------------------------------------------------------
+ ClassWriter cw = new ClassWriter(COMPUTE_FRAMES);
+ FieldVisitor fv;
+ MethodDebugVisitor mv;
+ AnnotationVisitor av;
+
+ cw.visit(V11, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, null, "java/lang/Object", null);
+ final List asmParams = methodBean.getParams();
+ for (int i = 1; i <= paramClasses.length; i++) {
+ AsmMethodParam param = asmParams.get(i - 1);
+ String paramDesc = org.redkale.asm.Type.getDescriptor(paramClasses[i - 1]);
+ fv = cw.visitField(ACC_PUBLIC, "arg" + i, paramDesc, param.getSignature(), null);
+ av = fv.visitAnnotation(columnDesc, true);
+ av.visit("index", i);
+ av.visitEnd();
+ fv.visitEnd();
+ }
+ { // 空参数构造函数
+ mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "", "()V", null, null));
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false);
+ mv.visitInsn(RETURN);
+ mv.visitMaxs(1, 1);
+ mv.visitEnd();
+ }
+ { // 带参数构造函数
+ mv = new MethodDebugVisitor(cw.visitMethod(ACC_PUBLIC, "", "([Ljava/lang/Object;)V", null, null));
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false);
+ for (int i = 1; i <= paramClasses.length; i++) {
+ String paramDesc = org.redkale.asm.Type.getDescriptor(paramClasses[i - 1]);
+ mv.visitVarInsn(ALOAD, 0);
+ mv.visitVarInsn(ALOAD, 1);
+ Asms.visitInsn(mv, i - 1);
+ mv.visitInsn(AALOAD);
+ Asms.visitCheckCast(mv, paramClasses[i - 1]);
+ mv.visitFieldInsn(PUTFIELD, newDynName, "arg" + i, paramDesc);
+ }
+ mv.visitInsn(RETURN);
+ mv.visitMaxs(3, 2);
+ mv.visitEnd();
+ }
+ cw.visitEnd();
+
+ byte[] bytes = cw.toByteArray();
+ Class newClazz = new ClassLoader(serviceClass.getClassLoader()) {
+ 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.putReflectionDeclaredConstructors(newClazz, newDynName.replace('/', '.'));
+ return newClazz;
+ }
+}
diff --git a/src/main/java/org/redkale/net/sncp/SncpRemoteInfo.java b/src/main/java/org/redkale/net/sncp/SncpRemoteInfo.java
index 6dfa6c981..1829b659c 100644
--- a/src/main/java/org/redkale/net/sncp/SncpRemoteInfo.java
+++ b/src/main/java/org/redkale/net/sncp/SncpRemoteInfo.java
@@ -3,7 +3,6 @@
*/
package org.redkale.net.sncp;
-import java.lang.annotation.Annotation;
import java.lang.reflect.*;
import java.net.*;
import java.nio.ByteBuffer;
@@ -348,194 +347,4 @@ public class SncpRemoteInfo {
public Set getRemoteAddresses() {
return remoteAddresses;
}
-
- public static final class SncpRemoteAction {
-
- protected final Uint128 actionid;
-
- protected final Method method;
-
- protected final Type returnObjectType; // void必须设为null
-
- protected final Type[] paramTypes;
-
- protected final Class[] paramClasses;
-
- protected final int paramHandlerIndex;
-
- protected final int paramHandlerAttachIndex;
-
- protected final int paramAddressTargetIndex;
-
- protected final int paramAddressSourceIndex;
-
- protected final int paramTopicTargetIndex;
-
- protected final Class extends CompletionHandler> paramHandlerClass; // CompletionHandler参数的类型
-
- protected final java.lang.reflect.Type paramHandlerResultType; // CompletionHandler.completed第一个参数的类型
-
- protected final java.lang.reflect.Type returnFutureResultType; // 返回结果的CompletableFuture的结果泛型类型
-
- protected final Class extends Future> returnFutureClass; // 返回结果的CompletableFuture类型
-
- protected final Creator extends CompletableFuture> returnFutureCreator; // 返回CompletableFuture类型的构建器
-
- protected final SncpHeader header;
-
- @SuppressWarnings("unchecked")
- SncpRemoteAction(
- final Class serviceImplClass,
- Class resourceType,
- Method method,
- Uint128 serviceid,
- Uint128 actionid,
- final SncpClient sncpClient) {
- this.actionid = actionid == null ? Sncp.actionid(method) : actionid;
- Type rt = TypeToken.getGenericType(method.getGenericReturnType(), serviceImplClass);
- this.returnObjectType = rt == void.class || rt == Void.class ? null : rt;
- this.paramTypes = TypeToken.getGenericType(method.getGenericParameterTypes(), serviceImplClass);
- this.paramClasses = method.getParameterTypes();
- this.method = method;
- Annotation[][] anns = method.getParameterAnnotations();
- int topicAddrIndex = -1;
- int targetAddrIndex = -1;
- int sourceAddrIndex = -1;
- int handlerAttachIndex = -1;
- int handlerFuncIndex = -1;
- Class handlerFuncClass = null;
- java.lang.reflect.Type handlerResultType = null;
- Class>[] params = method.getParameterTypes();
- Type[] genericParams = method.getGenericParameterTypes();
- for (int i = 0; i < params.length; i++) {
- if (CompletionHandler.class.isAssignableFrom(params[i])) {
- if (Future.class.isAssignableFrom(method.getReturnType())) {
- throw new SncpException(method + " have both CompletionHandler and CompletableFuture");
- }
- if (handlerFuncIndex >= 0) {
- throw new SncpException(method + " have more than one CompletionHandler type parameter");
- }
- Sncp.checkAsyncModifier(params[i], method);
- handlerFuncIndex = i;
- handlerFuncClass = paramClasses[i];
- java.lang.reflect.Type handlerType = TypeToken.getGenericType(genericParams[i], serviceImplClass);
- if (handlerType instanceof Class) {
- handlerResultType = Object.class;
- } else if (handlerType instanceof ParameterizedType) {
- handlerResultType = TypeToken.getGenericType(
- ((ParameterizedType) handlerType).getActualTypeArguments()[0], handlerType);
- } else {
- throw new SncpException(serviceImplClass + " had unknown genericType in " + method);
- }
- if (method.getReturnType() != void.class) {
- throw new SncpException(
- method + " have CompletionHandler type parameter but return type is not void");
- }
- break;
- }
- }
- if (anns.length > 0) {
- for (int i = 0; i < anns.length; i++) {
- if (anns[i].length > 0) {
- for (Annotation ann : anns[i]) {
- if (ann.annotationType() == RpcAttachment.class) {
- if (handlerAttachIndex >= 0) {
- throw new SncpException(method + " have more than one @RpcAttachment parameter");
- }
- handlerAttachIndex = i;
- } else if (ann.annotationType() == RpcTargetAddress.class) {
- if (SocketAddress.class.isAssignableFrom(params[i])) {
- if (sourceAddrIndex >= 0) {
- throw new SncpException(
- method + " have more than one @RpcTargetAddress parameter");
- } else {
- targetAddrIndex = i;
- }
- } else {
- throw new SncpException(
- method + " must be SocketAddress Type on @RpcTargetAddress parameter");
- }
- } else if (ann.annotationType() == RpcSourceAddress.class) {
- if (SocketAddress.class.isAssignableFrom(params[i])) {
- if (sourceAddrIndex >= 0) {
- throw new SncpException(
- method + " have more than one @RpcSourceAddress parameter");
- } else {
- sourceAddrIndex = i;
- }
- } else {
- throw new SncpException(
- method + " must be SocketAddress Type on @RpcSourceAddress parameter");
- }
- } else if (ann.annotationType() == RpcTargetTopic.class) {
- if (String.class.isAssignableFrom(params[i])) {
- if (sourceAddrIndex >= 0) {
- throw new SncpException(
- method + " have more than one @RpcTargetTopic parameter");
- } else {
- topicAddrIndex = i;
- }
- } else {
- throw new SncpException(
- method + " must be String Type on @RpcTargetTopic parameter");
- }
- }
- }
- }
- }
- }
- this.paramTopicTargetIndex = topicAddrIndex;
- this.paramAddressTargetIndex = targetAddrIndex;
- this.paramAddressSourceIndex = sourceAddrIndex;
- this.paramHandlerIndex = handlerFuncIndex;
- this.paramHandlerClass = handlerFuncClass;
- this.paramHandlerResultType = handlerResultType;
- this.paramHandlerAttachIndex = handlerAttachIndex;
- this.header = SncpHeader.create(
- sncpClient == null ? null : sncpClient.getClientSncpAddress(),
- serviceid,
- resourceType.getName(),
- actionid,
- method.getName());
- if (this.paramHandlerIndex >= 0 && method.getReturnType() != void.class) {
- throw new SncpException(method + " have CompletionHandler type parameter but return type is not void");
- }
- if (Future.class.isAssignableFrom(method.getReturnType())) {
- java.lang.reflect.Type futureType =
- TypeToken.getGenericType(method.getGenericReturnType(), serviceImplClass);
- java.lang.reflect.Type returnType = null;
- if (futureType instanceof Class) {
- returnType = Object.class;
- } else if (futureType instanceof ParameterizedType) {
- returnType = TypeToken.getGenericType(
- ((ParameterizedType) futureType).getActualTypeArguments()[0], futureType);
- } else {
- throw new SncpException(serviceImplClass + " had unknown return genericType in " + method);
- }
- this.returnFutureResultType = returnType;
- this.returnFutureClass = method.getReturnType().isAssignableFrom(CompletableFuture.class)
- ? CompletableFuture.class
- : (Class) method.getReturnType();
- if (method.getReturnType().isAssignableFrom(CompletableFuture.class)
- || CompletableFuture.class.isAssignableFrom(method.getReturnType())) {
- this.returnFutureCreator = (Creator) Creator.create(this.returnFutureClass);
- } else {
- throw new SncpException(serviceImplClass + " return must be CompletableFuture or subclass");
- }
- } else {
- this.returnFutureResultType = null;
- this.returnFutureClass = null;
- this.returnFutureCreator = null;
- }
- }
-
- public String actionName() {
- return method.getDeclaringClass().getSimpleName() + "." + method.getName();
- }
-
- @Override
- public String toString() {
- return "{" + actionid + "," + (method == null ? "null" : method.getName()) + "}";
- }
- }
}
diff --git a/src/main/java/org/redkale/net/sncp/SncpResponse.java b/src/main/java/org/redkale/net/sncp/SncpResponse.java
index 474e5f0cd..80df56f9f 100644
--- a/src/main/java/org/redkale/net/sncp/SncpResponse.java
+++ b/src/main/java/org/redkale/net/sncp/SncpResponse.java
@@ -139,6 +139,7 @@ public class SncpResponse extends Response {
finish(RETCODE_THROWEXCEPTION, null);
}
+ @ClassDepends
public final void finishVoid() {
int headerSize = SncpHeader.calcHeaderSize(request);
ProtobufWriter out = getWriter();
@@ -146,6 +147,7 @@ public class SncpResponse extends Response {
finish(0, out);
}
+ @ClassDepends
public final void finishFuture(final Type futureResultType, final Future future) {
if (future == null) {
finishVoid();
diff --git a/src/main/java/org/redkale/net/sncp/SncpServlet.java b/src/main/java/org/redkale/net/sncp/SncpServlet.java
index 663c82706..787cbc276 100644
--- a/src/main/java/org/redkale/net/sncp/SncpServlet.java
+++ b/src/main/java/org/redkale/net/sncp/SncpServlet.java
@@ -7,17 +7,9 @@ package org.redkale.net.sncp;
import java.io.IOException;
import java.lang.reflect.*;
-import java.nio.channels.CompletionHandler;
import java.util.*;
import java.util.concurrent.*;
import java.util.logging.Level;
-import org.redkale.annotation.NonBlocking;
-import org.redkale.asm.*;
-import static org.redkale.asm.ClassWriter.COMPUTE_FRAMES;
-import static org.redkale.asm.Opcodes.*;
-import org.redkale.asm.Type;
-import org.redkale.convert.*;
-import org.redkale.convert.pb.ProtobufFactory;
import org.redkale.net.*;
import org.redkale.service.Service;
import org.redkale.util.*;
@@ -39,7 +31,7 @@ public class SncpServlet extends Servlet
private final HashMap actions = new HashMap<>();
- private SncpServlet(String resourceName, Class resourceType, Service service, Uint128 serviceid) {
+ protected SncpServlet(String resourceName, Class resourceType, Service service, Uint128 serviceid) {
Objects.requireNonNull(resourceName);
Objects.requireNonNull(resourceType);
Objects.requireNonNull(service);
@@ -194,601 +186,4 @@ public class SncpServlet extends Servlet
public final int hashCode() {
return Objects.hashCode(getServiceid());
}
-
- public abstract static class SncpActionServlet extends SncpServlet {
-
- protected final Method method;
-
- protected final Uint128 actionid;
-
- protected final boolean nonBlocking;
-
- protected final java.lang.reflect.Type[] paramTypes; // 第一个元素存放返回类型return type, void的返回参数类型为null, 数组长度为:1+参数个数
-
- protected final java.lang.reflect.Type returnObjectType; // 返回结果类型 void必须设为null
-
- protected final int paramHandlerIndex; // >=0表示存在CompletionHandler参数
-
- protected final Class extends CompletionHandler> paramHandlerClass; // CompletionHandler参数的类型
-
- protected final java.lang.reflect.Type paramHandlerResultType; // CompletionHandler.completed第一个参数的类型
-
- protected final java.lang.reflect.Type returnFutureResultType; // 返回结果的CompletableFuture的结果泛型类型
-
- protected final java.lang.reflect.Type paramComposeType;
-
- protected SncpActionServlet(
- String resourceName,
- Class resourceType,
- Service service,
- Uint128 serviceid,
- Uint128 actionid,
- final Method method) {
- super(resourceName, resourceType, service, serviceid);
- Objects.requireNonNull(method);
- this.actionid = actionid;
- this.method = method;
- this.paramComposeType = null; // 待实现
-
- int handlerFuncIndex = -1;
- Class handlerFuncClass = null;
- java.lang.reflect.Type handlerResultType = null;
- try {
- final Class[] paramClasses = method.getParameterTypes();
- java.lang.reflect.Type[] genericParams = method.getGenericParameterTypes();
- for (int i = 0; i < paramClasses.length; i++) { // 反序列化方法的每个参数
- if (CompletionHandler.class.isAssignableFrom(paramClasses[i])) {
- handlerFuncIndex = i;
- handlerFuncClass = paramClasses[i];
- java.lang.reflect.Type handlerType =
- TypeToken.getGenericType(genericParams[i], service.getClass());
- if (handlerType instanceof Class) {
- handlerResultType = Object.class;
- } else if (handlerType instanceof ParameterizedType) {
- handlerResultType = TypeToken.getGenericType(
- ((ParameterizedType) handlerType).getActualTypeArguments()[0], handlerType);
- } else {
- throw new SncpException(service.getClass() + " had unknown genericType in " + method);
- }
- if (method.getReturnType() != void.class) {
- throw new SncpException(
- method + " have CompletionHandler type parameter but return type is not void");
- }
- break;
- }
- }
- } catch (Throwable ex) {
- // do nothing
- }
- java.lang.reflect.Type[] originalParamTypes =
- TypeToken.getGenericType(method.getGenericParameterTypes(), service.getClass());
- java.lang.reflect.Type originalReturnType =
- TypeToken.getGenericType(method.getGenericReturnType(), service.getClass());
- java.lang.reflect.Type[] types = new java.lang.reflect.Type[originalParamTypes.length + 1];
- types[0] = originalReturnType;
- System.arraycopy(originalParamTypes, 0, types, 1, originalParamTypes.length);
- this.paramTypes = types;
- this.paramHandlerIndex = handlerFuncIndex;
- this.paramHandlerClass = handlerFuncClass;
- this.paramHandlerResultType = handlerResultType;
- this.returnObjectType =
- originalReturnType == void.class || originalReturnType == Void.class ? null : originalReturnType;
- if (Future.class.isAssignableFrom(method.getReturnType())) {
- java.lang.reflect.Type futureType =
- TypeToken.getGenericType(method.getGenericReturnType(), service.getClass());
- java.lang.reflect.Type returnType = null;
- if (futureType instanceof Class) {
- returnType = Object.class;
- } else if (futureType instanceof ParameterizedType) {
- returnType = TypeToken.getGenericType(
- ((ParameterizedType) futureType).getActualTypeArguments()[0], futureType);
- } else {
- throw new SncpException(service.getClass() + " had unknown return genericType in " + method);
- }
- this.returnFutureResultType = returnType;
- } else {
- this.returnFutureResultType = null;
- }
- NonBlocking non = method.getAnnotation(NonBlocking.class);
- if (non == null) {
- non = service.getClass().getAnnotation(NonBlocking.class);
- }
- // Future代替CompletionStage 不容易判断异步
- this.nonBlocking = non == null
- && (CompletionStage.class.isAssignableFrom(method.getReturnType()) || this.paramHandlerIndex >= 0);
- }
-
- @Override
- public final void execute(SncpRequest request, SncpResponse response) throws IOException {
- if (paramHandlerIndex > 0) {
- response.paramAsyncHandler(paramHandlerClass, paramHandlerResultType);
- }
- try {
- action(request, response);
- } catch (IOException e) {
- throw e;
- } catch (Throwable t) {
- throw new IOException(t);
- }
- }
-
- protected abstract void action(SncpRequest request, SncpResponse response) throws Throwable;
-
- public T service() {
- return (T) service;
- }
-
- @Override
- public Uint128 getServiceid() {
- return serviceid;
- }
-
- public Uint128 getActionid() {
- return actionid;
- }
-
- public String actionName() {
- return method.getDeclaringClass().getSimpleName() + "." + method.getName();
- }
-
- /**
- *
- *
- *
- *
- *
- * public interface TestService extends Service {
- *
- * public boolean change(TestBean bean, String name, int id);
- *
- * public void insert(BooleanHandler handler, TestBean bean, String name, int id);
- *
- * public void update(long show, short v2, CompletionHandler<Boolean, TestBean> handler, TestBean bean, String name, int id);
- *
- * public CompletableFuture<String> changeName(TestBean bean, String name, int id);
- *
- * }
- *
- * @ResourceType(TestService.class)
- * public class TestServiceImpl implements TestService {
- *
- * @Override
- * public boolean change(TestBean bean, String name, int id) {
- * return false;
- * }
- *
- * @Override
- * public void insert(BooleanHandler handler, TestBean bean, String name, int id) {
- * }
- *
- * @Override
- * public void update(long show, short v2, CompletionHandler<Boolean, TestBean> handler, TestBean bean, String name, int id) {
- * }
- *
- * @Override
- * public CompletableFuture<String> changeName(TestBean bean, String name, int id) {
- * return null;
- * }
- * }
- *
- * public class BooleanHandler implements CompletionHandler<Boolean, TestBean> {
- *
- * @Override
- * public void completed(Boolean result, TestBean attachment) {
- * }
- *
- * @Override
- * public void failed(Throwable exc, TestBean attachment) {
- * }
- *
- * }
- *
- * public class DynActionTestService_change extends SncpActionServlet {
- *
- * public DynActionTestService_change(String resourceName, Class resourceType, Service service, Uint128 serviceid, Uint128 actionid, final Method method) {
- * super(resourceName, resourceType, service, serviceid, actionid, method);
- * }
- *
- * @Override
- * public void action(SncpRequest request, SncpResponse response) throws Throwable {
- * Convert<Reader, Writer> convert = request.getConvert();
- * Reader in = request.getReader();
- * TestBean arg1 = convert.convertFrom(paramTypes[1], in);
- * String arg2 = convert.convertFrom(paramTypes[2], in);
- * int arg3 = convert.convertFrom(paramTypes[3], in);
- * TestService serviceObj = (TestService) service();
- * Object rs = serviceObj.change(arg1, arg2, arg3);
- * response.finish(boolean.class, rs);
- * }
- * }
- *
- * public class DynActionTestService_insert extends SncpActionServlet {
- *
- * public DynActionTestService_insert(String resourceName, Class resourceType, Service service, Uint128 serviceid, Uint128 actionid, final Method method) {
- * super(resourceName, resourceType, service, serviceid, actionid, method);
- * }
- *
- * @Override
- * public void action(SncpRequest request, SncpResponse response) throws Throwable {
- * Convert<Reader, Writer> convert = request.getConvert();
- * Reader in = request.getReader();
- * BooleanHandler arg0 = response.getParamAsyncHandler();
- * convert.convertFrom(CompletionHandler.class, in);
- * TestBean arg1 = convert.convertFrom(paramTypes[2], in);
- * String arg2 = convert.convertFrom(paramTypes[3], in);
- * int arg3 = convert.convertFrom(paramTypes[4], in);
- * TestService serviceObj = (TestService) service();
- * serviceObj.insert(arg0, arg1, arg2, arg3);
- * response.finishVoid();
- * }
- * }
- *
- * public class DynActionTestService_update extends SncpActionServlet {
- *
- * public DynActionTestService_update(String resourceName, Class resourceType, Service service, Uint128 serviceid, Uint128 actionid, final Method method) {
- * super(resourceName, resourceType, service, serviceid, actionid, method);
- * }
- *
- * @Override
- * public void action(SncpRequest request, SncpResponse response) throws Throwable {
- * Convert<Reader, Writer> convert = request.getConvert();
- * Reader in = request.getReader();
- * long a1 = convert.convertFrom(paramTypes[1], in);
- * short a2 = convert.convertFrom(paramTypes[2], in);
- * CompletionHandler a3 = response.getParamAsyncHandler();
- * convert.convertFrom(CompletionHandler.class, in);
- * TestBean arg1 = convert.convertFrom(paramTypes[4], in);
- * String arg2 = convert.convertFrom(paramTypes[5], in);
- * int arg3 = convert.convertFrom(paramTypes[6], in);
- * TestService serviceObj = (TestService) service();
- * serviceObj.update(a1, a2, a3, arg1, arg2, arg3);
- * response.finishVoid();
- * }
- * }
- *
- * public class DynActionTestService_changeName extends SncpActionServlet {
- *
- * public DynActionTestService_changeName(String resourceName, Class resourceType, Service service, Uint128 serviceid, Uint128 actionid, final Method method) {
- * super(resourceName, resourceType, service, serviceid, actionid, method);
- * }
- *
- * @Override
- * public void action(SncpRequest request, SncpResponse response) throws Throwable {
- * Convert<Reader, Writer> convert = request.getConvert();
- * Reader in = request.getReader();
- * TestBean arg1 = convert.convertFrom(paramTypes[1], in);
- * String arg2 = convert.convertFrom(paramTypes[2], in);
- * int arg3 = convert.convertFrom(paramTypes[3], in);
- * TestService serviceObj = (TestService) service();
- * CompletableFuture future = serviceObj.changeName(arg1, arg2, arg3);
- * response.finishFuture(paramHandlerResultType, future);
- * }
- * }
- *
- *
- *
- *
- *
- * @param resourceName 资源名
- * @param resourceType 资源类
- * @param serviceImplClass Service实现类
- * @param service Service
- * @param serviceid 类ID
- * @param actionid 操作ID
- * @param method 方法
- * @return SncpActionServlet
- */
- @SuppressWarnings("unchecked")
- public static SncpActionServlet create(
- final String resourceName,
- final Class resourceType,
- final Class serviceImplClass,
- final Service service,
- final Uint128 serviceid,
- final Uint128 actionid,
- final Method method) {
-
- final Class serviceClass = service.getClass();
- final String supDynName = SncpActionServlet.class.getName().replace('.', '/');
- final String serviceImpTypeName = serviceImplClass.getName().replace('.', '/');
- final String convertName = Convert.class.getName().replace('.', '/');
- final String uint128Desc = Type.getDescriptor(Uint128.class);
- final String convertDesc = Type.getDescriptor(Convert.class);
- final String readerDesc = Type.getDescriptor(Reader.class);
- final String requestName = SncpRequest.class.getName().replace('.', '/');
- final String responseName = SncpResponse.class.getName().replace('.', '/');
- final String requestDesc = Type.getDescriptor(SncpRequest.class);
- final String responseDesc = Type.getDescriptor(SncpResponse.class);
- final String serviceDesc = Type.getDescriptor(Service.class);
- final boolean boolReturnTypeFuture = Future.class.isAssignableFrom(method.getReturnType());
- final String newDynName = "org/redkaledyn/sncp/servlet/action/_DynSncpActionServlet__"
- + resourceType.getSimpleName() + "_" + method.getName() + "_" + actionid;
-
- Class> newClazz = null;
- try {
- Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.'));
- newClazz = clz == null
- ? Thread.currentThread().getContextClassLoader().loadClass(newDynName.replace('/', '.'))
- : clz;
- } catch (Throwable ex) {
- // do nothing
- }
-
- final java.lang.reflect.Type[] originalParamTypes =
- TypeToken.getGenericType(method.getGenericParameterTypes(), serviceClass);
- final java.lang.reflect.Type originalReturnType =
- TypeToken.getGenericType(method.getGenericReturnType(), serviceClass);
- if (newClazz == null) {
- // -------------------------------------------------------------
- ClassWriter cw = new ClassWriter(COMPUTE_FRAMES);
- MethodDebugVisitor mv;
-
- cw.visit(V11, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, null, supDynName, null);
- {
- mv = new MethodDebugVisitor(cw.visitMethod(
- ACC_PUBLIC,
- "",
- "(Ljava/lang/String;Ljava/lang/Class;" + serviceDesc + uint128Desc + uint128Desc
- + "Ljava/lang/reflect/Method;)V",
- null,
- null));
- mv.visitVarInsn(ALOAD, 0);
- mv.visitVarInsn(ALOAD, 1);
- mv.visitVarInsn(ALOAD, 2);
- mv.visitVarInsn(ALOAD, 3);
- mv.visitVarInsn(ALOAD, 4);
- mv.visitVarInsn(ALOAD, 5);
- mv.visitVarInsn(ALOAD, 6);
- mv.visitMethodInsn(
- INVOKESPECIAL,
- supDynName,
- "",
- "(Ljava/lang/String;Ljava/lang/Class;" + serviceDesc + uint128Desc + uint128Desc
- + "Ljava/lang/reflect/Method;)V",
- false);
- mv.visitInsn(RETURN);
- mv.visitMaxs(7, 7);
- mv.visitEnd();
- }
- String convertFromDesc = "(Ljava/lang/reflect/Type;" + readerDesc + ")Ljava/lang/Object;";
- try {
- convertFromDesc = Type.getMethodDescriptor(
- Convert.class.getMethod("convertFrom", java.lang.reflect.Type.class, Reader.class));
- } catch (Exception ex) {
- throw new SncpException(ex); // 不可能会发生
- }
- { // action方法
- mv = new MethodDebugVisitor(cw.visitMethod(
- ACC_PUBLIC, "action", "(" + requestDesc + responseDesc + ")V", null, new String[] {
- "java/lang/Throwable"
- }));
- // mv.setDebug(true);
- { // Convert
- mv.visitVarInsn(ALOAD, 1);
- mv.visitMethodInsn(INVOKEVIRTUAL, requestName, "getConvert", "()" + convertDesc, false);
- mv.visitVarInsn(ASTORE, 3);
- }
- { // Reader
- mv.visitVarInsn(ALOAD, 1);
- mv.visitMethodInsn(INVOKEVIRTUAL, requestName, "getReader", "()" + readerDesc, false);
- mv.visitVarInsn(ASTORE, 4);
- }
- int iconst = ICONST_1;
- int intconst = 1;
- int store = 5; // action的参数个数+2
- final Class[] paramClasses = method.getParameterTypes();
- int[][] codes = new int[paramClasses.length][2];
- int handlerFuncIndex = -1;
- for (int i = 0; i < paramClasses.length; i++) { // 反序列化方法的每个参数
- if (CompletionHandler.class.isAssignableFrom(paramClasses[i])) {
- if (boolReturnTypeFuture) {
- throw new SncpException(method + " have both CompletionHandler and CompletableFuture");
- }
- if (handlerFuncIndex >= 0) {
- throw new SncpException(
- method + " have more than one CompletionHandler type parameter");
- }
- Sncp.checkAsyncModifier(paramClasses[i], method);
- handlerFuncIndex = i;
- mv.visitVarInsn(ALOAD, 2);
- mv.visitMethodInsn(
- INVOKEVIRTUAL,
- responseName,
- "getParamAsyncHandler",
- "()Ljava/nio/channels/CompletionHandler;",
- false);
- mv.visitTypeInsn(
- CHECKCAST, paramClasses[i].getName().replace('.', '/'));
- mv.visitVarInsn(ASTORE, store);
- codes[i] = new int[] {ALOAD, store};
- store++;
- iconst++;
- intconst++;
- mv.visitVarInsn(ALOAD, 3);
- mv.visitLdcInsn(Type.getType(Type.getDescriptor(CompletionHandler.class)));
- mv.visitVarInsn(ALOAD, 4);
- mv.visitMethodInsn(INVOKEVIRTUAL, convertName, "convertFrom", convertFromDesc, false);
- mv.visitInsn(POP);
- continue;
- }
- mv.visitVarInsn(ALOAD, 3);
- mv.visitVarInsn(ALOAD, 0);
- mv.visitFieldInsn(GETFIELD, newDynName, "paramTypes", "[Ljava/lang/reflect/Type;");
-
- if (intconst < 6) {
- mv.visitInsn(ICONST_0 + intconst);
- } else if (iconst <= Byte.MAX_VALUE) {
- mv.visitIntInsn(BIPUSH, intconst);
- } else if (iconst <= Short.MAX_VALUE) {
- mv.visitIntInsn(SIPUSH, intconst);
- } else {
- mv.visitLdcInsn(intconst);
- }
- mv.visitInsn(AALOAD);
- mv.visitVarInsn(ALOAD, 4);
-
- mv.visitMethodInsn(INVOKEVIRTUAL, convertName, "convertFrom", convertFromDesc, false);
- int load = ALOAD;
- int v = 0;
- if (paramClasses[i].isPrimitive()) {
- int storecode = ISTORE;
- load = ILOAD;
- if (paramClasses[i] == long.class) {
- storecode = LSTORE;
- load = LLOAD;
- v = 1;
- } else if (paramClasses[i] == float.class) {
- storecode = FSTORE;
- load = FLOAD;
- v = 1;
- } else if (paramClasses[i] == double.class) {
- storecode = DSTORE;
- load = DLOAD;
- v = 1;
- }
- Class bigPrimitiveClass = TypeToken.primitiveToWrapper(paramClasses[i]);
- String bigPrimitiveName =
- bigPrimitiveClass.getName().replace('.', '/');
- try {
- Method pm = bigPrimitiveClass.getMethod(paramClasses[i].getSimpleName() + "Value");
- mv.visitTypeInsn(CHECKCAST, bigPrimitiveName);
- mv.visitMethodInsn(
- INVOKEVIRTUAL,
- bigPrimitiveName,
- pm.getName(),
- Type.getMethodDescriptor(pm),
- false);
- } catch (Exception ex) {
- throw new SncpException(ex); // 不可能会发生
- }
- mv.visitVarInsn(storecode, store);
- } else {
- mv.visitTypeInsn(
- CHECKCAST, paramClasses[i].getName().replace('.', '/'));
- mv.visitVarInsn(ASTORE, store); //
- }
- codes[i] = new int[] {load, store};
- store += v;
- iconst++;
- intconst++;
- store++;
- }
- { // 调用service
- mv.visitVarInsn(ALOAD, 0);
- mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "service", "()" + serviceDesc, false);
- mv.visitTypeInsn(CHECKCAST, serviceImpTypeName);
- mv.visitVarInsn(ASTORE, store);
-
- mv.visitVarInsn(ALOAD, store);
- for (int[] j : codes) {
- mv.visitVarInsn(j[0], j[1]);
- }
- mv.visitMethodInsn(
- serviceImplClass.isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL,
- serviceImpTypeName,
- method.getName(),
- Type.getMethodDescriptor(method),
- serviceImplClass.isInterface());
- store++;
- }
- if (method.getReturnType() != void.class) {
- final Class returnClass = method.getReturnType();
- if (returnClass.isPrimitive()) {
- Class bigClass = TypeToken.primitiveToWrapper(returnClass);
- try {
- Method vo = bigClass.getMethod("valueOf", returnClass);
- mv.visitMethodInsn(
- INVOKESTATIC,
- bigClass.getName().replace('.', '/'),
- vo.getName(),
- Type.getMethodDescriptor(vo),
- false);
- } catch (Exception ex) {
- throw new SncpException(ex); // 不可能会发生
- }
- }
- mv.visitVarInsn(ASTORE, store); // 11
-
- if (boolReturnTypeFuture) { // 返回类型为Future
- mv.visitVarInsn(ALOAD, 2);
- mv.visitVarInsn(ALOAD, 0);
- mv.visitFieldInsn(
- GETFIELD, newDynName, "returnFutureResultType", "Ljava/lang/reflect/Type;");
- mv.visitVarInsn(ALOAD, store);
- mv.visitMethodInsn(
- INVOKEVIRTUAL,
- responseName,
- "finishFuture",
- "(Ljava/lang/reflect/Type;Ljava/util/concurrent/Future;)V",
- false);
- } else if (handlerFuncIndex >= 0) { // 参数有CompletionHandler
- mv.visitVarInsn(ALOAD, 2);
- mv.visitMethodInsn(INVOKEVIRTUAL, responseName, "finishVoid", "()V", false);
- } else { // 普通对象
- mv.visitVarInsn(ALOAD, 2);
- mv.visitVarInsn(ALOAD, 0);
- mv.visitFieldInsn(GETFIELD, newDynName, "returnObjectType", "Ljava/lang/reflect/Type;");
- mv.visitVarInsn(ALOAD, store);
- mv.visitMethodInsn(
- INVOKEVIRTUAL,
- responseName,
- "finish",
- "(Ljava/lang/reflect/Type;Ljava/lang/Object;)V",
- false);
- }
- } else { // void返回类型
- mv.visitVarInsn(ALOAD, 2);
- mv.visitMethodInsn(INVOKEVIRTUAL, responseName, "finishVoid", "()V", false);
- }
- mv.visitInsn(RETURN);
- mv.visitMaxs(8, store);
- mv.visitEnd();
- }
- cw.visitEnd();
-
- byte[] bytes = cw.toByteArray();
- newClazz = new ClassLoader(serviceClass.getClassLoader()) {
- 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.putReflectionDeclaredConstructors(newClazz, newDynName.replace('/', '.'));
- try {
- RedkaleClassLoader.putReflectionField(newDynName.replace('/', '.'), newClazz.getField("service"));
- } catch (Exception e) {
- // do nothing
- }
- for (java.lang.reflect.Type t : originalParamTypes) {
- if (t == java.io.Serializable.class
- || t == java.io.Serializable[].class
- || t.toString().startsWith("java.lang.")) {
- continue;
- }
- ProtobufFactory.root().loadDecoder(t);
- }
- if (originalReturnType != void.class && originalReturnType != Void.class) {
- if (boolReturnTypeFuture && method.getReturnType() != method.getGenericReturnType()) {
- java.lang.reflect.Type t =
- ((ParameterizedType) method.getGenericReturnType()).getActualTypeArguments()[0];
- if (t != Void.class && t != java.lang.reflect.Type.class) {
- ProtobufFactory.root().loadEncoder(t);
- }
- } else {
- try {
- ProtobufFactory.root().loadEncoder(originalReturnType);
- } catch (Exception e) {
- System.err.println(method);
- }
- }
- }
- }
- try {
- return (SncpActionServlet) newClazz.getConstructors()[0].newInstance(
- resourceName, resourceType, service, serviceid, actionid, method);
- } catch (Exception ex) {
- throw new SncpException(ex); // 不可能会发生
- }
- }
- }
}
diff --git a/src/main/java/org/redkale/util/Creator.java b/src/main/java/org/redkale/util/Creator.java
index fd4de1c43..5c3be916c 100644
--- a/src/main/java/org/redkale/util/Creator.java
+++ b/src/main/java/org/redkale/util/Creator.java
@@ -4,8 +4,6 @@
*/
package org.redkale.util;
-import static org.redkale.asm.Opcodes.*;
-
import java.io.*;
import java.lang.reflect.*;
import java.net.*;
@@ -15,6 +13,7 @@ import java.util.concurrent.*;
import java.util.function.*;
import org.redkale.annotation.ConstructorParameters;
import org.redkale.asm.*;
+import static org.redkale.asm.Opcodes.*;
import org.redkale.asm.Type;
/**
@@ -385,7 +384,7 @@ public interface Creator {
throw new RedkaleException(
"[" + clazz + "] have no public or ConstructorParameters-Annotation constructor.");
}
- final int[] iconsts = {ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5};
+
// -------------------------------------------------------------
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
FieldVisitor fv;
@@ -410,29 +409,13 @@ public interface Creator {
{ // paramTypes 方法
mv = cw.visitMethod(ACC_PUBLIC, "paramTypes", "()[Ljava/lang/Class;", null, null);
int paramLen = constructorParameters.length;
- if (paramLen < 6) {
- mv.visitInsn(ICONST_0 + paramLen);
- } else if (paramLen <= Byte.MAX_VALUE) {
- mv.visitIntInsn(BIPUSH, paramLen);
- } else if (paramLen <= Short.MAX_VALUE) {
- mv.visitIntInsn(SIPUSH, paramLen);
- } else {
- mv.visitLdcInsn(paramLen);
- }
+ Asms.visitInsn(mv, paramLen);
mv.visitTypeInsn(ANEWARRAY, "java/lang/Class");
for (int i = 0; i < constructorParameters.length; i++) {
final Class pt = constructorParameters[i].getValue();
mv.visitInsn(DUP);
- if (i < 6) {
- mv.visitInsn(iconsts[i]);
- } else if (i <= Byte.MAX_VALUE) {
- mv.visitIntInsn(BIPUSH, i);
- } else if (i <= Short.MAX_VALUE) {
- mv.visitIntInsn(SIPUSH, i);
- } else {
- mv.visitLdcInsn(i);
- }
+ Asms.visitInsn(mv, i);
Asms.visitFieldInsn(mv, pt);
mv.visitInsn(AASTORE);
}
@@ -459,28 +442,12 @@ public interface Creator {
continue;
}
mv.visitVarInsn(ALOAD, 1);
- if (i < 6) {
- mv.visitInsn(iconsts[i]);
- } else if (i <= Byte.MAX_VALUE) {
- mv.visitIntInsn(BIPUSH, i);
- } else if (i <= Short.MAX_VALUE) {
- mv.visitIntInsn(SIPUSH, i);
- } else {
- mv.visitLdcInsn(i);
- }
+ Asms.visitInsn(mv, i);
mv.visitInsn(AALOAD);
Label lab = new Label();
mv.visitJumpInsn(IFNONNULL, lab);
mv.visitVarInsn(ALOAD, 1);
- if (i < 6) {
- mv.visitInsn(iconsts[i]);
- } else if (i <= Byte.MAX_VALUE) {
- mv.visitIntInsn(BIPUSH, i);
- } else if (i <= Short.MAX_VALUE) {
- mv.visitIntInsn(SIPUSH, i);
- } else {
- mv.visitLdcInsn(i);
- }
+ Asms.visitInsn(mv, i);
if (pt == int.class) {
mv.visitInsn(ICONST_0);
mv.visitMethodInsn(
@@ -517,15 +484,7 @@ public interface Creator {
{
for (int i = 0; i < constructorParameters.length; i++) {
mv.visitVarInsn(ALOAD, 1);
- if (i < 6) {
- mv.visitInsn(iconsts[i]);
- } else if (i <= Byte.MAX_VALUE) {
- mv.visitIntInsn(BIPUSH, i);
- } else if (i <= Short.MAX_VALUE) {
- mv.visitIntInsn(SIPUSH, i);
- } else {
- mv.visitLdcInsn(i);
- }
+ Asms.visitInsn(mv, i);
mv.visitInsn(AALOAD);
final Class ct = constructorParameters[i].getValue();
if (ct.isPrimitive()) {
diff --git a/src/test/java/org/redkale/test/sncp/SncpClientCodecTest.java b/src/test/java/org/redkale/test/sncp/SncpClientCodecTest.java
index 1c47f0012..be640a249 100644
--- a/src/test/java/org/redkale/test/sncp/SncpClientCodecTest.java
+++ b/src/test/java/org/redkale/test/sncp/SncpClientCodecTest.java
@@ -16,11 +16,8 @@ import org.redkale.util.*;
/** @author zhangjx */
public class SncpClientCodecTest {
- private boolean main;
-
public static void main(String[] args) throws Throwable {
SncpClientCodecTest test = new SncpClientCodecTest();
- test.main = true;
test.run();
}
diff --git a/src/test/java/org/redkale/test/sncp/SncpHandlerTest.java b/src/test/java/org/redkale/test/sncp/SncpHandlerTest.java
index 03fea76ff..70410f028 100644
--- a/src/test/java/org/redkale/test/sncp/SncpHandlerTest.java
+++ b/src/test/java/org/redkale/test/sncp/SncpHandlerTest.java
@@ -12,11 +12,9 @@ import org.redkale.net.sncp.SncpAsyncHandler;
/** @author zhangjx */
public class SncpHandlerTest {
- private boolean main;
-
public static void main(String[] args) throws Throwable {
SncpHandlerTest test = new SncpHandlerTest();
- test.main = true;
+
test.run();
}
@@ -25,9 +23,7 @@ public class SncpHandlerTest {
SncpAsyncHandler.createHandler(CompletionHandler.class, new CompletionHandler() {
@Override
public void completed(Object result, Object attachment) {
- if (main) {
- System.out.println("handler result: " + result + ", attachment: " + attachment);
- }
+ System.out.println("handler result: " + result + ", attachment: " + attachment);
}
@Override
diff --git a/src/test/java/org/redkale/test/sncp/SncpRequestParseTest.java b/src/test/java/org/redkale/test/sncp/SncpRequestParseTest.java
index 6262438ce..a37d6b6a2 100644
--- a/src/test/java/org/redkale/test/sncp/SncpRequestParseTest.java
+++ b/src/test/java/org/redkale/test/sncp/SncpRequestParseTest.java
@@ -16,11 +16,8 @@ import org.redkale.util.*;
/** @author zhangjx */
public class SncpRequestParseTest {
- private boolean main;
-
public static void main(String[] args) throws Throwable {
SncpRequestParseTest test = new SncpRequestParseTest();
- test.main = true;
test.run();
}
diff --git a/src/test/java/org/redkale/test/sncp/SncpSleepTest.java b/src/test/java/org/redkale/test/sncp/SncpSleepTest.java
index c07a2147f..fda04693f 100644
--- a/src/test/java/org/redkale/test/sncp/SncpSleepTest.java
+++ b/src/test/java/org/redkale/test/sncp/SncpSleepTest.java
@@ -1,8 +1,6 @@
package org.redkale.test.sncp;
-import java.io.File;
import java.net.InetSocketAddress;
-import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import org.junit.jupiter.api.*;
@@ -64,7 +62,7 @@ public class SncpSleepTest {
CompletableFuture.allOf(futures).join();
long e = System.currentTimeMillis() - s;
System.out.println("耗时: " + e + " ms");
- remoteCService.test(333L, new String[] {"aaa", "bbb"}, List.of(new File("D:/a.txt"), new File("D:/b.txt")));
+ //remoteCService.test(333L, new String[] {"aaa", "bbb"}, List.of(new File("D:/a.txt"), new File("D:/b.txt")));
server.shutdown();
workExecutor.shutdown();
Assertions.assertTrue(e < 600);
diff --git a/src/test/java/org/redkale/test/sncp/TestService.java b/src/test/java/org/redkale/test/sncp/TestService.java
deleted file mode 100644
index 927749c0c..000000000
--- a/src/test/java/org/redkale/test/sncp/TestService.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- *
- */
-package org.redkale.test.sncp;
-
-import java.lang.reflect.Method;
-import java.nio.channels.CompletionHandler;
-import java.util.concurrent.CompletableFuture;
-import org.redkale.annotation.ResourceType;
-import org.redkale.convert.*;
-import org.redkale.net.sncp.*;
-import org.redkale.net.sncp.SncpServlet.SncpActionServlet;
-import org.redkale.service.Service;
-import org.redkale.test.util.TestBean;
-import org.redkale.util.Uint128;
-
-/** @author zhangjx */
-public interface TestService extends Service {
-
- public boolean change(TestBean bean, String name, int id);
-
- public void insert(BooleanHandler handler, TestBean bean, String name, int id);
-
- public void update(
- long show, short v2, CompletionHandler handler, TestBean bean, String name, int id);
-
- public CompletableFuture changeName(TestBean bean, String name, int id);
-}
-
-@ResourceType(TestService.class)
-class TestServiceImpl implements TestService {
-
- @Override
- public boolean change(TestBean bean, String name, int id) {
- return false;
- }
-
- public void delete(TestBean bean) {}
-
- @Override
- public void insert(BooleanHandler handler, TestBean bean, String name, int id) {}
-
- @Override
- public void update(
- long show, short v2, CompletionHandler handler, TestBean bean, String name, int id) {}
-
- @Override
- public CompletableFuture changeName(TestBean bean, String name, int id) {
- return null;
- }
-}
-
-class BooleanHandler implements CompletionHandler {
-
- @Override
- public void completed(Boolean result, TestBean attachment) {}
-
- @Override
- public void failed(Throwable exc, TestBean attachment) {}
-}
-
-class DynActionTestService_change extends SncpActionServlet {
-
- public DynActionTestService_change(
- String resourceName,
- Class resourceType,
- Service service,
- Uint128 serviceid,
- Uint128 actionid,
- final Method method) {
- super(resourceName, resourceType, service, serviceid, actionid, method);
- }
-
- @Override
- public void action(SncpRequest request, SncpResponse response) throws Throwable {
- Convert convert = request.getConvert();
- Reader in = request.getReader();
- TestBean arg1 = convert.convertFrom(paramTypes[1], in);
- String arg2 = convert.convertFrom(paramTypes[2], in);
- int arg3 = convert.convertFrom(paramTypes[3], in);
- TestService serviceObj = (TestService) service();
- Object rs = serviceObj.change(arg1, arg2, arg3);
- response.finish(boolean.class, rs);
- }
-}
-
-class DynActionTestService_insert extends SncpActionServlet {
-
- public DynActionTestService_insert(
- String resourceName,
- Class resourceType,
- Service service,
- Uint128 serviceid,
- Uint128 actionid,
- final Method method) {
- super(resourceName, resourceType, service, serviceid, actionid, method);
- }
-
- @Override
- public void action(SncpRequest request, SncpResponse response) throws Throwable {
- Convert convert = request.getConvert();
- Reader in = request.getReader();
- BooleanHandler arg0 = response.getParamAsyncHandler();
- convert.convertFrom(CompletionHandler.class, in);
- TestBean arg1 = convert.convertFrom(paramTypes[2], in);
- String arg2 = convert.convertFrom(paramTypes[3], in);
- int arg3 = convert.convertFrom(paramTypes[4], in);
- TestService serviceObj = (TestService) service();
- serviceObj.insert(arg0, arg1, arg2, arg3);
- response.finishVoid();
- }
-}
-
-class DynActionTestService_update extends SncpActionServlet {
-
- public DynActionTestService_update(
- String resourceName,
- Class resourceType,
- Service service,
- Uint128 serviceid,
- Uint128 actionid,
- final Method method) {
- super(resourceName, resourceType, service, serviceid, actionid, method);
- }
-
- @Override
- public void action(SncpRequest request, SncpResponse response) throws Throwable {
- Convert convert = request.getConvert();
- Reader in = request.getReader();
- long a1 = convert.convertFrom(paramTypes[1], in);
- short a2 = convert.convertFrom(paramTypes[2], in);
- CompletionHandler a3 = response.getParamAsyncHandler();
- convert.convertFrom(CompletionHandler.class, in);
- TestBean arg1 = convert.convertFrom(paramTypes[4], in);
- String arg2 = convert.convertFrom(paramTypes[5], in);
- int arg3 = convert.convertFrom(paramTypes[6], in);
- TestService serviceObj = (TestService) service();
- serviceObj.update(a1, a2, a3, arg1, arg2, arg3);
- response.finishVoid();
- }
-}
-
-class DynActionTestService_changeName extends SncpActionServlet {
-
- public DynActionTestService_changeName(
- String resourceName,
- Class resourceType,
- Service service,
- Uint128 serviceid,
- Uint128 actionid,
- final Method method) {
- super(resourceName, resourceType, service, serviceid, actionid, method);
- }
-
- @Override
- public void action(SncpRequest request, SncpResponse response) throws Throwable {
- Convert convert = request.getConvert();
- Reader in = request.getReader();
- TestBean arg1 = convert.convertFrom(paramTypes[1], in);
- String arg2 = convert.convertFrom(paramTypes[2], in);
- int arg3 = convert.convertFrom(paramTypes[3], in);
- TestService serviceObj = (TestService) service();
- CompletableFuture future = serviceObj.changeName(arg1, arg2, arg3);
- response.finishFuture(paramHandlerResultType, future);
- }
-}
diff --git a/src/test/java/org/redkale/test/sncp/_DynLocalSncpTestService.java b/src/test/java/org/redkale/test/sncp/_DynLocalSncpTestService.java
deleted file mode 100644
index 1a97b4cf7..000000000
--- a/src/test/java/org/redkale/test/sncp/_DynLocalSncpTestService.java
+++ /dev/null
@@ -1,12 +0,0 @@
-/*
- * To change this license header, choose License Headers in Project Properties.
- * To change this template file, choose Tools | Templates
- * and open the template in the editor.
- */
-package org.redkale.test.sncp;
-
-import org.redkale.annotation.ResourceType;
-
-/** @author zhangjx */
-@ResourceType(SncpTestIService.class)
-public class _DynLocalSncpTestService extends SncpTestServiceImpl {}
diff --git a/src/test/java/org/redkale/test/sncp/dyn/DynActionTestService_change.java b/src/test/java/org/redkale/test/sncp/dyn/DynActionTestService_change.java
index d66c6017e..11c051744 100644
--- a/src/test/java/org/redkale/test/sncp/dyn/DynActionTestService_change.java
+++ b/src/test/java/org/redkale/test/sncp/dyn/DynActionTestService_change.java
@@ -9,9 +9,9 @@ import org.redkale.convert.Convert;
import org.redkale.convert.ConvertColumn;
import org.redkale.convert.Reader;
import org.redkale.convert.Writer;
+import org.redkale.net.sncp.SncpActionServlet;
import org.redkale.net.sncp.SncpRequest;
import org.redkale.net.sncp.SncpResponse;
-import org.redkale.net.sncp.SncpServlet.SncpActionServlet;
import org.redkale.service.Service;
import org.redkale.test.util.TestBean;
import org.redkale.util.Uint128;
@@ -36,7 +36,7 @@ public class DynActionTestService_change extends SncpActionServlet {
public void action(SncpRequest request, SncpResponse response) throws Throwable {
Convert convert = request.getConvert();
Reader in = request.getReader();
- DynActionTestService_change_paramBean bean = convert.convertFrom(paramComposeType, in);
+ DynActionTestService_change_paramBean bean = convert.convertFrom(paramComposeBeanType, in);
TestService serviceObj = (TestService) service();
Object rs = serviceObj.change(bean.arg1, bean.arg2, bean.arg3);
response.finish(boolean.class, rs);
diff --git a/src/test/java/org/redkale/test/sncp/dyn/DynActionTestService_changeName.java b/src/test/java/org/redkale/test/sncp/dyn/DynActionTestService_changeName.java
index dd8345246..4b1f0a93a 100644
--- a/src/test/java/org/redkale/test/sncp/dyn/DynActionTestService_changeName.java
+++ b/src/test/java/org/redkale/test/sncp/dyn/DynActionTestService_changeName.java
@@ -10,9 +10,9 @@ import org.redkale.convert.Convert;
import org.redkale.convert.ConvertColumn;
import org.redkale.convert.Reader;
import org.redkale.convert.Writer;
+import org.redkale.net.sncp.SncpActionServlet;
import org.redkale.net.sncp.SncpRequest;
import org.redkale.net.sncp.SncpResponse;
-import org.redkale.net.sncp.SncpServlet.SncpActionServlet;
import org.redkale.service.Service;
import org.redkale.test.util.TestBean;
import org.redkale.util.Uint128;
@@ -37,7 +37,7 @@ public class DynActionTestService_changeName extends SncpActionServlet {
public void action(SncpRequest request, SncpResponse response) throws Throwable {
Convert convert = request.getConvert();
Reader in = request.getReader();
- DynActionTestService_changeName_paramBean bean = convert.convertFrom(paramComposeType, in);
+ DynActionTestService_changeName_paramBean bean = convert.convertFrom(paramComposeBeanType, in);
TestService serviceObj = (TestService) service();
CompletableFuture future = serviceObj.changeName(bean.arg1, bean.arg2, bean.arg3);
response.finishFuture(paramHandlerResultType, future);
diff --git a/src/test/java/org/redkale/test/sncp/dyn/DynActionTestService_hello.java b/src/test/java/org/redkale/test/sncp/dyn/DynActionTestService_hello.java
index ed063fa2e..d6838b0f6 100644
--- a/src/test/java/org/redkale/test/sncp/dyn/DynActionTestService_hello.java
+++ b/src/test/java/org/redkale/test/sncp/dyn/DynActionTestService_hello.java
@@ -8,9 +8,9 @@ import java.lang.reflect.Method;
import org.redkale.convert.Convert;
import org.redkale.convert.Reader;
import org.redkale.convert.Writer;
+import org.redkale.net.sncp.SncpActionServlet;
import org.redkale.net.sncp.SncpRequest;
import org.redkale.net.sncp.SncpResponse;
-import org.redkale.net.sncp.SncpServlet;
import org.redkale.service.Service;
import org.redkale.test.util.TestBean;
import org.redkale.util.Uint128;
@@ -19,7 +19,7 @@ import org.redkale.util.Uint128;
*
* @author zhangjx
*/
-public class DynActionTestService_hello extends SncpServlet.SncpActionServlet {
+public class DynActionTestService_hello extends SncpActionServlet {
public DynActionTestService_hello(
String resourceName,
@@ -35,7 +35,7 @@ public class DynActionTestService_hello extends SncpServlet.SncpActionServlet {
public void action(SncpRequest request, SncpResponse response) throws Throwable {
Convert convert = request.getConvert();
Reader in = request.getReader();
- TestBean bean = convert.convertFrom(paramComposeType, in);
+ TestBean bean = convert.convertFrom(paramComposeBeanType, in);
TestService serviceObj = (TestService) service();
serviceObj.hello(bean);
response.finishVoid();
diff --git a/src/test/java/org/redkale/test/sncp/dyn/DynActionTestService_insert.java b/src/test/java/org/redkale/test/sncp/dyn/DynActionTestService_insert.java
index 8cd403f20..25fd85ac6 100644
--- a/src/test/java/org/redkale/test/sncp/dyn/DynActionTestService_insert.java
+++ b/src/test/java/org/redkale/test/sncp/dyn/DynActionTestService_insert.java
@@ -9,9 +9,9 @@ import org.redkale.convert.Convert;
import org.redkale.convert.ConvertColumn;
import org.redkale.convert.Reader;
import org.redkale.convert.Writer;
+import org.redkale.net.sncp.SncpActionServlet;
import org.redkale.net.sncp.SncpRequest;
import org.redkale.net.sncp.SncpResponse;
-import org.redkale.net.sncp.SncpServlet.SncpActionServlet;
import org.redkale.service.Service;
import org.redkale.test.util.TestBean;
import org.redkale.util.Uint128;
@@ -36,7 +36,7 @@ public class DynActionTestService_insert extends SncpActionServlet {
public void action(SncpRequest request, SncpResponse response) throws Throwable {
Convert convert = request.getConvert();
Reader in = request.getReader();
- DynActionTestService_insert_paramBean bean = convert.convertFrom(paramComposeType, in);
+ DynActionTestService_insert_paramBean bean = convert.convertFrom(paramComposeBeanType, in);
bean.arg0 = response.getParamAsyncHandler();
TestService serviceObj = (TestService) service();
serviceObj.insert(bean.arg0, bean.arg1, bean.arg2, bean.arg3);
diff --git a/src/test/java/org/redkale/test/sncp/dyn/DynActionTestService_update.java b/src/test/java/org/redkale/test/sncp/dyn/DynActionTestService_update.java
index 2d18ef30d..0f927caa8 100644
--- a/src/test/java/org/redkale/test/sncp/dyn/DynActionTestService_update.java
+++ b/src/test/java/org/redkale/test/sncp/dyn/DynActionTestService_update.java
@@ -10,9 +10,9 @@ import org.redkale.convert.Convert;
import org.redkale.convert.ConvertColumn;
import org.redkale.convert.Reader;
import org.redkale.convert.Writer;
+import org.redkale.net.sncp.SncpActionServlet;
import org.redkale.net.sncp.SncpRequest;
import org.redkale.net.sncp.SncpResponse;
-import org.redkale.net.sncp.SncpServlet.SncpActionServlet;
import org.redkale.service.Service;
import org.redkale.test.util.TestBean;
import org.redkale.util.Uint128;
@@ -37,7 +37,7 @@ public class DynActionTestService_update extends SncpActionServlet {
public void action(SncpRequest request, SncpResponse response) throws Throwable {
Convert convert = request.getConvert();
Reader in = request.getReader();
- DynActionTestService_update_paramBean bean = convert.convertFrom(paramComposeType, in);
+ DynActionTestService_update_paramBean bean = convert.convertFrom(paramComposeBeanType, in);
bean.arg3 = response.getParamAsyncHandler();
TestService serviceObj = (TestService) service();
serviceObj.update(bean.arg1, bean.arg2, bean.arg3, bean.arg4, bean.arg5, bean.arg6);
@@ -75,4 +75,4 @@ public class DynActionTestService_update extends SncpActionServlet {
@ConvertColumn(index = 6)
public int arg6;
}
- }
\ No newline at end of file
+}