public void onResponse()

in dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericImplFilter.java [148:243]


    public void onResponse(Result appResponse, Invoker<?> invoker, Invocation invocation) {
        String generic = invoker.getUrl().getParameter(GENERIC_KEY);
        String methodName = invocation.getMethodName();
        Class<?>[] parameterTypes = invocation.getParameterTypes();
        Object genericImplMarker = invocation.get(GENERIC_IMPL_MARKER);
        if (genericImplMarker != null && (boolean) invocation.get(GENERIC_IMPL_MARKER)) {
            if (!appResponse.hasException()) {
                Object value = appResponse.getValue();
                try {
                    Class<?> invokerInterface = invoker.getInterface();
                    if (!$INVOKE.equals(methodName)
                            && !$INVOKE_ASYNC.equals(methodName)
                            && invokerInterface.isAssignableFrom(GenericService.class)) {
                        try {
                            // find the real interface from url
                            String realInterface = invoker.getUrl().getParameter(Constants.INTERFACE);
                            invokerInterface = ReflectUtils.forName(realInterface);
                        } catch (Exception e) {
                            // ignore
                        }
                    }

                    Method method = invokerInterface.getMethod(methodName, parameterTypes);
                    if (ProtocolUtils.isBeanGenericSerialization(generic)) {
                        if (value == null) {
                            appResponse.setValue(value);
                        } else if (value instanceof JavaBeanDescriptor) {
                            appResponse.setValue(JavaBeanSerializeUtil.deserialize((JavaBeanDescriptor) value));
                        } else {
                            throw new RpcException("The type of result value is "
                                    + value.getClass().getName() + " other than " + JavaBeanDescriptor.class.getName()
                                    + ", and the result is " + value);
                        }
                    } else {
                        Type[] types = ReflectUtils.getReturnTypes(method);
                        appResponse.setValue(PojoUtils.realize(value, (Class<?>) types[0], types[1]));
                    }
                } catch (NoSuchMethodException e) {
                    throw new RpcException(e.getMessage(), e);
                }
            } else if (Dubbo2CompactUtils.isEnabled()
                    && Dubbo2GenericExceptionUtils.isGenericExceptionClassLoaded()
                    && Dubbo2GenericExceptionUtils.getGenericExceptionClass()
                            .isAssignableFrom(appResponse.getException().getClass())) {
                // TODO we should cast if is apache GenericException or not?
                org.apache.dubbo.rpc.service.GenericException exception =
                        (org.apache.dubbo.rpc.service.GenericException) appResponse.getException();
                try {
                    String className = exception.getExceptionClass();
                    DefaultSerializeClassChecker classChecker = moduleModel
                            .getApplicationModel()
                            .getFrameworkModel()
                            .getBeanFactory()
                            .getBean(DefaultSerializeClassChecker.class);
                    Class<?> clazz =
                            classChecker.loadClass(Thread.currentThread().getContextClassLoader(), className);
                    Throwable targetException = null;
                    Throwable lastException = null;
                    try {
                        targetException =
                                (Throwable) clazz.getDeclaredConstructor().newInstance();
                    } catch (Throwable e) {
                        lastException = e;
                        for (Constructor<?> constructor : clazz.getConstructors()) {
                            try {
                                targetException = (Throwable)
                                        constructor.newInstance(new Object[constructor.getParameterTypes().length]);
                                break;
                            } catch (Throwable e1) {
                                lastException = e1;
                            }
                        }
                    }
                    if (targetException != null) {
                        try {
                            Field field = Throwable.class.getDeclaredField("detailMessage");
                            if (!field.isAccessible()) {
                                field.setAccessible(true);
                            }
                            field.set(targetException, exception.getExceptionMessage());
                        } catch (Throwable e) {
                            logger.warn(COMMON_REFLECTIVE_OPERATION_FAILED, "", "", e.getMessage(), e);
                        }
                        appResponse.setException(targetException);
                    } else if (lastException != null) {
                        throw lastException;
                    }
                } catch (Throwable e) {
                    throw new RpcException(
                            "Can not deserialize exception " + exception.getExceptionClass() + ", message: "
                                    + exception.getExceptionMessage(),
                            e);
                }
            }
        }
    }