This is an automated email from the ASF dual-hosted git repository.

liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git

commit 3ca240d5cd88d432e08e31b5503701323e485859
Author: liubao <[email protected]>
AuthorDate: Thu Jan 23 16:09:24 2020 +0800

    [SCB-1732]support inheritance schema definition
---
 coverage-reports/pom.xml                           |  20 ---
 .../it-common/src/main/resources/logback.xml       |   8 ++
 .../it-common/src/main/resources/microservice.yaml |   4 +-
 .../org/apache/servicecomb/it/ConsumerMain.java    |   6 +-
 .../servicecomb/it/schema/generic/MyEndpoint.java  |   4 +-
 .../it/schema/generic/MyEndpointWithInterface.java |   3 +-
 .../pojo/definition/PojoConsumerOperationMeta.java |   7 +-
 swagger/swagger-generator/generator-core/pom.xml   |   5 +
 .../swagger/generator/ParameterGenerator.java      |   4 +-
 .../generator/core/AbstractOperationGenerator.java |  11 +-
 .../generator/core/AbstractSwaggerGenerator.java   |   2 +-
 .../swagger/generator/core/utils/MethodUtils.java  |  27 ++--
 .../swagger/generator/core/utils/ParamUtils.java   | 103 +++++++++++++++
 .../swagger/generator/core/TestParamUtils.java     | 123 ------------------
 .../swagger/generator/core/TestSwaggerUtils.java   | 100 ++++++++++++++-
 .../generator/core/utils/TestMethodUtils.java      |  19 ++-
 .../generator/core/utils/TestParamUtils.java       | 140 +++++++++++++++++++++
 .../{ => methodUtilsModel}/AbstractBaseClass.java  |   2 +-
 .../utils/{ => methodUtilsModel}/AbstractBean.java |   2 +-
 .../{ => methodUtilsModel}/BaseInterface.java      |   2 +-
 .../{ => methodUtilsModel}/Hello2Endpoint.java     |   2 +-
 .../utils/{ => methodUtilsModel}/HelloBean.java    |   2 +-
 .../{ => methodUtilsModel}/HelloEndpoint.java      |   2 +-
 .../{ => methodUtilsModel}/ServiceInterface.java   |   5 +-
 .../paramUtilsModel}/AbstractBaseService.java      |   6 +-
 .../{ => utils/paramUtilsModel}/AbstractBean.java  |   2 +-
 .../{ => utils/paramUtilsModel}/IBaseService.java  |   4 +-
 .../{ => utils/paramUtilsModel}/IMyService.java    |   7 +-
 .../paramUtilsModel}/IMyServiceChild.java          |   2 +-
 .../paramUtilsModel}/IMyServiceChild2.java         |   2 +-
 .../{ => utils/paramUtilsModel}/MyEndpoint.java    |  10 +-
 .../{ => utils/paramUtilsModel}/MyEndpoint2.java   |  11 +-
 .../{ => utils/paramUtilsModel}/PersonBean.java    |   2 +-
 .../swagger/engine/SwaggerConsumerOperation.java   |  10 ++
 .../swagger/engine/SwaggerEnvironment.java         |  21 +---
 .../arguments/AbstractArgumentsMapperCreator.java  |   5 +-
 .../consumer/ConsumerArgumentsMapperCreator.java   |   4 +-
 .../producer/ProducerArgumentsMapperCreator.java   |  13 +-
 38 files changed, 485 insertions(+), 217 deletions(-)

diff --git a/coverage-reports/pom.xml b/coverage-reports/pom.xml
index 7aab075..1103359 100644
--- a/coverage-reports/pom.xml
+++ b/coverage-reports/pom.xml
@@ -251,21 +251,6 @@
       <version>2.0.0-SNAPSHOT</version>
     </dependency>
     <dependency>
-      <groupId>org.apache.servicecomb.demo</groupId>
-      <artifactId>demo-spring-boot-discovery-server</artifactId>
-      <version>2.0.0-SNAPSHOT</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.servicecomb.demo</groupId>
-      <artifactId>demo-spring-boot-discovery-client</artifactId>
-      <version>2.0.0-SNAPSHOT</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.servicecomb.demo</groupId>
-      <artifactId>demo-spring-boot-zuul-proxy</artifactId>
-      <version>2.0.0-SNAPSHOT</version>
-    </dependency>
-    <dependency>
       <groupId>org.apache.servicecomb.tests</groupId>
       <artifactId>jaxrs-tests</artifactId>
       <version>2.0.0-SNAPSHOT</version>
@@ -292,11 +277,6 @@
     </dependency>
     <dependency>
       <groupId>org.apache.servicecomb.tests</groupId>
-      <artifactId>spring-zuul-tracing-tests</artifactId>
-      <version>2.0.0-SNAPSHOT</version>
-    </dependency>
-    <dependency>
-      <groupId>org.apache.servicecomb.tests</groupId>
       <artifactId>springmvc-tests-general</artifactId>
       <version>2.0.0-SNAPSHOT</version>
     </dependency>
diff --git a/integration-tests/it-common/src/main/resources/logback.xml 
b/integration-tests/it-common/src/main/resources/logback.xml
index 897ed2e..c327198 100644
--- a/integration-tests/it-common/src/main/resources/logback.xml
+++ b/integration-tests/it-common/src/main/resources/logback.xml
@@ -23,9 +23,17 @@
       <pattern>%d [%level] [%thread][%marker] - %msg (%F:%L\)%n</pattern>
     </encoder>
   </appender>
+  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
+    <file>servicecomb.log</file>
+    <append>true</append>
+    <encoder>
+      <pattern>%d [%level] [%thread][%marker] - %msg (%F:%L\)%n</pattern>
+    </encoder>
+  </appender>
   <logger name="org.apache.servicecomb.common.javassist.JavassistUtils" 
level="WARN"/>
   <logger 
name="org.apache.servicecomb.core.definition.schema.ProducerSchemaFactory" 
level="WARN"/>
   <root level="WARN">
     <appender-ref ref="STDOUT"/>
+    <appender-ref ref="FILE"/>
   </root>
 </configuration>
\ No newline at end of file
diff --git a/integration-tests/it-common/src/main/resources/microservice.yaml 
b/integration-tests/it-common/src/main/resources/microservice.yaml
index a48fad2..dc0c937 100644
--- a/integration-tests/it-common/src/main/resources/microservice.yaml
+++ b/integration-tests/it-common/src/main/resources/microservice.yaml
@@ -48,4 +48,6 @@ servicecomb:
     client:
       verticle-count: 8
   uploads:
-    directory: target
\ No newline at end of file
+    directory: target
+  codec:
+    printErrorMessage: true
\ No newline at end of file
diff --git 
a/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/ConsumerMain.java
 
b/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/ConsumerMain.java
index ef852b0..a0420df 100644
--- 
a/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/ConsumerMain.java
+++ 
b/integration-tests/it-consumer/src/main/java/org/apache/servicecomb/it/ConsumerMain.java
@@ -22,7 +22,7 @@ import org.apache.servicecomb.it.deploy.Deploys;
 import org.apache.servicecomb.it.deploy.MicroserviceDeploy;
 import org.apache.servicecomb.it.junit.ITJUnitUtils;
 import org.apache.servicecomb.it.schema.TestApiOperation;
-import org.apache.servicecomb.it.testcase.weak.consumer.TestSpringmvcBasic;
+import org.apache.servicecomb.it.schema.generic.TestMyService;
 import org.apache.servicecomb.it.testcase.TestAcceptType;
 import org.apache.servicecomb.it.testcase.TestAnnotatedAttribute;
 import org.apache.servicecomb.it.testcase.TestApiOperationOverride;
@@ -53,6 +53,7 @@ import 
org.apache.servicecomb.it.testcase.objectparams.TestJAXRSObjectParamType;
 import org.apache.servicecomb.it.testcase.objectparams.TestRPCObjectParamType;
 import 
org.apache.servicecomb.it.testcase.objectparams.TestSpringMVCObjectParamType;
 import org.apache.servicecomb.it.testcase.thirdparty.Test3rdPartyInvocation;
+import org.apache.servicecomb.it.testcase.weak.consumer.TestSpringmvcBasic;
 
 public class ConsumerMain {
   private static ResultPrinter resultPrinter = new ResultPrinter();
@@ -109,8 +110,7 @@ public class ConsumerMain {
     ITJUnitUtils.runWithHighwayAndRest(TestChangeTransport.class);
     ITJUnitUtils.runWithHighwayAndRest(TestDataTypePrimitive.class);
     ITJUnitUtils.runWithHighwayAndRest(TestAnnotatedAttribute.class);
-    // TODO : WEAK RPC & highway both not support this now , need fix it
-    //    ITJUnitUtils.runWithHighwayAndRest(TestMyService.class);
+    ITJUnitUtils.runWithHighwayAndRest(TestMyService.class);
 
     // only rest support default value feature
     ITJUnitUtils.runWithRest(TestDefaultValue.class);
diff --git 
a/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/generic/MyEndpoint.java
 
b/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/generic/MyEndpoint.java
index c206569..9955154 100644
--- 
a/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/generic/MyEndpoint.java
+++ 
b/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/generic/MyEndpoint.java
@@ -17,10 +17,10 @@
 
 package org.apache.servicecomb.it.schema.generic;
 
+import org.apache.servicecomb.provider.pojo.RpcSchema;
 import org.springframework.beans.factory.annotation.Autowired;
 
-// TODO : WEAK RPC & highway both not support this now , need fix it
-//@RpcSchema(schemaId = "MyEndpoint")
+@RpcSchema(schemaId = "MyEndpoint")
 public class MyEndpoint extends AbstractBaseService<PersonBean> implements 
IMyService {
   public MyEndpoint(@Autowired IMyService other) {
     super(other);
diff --git 
a/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/generic/MyEndpointWithInterface.java
 
b/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/generic/MyEndpointWithInterface.java
index b016b17..1f8024e 100644
--- 
a/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/generic/MyEndpointWithInterface.java
+++ 
b/integration-tests/it-producer/src/main/java/org/apache/servicecomb/it/schema/generic/MyEndpointWithInterface.java
@@ -22,8 +22,7 @@ import org.apache.servicecomb.provider.pojo.RpcSchema;
 
 import io.swagger.annotations.ApiOperation;
 
-// TODO : WEAK RPC & highway both not support this now , need fix it
-//@RpcSchema(schemaId = "MyEndpointWithInterface")
+@RpcSchema(schemaId = "MyEndpointWithInterface")
 public class MyEndpointWithInterface implements IMyService {
   @Override
   @ApiOperation(nickname = "hello", value = "hello")
diff --git 
a/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/definition/PojoConsumerOperationMeta.java
 
b/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/definition/PojoConsumerOperationMeta.java
index 1fadac9..78dec42 100644
--- 
a/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/definition/PojoConsumerOperationMeta.java
+++ 
b/providers/provider-pojo/src/main/java/org/apache/servicecomb/provider/pojo/definition/PojoConsumerOperationMeta.java
@@ -25,6 +25,7 @@ import javax.ws.rs.core.Response.Status;
 
 import org.apache.servicecomb.core.definition.OperationMeta;
 import org.apache.servicecomb.swagger.engine.SwaggerConsumerOperation;
+import org.apache.servicecomb.swagger.generator.core.utils.ParamUtils;
 import org.apache.servicecomb.swagger.invocation.response.ResponsesMeta;
 
 import com.fasterxml.jackson.databind.type.TypeFactory;
@@ -51,7 +52,11 @@ public class PojoConsumerOperationMeta {
     operationMeta.getResponsesMeta().cloneTo(responsesMeta);
     operationMeta.setSwaggerConsumerOperation(swaggerConsumerOperation);
     responsesMeta.init(intfSwagger, intfOperation);
-    Type intfResponseType = 
swaggerConsumerOperation.getConsumerMethod().getGenericReturnType();
+    Type intfResponseType = ParamUtils
+        .getGenericParameterType(swaggerConsumerOperation.getConsumerClass(),
+            swaggerConsumerOperation.getConsumerMethod().getDeclaringClass(),
+            
swaggerConsumerOperation.getConsumerMethod().getGenericReturnType());
+
     if (intfResponseType instanceof Class && 
Part.class.isAssignableFrom((Class<?>) intfResponseType)) {
       return;
     }
diff --git a/swagger/swagger-generator/generator-core/pom.xml 
b/swagger/swagger-generator/generator-core/pom.xml
index 3b5b774..f2c3bce 100644
--- a/swagger/swagger-generator/generator-core/pom.xml
+++ b/swagger/swagger-generator/generator-core/pom.xml
@@ -69,5 +69,10 @@
       <groupId>org.apache.servicecomb</groupId>
       <artifactId>foundation-test-scaffolding</artifactId>
     </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>spring-web</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 </project>
diff --git 
a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/ParameterGenerator.java
 
b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/ParameterGenerator.java
index e1a1ccf..d291b6c 100644
--- 
a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/ParameterGenerator.java
+++ 
b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/ParameterGenerator.java
@@ -62,12 +62,12 @@ public class ParameterGenerator {
   }
 
   public ParameterGenerator(Executable executable, Map<String, 
List<Annotation>> methodAnnotationMap,
-      java.lang.reflect.Parameter methodParameter) {
+      java.lang.reflect.Parameter methodParameter, Type genericType) {
     this(executable,
         methodAnnotationMap,
         methodParameter.isNamePresent() ? methodParameter.getName() : null,
         methodParameter.getAnnotations(),
-        methodParameter.getParameterizedType());
+        genericType);
   }
 
   public ParameterGenerator(String parameterName, List<Annotation> 
annotations) {
diff --git 
a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/AbstractOperationGenerator.java
 
b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/AbstractOperationGenerator.java
index fedfafc..0e38027 100644
--- 
a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/AbstractOperationGenerator.java
+++ 
b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/AbstractOperationGenerator.java
@@ -48,6 +48,7 @@ import 
org.apache.servicecomb.swagger.generator.ResponseTypeProcessor;
 import org.apache.servicecomb.swagger.generator.SwaggerConst;
 import org.apache.servicecomb.swagger.generator.core.model.HttpParameterType;
 import org.apache.servicecomb.swagger.generator.core.utils.MethodUtils;
+import org.apache.servicecomb.swagger.generator.core.utils.ParamUtils;
 
 import com.fasterxml.jackson.databind.BeanDescription;
 import com.fasterxml.jackson.databind.JavaType;
@@ -83,6 +84,8 @@ public abstract class AbstractOperationGenerator implements 
OperationGenerator {
 
   protected Swagger swagger;
 
+  protected Class<?> clazz;
+
   protected Method method;
 
   protected String httpMethod;
@@ -100,6 +103,7 @@ public abstract class AbstractOperationGenerator implements 
OperationGenerator {
   public AbstractOperationGenerator(AbstractSwaggerGenerator swaggerGenerator, 
Method method) {
     this.swaggerGenerator = swaggerGenerator;
     this.swagger = swaggerGenerator.getSwagger();
+    this.clazz = swaggerGenerator.getClazz();
     this.method = method;
     this.httpMethod = swaggerGenerator.getHttpMethod();
 
@@ -222,7 +226,9 @@ public abstract class AbstractOperationGenerator implements 
OperationGenerator {
 
   protected void initMethodParameterGenerators(Map<String, List<Annotation>> 
methodAnnotationMap) {
     for (java.lang.reflect.Parameter methodParameter : method.getParameters()) 
{
-      ParameterGenerator parameterGenerator = new ParameterGenerator(method, 
methodAnnotationMap, methodParameter);
+      Type genericType = ParamUtils.getGenericParameterType(clazz, method, 
methodParameter);
+      ParameterGenerator parameterGenerator = new ParameterGenerator(method, 
methodAnnotationMap, methodParameter,
+          genericType);
       validateParameter(parameterGenerator.getGenericType());
       if (isContextParameter(parameterGenerator.getGenericType())) {
         continue;
@@ -486,7 +492,8 @@ public abstract class AbstractOperationGenerator implements 
OperationGenerator {
   }
 
   protected Model createResponseModel() {
-    Type responseType = method.getGenericReturnType();
+    Type responseType = ParamUtils
+        .getGenericParameterType(clazz, method.getDeclaringClass(), 
method.getGenericReturnType());
     if (ReflectionUtils.isVoid(responseType)) {
       return null;
     }
diff --git 
a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/AbstractSwaggerGenerator.java
 
b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/AbstractSwaggerGenerator.java
index 6fea384..b1f4d5c 100644
--- 
a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/AbstractSwaggerGenerator.java
+++ 
b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/AbstractSwaggerGenerator.java
@@ -284,7 +284,7 @@ public abstract class AbstractSwaggerGenerator implements 
SwaggerGenerator {
   }
 
   protected void scanMethods() {
-    List<Method> methods = MethodUtils.findProducerMethods(cls);
+    List<Method> methods = MethodUtils.findSwaggerMethods(cls);
 
     for (Method method : methods) {
       if (isSkipMethod(method)) {
diff --git 
a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/utils/MethodUtils.java
 
b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/utils/MethodUtils.java
index b077d9f..e2d34b8 100644
--- 
a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/utils/MethodUtils.java
+++ 
b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/utils/MethodUtils.java
@@ -21,7 +21,9 @@ import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 import java.util.Comparator;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.commons.lang3.StringUtils;
 
@@ -33,20 +35,27 @@ public class MethodUtils {
    * @param cls The REST interface class, or so called "controller" class, to 
be analysed.
    * @return the valid methods to be used to generate Swagger schema, sorted 
by their Swagger operation name.
    */
-  public static List<Method> findProducerMethods(Class<?> cls) {
+  public static List<Method> findSwaggerMethods(Class<?> cls) {
     Method[] methods = cls.getMethods();
-    List<Method> producerMethods = new ArrayList<>(methods.length);
+    List<Method> result = new ArrayList<>(methods.length);
 
     for (Method m : methods) {
       if (!isSkipMethod(cls, m)) {
-        producerMethods.add(m);
+        result.add(m);
       }
     }
 
     // order of cls.getMethods() is undefined and not stable
     // so we must sort them first to make generation is stable
-    
producerMethods.sort(Comparator.comparing(MethodUtils::findSwaggerMethodName));
-    return producerMethods;
+    result.sort(Comparator.comparing(MethodUtils::findSwaggerMethodName));
+    return result;
+  }
+
+  public static Map<String, Method> 
findSwaggerMethodsMapOfOperationId(Class<?> cls) {
+    List<Method> methods = findSwaggerMethods(cls);
+    Map<String, Method> result = new HashMap<>();
+    methods.forEach((item) -> result.put(findSwaggerMethodName(item), item));
+    return result;
   }
 
   /**
@@ -98,12 +107,4 @@ public class MethodUtils {
 
     return apiOperationAnnotation.nickname();
   }
-
-  /**
-   * @return true if this method should NOT be displayed in schema; otherwise 
false
-   */
-  public static boolean isHiddenInSwagger(Method method) {
-    ApiOperation apiOperationAnnotation = 
method.getAnnotation(ApiOperation.class);
-    return null != apiOperationAnnotation && apiOperationAnnotation.hidden();
-  }
 }
diff --git 
a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/utils/ParamUtils.java
 
b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/utils/ParamUtils.java
new file mode 100644
index 0000000..0864045
--- /dev/null
+++ 
b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/utils/ParamUtils.java
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.swagger.generator.core.utils;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.Method;
+import java.lang.reflect.Parameter;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+
+import org.apache.commons.lang3.reflect.TypeUtils;
+
+public final class ParamUtils {
+  private ParamUtils() {
+
+  }
+
+  public static Type getGenericParameterType(Class<?> mainClass, Method 
method, Parameter param) {
+    Type type = param.getParameterizedType();
+    return getGenericParameterType(mainClass, method.getDeclaringClass(), 
type);
+  }
+
+  public static Type getGenericParameterType(Class<?> mainClass, Class<?> 
declaringClass, Type type) {
+    if (type instanceof Class<?> || mainClass == declaringClass) {
+      return type;
+    }
+
+    if (type instanceof TypeVariable) {
+      TypeVariable<?>[] typeVariables = declaringClass.getTypeParameters();
+      Type[] actualTypes;
+      if (mainClass.getGenericSuperclass() != null) {
+        actualTypes = getActualTypes(mainClass.getGenericSuperclass());
+      } else {
+        actualTypes = new Type[0];
+        Type[] interfaceTypes = mainClass.getGenericInterfaces();
+        for (Type t : interfaceTypes) {
+          Type[] ttTypes = getActualTypes(t);
+          Type[] tempTypes = new Type[actualTypes.length + ttTypes.length];
+          System.arraycopy(actualTypes, 0, tempTypes, 0, actualTypes.length);
+          System.arraycopy(ttTypes, 0, tempTypes, actualTypes.length, 
ttTypes.length);
+          actualTypes = tempTypes;
+        }
+      }
+      if (typeVariables.length != actualTypes.length) {
+        throw new IllegalArgumentException(String
+            .format("not implement (%s) (%s) (%s), "
+                    + "e.g. extends multiple typed interface or too deep 
inheritance.",
+                mainClass.getName(), declaringClass.getName(), 
type.getTypeName()));
+      }
+      for (int i = 0; i < typeVariables.length; i++) {
+        if (typeVariables[i] == type) {
+          return actualTypes[i];
+        }
+      }
+    } else if (type instanceof GenericArrayType) {
+      Class<?> t = (Class<?>) getGenericParameterType(mainClass, 
declaringClass,
+          ((GenericArrayType) type).getGenericComponentType());
+      return Array.newInstance(t, 0).getClass();
+    } else if (type instanceof ParameterizedType) {
+      ParameterizedType parameterizedType = (ParameterizedType) type;
+      Type[] targetTypes = new 
Type[parameterizedType.getActualTypeArguments().length];
+      for (int i = 0; i < parameterizedType.getActualTypeArguments().length; 
i++) {
+        targetTypes[i] = getGenericParameterType(mainClass, declaringClass,
+            parameterizedType.getActualTypeArguments()[i]);
+      }
+      return TypeUtils.parameterize((Class) parameterizedType.getRawType(), 
targetTypes);
+    }
+    throw new IllegalArgumentException(String
+        .format("not implement (%s) (%s) (%s)",
+            mainClass.getName(), declaringClass.getName(), 
type.getTypeName()));
+  }
+
+  private static Type[] getActualTypes(Type type) {
+    if (type instanceof Class<?>) {
+      if (((Class<?>) type).getSuperclass() != null) {
+        return getActualTypes(((Class<?>) type).getSuperclass());
+      } else {
+        return getActualTypes(((Class<?>) type).getGenericInterfaces()[0]);
+      }
+    }
+    if (type instanceof ParameterizedType) {
+      return ((ParameterizedType) type).getActualTypeArguments();
+    }
+    return new Type[0];
+  }
+}
diff --git 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestParamUtils.java
 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestParamUtils.java
deleted file mode 100644
index 5ff247e..0000000
--- 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestParamUtils.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.swagger.generator.core;
-
-import static junit.framework.TestCase.fail;
-import static org.hamcrest.Matchers.containsString;
-import static org.junit.Assert.assertThat;
-import static org.mockito.Mockito.when;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Type;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.servicecomb.swagger.SwaggerUtils;
-import org.apache.servicecomb.swagger.generator.SwaggerConst;
-import org.apache.servicecomb.swagger.generator.core.pojo.TestType1;
-import org.apache.servicecomb.swagger.generator.core.pojo.TestType2;
-import org.junit.Assert;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-import io.swagger.models.Swagger;
-import io.swagger.models.parameters.Parameter;
-import io.swagger.models.properties.ArrayProperty;
-import io.swagger.models.properties.MapProperty;
-import io.swagger.models.properties.ObjectProperty;
-import io.swagger.models.properties.Property;
-import io.swagger.models.properties.RefProperty;
-import io.swagger.models.properties.StringProperty;
-
-public class TestParamUtils {
-  @Test
-  public void testGetRawJsonType() {
-    Parameter param = Mockito.mock(Parameter.class);
-    Map<String, Object> extensions = new HashMap<>();
-    when(param.getVendorExtensions()).thenReturn(extensions);
-
-    extensions.put(SwaggerConst.EXT_RAW_JSON_TYPE, true);
-    Assert.assertTrue(SwaggerUtils.isRawJsonType(param));
-
-    extensions.put(SwaggerConst.EXT_RAW_JSON_TYPE, "test");
-    Assert.assertFalse(SwaggerUtils.isRawJsonType(param));
-  }
-
-  @Test
-  public void isComplexProperty() {
-    Property property = new RefProperty("ref");
-    Assert.assertTrue(SwaggerUtils.isComplexProperty(property));
-    property = new ObjectProperty();
-    Assert.assertTrue(SwaggerUtils.isComplexProperty(property));
-    property = new MapProperty();
-    Assert.assertTrue(SwaggerUtils.isComplexProperty(property));
-    property = new ArrayProperty(new ObjectProperty());
-    Assert.assertTrue(SwaggerUtils.isComplexProperty(property));
-
-    property = new ArrayProperty(new StringProperty());
-    Assert.assertFalse(SwaggerUtils.isComplexProperty(property));
-    property = new StringProperty();
-    Assert.assertFalse(SwaggerUtils.isComplexProperty(property));
-  }
-
-  private static class AllTypeTest1 {
-    TestType1 t1;
-
-    List<TestType1> t2;
-
-    Map<String, TestType1> t3;
-
-    TestType1[] t4;
-  }
-
-  private static class AllTypeTest2 {
-    TestType2 t1;
-
-    List<TestType2> t2;
-
-    Map<String, TestType2> t3;
-
-    TestType2[] t4;
-  }
-
-  @Test
-  public void testAddDefinitions() {
-    Field[] fields1 = AllTypeTest1.class.getDeclaredFields();
-    Field[] fields2 = AllTypeTest2.class.getDeclaredFields();
-    for (int i = 0; i < fields1.length; i++) {
-      for (int j = 0; j < fields2.length; j++) {
-        if (fields1[i].isSynthetic() || fields2[j].isSynthetic()) {
-          continue;
-        }
-        try {
-          testExcep(fields1[i].getGenericType(), fields2[j].getGenericType());
-          fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException e) {
-          assertThat(e.getMessage(), containsString("duplicate param model:"));
-        }
-      }
-    }
-  }
-
-  private void testExcep(Type f1, Type f2) {
-    Swagger swagger = new Swagger();
-    SwaggerUtils.addDefinitions(swagger, f1);
-    SwaggerUtils.addDefinitions(swagger, f2);
-  }
-}
diff --git 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestSwaggerUtils.java
 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestSwaggerUtils.java
index 1c1e435..b877fec 100644
--- 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestSwaggerUtils.java
+++ 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestSwaggerUtils.java
@@ -17,19 +17,42 @@
 
 package org.apache.servicecomb.swagger.generator.core;
 
+import static junit.framework.TestCase.fail;
+import static org.hamcrest.Matchers.containsString;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.when;
+
+import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.lang.reflect.Parameter;
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 import org.apache.servicecomb.foundation.common.utils.ReflectUtils;
+import org.apache.servicecomb.swagger.SwaggerUtils;
+import org.apache.servicecomb.swagger.generator.SwaggerConst;
 import org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils;
+import org.apache.servicecomb.swagger.generator.core.pojo.TestType1;
+import org.apache.servicecomb.swagger.generator.core.pojo.TestType2;
 import 
org.apache.servicecomb.swagger.generator.core.schema.InvalidResponseHeader;
 import org.apache.servicecomb.swagger.generator.core.schema.RepeatOperation;
 import org.apache.servicecomb.swagger.generator.core.schema.Schema;
 import 
org.apache.servicecomb.swagger.generator.core.unittest.UnitTestSwaggerUtils;
+import org.junit.Assert;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
-
+import org.mockito.Mockito;
+
+import io.swagger.models.Swagger;
+import io.swagger.models.properties.ArrayProperty;
+import io.swagger.models.properties.MapProperty;
+import io.swagger.models.properties.ObjectProperty;
+import io.swagger.models.properties.Property;
+import io.swagger.models.properties.RefProperty;
+import io.swagger.models.properties.StringProperty;
 import mockit.Expectations;
 
 public class TestSwaggerUtils {
@@ -262,4 +285,79 @@ public class TestSwaggerUtils {
             + "    </plugin>");
     SwaggerGeneratorUtils.collectParameterName(parameter);
   }
+
+  @Test
+  public void testGetRawJsonType() {
+    io.swagger.models.parameters.Parameter param = 
Mockito.mock(io.swagger.models.parameters.Parameter.class);
+    Map<String, Object> extensions = new HashMap<>();
+    when(param.getVendorExtensions()).thenReturn(extensions);
+
+    extensions.put(SwaggerConst.EXT_RAW_JSON_TYPE, true);
+    Assert.assertTrue(SwaggerUtils.isRawJsonType(param));
+
+    extensions.put(SwaggerConst.EXT_RAW_JSON_TYPE, "test");
+    Assert.assertFalse(SwaggerUtils.isRawJsonType(param));
+  }
+
+  @Test
+  public void isComplexProperty() {
+    Property property = new RefProperty("ref");
+    Assert.assertTrue(SwaggerUtils.isComplexProperty(property));
+    property = new ObjectProperty();
+    Assert.assertTrue(SwaggerUtils.isComplexProperty(property));
+    property = new MapProperty();
+    Assert.assertTrue(SwaggerUtils.isComplexProperty(property));
+    property = new ArrayProperty(new ObjectProperty());
+    Assert.assertTrue(SwaggerUtils.isComplexProperty(property));
+
+    property = new ArrayProperty(new StringProperty());
+    Assert.assertFalse(SwaggerUtils.isComplexProperty(property));
+    property = new StringProperty();
+    Assert.assertFalse(SwaggerUtils.isComplexProperty(property));
+  }
+
+  private static class AllTypeTest1 {
+    TestType1 t1;
+
+    List<TestType1> t2;
+
+    Map<String, TestType1> t3;
+
+    TestType1[] t4;
+  }
+
+  private static class AllTypeTest2 {
+    TestType2 t1;
+
+    List<TestType2> t2;
+
+    Map<String, TestType2> t3;
+
+    TestType2[] t4;
+  }
+
+  @Test
+  public void testAddDefinitions() {
+    Field[] fields1 = AllTypeTest1.class.getDeclaredFields();
+    Field[] fields2 = AllTypeTest2.class.getDeclaredFields();
+    for (int i = 0; i < fields1.length; i++) {
+      for (int j = 0; j < fields2.length; j++) {
+        if (fields1[i].isSynthetic() || fields2[j].isSynthetic()) {
+          continue;
+        }
+        try {
+          testExcep(fields1[i].getGenericType(), fields2[j].getGenericType());
+          fail("IllegalArgumentException expected");
+        } catch (IllegalArgumentException e) {
+          assertThat(e.getMessage(), containsString("duplicate param model:"));
+        }
+      }
+    }
+  }
+
+  private void testExcep(Type f1, Type f2) {
+    Swagger swagger = new Swagger();
+    SwaggerUtils.addDefinitions(swagger, f1);
+    SwaggerUtils.addDefinitions(swagger, f2);
+  }
 }
diff --git 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/TestMethodUtils.java
 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/TestMethodUtils.java
index ee57577..ae1ec1c 100644
--- 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/TestMethodUtils.java
+++ 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/TestMethodUtils.java
@@ -20,19 +20,32 @@ package org.apache.servicecomb.swagger.generator.core.utils;
 import java.lang.reflect.Method;
 import java.util.List;
 
+import 
org.apache.servicecomb.swagger.generator.core.utils.methodUtilsModel.AbstractBaseClass;
+import 
org.apache.servicecomb.swagger.generator.core.utils.methodUtilsModel.BaseInterface;
+import 
org.apache.servicecomb.swagger.generator.core.utils.methodUtilsModel.Hello2Endpoint;
+import 
org.apache.servicecomb.swagger.generator.core.utils.methodUtilsModel.HelloEndpoint;
+import 
org.apache.servicecomb.swagger.generator.core.utils.methodUtilsModel.ServiceInterface;
 import org.junit.Assert;
 import org.junit.Test;
 
 public class TestMethodUtils {
   @Test
   public void testGetClassMethods() throws Exception {
-    List<Method> methods = 
MethodUtils.findProducerMethods(Hello2Endpoint.class);
+    List<Method> methods = 
MethodUtils.findSwaggerMethods(Hello2Endpoint.class);
     Assert.assertEquals(3, methods.size());
+    Assert.assertEquals(Hello2Endpoint.class, 
methods.get(0).getDeclaringClass());
+    Assert.assertEquals(Hello2Endpoint.class, 
methods.get(1).getDeclaringClass());
+    Assert.assertEquals(Hello2Endpoint.class, 
methods.get(2).getDeclaringClass());
 
-    methods = MethodUtils.findProducerMethods(HelloEndpoint.class);
+    methods = MethodUtils.findSwaggerMethods(HelloEndpoint.class);
     Assert.assertEquals(2, methods.size());
+    Assert.assertEquals(HelloEndpoint.class, 
methods.get(0).getDeclaringClass()); // get
+    Assert.assertEquals(AbstractBaseClass.class, 
methods.get(1).getDeclaringClass()); // getBase
 
-    methods = MethodUtils.findProducerMethods(ServiceInterface.class);
+    methods = MethodUtils.findSwaggerMethods(ServiceInterface.class);
     Assert.assertEquals(3, methods.size());
+    Assert.assertEquals(BaseInterface.class, 
methods.get(0).getDeclaringClass()); // get
+    Assert.assertEquals(BaseInterface.class, 
methods.get(1).getDeclaringClass()); // getArray
+    Assert.assertEquals(ServiceInterface.class, 
methods.get(2).getDeclaringClass()); // getBase
   }
 }
diff --git 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/TestParamUtils.java
 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/TestParamUtils.java
new file mode 100644
index 0000000..87c28a0
--- /dev/null
+++ 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/TestParamUtils.java
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.swagger.generator.core.utils;
+
+import static org.junit.Assert.assertEquals;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.apache.commons.lang3.reflect.TypeUtils;
+import 
org.apache.servicecomb.swagger.generator.core.utils.paramUtilsModel.AbstractBaseService;
+import 
org.apache.servicecomb.swagger.generator.core.utils.paramUtilsModel.AbstractBean;
+import 
org.apache.servicecomb.swagger.generator.core.utils.paramUtilsModel.IBaseService;
+import 
org.apache.servicecomb.swagger.generator.core.utils.paramUtilsModel.IMyService;
+import 
org.apache.servicecomb.swagger.generator.core.utils.paramUtilsModel.MyEndpoint;
+import 
org.apache.servicecomb.swagger.generator.core.utils.paramUtilsModel.MyEndpoint2;
+import 
org.apache.servicecomb.swagger.generator.core.utils.paramUtilsModel.PersonBean;
+import org.junit.Assert;
+import org.junit.Test;
+import org.springframework.web.multipart.MultipartFile;
+
+public class TestParamUtils {
+
+  @Test
+  public void testGenericTypeInheritance() throws Exception {
+    Method hello = IMyService.class.getMethod("hello", AbstractBean.class);
+    assertEquals(PersonBean.class,
+        ParamUtils.getGenericParameterType(IMyService.class, 
IBaseService.class, hello.getGenericReturnType()));
+    assertEquals(PersonBean.class,
+        ParamUtils.getGenericParameterType(IMyService.class, hello, 
hello.getParameters()[0]));
+
+    hello = MyEndpoint.class.getMethod("hello", AbstractBean.class);
+    assertEquals(PersonBean.class,
+        ParamUtils.getGenericParameterType(MyEndpoint.class, 
AbstractBaseService.class, hello.getGenericReturnType()));
+    assertEquals(PersonBean.class,
+        ParamUtils.getGenericParameterType(MyEndpoint.class, hello, 
hello.getParameters()[0]));
+
+    hello = MyEndpoint2.class.getMethod("hello", PersonBean.class);
+    assertEquals(PersonBean.class,
+        ParamUtils.getGenericParameterType(MyEndpoint2.class, 
MyEndpoint2.class, hello.getGenericReturnType()));
+    assertEquals(PersonBean.class,
+        ParamUtils.getGenericParameterType(MyEndpoint2.class, hello, 
hello.getParameters()[0]));
+
+    Method helloBody = IMyService.class.getMethod("helloBody", 
AbstractBean[].class);
+    assertEquals(PersonBean[].class,
+        ParamUtils.getGenericParameterType(IMyService.class, 
IBaseService.class, helloBody.getGenericReturnType()));
+    assertEquals(PersonBean[].class,
+        ParamUtils.getGenericParameterType(MyEndpoint.class, helloBody, 
helloBody.getParameters()[0]));
+
+    helloBody = MyEndpoint.class.getMethod("helloBody", AbstractBean[].class);
+    assertEquals(PersonBean[].class, ParamUtils
+        .getGenericParameterType(MyEndpoint.class, AbstractBaseService.class, 
helloBody.getGenericReturnType()));
+    assertEquals(PersonBean[].class,
+        ParamUtils.getGenericParameterType(MyEndpoint.class, helloBody, 
helloBody.getParameters()[0]));
+
+    Method helloList = IMyService.class.getMethod("helloList", List.class);
+    assertEquals(TypeUtils.parameterize(List.class, PersonBean.class),
+        ParamUtils.getGenericParameterType(IMyService.class, 
IBaseService.class, helloList.getGenericReturnType()));
+    assertEquals(TypeUtils.parameterize(List.class, PersonBean.class),
+        ParamUtils.getGenericParameterType(IMyService.class, helloList, 
helloList.getParameters()[0]));
+
+    helloList = MyEndpoint.class.getMethod("helloList", List.class);
+    assertEquals(TypeUtils.parameterize(List.class, PersonBean.class), 
ParamUtils
+        .getGenericParameterType(MyEndpoint.class, AbstractBaseService.class, 
helloList.getGenericReturnType()));
+    assertEquals(TypeUtils.parameterize(List.class, PersonBean.class),
+        ParamUtils.getGenericParameterType(MyEndpoint.class, helloList, 
helloList.getParameters()[0]));
+
+    Method actual = IMyService.class.getMethod("actual", PersonBean.class);
+    assertEquals(PersonBean.class,
+        ParamUtils.getGenericParameterType(IMyService.class, 
IBaseService.class, actual.getGenericReturnType()));
+    assertEquals(PersonBean.class,
+        ParamUtils.getGenericParameterType(IMyService.class, actual, 
actual.getParameters()[0]));
+
+    helloList = MyEndpoint.class.getMethod("actual", PersonBean.class);
+    assertEquals(PersonBean.class,
+        ParamUtils
+            .getGenericParameterType(MyEndpoint.class, 
AbstractBaseService.class, helloList.getGenericReturnType()));
+    assertEquals(PersonBean.class,
+        ParamUtils.getGenericParameterType(MyEndpoint.class, helloList, 
helloList.getParameters()[0]));
+
+    Method parentHello = IMyService.class.getMethod("parentHello", List.class);
+    assertEquals(TypeUtils.parameterize(List.class, MultipartFile.class),
+        ParamUtils
+            .getGenericParameterType(IMyService.class, IMyService.class, 
parentHello.getGenericReturnType()));
+    assertEquals(TypeUtils.parameterize(List.class, MultipartFile.class),
+        ParamUtils
+            .getGenericParameterType(IMyService.class, parentHello, 
parentHello.getParameters()[0]));
+  }
+
+  @Test
+  public void testGenericTypeInheritanceWithMethodUtils() throws Exception {
+    List<Method> methods = MethodUtils.findSwaggerMethods(MyEndpoint.class);
+    Assert.assertEquals(5, methods.size());
+    assertEquals(PersonBean.class, ParamUtils
+        .getGenericParameterType(MyEndpoint.class, 
methods.get(0).getDeclaringClass(),
+            methods.get(0).getGenericReturnType())); // actual
+    assertEquals(PersonBean.class, ParamUtils
+        .getGenericParameterType(MyEndpoint.class, methods.get(0),
+            methods.get(0).getParameters()[0])); // actual
+    assertEquals(PersonBean.class, ParamUtils
+        .getGenericParameterType(MyEndpoint.class, 
methods.get(1).getDeclaringClass(),
+            methods.get(1).getGenericReturnType())); // hello
+    assertEquals(PersonBean.class, ParamUtils
+        .getGenericParameterType(MyEndpoint.class, methods.get(1),
+            methods.get(1).getParameters()[0])); // hello
+    assertEquals(PersonBean[].class, ParamUtils
+        .getGenericParameterType(MyEndpoint.class, 
methods.get(2).getDeclaringClass(),
+            methods.get(2).getGenericReturnType())); // helloBody
+    assertEquals(PersonBean[].class, ParamUtils
+        .getGenericParameterType(MyEndpoint.class, methods.get(2),
+            methods.get(2).getParameters()[0])); // helloBody
+    assertEquals(TypeUtils.parameterize(List.class, PersonBean.class), 
ParamUtils
+        .getGenericParameterType(MyEndpoint.class, 
methods.get(3).getDeclaringClass(),
+            methods.get(3).getGenericReturnType())); // helloList
+    assertEquals(TypeUtils.parameterize(List.class, PersonBean.class), 
ParamUtils
+        .getGenericParameterType(MyEndpoint.class, methods.get(3),
+            methods.get(3).getParameters()[0])); // helloList
+    assertEquals(TypeUtils.parameterize(List.class, MultipartFile.class), 
ParamUtils
+        .getGenericParameterType(MyEndpoint.class, 
methods.get(4).getDeclaringClass(),
+            methods.get(4).getGenericReturnType())); // parentHello
+    assertEquals(TypeUtils.parameterize(List.class, MultipartFile.class), 
ParamUtils
+        .getGenericParameterType(MyEndpoint.class, methods.get(4),
+            methods.get(4).getParameters()[0])); // parentHello
+  }
+}
diff --git 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/AbstractBaseClass.java
 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/methodUtilsModel/AbstractBaseClass.java
similarity index 92%
rename from 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/AbstractBaseClass.java
rename to 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/methodUtilsModel/AbstractBaseClass.java
index 50c577d..f5d4f56 100644
--- 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/AbstractBaseClass.java
+++ 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/methodUtilsModel/AbstractBaseClass.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.swagger.generator.core.utils;
+package org.apache.servicecomb.swagger.generator.core.utils.methodUtilsModel;
 
 public abstract class AbstractBaseClass<T extends AbstractBean> {
   abstract T get(T param);
diff --git 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/AbstractBean.java
 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/methodUtilsModel/AbstractBean.java
similarity index 92%
rename from 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/AbstractBean.java
rename to 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/methodUtilsModel/AbstractBean.java
index 85515b5..521f559 100644
--- 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/AbstractBean.java
+++ 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/methodUtilsModel/AbstractBean.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.swagger.generator.core.utils;
+package org.apache.servicecomb.swagger.generator.core.utils.methodUtilsModel;
 
 public abstract class AbstractBean {
   private String type;
diff --git 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/BaseInterface.java
 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/methodUtilsModel/BaseInterface.java
similarity index 92%
rename from 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/BaseInterface.java
rename to 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/methodUtilsModel/BaseInterface.java
index 1cef6c4..fd7b60f 100644
--- 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/BaseInterface.java
+++ 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/methodUtilsModel/BaseInterface.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.servicecomb.swagger.generator.core.utils;
+package org.apache.servicecomb.swagger.generator.core.utils.methodUtilsModel;
 
 public interface BaseInterface<T extends AbstractBean> {
   T get(T param);
diff --git 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/Hello2Endpoint.java
 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/methodUtilsModel/Hello2Endpoint.java
similarity index 93%
rename from 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/Hello2Endpoint.java
rename to 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/methodUtilsModel/Hello2Endpoint.java
index 4f40fe7..42ec7d8 100644
--- 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/Hello2Endpoint.java
+++ 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/methodUtilsModel/Hello2Endpoint.java
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.servicecomb.swagger.generator.core.utils;
+package org.apache.servicecomb.swagger.generator.core.utils.methodUtilsModel;
 
 public class Hello2Endpoint implements ServiceInterface {
   @Override
diff --git 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/HelloBean.java
 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/methodUtilsModel/HelloBean.java
similarity index 92%
rename from 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/HelloBean.java
rename to 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/methodUtilsModel/HelloBean.java
index a380e7e..e8adb9c 100644
--- 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/HelloBean.java
+++ 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/methodUtilsModel/HelloBean.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.swagger.generator.core.utils;
+package org.apache.servicecomb.swagger.generator.core.utils.methodUtilsModel;
 
 public class HelloBean extends AbstractBean {
   private String hello;
diff --git 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/HelloEndpoint.java
 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/methodUtilsModel/HelloEndpoint.java
similarity index 92%
rename from 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/HelloEndpoint.java
rename to 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/methodUtilsModel/HelloEndpoint.java
index 1901250..1736e04 100644
--- 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/HelloEndpoint.java
+++ 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/methodUtilsModel/HelloEndpoint.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.swagger.generator.core.utils;
+package org.apache.servicecomb.swagger.generator.core.utils.methodUtilsModel;
 
 public class HelloEndpoint extends AbstractBaseClass<HelloBean> {
   @Override
diff --git 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/ServiceInterface.java
 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/methodUtilsModel/ServiceInterface.java
similarity index 78%
rename from 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/ServiceInterface.java
rename to 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/methodUtilsModel/ServiceInterface.java
index ef58d03..2ec156f 100644
--- 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/ServiceInterface.java
+++ 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/methodUtilsModel/ServiceInterface.java
@@ -15,7 +15,10 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.swagger.generator.core.utils;
+package org.apache.servicecomb.swagger.generator.core.utils.methodUtilsModel;
+
+import 
org.apache.servicecomb.swagger.generator.core.utils.methodUtilsModel.BaseInterface;
+import 
org.apache.servicecomb.swagger.generator.core.utils.methodUtilsModel.HelloBean;
 
 public interface ServiceInterface extends BaseInterface<HelloBean> {
   HelloBean getBase(HelloBean param);
diff --git 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/AbstractBaseService.java
 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/AbstractBaseService.java
similarity index 89%
rename from 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/AbstractBaseService.java
rename to 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/AbstractBaseService.java
index 8a6f37c..a68a2e4 100644
--- 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/AbstractBaseService.java
+++ 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/AbstractBaseService.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.swagger.generator.core;
+package org.apache.servicecomb.swagger.generator.core.utils.paramUtilsModel;
 
 import java.util.List;
 
@@ -42,7 +42,7 @@ public class AbstractBaseService<T extends AbstractBean> 
implements IBaseService
   }
 
   @Override
-  public PersonBean actual() {
-    return target.actual();
+  public PersonBean actual(PersonBean bean) {
+    return target.actual(bean);
   }
 }
diff --git 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/AbstractBean.java
 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/AbstractBean.java
similarity index 92%
rename from 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/AbstractBean.java
rename to 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/AbstractBean.java
index cca7929..9e3dc72 100644
--- 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/AbstractBean.java
+++ 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/AbstractBean.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.swagger.generator.core;
+package org.apache.servicecomb.swagger.generator.core.utils.paramUtilsModel;
 
 public abstract class AbstractBean {
   private String name;
diff --git 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/IBaseService.java
 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/IBaseService.java
similarity index 89%
rename from 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/IBaseService.java
rename to 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/IBaseService.java
index 09db55e..d2e0ec4 100644
--- 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/IBaseService.java
+++ 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/IBaseService.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.swagger.generator.core;
+package org.apache.servicecomb.swagger.generator.core.utils.paramUtilsModel;
 
 import java.util.List;
 
@@ -26,5 +26,5 @@ public interface IBaseService<T extends AbstractBean> {
 
   List<T> helloList(List<T> a);
 
-  PersonBean actual();
+  PersonBean actual(PersonBean bean);
 }
diff --git 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/IMyService.java
 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/IMyService.java
similarity index 79%
rename from 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/IMyService.java
rename to 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/IMyService.java
index 99dc529..47cc70e 100644
--- 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/IMyService.java
+++ 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/IMyService.java
@@ -15,7 +15,12 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.swagger.generator.core;
+package org.apache.servicecomb.swagger.generator.core.utils.paramUtilsModel;
+
+import java.util.List;
+
+import org.springframework.web.multipart.MultipartFile;
 
 public interface IMyService extends IBaseService<PersonBean> {
+  List<MultipartFile> parentHello(List<MultipartFile> bean);
 }
diff --git 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/IMyServiceChild.java
 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/IMyServiceChild.java
similarity index 91%
rename from 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/IMyServiceChild.java
rename to 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/IMyServiceChild.java
index 07405e2..d6025ce 100644
--- 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/IMyServiceChild.java
+++ 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/IMyServiceChild.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.swagger.generator.core;
+package org.apache.servicecomb.swagger.generator.core.utils.paramUtilsModel;
 
 public interface IMyServiceChild extends IMyService {
 }
diff --git 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/IMyServiceChild2.java
 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/IMyServiceChild2.java
similarity index 92%
rename from 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/IMyServiceChild2.java
rename to 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/IMyServiceChild2.java
index 0828846..7f8c758 100644
--- 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/IMyServiceChild2.java
+++ 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/IMyServiceChild2.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.swagger.generator.core;
+package org.apache.servicecomb.swagger.generator.core.utils.paramUtilsModel;
 
 public interface IMyServiceChild2 extends IMyService, IBaseService<PersonBean> 
{
 }
diff --git 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/MyEndpoint.java
 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/MyEndpoint.java
similarity index 79%
rename from 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/MyEndpoint.java
rename to 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/MyEndpoint.java
index 1792814..98ff012 100644
--- 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/MyEndpoint.java
+++ 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/MyEndpoint.java
@@ -15,12 +15,20 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.swagger.generator.core;
+package org.apache.servicecomb.swagger.generator.core.utils.paramUtilsModel;
+
+import java.util.List;
 
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.multipart.MultipartFile;
 
 public class MyEndpoint extends AbstractBaseService<PersonBean> implements 
IMyService {
   public MyEndpoint(@Autowired IMyService other) {
     super(other);
   }
+
+  @Override
+  public List<MultipartFile> parentHello(List<MultipartFile> bean) {
+    return null;
+  }
 }
diff --git 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/MyEndpoint2.java
 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/MyEndpoint2.java
similarity index 80%
rename from 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/MyEndpoint2.java
rename to 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/MyEndpoint2.java
index 8ece9e8..f8fef7d 100644
--- 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/MyEndpoint2.java
+++ 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/MyEndpoint2.java
@@ -14,10 +14,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.servicecomb.swagger.generator.core;
+package org.apache.servicecomb.swagger.generator.core.utils.paramUtilsModel;
 
 import java.util.List;
 
+import org.springframework.web.multipart.MultipartFile;
+
 public class MyEndpoint2 implements IMyService {
   @Override
   public PersonBean hello(PersonBean a) {
@@ -35,7 +37,12 @@ public class MyEndpoint2 implements IMyService {
   }
 
   @Override
-  public PersonBean actual() {
+  public PersonBean actual(PersonBean bean) {
+    return null;
+  }
+
+  @Override
+  public List<MultipartFile> parentHello(List<MultipartFile> bean) {
     return null;
   }
 }
diff --git 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/PersonBean.java
 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/PersonBean.java
similarity index 91%
rename from 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/PersonBean.java
rename to 
swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/PersonBean.java
index b2c4eff..508d302 100644
--- 
a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/PersonBean.java
+++ 
b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/utils/paramUtilsModel/PersonBean.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.swagger.generator.core;
+package org.apache.servicecomb.swagger.generator.core.utils.paramUtilsModel;
 
 public class PersonBean extends AbstractBean {
 }
diff --git 
a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerConsumerOperation.java
 
b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerConsumerOperation.java
index c8bbb82..b236d9a 100644
--- 
a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerConsumerOperation.java
+++ 
b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerConsumerOperation.java
@@ -24,6 +24,8 @@ import 
org.apache.servicecomb.swagger.invocation.arguments.consumer.ConsumerArgu
 import 
org.apache.servicecomb.swagger.invocation.response.consumer.ConsumerResponseMapper;
 
 public class SwaggerConsumerOperation {
+  private Class<?> consumerClass;
+
   private Method consumerMethod;
 
   private SwaggerOperation swaggerOperation;
@@ -44,6 +46,14 @@ public class SwaggerConsumerOperation {
     this.consumerMethod = consumerMethod;
   }
 
+  public Class<?> getConsumerClass() {
+    return consumerClass;
+  }
+
+  public void setConsumerClass(Class<?> consumerClass) {
+    this.consumerClass = consumerClass;
+  }
+
   public SwaggerOperation getSwaggerOperation() {
     return swaggerOperation;
   }
diff --git 
a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerEnvironment.java
 
b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerEnvironment.java
index cd0d509..ac6f4a4 100644
--- 
a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerEnvironment.java
+++ 
b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/engine/SwaggerEnvironment.java
@@ -17,7 +17,6 @@
 package org.apache.servicecomb.swagger.engine;
 
 import java.lang.reflect.Method;
-import java.util.HashMap;
 import java.util.Map;
 import java.util.function.Function;
 import java.util.stream.Collectors;
@@ -61,7 +60,7 @@ public class SwaggerEnvironment {
 
     SwaggerConsumer consumer = new SwaggerConsumer();
     consumer.setConsumerIntf(consumerIntf);
-    for (Method consumerMethod : consumerIntf.getMethods()) {
+    for (Method consumerMethod : MethodUtils.findSwaggerMethods(consumerIntf)) 
{
       String operationId = findOperationId(consumerMethod);
       SwaggerOperation swaggerOperation = 
swaggerOperations.findOperation(operationId);
       if (swaggerOperation == null) {
@@ -76,6 +75,7 @@ public class SwaggerEnvironment {
       ConsumerArgumentsMapperCreator creator = new 
ConsumerArgumentsMapperCreator(
           Json.mapper().getSerializationConfig(),
           contextFactorys,
+          consumerIntf,
           consumerMethod,
           swaggerOperation);
       ConsumerArgumentsMapper argsMapper = creator.createArgumentsMapper();
@@ -83,6 +83,7 @@ public class SwaggerEnvironment {
           .createResponseMapper(consumerMethod.getGenericReturnType());
 
       SwaggerConsumerOperation op = new SwaggerConsumerOperation();
+      op.setConsumerClass(consumerIntf);
       op.setConsumerMethod(consumerMethod);
       op.setSwaggerOperation(swaggerOperation);
       op.setArgumentsMapper(argsMapper);
@@ -114,7 +115,7 @@ public class SwaggerEnvironment {
     SwaggerOperations swaggerOperations = new SwaggerOperations(swagger);
 
     Class<?> producerCls = BeanUtils.getImplClassFromBean(producerInstance);
-    Map<String, Method> visibleProducerMethods = 
retrieveVisibleMethods(producerCls);
+    Map<String, Method> visibleProducerMethods = 
MethodUtils.findSwaggerMethodsMapOfOperationId(producerCls);
 
     SwaggerProducer producer = new SwaggerProducer();
     producer.setSwagger(swagger);
@@ -135,6 +136,7 @@ public class SwaggerEnvironment {
       ProducerArgumentsMapperCreator creator = new 
ProducerArgumentsMapperCreator(
           Json.mapper().getSerializationConfig(),
           contextFactorys,
+          producerCls,
           producerMethod,
           swaggerOperation);
       ProducerArgumentsMapper argsMapper = creator.createArgumentsMapper();
@@ -155,17 +157,4 @@ public class SwaggerEnvironment {
 
     return producer;
   }
-
-  private Map<String, Method> retrieveVisibleMethods(Class<?> clazz) {
-    Map<String, Method> visibleMethods = new HashMap<>();
-    for (Method method : clazz.getMethods()) {
-      if (MethodUtils.isHiddenInSwagger(method)) {
-        continue;
-      }
-      String operationId = MethodUtils.findSwaggerMethodName(method);
-
-      visibleMethods.put(operationId, method);
-    }
-    return visibleMethods;
-  }
 }
diff --git 
a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/AbstractArgumentsMapperCreator.java
 
b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/AbstractArgumentsMapperCreator.java
index 0ac0365..e85e423 100644
--- 
a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/AbstractArgumentsMapperCreator.java
+++ 
b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/AbstractArgumentsMapperCreator.java
@@ -99,6 +99,8 @@ public abstract class AbstractArgumentsMapperCreator {
   // consumer or producer
   protected Method providerMethod;
 
+  protected Class<?> providerClass;
+
   protected SwaggerOperation swaggerOperation;
 
   protected List<ArgumentMapper> mappers = new ArrayList<>();
@@ -115,10 +117,11 @@ public abstract class AbstractArgumentsMapperCreator {
   protected Set<String> processedSwaggerParamters;
 
   public AbstractArgumentsMapperCreator(SerializationConfig 
serializationConfig,
-      Map<Class<?>, ContextArgumentMapperFactory> contextFactorys,
+      Map<Class<?>, ContextArgumentMapperFactory> contextFactorys, Class<?> 
providerClass,
       Method providerMethod, SwaggerOperation swaggerOperation) {
     this.serializationConfig = serializationConfig;
     this.contextFactorys = contextFactorys;
+    this.providerClass = providerClass;
     this.providerMethod = providerMethod;
     this.swaggerOperation = swaggerOperation;
 
diff --git 
a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/ConsumerArgumentsMapperCreator.java
 
b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/ConsumerArgumentsMapperCreator.java
index 24bea6a..03f0599 100644
--- 
a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/ConsumerArgumentsMapperCreator.java
+++ 
b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/consumer/ConsumerArgumentsMapperCreator.java
@@ -44,9 +44,9 @@ public class ConsumerArgumentsMapperCreator extends 
AbstractArgumentsMapperCreat
   private int unknownConsumerParams = 0;
 
   public ConsumerArgumentsMapperCreator(SerializationConfig 
serializationConfig,
-      Map<Class<?>, ContextArgumentMapperFactory> contextFactorys,
+      Map<Class<?>, ContextArgumentMapperFactory> contextFactorys, Class<?> 
consumerClass,
       Method consumerMethod, SwaggerOperation swaggerOperation) {
-    super(serializationConfig, contextFactorys, consumerMethod, 
swaggerOperation);
+    super(serializationConfig, contextFactorys, consumerClass, consumerMethod, 
swaggerOperation);
   }
 
   private boolean isAllSameMapper() {
diff --git 
a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerArgumentsMapperCreator.java
 
b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerArgumentsMapperCreator.java
index 3b4d33f..aec3852 100644
--- 
a/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerArgumentsMapperCreator.java
+++ 
b/swagger/swagger-invocation/invocation-core/src/main/java/org/apache/servicecomb/swagger/invocation/arguments/producer/ProducerArgumentsMapperCreator.java
@@ -28,6 +28,7 @@ import java.util.Map;
 import org.apache.servicecomb.foundation.common.utils.LambdaMetafactoryUtils;
 import org.apache.servicecomb.foundation.common.utils.bean.Setter;
 import org.apache.servicecomb.swagger.generator.core.model.SwaggerOperation;
+import org.apache.servicecomb.swagger.generator.core.utils.ParamUtils;
 import 
org.apache.servicecomb.swagger.invocation.arguments.AbstractArgumentsMapperCreator;
 import org.apache.servicecomb.swagger.invocation.arguments.ArgumentMapper;
 import 
org.apache.servicecomb.swagger.invocation.arguments.ContextArgumentMapperFactory;
@@ -44,9 +45,9 @@ public class ProducerArgumentsMapperCreator extends 
AbstractArgumentsMapperCreat
   private Map<String, Type> swaggerParameterTypes;
 
   public ProducerArgumentsMapperCreator(SerializationConfig 
serializationConfig,
-      Map<Class<?>, ContextArgumentMapperFactory> contextFactorys,
+      Map<Class<?>, ContextArgumentMapperFactory> contextFactorys, Class<?> 
producerClass,
       Method producerMethod, SwaggerOperation swaggerOperation) {
-    super(serializationConfig, contextFactorys, producerMethod, 
swaggerOperation);
+    super(serializationConfig, contextFactorys, producerClass, producerMethod, 
swaggerOperation);
 
     swaggerParameterTypes = new HashMap<>();
   }
@@ -75,8 +76,10 @@ public class ProducerArgumentsMapperCreator extends 
AbstractArgumentsMapperCreat
   @Override
   protected ArgumentMapper createKnownParameterMapper(int providerParamIdx, 
Integer swaggerIdx) {
     String swaggerArgumentName = swaggerParameters.get(swaggerIdx).getName();
+    final Type providerType = 
ParamUtils.getGenericParameterType(this.providerClass, this.providerMethod,
+        this.providerMethod.getParameters()[providerParamIdx]);
     swaggerParameterTypes
-        .put(swaggerArgumentName, 
providerMethod.getParameters()[providerParamIdx].getParameterizedType());
+        .put(swaggerArgumentName, providerType);
     return new 
ProducerArgumentSame(providerMethod.getParameters()[providerParamIdx].getName(),
 swaggerArgumentName);
   }
 
@@ -86,9 +89,11 @@ public class ProducerArgumentsMapperCreator extends 
AbstractArgumentsMapperCreat
     String swaggerArgumentName = 
swaggerParameters.get(swaggerBodyIdx).getName();
     swaggerParameterTypes
         .put(swaggerArgumentName, Object.class);
+    Type parameterType = 
ParamUtils.getGenericParameterType(this.providerClass, this.providerMethod,
+        providerMethod.getParameters()[producerParamIdx]);
     return new 
SwaggerBodyFieldToProducerArgument(providerMethod.getParameters()[producerParamIdx].getName(),
         swaggerArgumentName,
-        parameterName, 
providerMethod.getParameters()[producerParamIdx].getParameterizedType());
+        parameterName, parameterType);
   }
 
   @Override

Reply via email to