You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2020/01/14 11:52:21 UTC

[servicecomb-java-chassis] branch master updated: [SCB-1714]highway support different models and arguments types in consumer and provider

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


The following commit(s) were added to refs/heads/master by this push:
     new 3f88aa6  [SCB-1714]highway support different models and arguments types in consumer and provider
3f88aa6 is described below

commit 3f88aa62e2a586b0a4b49645f2f50798cf98e22f
Author: liubao <bi...@qq.com>
AuthorDate: Tue Jan 14 15:46:19 2020 +0800

    [SCB-1714]highway support different models and arguments types in consumer and provider
---
 .../runtime/ProtobufCompatibleUtils.java           |  93 ----------
 .../runtime/RuntimeMapFieldProtobuf.java           | 161 -----------------
 .../protobuf/definition/OperationProtobuf.java     | 159 ++++++++++------
 .../definition}/RequestRootDeserializer.java       |   8 +-
 .../definition}/RequestRootSerializer.java         |  14 +-
 .../definition}/ResponseRootDeserializer.java      |   3 +-
 .../definition/ResponseRootSerializer.java         |  25 ++-
 .../converter/SwaggerToProtoGenerator.java         |   7 +-
 .../codec/protobuf/utils/ProtobufSchemaUtils.java  |  96 ----------
 .../runtime/TestProtobufCompatibleUtils.java       |  96 ----------
 .../internal/converter/TestSchemaMetaCodec.java    | 199 ++++++++++++++++-----
 .../converter/TestSchemaMetaCodecRestTemplate.java |  26 +--
 .../internal/converter/model/ProtoSchema.java      |   2 +-
 .../internal/converter/model/ProtoSchemaIntf.java  | 104 +++++++++++
 .../internal/converter/model/ProtoSchemaPojo.java  |   2 +-
 .../apache/servicecomb/common/rest/RestConst.java  |   2 -
 .../rest/filter/inner/ClientRestArgsFilter.java    |  10 +-
 .../org/apache/servicecomb/core/Invocation.java    |  12 ++
 .../servicecomb/demo/pojo/client/PojoClient.java   |   6 +-
 .../servicecomb/demo/CategorizedTestCase.java      |  22 ++-
 .../demo/CategorizedTestCaseRunner.java            |  45 +++++
 .../demo/springmvc/client/SpringmvcClient.java     |  13 +-
 .../demo/springmvc/client/TestWeakSpringmvc.java   |  98 ++++++++++
 .../springmvc/server/ProducerTestsAfterBootup.java |   2 +-
 .../demo/springmvc/server/WeakSpringmvc.java       |  29 ++-
 .../common/utils/LambdaMetafactoryUtils.java       |   4 +
 .../foundation/protobuf/ProtoMapper.java           |  25 +--
 .../deserializer/DeserializerSchemaManager.java    |  28 +--
 .../schema/deserializer/MessageReadSchema.java     |  35 ++--
 .../schema/serializer/MessageWriteSchema.java      |  46 +----
 .../serializer/RootPropertyWrapperWriteSchema.java |  58 ------
 .../schema/serializer/SerializerSchemaManager.java |  27 +--
 .../springmvc/reference/CseClientHttpRequest.java  |   2 +-
 .../transport/highway/HighwayCodec.java            |  49 ++++-
 .../transport/highway/HighwayOutputStream.java     |   7 +-
 .../transport/highway/HighwayServerInvoke.java     |   4 +-
 .../transport/highway/TestHighwayClient.java       |   7 -
 .../transport/highway/TestHighwayCodec.java        |  10 +-
 .../transport/highway/TestHighwayTransport.java    |   5 +-
 39 files changed, 679 insertions(+), 862 deletions(-)

diff --git a/common/common-protobuf/src/main/java/io/protostuff/runtime/ProtobufCompatibleUtils.java b/common/common-protobuf/src/main/java/io/protostuff/runtime/ProtobufCompatibleUtils.java
deleted file mode 100644
index ac625b7..0000000
--- a/common/common-protobuf/src/main/java/io/protostuff/runtime/ProtobufCompatibleUtils.java
+++ /dev/null
@@ -1,93 +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 io.protostuff.runtime;
-
-import java.io.IOException;
-import java.util.Map;
-
-import org.apache.servicecomb.foundation.common.utils.ReflectUtils;
-
-import io.protostuff.Input;
-import io.protostuff.Output;
-import io.protostuff.Pipe;
-import io.protostuff.WireFormat.FieldType;
-
-/**
- * protostuff实现protobuf逻辑时,关于map的编码与protobuf不兼容
- * 这里修改map的编码逻辑
- */
-public final class ProtobufCompatibleUtils {
-  private static boolean inited = false;
-
-  private ProtobufCompatibleUtils() {
-  }
-
-  public static void init() {
-    if (inited) {
-      return;
-    }
-
-    replaceRuntimeFieldFactoryMap();
-
-    inited = true;
-  }
-
-  protected static void replaceRuntimeFieldFactoryMap() {
-    RuntimeFieldFactory<Map<?, ?>> org = RuntimeMapFieldFactory.MAP;
-    RuntimeFieldFactory<Map<?, ?>> map = new RuntimeFieldFactory<Map<?, ?>>(
-        RuntimeFieldFactory.ID_MAP) {
-
-      @Override
-      public FieldType getFieldType() {
-        return org.getFieldType();
-      }
-
-      @Override
-      public Map<?, ?> readFrom(Input input) throws IOException {
-        return org.readFrom(input);
-      }
-
-      @Override
-      public void writeTo(Output output, int number, Map<?, ?> value,
-          boolean repeated) throws IOException {
-        org.writeTo(output, number, value, repeated);
-      }
-
-      @Override
-      public void transfer(Pipe pipe, Input input, Output output, int number,
-          boolean repeated) throws IOException {
-        org.transfer(pipe, input, output, number, repeated);
-      }
-
-      @Override
-      public Class<?> typeClass() {
-        return org.typeClass();
-      }
-
-      @Override
-      public <T> Field<T> create(int number, String name, java.lang.reflect.Field field, IdStrategy strategy) {
-        @SuppressWarnings("unchecked")
-        RuntimeMapField<T, Object, Object> runtimeMapField =
-            (RuntimeMapField<T, Object, Object>) org.create(number, name, field, strategy);
-
-        return new RuntimeMapFieldProtobuf<>(runtimeMapField, field);
-      }
-    };
-
-    ReflectUtils.setField(RuntimeMapFieldFactory.class, null, "MAP", map);
-  }
-}
diff --git a/common/common-protobuf/src/main/java/io/protostuff/runtime/RuntimeMapFieldProtobuf.java b/common/common-protobuf/src/main/java/io/protostuff/runtime/RuntimeMapFieldProtobuf.java
deleted file mode 100644
index 4489cbf..0000000
--- a/common/common-protobuf/src/main/java/io/protostuff/runtime/RuntimeMapFieldProtobuf.java
+++ /dev/null
@@ -1,161 +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 io.protostuff.runtime;
-
-import java.io.IOException;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.springframework.util.ReflectionUtils;
-
-import io.protostuff.ByteArrayInput;
-import io.protostuff.ByteBufferInput;
-import io.protostuff.Input;
-import io.protostuff.MapSchema;
-import io.protostuff.MapSchema.MapWrapper;
-import io.protostuff.MapSchemaUtils;
-import io.protostuff.Output;
-import io.protostuff.Pipe;
-import io.protostuff.ProtostuffException;
-import io.protostuff.Schema;
-
-public class RuntimeMapFieldProtobuf<T> extends RuntimeMapField<T, Object, Object> {
-  private static java.lang.reflect.Field entrySchemaField =
-      ReflectionUtils.findField(MapSchema.class, "entrySchema");
-
-  static {
-    entrySchemaField.setAccessible(true);
-  }
-
-  private RuntimeMapField<T, Object, Object> runtimeMapField;
-
-  private java.lang.reflect.Field field;
-
-  private Schema<Entry<Object, Object>> entrySchema;
-
-  @SuppressWarnings("unchecked")
-  public RuntimeMapFieldProtobuf(RuntimeMapField<T, Object, Object> runtimeMapField,
-      java.lang.reflect.Field field) {
-    super(runtimeMapField.type, runtimeMapField.number, runtimeMapField.name, null,
-        runtimeMapField.schema.messageFactory);
-
-    entrySchema = (Schema<Entry<Object, Object>>) ReflectionUtils.getField(entrySchemaField,
-        runtimeMapField.schema);
-
-    this.runtimeMapField = runtimeMapField;
-    this.field = field;
-  }
-
-  @SuppressWarnings("unchecked")
-  @Override
-  protected void mergeFrom(Input input, T message) throws IOException {
-    Map<Object, Object> value = null;
-    try {
-      value = (Map<Object, Object>) field.get(message);
-      if (value == null) {
-        value = schema.newMessage();
-        field.set(message, value);
-      }
-    } catch (Exception e) {
-      throw new ProtostuffException(
-          "Failed to get or set map field " + field.getDeclaringClass().getName() + ":" + field.getName(),
-          e);
-    }
-
-    MapWrapper<Object, Object> mapWrapper = MapSchemaUtils.createMapWrapper(value);
-    if (ByteArrayInput.class.isInstance(input)) {
-      ((ByteArrayInput) input).readRawVarint32();
-    } else if (ByteBufferInput.class.isInstance(input)) {
-      ((ByteBufferInput) input).readRawVarint32();
-    } else {
-      throw new Error("not handler " + input.getClass().getName());
-    }
-
-    int keyNumber = input.readFieldNumber(schema);
-    if (keyNumber != 1) {
-      throw new ProtostuffException(
-          "The map was incorrectly serialized, expect key number 1, but be " + keyNumber);
-    }
-    Object key = kFrom(input, mapWrapper);
-
-    int valueNumber = input.readFieldNumber(schema);
-    if (valueNumber != 2) {
-      throw new ProtostuffException(
-          "The map was incorrectly serialized, expect value number 2, but be " + valueNumber);
-    }
-    vPutFrom(input, mapWrapper, key);
-  }
-
-  @Override
-  @SuppressWarnings("unchecked")
-  protected void writeTo(Output output, T message) throws IOException {
-    final Map<Object, Object> existing;
-    try {
-      existing = (Map<Object, Object>) field.get(message);
-    } catch (Exception e) {
-      throw new RuntimeException(e);
-    }
-
-    if (existing != null) {
-      for (Entry<Object, Object> entry : existing.entrySet()) {
-        output.writeObject(number, entry, entrySchema, true);
-      }
-    }
-  }
-
-  @Override
-  protected void transfer(Pipe pipe, Input input, Output output,
-      boolean repeated) throws IOException {
-    runtimeMapField.transfer(pipe, input, output, repeated);
-  }
-
-  @Override
-  protected Object kFrom(Input input,
-      MapWrapper<Object, Object> wrapper) throws IOException {
-    return runtimeMapField.kFrom(input, wrapper);
-  }
-
-  @Override
-  protected void kTo(Output output, int fieldNumber, Object key,
-      boolean repeated) throws IOException {
-    runtimeMapField.kTo(output, fieldNumber, key, repeated);
-  }
-
-  @Override
-  protected void kTransfer(Pipe pipe, Input input, Output output,
-      int number, boolean repeated) throws IOException {
-    runtimeMapField.kTransfer(pipe, input, output, number, repeated);
-  }
-
-  @Override
-  protected void vPutFrom(Input input,
-      MapWrapper<Object, Object> wrapper, Object key) throws IOException {
-    runtimeMapField.vPutFrom(input, wrapper, key);
-  }
-
-  @Override
-  protected void vTo(Output output, int fieldNumber, Object val,
-      boolean repeated) throws IOException {
-    runtimeMapField.vTo(output, fieldNumber, val, repeated);
-  }
-
-  @Override
-  protected void vTransfer(Pipe pipe, Input input, Output output,
-      int number, boolean repeated) throws IOException {
-    runtimeMapField.vTransfer(pipe, input, output, number, repeated);
-  }
-}
diff --git a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/OperationProtobuf.java b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/OperationProtobuf.java
index 6c29780..eb6e22c 100644
--- a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/OperationProtobuf.java
+++ b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/OperationProtobuf.java
@@ -17,11 +17,9 @@
 
 package org.apache.servicecomb.codec.protobuf.definition;
 
-import java.lang.reflect.Method;
-import java.lang.reflect.Parameter;
 import java.lang.reflect.Type;
-import java.util.HashMap;
 import java.util.Map;
+import java.util.Map.Entry;
 
 import javax.ws.rs.core.Response.Status;
 import javax.ws.rs.core.Response.Status.Family;
@@ -29,90 +27,135 @@ import javax.ws.rs.core.Response.Status.Family;
 import org.apache.servicecomb.codec.protobuf.utils.ScopedProtobufSchemaManager;
 import org.apache.servicecomb.core.definition.OperationMeta;
 import org.apache.servicecomb.foundation.protobuf.ProtoMapper;
-import org.apache.servicecomb.foundation.protobuf.RequestRootDeserializer;
-import org.apache.servicecomb.foundation.protobuf.RequestRootSerializer;
-import org.apache.servicecomb.foundation.protobuf.ResponseRootDeserializer;
-import org.apache.servicecomb.foundation.protobuf.RootSerializer;
+import org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;
 
 import io.protostuff.compiler.model.Message;
 
 @SuppressWarnings("rawtypes")
 public class OperationProtobuf {
-  private ScopedProtobufSchemaManager scopedProtobufSchemaManager;
-
   private OperationMeta operationMeta;
 
-  private RequestRootSerializer requestSerializer;
+  private RequestRootSerializer requestRootSerializer;
 
-  // For wrapped parameters, this is a Map. While for POJO body, this is an Object.
-  private RequestRootDeserializer<Object> requestDeserializer;
+  private RequestRootDeserializer<Object> requestRootDeserializer;
 
-  private RootSerializer responseSerializer;
+  private ResponseRootSerializer responseRootSerializer;
 
-  private ResponseRootDeserializer<Object> responseDeserializer;
+  private ResponseRootDeserializer<Object> responseRootDeserializer;
 
   public OperationProtobuf(ScopedProtobufSchemaManager scopedProtobufSchemaManager, OperationMeta operationMeta) {
-    this.scopedProtobufSchemaManager = scopedProtobufSchemaManager;
     this.operationMeta = operationMeta;
+    initRequestCodec(scopedProtobufSchemaManager, operationMeta);
+    initResponseCodec(scopedProtobufSchemaManager, operationMeta);
+  }
 
-    ProtoMapper mapper = scopedProtobufSchemaManager.getOrCreateProtoMapper(operationMeta.getSchemaMeta());
-    Message requestMessage = mapper.getRequestMessage(operationMeta.getOperationId());
+  public RequestRootSerializer getRequestRootSerializer() {
+    return this.requestRootSerializer;
+  }
 
-    if (operationMeta.getSwaggerProducerOperation() != null) {
-      // producer invocation
-      requestDeserializer = mapper
-          .createRequestRootDeserializer(requestMessage, getMethodParameterTypesMap(
-              operationMeta.getSwaggerProducerOperation().getProducerMethod()));
-    } else if (operationMeta.getSwaggerConsumerOperation() != null) {
-      // consumer pojo invocation
-      requestSerializer = mapper.createRequestRootSerializer(requestMessage, (Map<String, Type>) null, true);
-    } else {
-      // consumer RestTemplate invocation
-      requestSerializer = mapper.createRequestRootSerializer(requestMessage, (Map<String, Type>) null, true);
-    }
+  public RequestRootDeserializer<Object> getRequestRootDeserializer() {
+    return this.requestRootDeserializer;
+  }
 
-    Message responseMessage = mapper.getResponseMessage(operationMeta.getOperationId());
-    responseSerializer = mapper
-        .createRootSerializer(responseMessage,
-            operationMeta.getResponsesMeta().findResponseType(Status.OK.getStatusCode()));
-    responseDeserializer = mapper
-        .createResponseRootDeserializer(responseMessage,
-            operationMeta.getResponsesMeta().findResponseType(Status.OK.getStatusCode()));
+  public ResponseRootSerializer findResponseRootSerializer(int statusCode) {
+    if (Family.SUCCESSFUL.equals(Family.familyOf(statusCode))) {
+      return this.responseRootSerializer;
+    }
+    // TODO : WEAK handles only one response type.
+    throw new IllegalStateException("not implemented now, statusCode = " + statusCode);
   }
 
-  private Map<String, Type> getMethodParameterTypesMap(Method method) {
-    Map<String, Type> parameters = new HashMap<>();
-    for (Parameter parameter : method.getParameters()) {
-      parameters.put(parameter.getName(), parameter.getParameterizedType());
+  public ResponseRootDeserializer<Object> findResponseRootDeserializer(int statusCode) {
+    if (Family.SUCCESSFUL.equals(Family.familyOf(statusCode))) {
+      return this.responseRootDeserializer;
     }
-    return parameters;
+    // TODO : WEAK handles only one response type.
+    throw new IllegalStateException("not implemented now, statusCode = " + statusCode);
   }
 
   public OperationMeta getOperationMeta() {
     return operationMeta;
   }
 
-  public RequestRootSerializer findRequestSerializer() {
-    return requestSerializer;
-  }
-
-  public RequestRootDeserializer<Object> findRequestDesirializer() {
-    return requestDeserializer;
-  }
+  private void initRequestCodec(ScopedProtobufSchemaManager scopedProtobufSchemaManager, OperationMeta operationMeta) {
+    ProtoMapper mapper = scopedProtobufSchemaManager.getOrCreateProtoMapper(operationMeta.getSchemaMeta());
+    Message requestMessage = mapper.getRequestMessage(operationMeta.getOperationId());
 
-  public RootSerializer findResponseSerializer(int statusCode) {
-    if (Family.SUCCESSFUL.equals(Family.familyOf(statusCode))) {
-      return responseSerializer;
+    if (operationMeta.getSwaggerProducerOperation() != null) {
+      Map<String, Type> swaggerParameterTypes = operationMeta.getSwaggerProducerOperation()
+          .getSwaggerParameterTypes();
+      if (ProtoUtils.isWrapArguments(requestMessage)) {
+        requestRootDeserializer = new RequestRootDeserializer<>(
+            mapper.createRootDeserializer(requestMessage, swaggerParameterTypes), true, null);
+      } else {
+        if (swaggerParameterTypes.isEmpty()) {
+          requestRootDeserializer = new RequestRootDeserializer<>(
+              mapper.createRootDeserializer(requestMessage, Object.class), false, null);
+        } else if (swaggerParameterTypes.size() == 1) {
+          Entry<String, Type> entry = swaggerParameterTypes.entrySet().iterator().next();
+          requestRootDeserializer = new RequestRootDeserializer<>(mapper.createRootDeserializer(requestMessage,
+              entry.getValue()), false, entry.getKey());
+        } else {
+          throw new IllegalStateException(
+              "unexpected operation definition " + operationMeta.getMicroserviceQualifiedName());
+        }
+      }
+    } else {
+      if (ProtoUtils.isWrapArguments(requestMessage)) {
+        requestRootSerializer = new RequestRootSerializer(
+            mapper.createRootSerializer(requestMessage, Object.class), true, false);
+      } else {
+        if (operationMeta.getSwaggerOperation().getParameters().isEmpty()) {
+          requestRootSerializer = new RequestRootSerializer(mapper.createRootSerializer(requestMessage, Object.class),
+              false, false);
+        } else if (operationMeta.getSwaggerOperation().getParameters().size() == 1) {
+          requestRootSerializer = new RequestRootSerializer(mapper.createRootSerializer(requestMessage,
+              Object.class), false, true);
+        } else {
+          throw new IllegalStateException(
+              "unexpected operation definition " + operationMeta.getMicroserviceQualifiedName());
+        }
+      }
     }
-    // TODO : WEAK handles only one response type.
-    return null;
   }
 
-  public ResponseRootDeserializer<Object> findResponseDesirialize(int statusCode) {
-    if (Family.SUCCESSFUL.equals(Family.familyOf(statusCode))) {
-      return responseDeserializer;
+  private void initResponseCodec(ScopedProtobufSchemaManager scopedProtobufSchemaManager, OperationMeta operationMeta) {
+    ProtoMapper mapper = scopedProtobufSchemaManager.getOrCreateProtoMapper(operationMeta.getSchemaMeta());
+    Message responseMessage = mapper.getResponseMessage(operationMeta.getOperationId());
+
+    Type responseType = operationMeta.getResponsesMeta().findResponseType(Status.OK.getStatusCode());
+    if (operationMeta.getSwaggerProducerOperation() != null) {
+      if (ProtoUtils.isWrapProperty(responseMessage)) {
+        responseRootSerializer = new ResponseRootSerializer(
+            mapper.createRootSerializer(responseMessage, responseType), true, false);
+      } else {
+        if (ProtoUtils.isEmptyMessage(responseMessage)) {
+          responseRootSerializer = new ResponseRootSerializer(mapper.createRootSerializer(responseMessage,
+              Object.class), false, false);
+        } else {
+          responseRootSerializer = new ResponseRootSerializer(mapper.createRootSerializer(responseMessage,
+              responseType), false, true);
+        }
+      }
+    } else {
+      if (ProtoUtils.isWrapProperty(responseMessage)) {
+        responseRootSerializer = new ResponseRootSerializer(
+            mapper.createRootSerializer(responseMessage, responseType), true, false);
+        responseRootDeserializer = new ResponseRootDeserializer<>(
+            mapper.createRootDeserializer(responseMessage, responseType), true, false);
+      } else {
+        if (ProtoUtils.isEmptyMessage(responseMessage)) {
+          responseRootSerializer = new ResponseRootSerializer(mapper.createRootSerializer(responseMessage,
+              Object.class), false, false);
+          responseRootDeserializer = new ResponseRootDeserializer<>(
+              mapper.createRootDeserializer(responseMessage, Object.class), false, true);
+        } else {
+          responseRootSerializer = new ResponseRootSerializer(mapper.createRootSerializer(responseMessage,
+              responseType), false, false);
+          responseRootDeserializer = new ResponseRootDeserializer<>(
+              mapper.createRootDeserializer(responseMessage, responseType), false, false);
+        }
+      }
     }
-    // TODO : WEAK handles only one response type.
-    throw new IllegalStateException("not implemented now, statusCode = " + statusCode);
   }
 }
diff --git a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/RequestRootDeserializer.java b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/RequestRootDeserializer.java
similarity index 91%
rename from foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/RequestRootDeserializer.java
rename to common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/RequestRootDeserializer.java
index 462fca2..049c7c0 100644
--- a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/RequestRootDeserializer.java
+++ b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/RequestRootDeserializer.java
@@ -14,12 +14,14 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.servicecomb.foundation.protobuf;
+package org.apache.servicecomb.codec.protobuf.definition;
 
 import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.servicecomb.foundation.protobuf.RootDeserializer;
+
 public class RequestRootDeserializer<T> {
   private boolean wrapArgument;
 
@@ -27,10 +29,6 @@ public class RequestRootDeserializer<T> {
 
   private RootDeserializer<T> rootDeserializer;
 
-  public RequestRootDeserializer(RootDeserializer<T> rootDeserializer) {
-    this(rootDeserializer, true, null);
-  }
-
   public RequestRootDeserializer(RootDeserializer<T> rootDeserializer, boolean wrapArgument, String parameterName) {
     this.rootDeserializer = rootDeserializer;
     this.wrapArgument = wrapArgument;
diff --git a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/RequestRootSerializer.java b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/RequestRootSerializer.java
similarity index 77%
copy from foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/RequestRootSerializer.java
copy to common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/RequestRootSerializer.java
index f18fbf5..0dde46e 100644
--- a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/RequestRootSerializer.java
+++ b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/RequestRootSerializer.java
@@ -14,12 +14,13 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.servicecomb.foundation.protobuf;
+package org.apache.servicecomb.codec.protobuf.definition;
 
 import java.io.IOException;
-import java.io.OutputStream;
 import java.util.Map;
 
+import org.apache.servicecomb.foundation.protobuf.RootSerializer;
+
 public class RequestRootSerializer {
   private RootSerializer rootSerializer;
 
@@ -41,13 +42,4 @@ public class RequestRootSerializer {
       return this.rootSerializer.serialize(value);
     }
   }
-
-  @SuppressWarnings("unchecked")
-  public void serialize(OutputStream outputStream, Object value) throws IOException {
-    if (noTypesInfo && !isWrap) {
-      this.rootSerializer.serialize(outputStream, ((Map<String, Object>) value).values().iterator().next());
-    } else {
-      this.rootSerializer.serialize(outputStream, value);
-    }
-  }
 }
diff --git a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/ResponseRootDeserializer.java b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/ResponseRootDeserializer.java
similarity index 93%
rename from foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/ResponseRootDeserializer.java
rename to common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/ResponseRootDeserializer.java
index b852725..467b07c 100644
--- a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/ResponseRootDeserializer.java
+++ b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/ResponseRootDeserializer.java
@@ -14,10 +14,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.servicecomb.foundation.protobuf;
+package org.apache.servicecomb.codec.protobuf.definition;
 
 import java.io.IOException;
 
+import org.apache.servicecomb.foundation.protobuf.RootDeserializer;
 import org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyWrapper;
 
 public class ResponseRootDeserializer<T> {
diff --git a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/RequestRootSerializer.java b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/ResponseRootSerializer.java
similarity index 63%
rename from foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/RequestRootSerializer.java
rename to common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/ResponseRootSerializer.java
index f18fbf5..d7034ca 100644
--- a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/RequestRootSerializer.java
+++ b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/definition/ResponseRootSerializer.java
@@ -14,40 +14,35 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.servicecomb.foundation.protobuf;
+package org.apache.servicecomb.codec.protobuf.definition;
 
 import java.io.IOException;
-import java.io.OutputStream;
+import java.util.HashMap;
 import java.util.Map;
 
-public class RequestRootSerializer {
+import org.apache.servicecomb.foundation.protobuf.RootSerializer;
+
+public class ResponseRootSerializer {
   private RootSerializer rootSerializer;
 
   private boolean noTypesInfo;
 
   private boolean isWrap;
 
-  public RequestRootSerializer(RootSerializer serializer, boolean isWrapp, boolean noTypesInfo) {
+  public ResponseRootSerializer(RootSerializer serializer, boolean isWrapp, boolean noTypesInfo) {
     this.rootSerializer = serializer;
     this.noTypesInfo = noTypesInfo;
     this.isWrap = isWrapp;
   }
 
-  @SuppressWarnings("unchecked")
   public byte[] serialize(Object value) throws IOException {
     if (noTypesInfo && !isWrap) {
-      return this.rootSerializer.serialize(((Map<String, Object>) value).values().iterator().next());
-    } else {
       return this.rootSerializer.serialize(value);
-    }
-  }
-
-  @SuppressWarnings("unchecked")
-  public void serialize(OutputStream outputStream, Object value) throws IOException {
-    if (noTypesInfo && !isWrap) {
-      this.rootSerializer.serialize(outputStream, ((Map<String, Object>) value).values().iterator().next());
     } else {
-      this.rootSerializer.serialize(outputStream, value);
+      Map<String, Object> responseValue = new HashMap<>(1);
+      // key is fixed to "value" in IDL
+      responseValue.put("value", value);
+      return this.rootSerializer.serialize(responseValue);
     }
   }
 }
diff --git a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/SwaggerToProtoGenerator.java b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/SwaggerToProtoGenerator.java
index 1734236..6b73b06 100644
--- a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/SwaggerToProtoGenerator.java
+++ b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/SwaggerToProtoGenerator.java
@@ -110,12 +110,7 @@ public class SwaggerToProtoGenerator {
       properties = Collections.emptyMap();
     }
 
-    // TODO: WEAK add a better way to check if it is POJO
-    if(modelName.endsWith("Body")) {
-      createMessage(modelName, (Map<String, Object>) (Object) properties, ProtoConst.ANNOTATION_WRAP_ARGUMENTS);
-    } else {
-      createMessage(modelName, (Map<String, Object>) (Object) properties);
-    }
+    createMessage(modelName, (Map<String, Object>) (Object) properties);
   }
 
   private void createMessage(String protoName, Map<String, Object> properties, String... annotations) {
diff --git a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/utils/ProtobufSchemaUtils.java b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/utils/ProtobufSchemaUtils.java
deleted file mode 100644
index f54ed51..0000000
--- a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/utils/ProtobufSchemaUtils.java
+++ /dev/null
@@ -1,96 +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.codec.protobuf.utils;
-
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.util.Collection;
-import java.util.Date;
-import java.util.Map;
-
-import org.apache.servicecomb.foundation.common.utils.JsonUtils;
-import org.springframework.util.ClassUtils;
-
-import io.protostuff.Input;
-import io.protostuff.Output;
-import io.protostuff.Pipe;
-import io.protostuff.WireFormat.FieldType;
-import io.protostuff.runtime.DefaultIdStrategy;
-import io.protostuff.runtime.Delegate;
-import io.protostuff.runtime.ProtobufCompatibleUtils;
-import io.protostuff.runtime.RuntimeEnv;
-
-public final class ProtobufSchemaUtils {
-  static {
-    initProtobufObjectCodec();
-    ProtobufCompatibleUtils.init();
-  }
-
-  protected static void initProtobufObjectCodec() {
-    ((DefaultIdStrategy) RuntimeEnv.ID_STRATEGY).registerDelegate(new Delegate<Object>() {
-      @Override
-      public FieldType getFieldType() {
-        return FieldType.BYTES;
-      }
-
-      @Override
-      public Object readFrom(Input input) throws IOException {
-        return JsonUtils.readValue(input.readByteArray(), Object.class);
-      }
-
-      @Override
-      public void writeTo(Output output, int number, Object value, boolean repeated) throws IOException {
-        output.writeByteArray(number, JsonUtils.writeValueAsBytes(value), false);
-      }
-
-      @Override
-      public void transfer(Pipe pipe, Input input, Output output, int number, boolean repeated) {
-        throw new IllegalStateException("not support.");
-      }
-
-      @Override
-      public Class<?> typeClass() {
-        return Object.class;
-      }
-    });
-  }
-
-  private ProtobufSchemaUtils() {
-  }
-
-  public static boolean isArgsNeedWrap(Method method) {
-    if (method.getParameterCount() != 1) {
-      return true;
-    }
-
-    // 单参数时,需要根据实际情况判断
-    return isNeedWrap(method.getParameterTypes()[0]);
-  }
-
-  public static boolean isNeedWrap(Class<?> cls) {
-    // protobuf不支持原子类型、enum、string、数组、collection等等作为msg
-    // 只有pojo类型才可以
-    // java.lang.Object也不可以,因为这可以是任意类型,结果不确定
-    return ClassUtils.isPrimitiveOrWrapper(cls) || cls.isArray() || cls.isEnum()
-        || String.class.isAssignableFrom(cls)
-        || Collection.class.isAssignableFrom(cls)
-        || Map.class.isAssignableFrom(cls)
-        || Date.class.isAssignableFrom(cls)
-        || Object.class.equals(cls);
-  }
-}
diff --git a/common/common-protobuf/src/test/java/io/protostuff/runtime/TestProtobufCompatibleUtils.java b/common/common-protobuf/src/test/java/io/protostuff/runtime/TestProtobufCompatibleUtils.java
deleted file mode 100644
index 22192c2..0000000
--- a/common/common-protobuf/src/test/java/io/protostuff/runtime/TestProtobufCompatibleUtils.java
+++ /dev/null
@@ -1,96 +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 io.protostuff.runtime;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-import io.protostuff.ByteArrayInput;
-import io.protostuff.LinkedBuffer;
-import io.protostuff.ProtobufOutput;
-import io.protostuff.runtime.model.ModelProtobuf;
-import io.protostuff.runtime.model.ModelProtostuff;
-import io.protostuff.runtime.model.User;
-
-public class TestProtobufCompatibleUtils {
-  @Test
-  public void test() throws IOException {
-    ProtobufCompatibleUtils.init();
-
-    Map<String, String> stringMap = new HashMap<>();
-    stringMap.put("k1", "v1");
-    stringMap.put("k2", "v2");
-
-    Map<String, User> userMap = new HashMap<>();
-    userMap.put("u1", new User("n1"));
-    userMap.put("u2", new User("n2"));
-
-    byte[] protostuffBytes = testProtostuff(stringMap, userMap);
-
-    io.protostuff.runtime.model.ModelProtobuf.RequestHeader r =
-        ModelProtobuf.RequestHeader.newBuilder()
-            .putAllCseContext(stringMap)
-            .putUserMap("u1", ModelProtobuf.User.newBuilder().setName("n1").build())
-            .putUserMap("u2", ModelProtobuf.User.newBuilder().setName("n2").build())
-            .addList("l1")
-            .addList("l2")
-            .build();
-
-    byte[] protoBufBytes = r.toByteArray();
-    Assert.assertArrayEquals(protostuffBytes, protoBufBytes);
-  }
-
-  protected byte[] testProtostuff(Map<String, String> map, Map<String, User> userMap) throws IOException {
-    ProtobufCompatibleUtils.init();
-
-    RuntimeSchema<ModelProtostuff> schema = RuntimeSchema.createFrom(ModelProtostuff.class);
-    ModelProtostuff model = new ModelProtostuff();
-
-    model.setContext(map);
-    model.setUserMap(userMap);
-    model.getList().add("l1");
-    model.getList().add("l2");
-
-    LinkedBuffer linkedBuffer = LinkedBuffer.allocate();
-    ProtobufOutput output = new ProtobufOutput(linkedBuffer);
-
-    schema.writeTo(output, model);
-
-    ByteArrayOutputStream s = new ByteArrayOutputStream();
-    LinkedBuffer.writeTo(s, linkedBuffer);
-    byte[] bytes = s.toByteArray();
-
-    ModelProtostuff newModel = new ModelProtostuff();
-    ByteArrayInput bai = new ByteArrayInput(bytes, false);
-
-    schema.mergeFrom(bai, newModel);
-
-    Assert.assertEquals("v1", newModel.getContext().get("k1"));
-    Assert.assertEquals("v2", newModel.getContext().get("k2"));
-    Assert.assertEquals("n1", newModel.getUserMap().get("u1").getName());
-    Assert.assertEquals("n2", newModel.getUserMap().get("u2").getName());
-    Assert.assertEquals("l1", newModel.getList().get(0));
-    Assert.assertEquals("l2", newModel.getList().get(1));
-
-    return bytes;
-  }
-}
diff --git a/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSchemaMetaCodec.java b/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSchemaMetaCodec.java
index 44ff896..4d74073 100644
--- a/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSchemaMetaCodec.java
+++ b/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSchemaMetaCodec.java
@@ -19,6 +19,7 @@ package org.apache.servicecomb.codec.protobuf.internal.converter;
 
 import java.io.IOException;
 import java.time.LocalDate;
+import java.time.temporal.ChronoField;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashMap;
@@ -27,15 +28,16 @@ import java.util.Map;
 
 import org.apache.servicecomb.codec.protobuf.definition.OperationProtobuf;
 import org.apache.servicecomb.codec.protobuf.definition.ProtobufManager;
+import org.apache.servicecomb.codec.protobuf.definition.RequestRootDeserializer;
+import org.apache.servicecomb.codec.protobuf.definition.RequestRootSerializer;
+import org.apache.servicecomb.codec.protobuf.definition.ResponseRootDeserializer;
+import org.apache.servicecomb.codec.protobuf.definition.ResponseRootSerializer;
 import org.apache.servicecomb.codec.protobuf.internal.converter.model.ProtoSchema;
+import org.apache.servicecomb.codec.protobuf.internal.converter.model.ProtoSchemaIntf;
 import org.apache.servicecomb.codec.protobuf.internal.converter.model.ProtoSchemaPojo;
 import org.apache.servicecomb.core.definition.MicroserviceMeta;
 import org.apache.servicecomb.core.definition.OperationMeta;
 import org.apache.servicecomb.core.definition.SchemaMeta;
-import org.apache.servicecomb.foundation.protobuf.RequestRootDeserializer;
-import org.apache.servicecomb.foundation.protobuf.RequestRootSerializer;
-import org.apache.servicecomb.foundation.protobuf.ResponseRootDeserializer;
-import org.apache.servicecomb.foundation.protobuf.RootSerializer;
 import org.apache.servicecomb.foundation.test.scaffolding.model.Color;
 import org.apache.servicecomb.foundation.test.scaffolding.model.Empty;
 import org.apache.servicecomb.foundation.test.scaffolding.model.User;
@@ -75,7 +77,7 @@ public class TestSchemaMetaCodec {
 
   }
 
-  private void mockSchemaMeta(AbstractSwaggerGenerator swaggerGenerator, Class<?> schemaClass) throws Exception {
+  private void mockSchemaMeta(AbstractSwaggerGenerator swaggerGenerator, Object producerInstance) throws Exception {
     new Expectations() {
       {
         providerMicroserviceMeta.getMicroserviceName();
@@ -92,14 +94,14 @@ public class TestSchemaMetaCodec {
     SwaggerEnvironment swaggerEnvironment = new SwaggerEnvironment();
 
     providerSchemaMeta = new SchemaMeta(providerMicroserviceMeta, "ProtoSchema", swagger);
-    SwaggerProducer swaggerProducer = swaggerEnvironment.createProducer(schemaClass.newInstance(), swagger);
+    SwaggerProducer swaggerProducer = swaggerEnvironment.createProducer(producerInstance, swagger);
     for (SwaggerProducerOperation producerOperation : swaggerProducer.getAllOperations()) {
       OperationMeta operationMeta = providerSchemaMeta.ensureFindOperation(producerOperation.getOperationId());
       operationMeta.setSwaggerProducerOperation(producerOperation);
     }
 
     consumerSchemaMeta = new SchemaMeta(consumerMicroserviceMeta, "ProtoSchema", swagger);
-    SwaggerConsumer swaggerConsumer = swaggerEnvironment.createConsumer(schemaClass, swagger);
+    SwaggerConsumer swaggerConsumer = swaggerEnvironment.createConsumer(ProtoSchemaIntf.class, swagger);
     for (SwaggerConsumerOperation consumerOperation : swaggerConsumer.getOperations().values()) {
       OperationMeta operationMeta = consumerSchemaMeta.ensureFindOperation(consumerOperation.getSchemaOperationId());
       operationMeta.setSwaggerConsumerOperation(consumerOperation);
@@ -108,13 +110,13 @@ public class TestSchemaMetaCodec {
 
   @Test
   public void testProtoSchemaOperationUserSpringMVC() throws Exception {
-    mockSchemaMeta(new SpringmvcSwaggerGenerator(ProtoSchema.class), ProtoSchema.class);
+    mockSchemaMeta(new SpringmvcSwaggerGenerator(ProtoSchema.class), new ProtoSchema());
     testProtoSchemaOperationUserImpl();
   }
 
   @Test
   public void testProtoSchemaOperationUserPOJO() throws Exception {
-    mockSchemaMeta(new PojoSwaggerGenerator(ProtoSchemaPojo.class), ProtoSchemaPojo.class);
+    mockSchemaMeta(new PojoSwaggerGenerator(ProtoSchemaPojo.class), new ProtoSchemaPojo());
     testProtoSchemaOperationUserImpl();
   }
 
@@ -134,12 +136,12 @@ public class TestSchemaMetaCodec {
 
     // request message
     Map<String, Object> args = new HashMap<>();
-    RequestRootSerializer requestSerializer = consumerOperationProtobuf.findRequestSerializer();
+    RequestRootSerializer requestSerializer = consumerOperationProtobuf.getRequestRootSerializer();
     user.friends = friends;
     args.put("user", user);
     values = requestSerializer.serialize(args);
 
-    RequestRootDeserializer<Object> requestDeserializer = providerOperationProtobuf.findRequestDesirializer();
+    RequestRootDeserializer<Object> requestDeserializer = providerOperationProtobuf.getRequestRootDeserializer();
     Map<String, Object> decodedUserArgs = requestDeserializer.deserialize(values);
     Assert.assertEquals(user.name, ((User) decodedUserArgs.get("user")).name);
     Assert.assertEquals(user.friends.get(0).name, ((User) decodedUserArgs.get("user")).friends.get(0).name);
@@ -161,9 +163,9 @@ public class TestSchemaMetaCodec {
     Assert.assertEquals(user.friends.get(0).name, ((User) decodedUserArgs.get("user")).friends.get(0).name);
 
     // response message
-    RootSerializer responseSerializer = providerOperationProtobuf.findResponseSerializer(200);
+    ResponseRootSerializer responseSerializer = providerOperationProtobuf.findResponseRootSerializer(200);
     values = responseSerializer.serialize(user);
-    ResponseRootDeserializer<Object> responseDeserializer = consumerOperationProtobuf.findResponseDesirialize(200);
+    ResponseRootDeserializer<Object> responseDeserializer = consumerOperationProtobuf.findResponseRootDeserializer(200);
     User decodedUser = (User) responseDeserializer.deserialize(values);
     Assert.assertEquals(user.name, decodedUser.name);
     Assert.assertEquals(user.friends.get(0).name, decodedUser.friends.get(0).name);
@@ -178,17 +180,17 @@ public class TestSchemaMetaCodec {
 
   @Test
   public void testProtoSchemaOperationmapUserSpringMVC() throws Exception {
-    mockSchemaMeta(new SpringmvcSwaggerGenerator(ProtoSchema.class), ProtoSchema.class);
-    testProtoSchemaOperationmapUserImpl();
+    mockSchemaMeta(new SpringmvcSwaggerGenerator(ProtoSchema.class), new ProtoSchema());
+    testProtoSchemaOperationmapUserImpl(false);
   }
 
   @Test
   public void testProtoSchemaOperationmapUserPOJO() throws Exception {
-    mockSchemaMeta(new PojoSwaggerGenerator(ProtoSchemaPojo.class), ProtoSchemaPojo.class);
-    testProtoSchemaOperationmapUserImpl();
+    mockSchemaMeta(new PojoSwaggerGenerator(ProtoSchemaPojo.class), new ProtoSchemaPojo());
+    testProtoSchemaOperationmapUserImpl(true);
   }
 
-  private void testProtoSchemaOperationmapUserImpl() throws IOException {
+  private void testProtoSchemaOperationmapUserImpl(boolean isPojo) throws IOException {
     OperationProtobuf providerOperationProtobuf = ProtobufManager
         .getOrCreateOperation(providerSchemaMeta.getOperations().get("mapUser"));
     OperationProtobuf consumerOperationProtobuf = ProtobufManager
@@ -206,21 +208,34 @@ public class TestSchemaMetaCodec {
 
     // request message
     Map<String, Object> args = new HashMap<>();
-    RequestRootSerializer requestSerializer = consumerOperationProtobuf.findRequestSerializer();
+    RequestRootSerializer requestSerializer = consumerOperationProtobuf.getRequestRootSerializer();
     user.friends = friends;
     args.put("users", userMap);
-    values = requestSerializer.serialize(args);
-
-    RequestRootDeserializer<Object> requestDeserializer = providerOperationProtobuf.findRequestDesirializer();
+    if (isPojo) {
+      Map<String, Object> swaggerArgs = new HashMap<>(1);
+      swaggerArgs.put("users", args);
+      values = requestSerializer.serialize(swaggerArgs);
+    } else {
+      values = requestSerializer.serialize(args);
+    }
+    RequestRootDeserializer<Object> requestDeserializer = providerOperationProtobuf.getRequestRootDeserializer();
     Map<String, Object> decodedUserArgs = requestDeserializer.deserialize(values);
-    Assert.assertEquals(user.name, ((Map<String, User>) decodedUserArgs.get("users")).get("test").name);
-    Assert.assertEquals(user.friends.get(0).name,
-        ((Map<String, User>) decodedUserArgs.get("users")).get("test").friends.get(0).name);
-
+    if (isPojo) {
+      decodedUserArgs = (Map<String, Object>) decodedUserArgs.get("users");
+      Assert.assertEquals(user.name,
+          ((Map<String, Map<String, Object>>) decodedUserArgs.get("users")).get("test").get("name"));
+      Assert.assertEquals(user.friends.get(0).name,
+          ((List<Map<String, Object>>) ((Map<String, Map<String, Object>>) decodedUserArgs.get("users")).get("test")
+              .get("friends")).get(0).get("name"));
+    } else {
+      Assert.assertEquals(user.name, ((Map<String, User>) decodedUserArgs.get("users")).get("test").name);
+      Assert.assertEquals(user.friends.get(0).name,
+          ((Map<String, User>) decodedUserArgs.get("users")).get("test").friends.get(0).name);
+    }
     // response message
-    RootSerializer responseSerializer = providerOperationProtobuf.findResponseSerializer(200);
+    ResponseRootSerializer responseSerializer = providerOperationProtobuf.findResponseRootSerializer(200);
     values = responseSerializer.serialize(userMap);
-    ResponseRootDeserializer<Object> responseDeserializer = consumerOperationProtobuf.findResponseDesirialize(200);
+    ResponseRootDeserializer<Object> responseDeserializer = consumerOperationProtobuf.findResponseRootDeserializer(200);
     Map<String, User> decodedUser = (Map<String, User>) responseDeserializer.deserialize(values);
     Assert.assertEquals(user.name, decodedUser.get("test").name);
     Assert.assertEquals(user.friends.get(0).name, decodedUser.get("test").friends.get(0).name);
@@ -235,18 +250,17 @@ public class TestSchemaMetaCodec {
 
   @Test
   public void testProtoSchemaOperationBaseSpringMVC() throws Exception {
-    mockSchemaMeta(new SpringmvcSwaggerGenerator(ProtoSchema.class), ProtoSchema.class);
-    testProtoSchemaOperationBaseImpl();
+    mockSchemaMeta(new SpringmvcSwaggerGenerator(ProtoSchema.class), new ProtoSchema());
+    testProtoSchemaOperationBaseImpl(false);
   }
 
   @Test
   public void testProtoSchemaOperationBasePOJO() throws Exception {
-    mockSchemaMeta(new PojoSwaggerGenerator(ProtoSchemaPojo.class), ProtoSchemaPojo.class);
-    testProtoSchemaOperationBaseImpl();
+    mockSchemaMeta(new PojoSwaggerGenerator(ProtoSchemaPojo.class), new ProtoSchemaPojo());
+    testProtoSchemaOperationBaseImpl(true);
   }
 
-  private void testProtoSchemaOperationBaseImpl() throws IOException {
-    // TODO : WEAK fix this line "java.lang.NoClassDefFoundError: org/apache/servicecomb/foundation/common/utils/bean/Getter"
+  private void testProtoSchemaOperationBaseImpl(boolean isPojo) throws IOException {
     OperationProtobuf providerOperationProtobuf = ProtobufManager
         .getOrCreateOperation(providerSchemaMeta.getOperations().get("base"));
     OperationProtobuf consumerOperationProtobuf = ProtobufManager
@@ -254,7 +268,7 @@ public class TestSchemaMetaCodec {
     byte[] values;
 
     // request message
-    RequestRootSerializer requestSerializer = consumerOperationProtobuf.findRequestSerializer();
+    RequestRootSerializer requestSerializer = consumerOperationProtobuf.getRequestRootSerializer();
     boolean boolValue = true;
     int iValue = 20;
     long lValue = 30L;
@@ -278,20 +292,43 @@ public class TestSchemaMetaCodec {
     args.put("localDate", localDate);
     args.put("date", date);
     args.put("empty", empty);
-    values = requestSerializer.serialize(args);
-    RequestRootDeserializer<Object> requestDeserializer = providerOperationProtobuf.findRequestDesirializer();
-    Map<String, Object> decodedArgs = requestDeserializer.deserialize(values);
+    if (isPojo) {
+      Map<String, Object> swaggerArgs = new HashMap<>();
+      swaggerArgs.put("baseBody", args);
+      values = requestSerializer.serialize(swaggerArgs);
+    } else {
+      values = requestSerializer.serialize(args);
+    }
+    RequestRootDeserializer<Object> requestDeserializer = providerOperationProtobuf.getRequestRootDeserializer();
+    Map<String, Object> decodedSwaggerArgs = requestDeserializer.deserialize(values);
+    Map<String, Object> decodedArgs;
+    if (isPojo) {
+      Assert.assertEquals(1, decodedSwaggerArgs.size());
+      decodedArgs = (Map<String, Object>) decodedSwaggerArgs.get("baseBody");
+    } else {
+      decodedArgs = decodedSwaggerArgs;
+    }
     Assert.assertEquals(boolValue, decodedArgs.get("boolValue"));
     Assert.assertEquals(iValue, decodedArgs.get("iValue"));
     Assert.assertEquals(lValue, decodedArgs.get("lValue"));
     Assert.assertEquals(fValue, decodedArgs.get("fValue"));
     Assert.assertEquals(dValue, decodedArgs.get("dValue"));
-    Assert.assertArrayEquals(iArray, (int[]) decodedArgs.get("iArray"));
-    Assert.assertEquals(color, decodedArgs.get("color"));
-    Assert.assertEquals(date, decodedArgs.get("date"));
-    Assert.assertTrue(decodedArgs.get("localDate") instanceof LocalDate);
-    Assert.assertEquals(localDate, decodedArgs.get("localDate"));
-    Assert.assertTrue(decodedArgs.get("empty") instanceof Empty);
+    if (isPojo) {
+      Assert.assertEquals(2, ((List<Integer>) decodedArgs.get("iArray")).size());
+      Assert.assertEquals(60, (((List<Integer>) decodedArgs.get("iArray")).get(0).intValue()));
+      Assert.assertEquals(70, (((List<Integer>) decodedArgs.get("iArray")).get(1).intValue()));
+      Assert.assertEquals(color.ordinal(), decodedArgs.get("color"));
+      Assert.assertEquals(date.getTime(), decodedArgs.get("date"));
+      Assert.assertEquals(localDate.getLong(ChronoField.EPOCH_DAY), decodedArgs.get("localDate"));
+      Assert.assertEquals(true, ((Map) decodedArgs.get("empty")).isEmpty());
+    } else {
+      Assert.assertArrayEquals(iArray, (int[]) decodedArgs.get("iArray"));
+      Assert.assertEquals(color, decodedArgs.get("color"));
+      Assert.assertEquals(date, decodedArgs.get("date"));
+      Assert.assertTrue(decodedArgs.get("localDate") instanceof LocalDate);
+      Assert.assertEquals(localDate, decodedArgs.get("localDate"));
+      Assert.assertTrue(decodedArgs.get("empty") instanceof Empty);
+    }
 
     // default value testing
     args.put("boolValue", false);
@@ -319,10 +356,80 @@ public class TestSchemaMetaCodec {
     Assert.assertEquals(null, decodedArgs.get("empty"));
 
     // response message
-    RootSerializer responseSerializer = providerOperationProtobuf.findResponseSerializer(200);
+    ResponseRootSerializer responseSerializer = providerOperationProtobuf.findResponseRootSerializer(200);
     values = responseSerializer.serialize(30);
-    ResponseRootDeserializer<Object> responseDeserializer = consumerOperationProtobuf.findResponseDesirialize(200);
+    ResponseRootDeserializer<Object> responseDeserializer = consumerOperationProtobuf.findResponseRootDeserializer(200);
     Object decodedValue = responseDeserializer.deserialize(values);
     Assert.assertEquals(30, (int) decodedValue);
   }
+
+  @Test
+  public void testProtoSchemaOperationlistListUserSpringMVC() throws Exception {
+    mockSchemaMeta(new SpringmvcSwaggerGenerator(ProtoSchema.class), new ProtoSchema());
+    testProtoSchemaOperationlistListUserImpl(false);
+  }
+
+  @Test
+  public void testProtoSchemaOperationlistListUserPOJO() throws Exception {
+    mockSchemaMeta(new PojoSwaggerGenerator(ProtoSchemaPojo.class), new ProtoSchemaPojo());
+    testProtoSchemaOperationlistListUserImpl(true);
+  }
+
+  private void testProtoSchemaOperationlistListUserImpl(boolean isPojo) throws IOException {
+    OperationProtobuf providerOperationProtobuf = ProtobufManager
+        .getOrCreateOperation(providerSchemaMeta.getOperations().get("listListUser"));
+    OperationProtobuf consumerOperationProtobuf = ProtobufManager
+        .getOrCreateOperation(consumerSchemaMeta.getOperations().get("listListUser"));
+    byte[] values;
+
+    // request message
+    RequestRootSerializer requestSerializer = consumerOperationProtobuf.getRequestRootSerializer();
+    User user = new User();
+    user.name = "user";
+    User friend = new User();
+    friend.name = "friend";
+    List<User> friends = new ArrayList<>();
+    friends.add(friend);
+    user.friends = friends;
+    List<User> users = new ArrayList<>();
+    users.add(user);
+    List<List<User>> listOfUsers = new ArrayList<>();
+    listOfUsers.add(users);
+    Map<String, Object> args = new HashMap<>();
+    args.put("value", listOfUsers);
+
+    if (isPojo) {
+      Map<String, Object> swaggerArgs = new HashMap<>();
+      swaggerArgs.put("value", args);
+      values = requestSerializer.serialize(swaggerArgs);
+    } else {
+      values = requestSerializer.serialize(args);
+    }
+    RequestRootDeserializer<Object> requestDeserializer = providerOperationProtobuf.getRequestRootDeserializer();
+    Map<String, Object> decodedSwaggerArgs = requestDeserializer.deserialize(values);
+    Map<String, Object> decodedArgs;
+    if (isPojo) {
+      Assert.assertEquals(1, decodedSwaggerArgs.size());
+      decodedArgs = (Map<String, Object>) decodedSwaggerArgs.get("value");
+    } else {
+      decodedArgs = decodedSwaggerArgs;
+    }
+    List<List<?>> listOfUsersRaw = (List<List<?>>) decodedArgs.get("value");
+    Assert.assertEquals(1, listOfUsersRaw.size());
+    List<?> mapUsersRaw = (List<?>) listOfUsersRaw.get(0);
+    Assert.assertEquals(1, mapUsersRaw.size());
+    if (isPojo) {
+      Map<String, Object> userMap = (Map<String, Object>) mapUsersRaw.get(0);
+      Assert.assertEquals("user", userMap.get("name"));
+      // proto buffer encode and decode empty list to be null
+      friends = (List<User>) userMap.get("friends");
+      Map<String, Object> friendMap = (Map<String, Object>) friends.get(0);
+      Assert.assertEquals("friend", friendMap.get("name"));
+    } else {
+      user = (User) mapUsersRaw.get(0);
+      Assert.assertEquals("user", user.name);
+      // proto buffer encode and decode empty list to be null
+      Assert.assertEquals("friend", user.friends.get(0).name);
+    }
+  }
 }
diff --git a/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSchemaMetaCodecRestTemplate.java b/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSchemaMetaCodecRestTemplate.java
index 4298ec8..25d4eb4 100644
--- a/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSchemaMetaCodecRestTemplate.java
+++ b/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSchemaMetaCodecRestTemplate.java
@@ -18,6 +18,7 @@
 package org.apache.servicecomb.codec.protobuf.internal.converter;
 
 import java.time.LocalDate;
+import java.time.temporal.ChronoField;
 import java.util.ArrayList;
 import java.util.Date;
 import java.util.HashMap;
@@ -26,14 +27,14 @@ import java.util.Map;
 
 import org.apache.servicecomb.codec.protobuf.definition.OperationProtobuf;
 import org.apache.servicecomb.codec.protobuf.definition.ProtobufManager;
+import org.apache.servicecomb.codec.protobuf.definition.RequestRootDeserializer;
+import org.apache.servicecomb.codec.protobuf.definition.RequestRootSerializer;
+import org.apache.servicecomb.codec.protobuf.definition.ResponseRootDeserializer;
+import org.apache.servicecomb.codec.protobuf.definition.ResponseRootSerializer;
 import org.apache.servicecomb.codec.protobuf.internal.converter.model.ProtoSchema;
 import org.apache.servicecomb.core.definition.MicroserviceMeta;
 import org.apache.servicecomb.core.definition.OperationMeta;
 import org.apache.servicecomb.core.definition.SchemaMeta;
-import org.apache.servicecomb.foundation.protobuf.RequestRootDeserializer;
-import org.apache.servicecomb.foundation.protobuf.RequestRootSerializer;
-import org.apache.servicecomb.foundation.protobuf.ResponseRootDeserializer;
-import org.apache.servicecomb.foundation.protobuf.RootSerializer;
 import org.apache.servicecomb.foundation.test.scaffolding.model.Color;
 import org.apache.servicecomb.foundation.test.scaffolding.model.Empty;
 import org.apache.servicecomb.foundation.test.scaffolding.model.User;
@@ -108,20 +109,20 @@ public class TestSchemaMetaCodecRestTemplate {
 
     // request message
     Map<String, Object> args = new HashMap<>();
-    RequestRootSerializer requestSerializer = consumerOperationProtobuf.findRequestSerializer();
+    RequestRootSerializer requestSerializer = consumerOperationProtobuf.getRequestRootSerializer();
     user.friends = friends;
     args.put("user", user);
     values = requestSerializer.serialize(args);
 
-    RequestRootDeserializer<Object> requestDeserializer = providerOperationProtobuf.findRequestDesirializer();
+    RequestRootDeserializer<Object> requestDeserializer = providerOperationProtobuf.getRequestRootDeserializer();
     Map<String, Object> decodedUserArgs = requestDeserializer.deserialize(values);
     Assert.assertEquals(user.name, ((User) decodedUserArgs.get("user")).name);
     Assert.assertEquals(user.friends.get(0).name, ((User) decodedUserArgs.get("user")).friends.get(0).name);
 
     // response message
-    RootSerializer responseSerializer = providerOperationProtobuf.findResponseSerializer(200);
+    ResponseRootSerializer responseSerializer = providerOperationProtobuf.findResponseRootSerializer(200);
     values = responseSerializer.serialize(user);
-    ResponseRootDeserializer<Object> responseDeserializer = consumerOperationProtobuf.findResponseDesirialize(200);
+    ResponseRootDeserializer<Object> responseDeserializer = consumerOperationProtobuf.findResponseRootDeserializer(200);
     User decodedUser = (User) responseDeserializer.deserialize(values);
     Assert.assertEquals(user.name, decodedUser.name);
     Assert.assertEquals(user.friends.get(0).name, decodedUser.friends.get(0).name);
@@ -137,7 +138,6 @@ public class TestSchemaMetaCodecRestTemplate {
   @Test
   @SuppressWarnings({"rawtypes", "unchecked"})
   public void testProtoSchemaOperationBase() throws Exception {
-    // TODO : WEAK fix this line "java.lang.NoClassDefFoundError: org/apache/servicecomb/foundation/common/utils/bean/Getter"
     OperationProtobuf providerOperationProtobuf = ProtobufManager
         .getOrCreateOperation(providerSchemaMeta.getOperations().get("base"));
     OperationProtobuf consumerOperationProtobuf = ProtobufManager
@@ -145,7 +145,7 @@ public class TestSchemaMetaCodecRestTemplate {
     byte[] values;
 
     // request message
-    RequestRootSerializer requestSerializer = consumerOperationProtobuf.findRequestSerializer();
+    RequestRootSerializer requestSerializer = consumerOperationProtobuf.getRequestRootSerializer();
     boolean boolValue = true;
     int iValue = 20;
     long lValue = 30L;
@@ -170,7 +170,7 @@ public class TestSchemaMetaCodecRestTemplate {
     args.put("date", date);
     args.put("empty", empty);
     values = requestSerializer.serialize(args);
-    RequestRootDeserializer<Object> requestDeserializer = providerOperationProtobuf.findRequestDesirializer();
+    RequestRootDeserializer<Object> requestDeserializer = providerOperationProtobuf.getRequestRootDeserializer();
     Map<String, Object> decodedArgs = requestDeserializer.deserialize(values);
     Assert.assertEquals(boolValue, decodedArgs.get("boolValue"));
     Assert.assertEquals(iValue, decodedArgs.get("iValue"));
@@ -210,9 +210,9 @@ public class TestSchemaMetaCodecRestTemplate {
     Assert.assertEquals(null, decodedArgs.get("empty"));
 
     // response message
-    RootSerializer responseSerializer = providerOperationProtobuf.findResponseSerializer(200);
+    ResponseRootSerializer responseSerializer = providerOperationProtobuf.findResponseRootSerializer(200);
     values = responseSerializer.serialize(30);
-    ResponseRootDeserializer<Object> responseDeserializer = consumerOperationProtobuf.findResponseDesirialize(200);
+    ResponseRootDeserializer<Object> responseDeserializer = consumerOperationProtobuf.findResponseRootDeserializer(200);
     Object decodedValue = responseDeserializer.deserialize(values);
     Assert.assertEquals(30, (int) decodedValue);
   }
diff --git a/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/model/ProtoSchema.java b/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/model/ProtoSchema.java
index 64afea6..ae4f2da 100644
--- a/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/model/ProtoSchema.java
+++ b/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/model/ProtoSchema.java
@@ -34,7 +34,7 @@ import io.swagger.annotations.ApiResponse;
 import io.swagger.annotations.ApiResponses;
 
 @RequestMapping(path = "/")
-public class ProtoSchema {
+public class ProtoSchema implements ProtoSchemaIntf {
   @ApiResponses(value = {@ApiResponse(code = 444, response = Color.class, message = "xxx")})
   @GetMapping(path = "/base")
   public int base(boolean boolValue, int iValue, long lValue, float fValue, double dValue, String sValue, int[] iArray,
diff --git a/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/model/ProtoSchemaIntf.java b/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/model/ProtoSchemaIntf.java
new file mode 100644
index 0000000..55c9156
--- /dev/null
+++ b/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/model/ProtoSchemaIntf.java
@@ -0,0 +1,104 @@
+/*
+ * 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.codec.protobuf.internal.converter.model;
+
+
+import java.time.LocalDate;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.servicecomb.foundation.test.scaffolding.model.Color;
+import org.apache.servicecomb.foundation.test.scaffolding.model.Empty;
+import org.apache.servicecomb.foundation.test.scaffolding.model.User;
+
+public interface ProtoSchemaIntf {
+  int base(boolean boolValue, int iValue, long lValue, float fValue, double dValue, String sValue, int[] iArray,
+      Color color,
+      LocalDate localDate, Date date, Empty empty);
+
+  byte[] bytes(byte[] value);
+
+
+  Color colorBody(Color color);
+
+
+  Object obj(Object value);
+
+
+  User user(User user);
+
+  User userWrapInProtobuf(User user, int ivalue);
+
+
+  List<Object> listObj(List<Object> objs);
+
+  List<User> listUser(List<User> users);
+
+
+  Map<String, User> mapUser(Map<String, User> users);
+
+  Map<String, Object> mapObj(Map<String, Object> objs);
+
+  Ref2 ref(Ref1 ref);
+
+
+  void noParamVoid();
+
+  List<List<String>> listListString(List<List<String>> value);
+
+
+  List<List<User>> listListUser(List<List<User>> value);
+
+
+  List<Map<String, String>> listMapString(List<Map<String, String>> value);
+
+
+  List<Map<String, User>> listMapUser(List<Map<String, User>> value);
+
+
+  Map<String, List<String>> mapListString(Map<String, List<String>> value);
+
+
+  Map<String, List<User>> mapListUser(Map<String, List<User>> value);
+
+  Map<String, Map<String, String>> mapMapString(Map<String, Map<String, String>> value);
+
+
+  Map<String, Map<String, User>> mapMapUser(Map<String, Map<String, User>> value);
+
+
+  List<List<List<String>>> listListListString(List<List<List<String>>> value);
+
+
+  List<List<Map<String, String>>> listListMapString(List<List<Map<String, String>>> value);
+
+  List<Map<String, List<String>>> listMapListString(List<Map<String, List<String>>> value);
+
+
+  List<Map<String, Map<String, String>>> listMapMapString(
+      List<Map<String, Map<String, String>>> value);
+
+
+  Map<String, Map<String, List<String>>> mapMapListString(
+      Map<String, Map<String, List<String>>> value);
+
+  Map<String, Map<String, Map<String, String>>> mapMapMapString(
+      Map<String, Map<String, Map<String, String>>> value);
+
+  FieldNeedWrap fieldNeedWrap(FieldNeedWrap fieldNeedWrap);
+}
diff --git a/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/model/ProtoSchemaPojo.java b/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/model/ProtoSchemaPojo.java
index 8e65e66..8f6a612 100644
--- a/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/model/ProtoSchemaPojo.java
+++ b/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/model/ProtoSchemaPojo.java
@@ -29,7 +29,7 @@ import org.apache.servicecomb.foundation.test.scaffolding.model.User;
 import io.swagger.annotations.ApiResponse;
 import io.swagger.annotations.ApiResponses;
 
-public class ProtoSchemaPojo {
+public class ProtoSchemaPojo implements ProtoSchemaIntf {
   @ApiResponses(value = {@ApiResponse(code = 444, response = Color.class, message = "xxx")})
   public int base(boolean boolValue, int iValue, long lValue, float fValue, double dValue, String sValue, int[] iArray,
       Color color,
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/RestConst.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/RestConst.java
index 87fcbf5..454ac62 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/RestConst.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/RestConst.java
@@ -53,8 +53,6 @@ public final class RestConst {
 
   public static final String REST_INVOCATION_CONTEXT = "servicecomb-rest-invocation-context";
 
-  public static final String IS_RESTTEMPLATE_INVOKE = "servicecomb-is-resttemplated-invoke";
-
   public static final String REST_REQUEST = "servicecomb-rest-request";
 
   public static final String CONSUMER_HEADER = "servicecomb-rest-consumer-header";
diff --git a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/filter/inner/ClientRestArgsFilter.java b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/filter/inner/ClientRestArgsFilter.java
index ecd34bd..1c4e3eb 100644
--- a/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/filter/inner/ClientRestArgsFilter.java
+++ b/common/common-rest/src/main/java/org/apache/servicecomb/common/rest/filter/inner/ClientRestArgsFilter.java
@@ -46,7 +46,7 @@ public class ClientRestArgsFilter implements HttpClientFilter {
     try {
       // POJO invoker for client
       if (swaggerRestOperation.getOperationMeta().getSwaggerConsumerOperation() != null && !invocation.isEdge()
-          && !isRestTemplateInvoke(invocation)) {
+          && !invocation.isWeakInvoke()) {
         RestCodec
             .argsToRest(swaggerRestOperation.getOperationMeta().getSwaggerConsumerOperation().getArgumentsMapper()
                     .invocationArgumentToSwaggerArguments(invocation,
@@ -63,14 +63,6 @@ public class ClientRestArgsFilter implements HttpClientFilter {
     }
   }
 
-  private boolean isRestTemplateInvoke(Invocation invocation) {
-    if (invocation.getLocalContext(RestConst.IS_RESTTEMPLATE_INVOKE) != null) {
-      return invocation.getLocalContext(RestConst.IS_RESTTEMPLATE_INVOKE);
-    } else {
-      return false;
-    }
-  }
-
   @Override
   public Response afterReceiveResponse(Invocation invocation, HttpServletResponseEx responseEx) {
     return null;
diff --git a/core/src/main/java/org/apache/servicecomb/core/Invocation.java b/core/src/main/java/org/apache/servicecomb/core/Invocation.java
index 0d27ddb..488b246 100644
--- a/core/src/main/java/org/apache/servicecomb/core/Invocation.java
+++ b/core/src/main/java/org/apache/servicecomb/core/Invocation.java
@@ -95,6 +95,10 @@ public class Invocation extends SwaggerInvocation {
   // because isEdge() only affect to apm/metrics output, no need to change so many logic
   private boolean edge;
 
+  // Check if consumer invocation without types info. e.g. using RestTemplate to invoke provider
+  // or using InvokerUtils to invoke provider and only provide operation id and arguments
+  private boolean weakInvoke;
+
   private long invocationId;
 
   private Map<String, Object> arguments;
@@ -377,6 +381,14 @@ public class Invocation extends SwaggerInvocation {
     return InvocationType.CONSUMER.equals(invocationType);
   }
 
+  public boolean isWeakInvoke() {
+    return weakInvoke;
+  }
+
+  public void setWeakInvoke(boolean weakInvoke) {
+    this.weakInvoke = weakInvoke;
+  }
+
   public boolean isEdge() {
     return edge;
   }
diff --git a/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/PojoClient.java b/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/PojoClient.java
index 598a3c8..5f3de3f 100644
--- a/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/PojoClient.java
+++ b/demo/demo-pojo/pojo-client/src/main/java/org/apache/servicecomb/demo/pojo/client/PojoClient.java
@@ -245,9 +245,9 @@ public class PojoClient {
   }
 
   private static void testSplitParam(Test test) {
-//    User result = test.splitParam(1, new User());
-//    LOGGER.info("split param result:{}", result);
-//    TestMgr.check("User [name=nameA,  users count:0, age=100, index=1]", result);
+    User result = test.splitParam(1, new User());
+    LOGGER.info("split param result:{}", result);
+    TestMgr.check("User [name=nameA,  users count:0, age=100, index=1]", result);
   }
 
   private static void testCommonInvoke(String transport) {
diff --git a/common/common-protobuf/src/main/java/io/protostuff/MapSchemaUtils.java b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/CategorizedTestCase.java
similarity index 66%
rename from common/common-protobuf/src/main/java/io/protostuff/MapSchemaUtils.java
rename to demo/demo-schema/src/main/java/org/apache/servicecomb/demo/CategorizedTestCase.java
index ab6362a..9b1f2cd 100644
--- a/common/common-protobuf/src/main/java/io/protostuff/MapSchemaUtils.java
+++ b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/CategorizedTestCase.java
@@ -14,17 +14,25 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package io.protostuff;
 
-import java.util.Map;
+package org.apache.servicecomb.demo;
 
-import io.protostuff.MapSchema.MapWrapper;
+public interface CategorizedTestCase {
+  /**
+   * test case which only successful in REST transport
+   */
+  default void testRestTransport() {
+  }
 
-public final class MapSchemaUtils {
-  private MapSchemaUtils() {
+  /**
+   * test case which only successful in HIGHWAY transport
+   */
+  default void testHighwayTransport() {
   }
 
-  public static MapWrapper<Object, Object> createMapWrapper(Map<Object, Object> map) {
-    return new MapWrapper<>(map);
+  /**
+   * test case which successful in both REST and HIGHWAY transport
+   */
+  default void testAllTransport() {
   }
 }
diff --git a/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/CategorizedTestCaseRunner.java b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/CategorizedTestCaseRunner.java
new file mode 100644
index 0000000..d107d98
--- /dev/null
+++ b/demo/demo-schema/src/main/java/org/apache/servicecomb/demo/CategorizedTestCaseRunner.java
@@ -0,0 +1,45 @@
+/*
+ * 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.demo;
+
+import java.util.Map;
+
+import org.apache.servicecomb.foundation.common.utils.BeanUtils;
+import org.apache.servicecomb.foundation.test.scaffolding.config.ArchaiusUtils;
+
+public class CategorizedTestCaseRunner {
+  public static void runCategorizedTestCase(String microserviceName) {
+    Map<String, CategorizedTestCase> tests = BeanUtils.getContext().getBeansOfType(CategorizedTestCase.class);
+    for (String transport : DemoConst.transports) {
+      changeTransport(microserviceName, transport);
+      for (CategorizedTestCase testCase : tests.values()) {
+        testCase.testAllTransport();
+        if ("rest".equals(transport)) {
+          testCase.testRestTransport();
+        } else if ("highway".equals(transport)) {
+          testCase.testHighwayTransport();
+        }
+      }
+    }
+  }
+
+  private static void changeTransport(String microserviceName, String transport) {
+    ArchaiusUtils.setProperty("servicecomb.references.transport." + microserviceName, transport);
+    TestMgr.setMsg(microserviceName, transport);
+  }
+}
diff --git a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java
index c599253..e970fc6 100644
--- a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java
+++ b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/SpringmvcClient.java
@@ -21,6 +21,7 @@ import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.http.HttpStatus;
+import org.apache.servicecomb.demo.CategorizedTestCaseRunner;
 import org.apache.servicecomb.demo.DemoConst;
 import org.apache.servicecomb.demo.TestMgr;
 import org.apache.servicecomb.demo.controller.Controller;
@@ -33,6 +34,8 @@ import org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;
 import org.apache.servicecomb.provider.springmvc.reference.UrlWithProviderPrefixClientHttpRequestFactory;
 import org.apache.servicecomb.provider.springmvc.reference.UrlWithServiceNameClientHttpRequestFactory;
 import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.http.HttpEntity;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpMethod;
@@ -45,6 +48,8 @@ import org.springframework.web.client.RestTemplate;
 import com.netflix.config.DynamicPropertyFactory;
 
 public class SpringmvcClient {
+  private static final Logger LOGGER = LoggerFactory.getLogger(SpringmvcClient.class);
+
   private static RestTemplate templateUrlWithServiceName = new CseRestTemplate();
 
   private static RestTemplate templateUrlWithProviderPrefix = new CseRestTemplate();
@@ -61,8 +66,8 @@ public class SpringmvcClient {
       run();
     } catch (Throwable e) {
       TestMgr.check("success", "failed");
-      System.err.println("-------------- test failed -------------");
-      e.printStackTrace();
+      LOGGER.error("-------------- test failed -------------");
+      LOGGER.error("", e);
       System.err.println("-------------- test failed -------------");
     }
     TestMgr.summary();
@@ -99,6 +104,7 @@ public class SpringmvcClient {
 
     testAllTransport(microserviceName);
     testRestTransport(microserviceName, prefix);
+    CategorizedTestCaseRunner.runCategorizedTestCase(microserviceName);
   }
 
   private static void testRestTransport(String microserviceName, String prefix) {
@@ -484,7 +490,8 @@ public class SpringmvcClient {
     TestMgr.check("Hello 345302", result);
   }
 
-  private static void testSpringMvcDefaultValuesJavaPrimitiveAllTransport(RestTemplate template, String microserviceName) {
+  private static void testSpringMvcDefaultValuesJavaPrimitiveAllTransport(RestTemplate template,
+      String microserviceName) {
     // TODO: WEAK primitive default value not supported in highway
 //    String cseUrlPrefix = "cse://" + microserviceName + "/SpringMvcDefaultValues/";
 //    //default values with primitive
diff --git a/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestWeakSpringmvc.java b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestWeakSpringmvc.java
new file mode 100644
index 0000000..d31a0d9
--- /dev/null
+++ b/demo/demo-springmvc/springmvc-client/src/main/java/org/apache/servicecomb/demo/springmvc/client/TestWeakSpringmvc.java
@@ -0,0 +1,98 @@
+/*
+ * 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.demo.springmvc.client;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.servicecomb.core.provider.consumer.InvokerUtils;
+import org.apache.servicecomb.demo.CategorizedTestCase;
+import org.apache.servicecomb.demo.TestMgr;
+import org.apache.servicecomb.provider.pojo.RpcReference;
+import org.apache.servicecomb.provider.springmvc.reference.RestTemplateBuilder;
+import org.springframework.stereotype.Component;
+import org.springframework.web.client.RestTemplate;
+
+/*
+This is the provider definition:
+
+<code>
+  @GetMapping(path = "/diffNames")
+  @ApiOperation(value = "differentName", nickname = "differentName")
+  public int diffNames(@RequestParam("x") int a, @RequestParam("y") int b)
+</code>
+
+and the swagger is:
+
+<code>
+  paths:
+    /diffNames:
+      get:
+        summary: "differentName"
+        operationId: "differentName"
+        parameters:
+        - name: "x"
+          in: "query"
+          required: true
+          type: "integer"
+          format: "int32"
+        - name: "y"
+          in: "query"
+          required: true
+          type: "integer"
+          format: "int32"
+        responses:
+          "200":
+            description: "response of 200"
+            schema:
+              type: "integer"
+              format: "int32"
+</code>
+
+In consumer, you can define any prototype that matches generated swagger of provider.
+ */
+
+interface DiffNames {
+  int differentName(int x, int y);
+}
+
+interface DiffNames2 {
+  int differentName(int y, int x);
+}
+
+@Component
+public class TestWeakSpringmvc implements CategorizedTestCase {
+  @RpcReference(microserviceName = "springmvc", schemaId = "weakSpringmvc")
+  private DiffNames diffNames;
+
+  @RpcReference(microserviceName = "springmvc", schemaId = "weakSpringmvc")
+  private DiffNames2 diffNames2;
+
+  private RestTemplate restTemplate = RestTemplateBuilder.create();
+
+  @Override
+  public void testAllTransport() {
+    TestMgr.check(7, diffNames.differentName(2, 3));
+    TestMgr.check(8, diffNames2.differentName(2, 3));
+    TestMgr.check(7, restTemplate.getForObject("cse://springmvc/weakSpringmvc/diffNames?x=2&y=3", Integer.class));
+    Map<String, Object> args = new HashMap<>();
+    args.put("x", 2);
+    args.put("y", 3);
+    TestMgr.check(7, InvokerUtils.syncInvoke("springmvc", "weakSpringmvc", "differentName", args));
+  }
+}
diff --git a/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/ProducerTestsAfterBootup.java b/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/ProducerTestsAfterBootup.java
index 5112980..155b690 100644
--- a/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/ProducerTestsAfterBootup.java
+++ b/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/ProducerTestsAfterBootup.java
@@ -89,7 +89,7 @@ public class ProducerTestsAfterBootup implements BootListener {
   }
 
   public void testRegisteredBasePath() {
-    TestMgr.check(12, RegistryUtils.getMicroservice().getPaths().size());
+    TestMgr.check(13, RegistryUtils.getMicroservice().getPaths().size());
   }
 
   private String getSwaggerContent(Swagger swagger) {
diff --git a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/RootPropertyWrapperDeserializer.java b/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/WeakSpringmvc.java
similarity index 52%
rename from foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/RootPropertyWrapperDeserializer.java
rename to demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/WeakSpringmvc.java
index aa192d9..2b447b4 100644
--- a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/RootPropertyWrapperDeserializer.java
+++ b/demo/demo-springmvc/springmvc-server/src/main/java/org/apache/servicecomb/demo/springmvc/server/WeakSpringmvc.java
@@ -14,24 +14,23 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer;
 
-import java.io.IOException;
+package org.apache.servicecomb.demo.springmvc.server;
 
-import org.apache.servicecomb.foundation.protobuf.RootDeserializer;
-import org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyWrapper;
+import org.apache.servicecomb.provider.rest.common.RestSchema;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
 
-public class RootPropertyWrapperDeserializer<T> extends RootDeserializer<T> {
-  private final RootDeserializer<PropertyWrapper<T>> deserializer;
+import io.swagger.annotations.ApiOperation;
 
-  public RootPropertyWrapperDeserializer(RootDeserializer<PropertyWrapper<T>> deserializer) {
-    super(null);
-    this.deserializer = deserializer;
-  }
-
-  @Override
-  public T deserialize(byte[] bytes) throws IOException {
-    PropertyWrapper<T> propertyWrapper = deserializer.deserialize(bytes);
-    return propertyWrapper.getValue();
+@RestSchema(schemaId = "weakSpringmvc")
+@RequestMapping(path = "/weakSpringmvc", produces = MediaType.APPLICATION_JSON_VALUE)
+public class WeakSpringmvc {
+  @GetMapping(path = "/diffNames")
+  @ApiOperation(value = "differentName", nickname = "differentName")
+  public int diffNames(@RequestParam("x") int a, @RequestParam("y") int b) {
+    return a * 2 + b;
   }
 }
diff --git a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/LambdaMetafactoryUtils.java b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/LambdaMetafactoryUtils.java
index 531a789..910dd5e 100644
--- a/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/LambdaMetafactoryUtils.java
+++ b/foundations/foundation-common/src/main/java/org/apache/servicecomb/foundation/common/utils/LambdaMetafactoryUtils.java
@@ -135,6 +135,10 @@ public final class LambdaMetafactoryUtils {
 
   @SuppressWarnings("unchecked")
   public static <T> T createLambda(Method instanceMethod, Class<?> functionalIntfCls) {
+    if (Modifier.isNative(instanceMethod.getModifiers())) {
+      // fix "Failed to create lambda from public final native java.lang.Class java.lang.Object.getClass()"
+      return null;
+    }
     try {
       Lookup lookup = LOOKUP.in(instanceMethod.getDeclaringClass());
       allowedModesField.set(lookup, ALL_MODES);
diff --git a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/ProtoMapper.java b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/ProtoMapper.java
index 1bb21e6..1a86e9b 100644
--- a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/ProtoMapper.java
+++ b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/ProtoMapper.java
@@ -117,14 +117,6 @@ public class ProtoMapper {
     return createRootSerializer(message, type);
   }
 
-  public synchronized RequestRootSerializer createRequestRootSerializer(Message message, Map<String, Type> types, boolean noTypesInfo) {
-    return serializerSchemaManager.createRequestRootSerializer(message, types, noTypesInfo);
-  }
-
-  public synchronized RootSerializer createRootSerializer(Message message, Map<String, Type> types) {
-    return serializerSchemaManager.createRootSerializer(message, types);
-  }
-
   public synchronized RootSerializer createRootSerializer(Message message, Type type) {
     return serializerSchemaManager.createRootSerializer(message, type);
   }
@@ -138,20 +130,11 @@ public class ProtoMapper {
     return createRootDeserializer(message, type);
   }
 
-  public synchronized <T> RequestRootDeserializer<T> createRequestRootDeserializer(Message message,
-      Map<String, Type> types) {
-    return deserializerSchemaManager.createRequestRootDeserializer(message, types);
-  }
-
-  public synchronized <T> RequestRootDeserializer<T> createRequestRootDeserializer(Message message, Type type) {
-    return deserializerSchemaManager.createRequestRootDeserializer(message, type);
-  }
-
-  public synchronized <T> ResponseRootDeserializer<T> createResponseRootDeserializer(Message message, Type type) {
-    return deserializerSchemaManager.createResponseRootDeserializer(message, type);
-  }
-
   public synchronized <T> RootDeserializer<T> createRootDeserializer(Message message, Type type) {
     return deserializerSchemaManager.createRootDeserializer(message, type);
   }
+
+  public synchronized <T> RootDeserializer<T> createRootDeserializer(Message message, Map<String, Type> types) {
+    return deserializerSchemaManager.createRootDeserializer(message, types);
+  }
 }
diff --git a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/DeserializerSchemaManager.java b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/DeserializerSchemaManager.java
index 60ee422..d0b0035 100644
--- a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/DeserializerSchemaManager.java
+++ b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/DeserializerSchemaManager.java
@@ -22,8 +22,6 @@ import java.lang.reflect.Type;
 import java.util.Map;
 
 import org.apache.servicecomb.foundation.protobuf.ProtoMapper;
-import org.apache.servicecomb.foundation.protobuf.RequestRootDeserializer;
-import org.apache.servicecomb.foundation.protobuf.ResponseRootDeserializer;
 import org.apache.servicecomb.foundation.protobuf.RootDeserializer;
 import org.apache.servicecomb.foundation.protobuf.internal.ProtoConst;
 import org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;
@@ -95,23 +93,9 @@ public class DeserializerSchemaManager extends SchemaManager {
     super(protoMapper);
   }
 
-  public <T> RequestRootDeserializer<T> createRequestRootDeserializer(Message message, Type type) {
-    JavaType javaType = TypeFactory.defaultInstance().constructType(type);
-    SchemaEx<T> messageSchema = getOrCreateMessageSchema(message, javaType);
-    RootDeserializer<T> rootDeserializer = new RootDeserializer<>(messageSchema);
-    return new RequestRootDeserializer<>(rootDeserializer);
-  }
-
-  public <T> RequestRootDeserializer<T> createRequestRootDeserializer(Message message, Map<String, Type> types) {
+  public <T> RootDeserializer<T> createRootDeserializer(Message message, Map<String, Type> types) {
     SchemaEx<T> messageSchema = getOrCreateMessageSchema(message, types);
-    RootDeserializer<T> rootDeserializer = new RootDeserializer<>(messageSchema);
-    if (!ProtoUtils.isWrapArguments(message)) {
-      if (types == null || types.size() == 0) {
-        return new RequestRootDeserializer<>(rootDeserializer, false, null);
-      }
-      return new RequestRootDeserializer<>(rootDeserializer, false, types.keySet().iterator().next());
-    }
-    return new RequestRootDeserializer<>(rootDeserializer);
+    return new RootDeserializer<>(messageSchema);
   }
 
   public <T> RootDeserializer<T> createRootDeserializer(Message message, Type type) {
@@ -120,14 +104,6 @@ public class DeserializerSchemaManager extends SchemaManager {
     return new RootDeserializer<>(messageSchema);
   }
 
-  public <T> ResponseRootDeserializer<T> createResponseRootDeserializer(Message message, Type type) {
-    JavaType javaType = TypeFactory.defaultInstance().constructType(type);
-    SchemaEx<T> messageSchema = getOrCreateMessageSchema(message, javaType);
-    RootDeserializer<T> rootDeserializer = new RootDeserializer<>(messageSchema);
-    return new ResponseRootDeserializer<>(rootDeserializer, ProtoUtils.isWrapProperty(message),
-        ProtoUtils.isEmptyMessage(message));
-  }
-
   @Override
   protected <T> SchemaEx<T> newMessageSchema(Message message, Map<String, Type> types) {
     return new MessageReadSchema<>(protoMapper, message, types);
diff --git a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/MessageReadSchema.java b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/MessageReadSchema.java
index b3d215b..4cd66e9 100644
--- a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/MessageReadSchema.java
+++ b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/deserializer/MessageReadSchema.java
@@ -25,14 +25,12 @@ import java.util.Map;
 
 import org.apache.servicecomb.foundation.protobuf.ProtoMapper;
 import org.apache.servicecomb.foundation.protobuf.internal.ProtoConst;
-import org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;
 import org.apache.servicecomb.foundation.protobuf.internal.bean.BeanDescriptor;
 import org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.fasterxml.jackson.databind.JavaType;
-import com.fasterxml.jackson.databind.type.TypeFactory;
 
 import io.protostuff.InputEx;
 import io.protostuff.OutputEx;
@@ -62,32 +60,26 @@ public class MessageReadSchema<T> implements SchemaEx<T> {
 
   private Instantiator<T> instantiator;
 
-  private final JavaType javaType;
+  private JavaType javaType;
 
-  private final Map<String, Type> types;
+  Map<String, Type> argumentsTypes;
+
+  private boolean argumentsRoot = false;
 
   @SuppressWarnings("unchecked")
-  // construct for request parameters
-  public MessageReadSchema(ProtoMapper protoMapper, Message message, Map<String, Type> types) {
+  public MessageReadSchema(ProtoMapper protoMapper, Message message, Map<String, Type> argumentsTypes) {
+    this.argumentsRoot = true;
     this.protoMapper = protoMapper;
     this.message = message;
-    this.types = types;
-    if (!ProtoUtils.isWrapArguments(message) && types.size() > 0) {
-      this.javaType = TypeFactory.defaultInstance().constructType(types.values().iterator().next());
-      this.instantiator = RuntimeEnv.newInstantiator((Class<T>) javaType.getRawClass());
-    } else {
-      this.javaType = ProtoConst.MAP_TYPE;
-      this.instantiator = RuntimeEnv.newInstantiator((Class<T>) ProtoConst.MAP_TYPE.getRawClass());
-    }
+    this.argumentsTypes = argumentsTypes;
+    this.instantiator = RuntimeEnv.newInstantiator((Class<T>) ProtoConst.MAP_TYPE.getRawClass());
   }
 
   @SuppressWarnings("unchecked")
-  // construct for response type
   public MessageReadSchema(ProtoMapper protoMapper, Message message, JavaType javaType) {
     this.protoMapper = protoMapper;
     this.message = message;
     this.javaType = javaType;
-    this.types = null;
     if (javaType.isJavaLangObject() || Map.class.isAssignableFrom(javaType.getRawClass())) {
       javaType = ProtoConst.MAP_TYPE;
     }
@@ -115,13 +107,9 @@ public class MessageReadSchema<T> implements SchemaEx<T> {
   @SuppressWarnings("unchecked")
   @Override
   public void init() {
-    if (types != null) {
-      if (ProtoUtils.isWrapArguments(message)) {
-        this.fieldMap = (FieldMapEx<T>) protoMapper.getDeserializerSchemaManager()
-            .createMapFields(message, types);
-        return;
-      }
-      this.createFieldMap();
+    if (argumentsRoot) {
+      this.fieldMap = (FieldMapEx<T>) protoMapper.getDeserializerSchemaManager()
+          .createMapFields(message, argumentsTypes);
       return;
     }
 
@@ -130,6 +118,7 @@ public class MessageReadSchema<T> implements SchemaEx<T> {
           .createMapFields(message);
       return;
     }
+
     this.createFieldMap();
   }
 
diff --git a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/MessageWriteSchema.java b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/MessageWriteSchema.java
index 5adb200..24717a2 100644
--- a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/MessageWriteSchema.java
+++ b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/MessageWriteSchema.java
@@ -27,13 +27,11 @@ import java.util.Map.Entry;
 
 import org.apache.servicecomb.foundation.common.concurrent.ConcurrentHashMapEx;
 import org.apache.servicecomb.foundation.protobuf.ProtoMapper;
-import org.apache.servicecomb.foundation.protobuf.internal.ProtoConst;
 import org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;
 import org.apache.servicecomb.foundation.protobuf.internal.bean.BeanDescriptor;
 import org.apache.servicecomb.foundation.protobuf.internal.bean.PropertyDescriptor;
 
 import com.fasterxml.jackson.databind.JavaType;
-import com.fasterxml.jackson.databind.type.TypeFactory;
 
 import io.protostuff.InputEx;
 import io.protostuff.OutputEx;
@@ -55,9 +53,7 @@ public class MessageWriteSchema<T> implements SchemaEx<T> {
 
   protected Message message;
 
-  private final JavaType javaType;
-
-  private final Map<String, Type> types;
+  private JavaType javaType;
 
   // mostly, one message only relate to one pojo
   private final Class<T> mainPojoCls;
@@ -70,24 +66,10 @@ public class MessageWriteSchema<T> implements SchemaEx<T> {
   private final Map<Class<?>, FieldMapEx<?>> pojoFieldMaps = new ConcurrentHashMapEx<>();
 
   @SuppressWarnings("unchecked")
-  public MessageWriteSchema(ProtoMapper protoMapper, Message message, Map<String, Type> types) {
-    this.protoMapper = protoMapper;
-    this.message = message;
-    this.types = types;
-    if (this.types == null || this.types.isEmpty()) {
-      this.javaType = ProtoConst.MAP_TYPE;
-    } else {
-      this.javaType = TypeFactory.defaultInstance().constructType(types.values().iterator().next());
-    }
-    this.mainPojoCls = (Class<T>) javaType.getRawClass();
-  }
-
-  @SuppressWarnings("unchecked")
   public MessageWriteSchema(ProtoMapper protoMapper, Message message, JavaType javaType) {
     this.protoMapper = protoMapper;
     this.message = message;
     this.javaType = javaType;
-    this.types = null;
     this.mainPojoCls = (Class<T>) javaType.getRawClass();
   }
 
@@ -119,24 +101,12 @@ public class MessageWriteSchema<T> implements SchemaEx<T> {
 
   @Override
   public void init() {
-    if (types != null && !types.isEmpty()) {
-      if (ProtoUtils.isWrapProperty(message)) {
-        this.mapFieldMaps = protoMapper.getDeserializerSchemaManager()
-            .createMapFields(message, types);
-        return;
-      }
-      this.mainPojoFieldMaps = createPojoFields(javaType);
-      this.mapFieldMaps = protoMapper.getSerializerSchemaManager().createMapFields(message);
-      return;
-    }
-
     if (ProtoUtils.isWrapProperty(message)) {
       this.mainPojoFieldMaps = createPropertyWrapperFields(javaType);
       return;
     }
 
     this.mainPojoFieldMaps = createPojoFields(javaType);
-    this.mapFieldMaps = protoMapper.getSerializerSchemaManager().createMapFields(message);
   }
 
   private FieldMapEx<T> createPropertyWrapperFields(JavaType javaType) {
@@ -177,16 +147,6 @@ public class MessageWriteSchema<T> implements SchemaEx<T> {
   @SuppressWarnings("unchecked")
   @Override
   public void writeTo(OutputEx output, Object value) throws IOException {
-    if (types != null && !types.isEmpty()) {
-      if (ProtoUtils.isWrapArguments(message)) {
-        writeFromMap(output, (Map<String, Object>) value);
-        return;
-      } else {
-        value = ((Map<String, Object>) value).values().iterator().next();
-      }
-    }
-
-    // write a POJO from map
     if (value instanceof Map) {
       writeFromMap(output, (Map<String, Object>) value);
       return;
@@ -218,6 +178,10 @@ public class MessageWriteSchema<T> implements SchemaEx<T> {
   }
 
   protected final void writeFromMap(OutputEx output, Map<String, Object> map) throws IOException {
+    if (mapFieldMaps == null) {
+      mapFieldMaps = protoMapper.getSerializerSchemaManager().createMapFields(message);
+    }
+
     for (Entry<String, Object> entry : map.entrySet()) {
       if (entry.getValue() == null) {
         continue;
diff --git a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/RootPropertyWrapperWriteSchema.java b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/RootPropertyWrapperWriteSchema.java
deleted file mode 100644
index 3e5b705..0000000
--- a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/RootPropertyWrapperWriteSchema.java
+++ /dev/null
@@ -1,58 +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.foundation.protobuf.internal.schema.serializer;
-
-import java.io.IOException;
-
-import org.apache.servicecomb.foundation.protobuf.internal.schema.deserializer.MessageReadSchema;
-
-import io.protostuff.InputEx;
-import io.protostuff.OutputEx;
-import io.protostuff.SchemaEx;
-import io.protostuff.runtime.FieldSchema;
-
-public class RootPropertyWrapperWriteSchema<T> implements SchemaEx<T> {
-  private final SchemaEx<T> schema;
-
-  private final FieldSchema<T> fieldSchema;
-
-  public RootPropertyWrapperWriteSchema(SchemaEx<T> schema) {
-    this.schema = schema;
-
-    if (schema instanceof MessageWriteSchema) {
-      fieldSchema = ((MessageWriteSchema<T>) schema).getMainPojoFieldMaps().getFieldByNumber(1);
-      return;
-    }
-
-    fieldSchema = ((MessageReadSchema<T>) schema).getFieldMap().getFieldByNumber(1);
-  }
-
-  @Override
-  public void init() {
-
-  }
-
-  @Override
-  public void writeTo(OutputEx output, Object value) throws IOException {
-    fieldSchema.writeTo(output, value);
-  }
-
-  @Override
-  public void mergeFrom(InputEx input, Object message) throws IOException {
-
-  }
-}
diff --git a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/SerializerSchemaManager.java b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/SerializerSchemaManager.java
index 838d92f..b71ddea 100644
--- a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/SerializerSchemaManager.java
+++ b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/serializer/SerializerSchemaManager.java
@@ -22,7 +22,6 @@ import java.lang.reflect.Type;
 import java.util.Map;
 
 import org.apache.servicecomb.foundation.protobuf.ProtoMapper;
-import org.apache.servicecomb.foundation.protobuf.RequestRootSerializer;
 import org.apache.servicecomb.foundation.protobuf.RootSerializer;
 import org.apache.servicecomb.foundation.protobuf.internal.ProtoConst;
 import org.apache.servicecomb.foundation.protobuf.internal.ProtoUtils;
@@ -93,32 +92,16 @@ public class SerializerSchemaManager extends SchemaManager {
     super(protoMapper);
   }
 
-  public RequestRootSerializer createRequestRootSerializer(Message message, Map<String, Type> types,
-      boolean noTypesInfo) {
-    SchemaEx<Object> messageSchema = getOrCreateMessageSchema(message, types);
-
-    RootSerializer rootSerializer = new RootSerializer(messageSchema);
-    return new RequestRootSerializer(rootSerializer,
-        ProtoUtils.isWrapArguments(message) || ProtoUtils.isEmptyMessage(message), noTypesInfo);
-  }
-
-  public RootSerializer createRootSerializer(Message message, Map<String, Type> types) {
-    SchemaEx<Object> messageSchema = getOrCreateMessageSchema(message, types);
-
-    return new RootSerializer(messageSchema);
-  }
-
   public RootSerializer createRootSerializer(Message message, Type type) {
     JavaType javaType = TypeFactory.defaultInstance().constructType(type);
     SchemaEx<Object> messageSchema = getOrCreateMessageSchema(message, javaType);
-
-    if (isWrapProperty(message)) {
-      messageSchema = new RootPropertyWrapperWriteSchema<>(messageSchema);
-    }
-
     return new RootSerializer(messageSchema);
   }
 
+  public RootSerializer createRootSerializer(Message message, Map<String, Type> types) {
+    throw new IllegalStateException("not implemented");
+  }
+
   @Override
   protected <T> SchemaEx<T> newMessageSchema(Message message, JavaType javaType) {
     return new MessageWriteSchema<>(protoMapper, message, javaType);
@@ -126,7 +109,7 @@ public class SerializerSchemaManager extends SchemaManager {
 
   @Override
   protected <T> SchemaEx<T> newMessageSchema(Message message, Map<String, Type> types) {
-    return new MessageWriteSchema<>(protoMapper, message, types);
+    throw new IllegalStateException("not implemented");
   }
 
   protected <T> FieldSchema<T> createScalarField(Field protoField, PropertyDescriptor propertyDescriptor) {
diff --git a/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseClientHttpRequest.java b/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseClientHttpRequest.java
index f4343bc..f0431ae 100644
--- a/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseClientHttpRequest.java
+++ b/providers/provider-springmvc/src/main/java/org/apache/servicecomb/provider/springmvc/reference/CseClientHttpRequest.java
@@ -213,7 +213,7 @@ public class CseClientHttpRequest implements ClientHttpRequest {
             requestMeta.getOperationMeta(),
             arguments);
 
-    invocation.addLocalContext(RestConst.IS_RESTTEMPLATE_INVOKE, true);
+    invocation.setWeakInvoke(true);
     invocation.getHandlerContext().put(RestConst.REST_CLIENT_REQUEST_PATH,
         path + (this.uri.getRawQuery() == null ? "" : "?" + this.uri.getRawQuery()));
 
diff --git a/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayCodec.java b/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayCodec.java
index b8ca139..6d06e1c 100644
--- a/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayCodec.java
+++ b/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayCodec.java
@@ -20,10 +20,11 @@ package org.apache.servicecomb.transport.highway;
 import java.util.Map;
 
 import org.apache.servicecomb.codec.protobuf.definition.OperationProtobuf;
+import org.apache.servicecomb.codec.protobuf.definition.ResponseRootSerializer;
 import org.apache.servicecomb.core.Invocation;
-import org.apache.servicecomb.foundation.protobuf.RequestRootDeserializer;
-import org.apache.servicecomb.foundation.protobuf.ResponseRootDeserializer;
-import org.apache.servicecomb.foundation.protobuf.RootDeserializer;
+import org.apache.servicecomb.core.definition.OperationMeta;
+import org.apache.servicecomb.codec.protobuf.definition.RequestRootDeserializer;
+import org.apache.servicecomb.codec.protobuf.definition.ResponseRootDeserializer;
 import org.apache.servicecomb.foundation.protobuf.RootSerializer;
 import org.apache.servicecomb.foundation.vertx.client.tcp.TcpData;
 import org.apache.servicecomb.foundation.vertx.tcp.TcpOutputStream;
@@ -49,16 +50,48 @@ public final class HighwayCodec {
     header.setContext(invocation.getContext());
 
     HighwayOutputStream os = new HighwayOutputStream(msgId);
-    os.write(header, operationProtobuf.findRequestSerializer(), invocation.getArguments());
+    os.write(header, operationProtobuf.getRequestRootSerializer(),
+        invocationArgumentsToSwaggerArguments(invocation, operationProtobuf.getOperationMeta(),
+            invocation.getArguments()));
     return os;
   }
 
+  private static Map<String, Object> invocationArgumentsToSwaggerArguments(Invocation invocation,
+      OperationMeta operationMeta,
+      Map<String, Object> invocationArguments) {
+    if (operationMeta.getSwaggerConsumerOperation() != null && !invocation.isEdge()
+        && !invocation.isWeakInvoke()) {
+      return operationMeta.getSwaggerConsumerOperation().getArgumentsMapper()
+          .invocationArgumentToSwaggerArguments(invocation,
+              invocation.getArguments());
+    } else {
+      return invocationArguments;
+    }
+  }
+
+  private static Map<String, Object> swaggerArgumentsToInvocationArguments(Invocation invocation,
+      OperationMeta operationMeta,
+      Map<String, Object> swaggerArguments) {
+    if (swaggerArguments == null || swaggerArguments.isEmpty()) {
+      // void types represented by null
+      return swaggerArguments;
+    }
+    if (operationMeta.getSwaggerProducerOperation() != null && !invocation.isEdge()) {
+      return operationMeta.getSwaggerProducerOperation().getArgumentsMapper()
+          .swaggerArgumentToInvocationArguments(invocation, swaggerArguments);
+    } else {
+      // edge
+      return swaggerArguments;
+    }
+  }
+
   @SuppressWarnings({"rawtypes", "unchecked"})
   public static void decodeRequest(Invocation invocation, RequestHeader header, OperationProtobuf operationProtobuf,
       Buffer bodyBuffer) throws Exception {
-    RequestRootDeserializer<Object> requestDesirializer = operationProtobuf.findRequestDesirializer();
+    RequestRootDeserializer<Object> requestDesirializer = operationProtobuf.getRequestRootDeserializer();
     Map<String, Object> args = requestDesirializer.deserialize(bodyBuffer.getBytes());
-    invocation.setArguments(args);
+    invocation
+        .setArguments(swaggerArgumentsToInvocationArguments(invocation, operationProtobuf.getOperationMeta(), args));
     invocation.mergeContext(header.getContext());
   }
 
@@ -66,7 +99,7 @@ public final class HighwayCodec {
     return RequestHeader.readObject(headerBuffer);
   }
 
-  public static Buffer encodeResponse(long msgId, ResponseHeader header, RootSerializer bodySchema,
+  public static Buffer encodeResponse(long msgId, ResponseHeader header, ResponseRootSerializer bodySchema,
       Object body) throws Exception {
     try (HighwayOutputStream os = new HighwayOutputStream(msgId)) {
       os.write(header, bodySchema, body);
@@ -81,7 +114,7 @@ public final class HighwayCodec {
       invocation.getContext().putAll(header.getContext());
     }
 
-    ResponseRootDeserializer<Object> bodySchema = operationProtobuf.findResponseDesirialize(header.getStatusCode());
+    ResponseRootDeserializer<Object> bodySchema = operationProtobuf.findResponseRootDeserializer(header.getStatusCode());
     Object body = bodySchema.deserialize(tcpData.getBodyBuffer().getBytes());
 
     Response response = Response.create(header.getStatusCode(), header.getReasonPhrase(), body);
diff --git a/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayOutputStream.java b/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayOutputStream.java
index 815796e..3eac978 100644
--- a/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayOutputStream.java
+++ b/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayOutputStream.java
@@ -16,7 +16,8 @@
  */
 package org.apache.servicecomb.transport.highway;
 
-import org.apache.servicecomb.foundation.protobuf.RequestRootSerializer;
+import org.apache.servicecomb.codec.protobuf.definition.RequestRootSerializer;
+import org.apache.servicecomb.codec.protobuf.definition.ResponseRootSerializer;
 import org.apache.servicecomb.foundation.protobuf.RootSerializer;
 import org.apache.servicecomb.foundation.vertx.tcp.TcpOutputStream;
 import org.apache.servicecomb.transport.highway.message.RequestHeader;
@@ -31,6 +32,10 @@ public class HighwayOutputStream extends TcpOutputStream {
     write(RequestHeader.getRootSerializer().serialize(header), requestRootSerializer.serialize(body));
   }
 
+  public void write(ResponseHeader header, ResponseRootSerializer responseRootSerializer, Object body) throws Exception {
+    write(ResponseHeader.getRootSerializer().serialize(header), responseRootSerializer.serialize(body));
+  }
+
   public void write(RequestHeader header, RootSerializer bodySchema, Object body) throws Exception {
     write(RequestHeader.getRootSerializer(), header, bodySchema, body);
   }
diff --git a/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayServerInvoke.java b/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayServerInvoke.java
index c426a90..2169b26 100644
--- a/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayServerInvoke.java
+++ b/transports/transport-highway/src/main/java/org/apache/servicecomb/transport/highway/HighwayServerInvoke.java
@@ -25,6 +25,7 @@ import javax.xml.ws.Holder;
 
 import org.apache.servicecomb.codec.protobuf.definition.OperationProtobuf;
 import org.apache.servicecomb.codec.protobuf.definition.ProtobufManager;
+import org.apache.servicecomb.codec.protobuf.definition.ResponseRootSerializer;
 import org.apache.servicecomb.core.Const;
 import org.apache.servicecomb.core.Endpoint;
 import org.apache.servicecomb.core.Handler;
@@ -34,7 +35,6 @@ import org.apache.servicecomb.core.definition.MicroserviceMeta;
 import org.apache.servicecomb.core.definition.OperationMeta;
 import org.apache.servicecomb.core.definition.SchemaMeta;
 import org.apache.servicecomb.core.invocation.InvocationFactory;
-import org.apache.servicecomb.foundation.protobuf.RootSerializer;
 import org.apache.servicecomb.foundation.vertx.tcp.TcpConnection;
 import org.apache.servicecomb.swagger.invocation.Response;
 import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
@@ -143,7 +143,7 @@ public class HighwayServerInvoke {
     header.setContext(context);
     header.setHeaders(response.getHeaders());
 
-    RootSerializer bodySchema = operationProtobuf.findResponseSerializer(response.getStatusCode());
+    ResponseRootSerializer bodySchema = operationProtobuf.findResponseRootSerializer(response.getStatusCode());
     Object body = response.getResult();
     if (response.isFailed()) {
       body = ((InvocationException) body).getErrorData();
diff --git a/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayClient.java b/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayClient.java
index 54f1291..cf609a2 100644
--- a/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayClient.java
+++ b/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayClient.java
@@ -22,7 +22,6 @@ import javax.xml.ws.Holder;
 
 import org.apache.servicecomb.codec.protobuf.definition.OperationProtobuf;
 import org.apache.servicecomb.codec.protobuf.definition.ProtobufManager;
-import org.apache.servicecomb.core.Const;
 import org.apache.servicecomb.core.Endpoint;
 import org.apache.servicecomb.core.Invocation;
 import org.apache.servicecomb.core.definition.OperationConfig;
@@ -37,20 +36,14 @@ import org.apache.servicecomb.foundation.vertx.client.tcp.NetClientWrapper;
 import org.apache.servicecomb.foundation.vertx.client.tcp.TcpClientConfig;
 import org.apache.servicecomb.foundation.vertx.client.tcp.TcpData;
 import org.apache.servicecomb.foundation.vertx.client.tcp.TcpResponseCallback;
-import org.apache.servicecomb.foundation.vertx.server.TcpParser;
-import org.apache.servicecomb.foundation.vertx.tcp.TcpOutputStream;
 import org.apache.servicecomb.swagger.invocation.Response;
 import org.apache.servicecomb.swagger.invocation.exception.InvocationException;
-import org.apache.servicecomb.transport.highway.message.LoginRequest;
-import org.apache.servicecomb.transport.highway.message.RequestHeader;
 import org.junit.AfterClass;
 import org.junit.Assert;
 import org.junit.BeforeClass;
 import org.junit.Test;
 import org.mockito.Mockito;
 
-import io.netty.buffer.ByteBuf;
-import io.protostuff.runtime.ProtobufCompatibleUtils;
 import io.vertx.core.AbstractVerticle;
 import io.vertx.core.DeploymentOptions;
 import io.vertx.core.Vertx;
diff --git a/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayCodec.java b/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayCodec.java
index 16d8c2d..0259dde 100644
--- a/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayCodec.java
+++ b/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayCodec.java
@@ -22,12 +22,12 @@ import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.servicecomb.codec.protobuf.definition.OperationProtobuf;
+import org.apache.servicecomb.codec.protobuf.definition.RequestRootSerializer;
+import org.apache.servicecomb.codec.protobuf.definition.ResponseRootSerializer;
 import org.apache.servicecomb.core.Endpoint;
 import org.apache.servicecomb.core.Invocation;
 import org.apache.servicecomb.core.definition.OperationMeta;
 import org.apache.servicecomb.core.definition.SchemaMeta;
-import org.apache.servicecomb.foundation.protobuf.RequestRootSerializer;
-import org.apache.servicecomb.foundation.protobuf.RootSerializer;
 import org.apache.servicecomb.foundation.vertx.server.TcpParser;
 import org.apache.servicecomb.foundation.vertx.tcp.TcpOutputStream;
 import org.apache.servicecomb.serviceregistry.RegistryUtils;
@@ -42,7 +42,6 @@ import org.junit.Test;
 import org.mockito.Mockito;
 
 import io.netty.buffer.ByteBuf;
-import io.protostuff.runtime.ProtobufCompatibleUtils;
 import io.vertx.core.buffer.Buffer;
 import mockit.Mocked;
 
@@ -68,7 +67,6 @@ public class TestHighwayCodec {
 
   @BeforeClass
   public static void setupClass() {
-    ProtobufCompatibleUtils.init();
   }
 
   @Before
@@ -183,7 +181,7 @@ public class TestHighwayCodec {
   @Test
   public void testEncodeResponse() {
     boolean status = true;
-    RootSerializer bodySchema = Mockito.mock(RootSerializer.class);
+    ResponseRootSerializer bodySchema = Mockito.mock(ResponseRootSerializer.class);
     try {
       commonMock();
       Object data = new Object();
@@ -236,7 +234,7 @@ public class TestHighwayCodec {
   }
 
   private void commonMock() {
-    Mockito.when(operationProtobuf.findRequestSerializer()).thenReturn(requestSerializer);
+    Mockito.when(operationProtobuf.getRequestRootSerializer()).thenReturn(requestSerializer);
     Mockito.when(bodyBuffer.getByteBuf()).thenReturn(lByteBuf);
     Mockito.when(lByteBuf.nioBuffer()).thenReturn(nioBuffer);
     Mockito.when(operationProtobuf.getOperationMeta()).thenReturn(operationMeta);
diff --git a/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayTransport.java b/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayTransport.java
index f9c04a3..55f15f7 100644
--- a/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayTransport.java
+++ b/transports/transport-highway/src/test/java/org/apache/servicecomb/transport/highway/TestHighwayTransport.java
@@ -20,12 +20,11 @@ package org.apache.servicecomb.transport.highway;
 import javax.xml.ws.Holder;
 
 import org.apache.servicecomb.codec.protobuf.definition.OperationProtobuf;
+import org.apache.servicecomb.codec.protobuf.definition.RequestRootSerializer;
 import org.apache.servicecomb.core.Endpoint;
 import org.apache.servicecomb.core.Invocation;
 import org.apache.servicecomb.core.definition.OperationMeta;
 import org.apache.servicecomb.foundation.common.net.URIEndpointObject;
-import org.apache.servicecomb.foundation.protobuf.RequestRootSerializer;
-import org.apache.servicecomb.foundation.protobuf.RootSerializer;
 import org.apache.servicecomb.foundation.vertx.VertxUtils;
 import org.apache.servicecomb.swagger.invocation.AsyncResponse;
 import org.junit.AfterClass;
@@ -105,7 +104,7 @@ public class TestHighwayTransport {
     Endpoint lEndpoint = Mockito.mock(Endpoint.class);
     Mockito.when(invocation.getEndpoint()).thenReturn(lEndpoint);
     RequestRootSerializer lWrapSchema = Mockito.mock(RequestRootSerializer.class);
-    Mockito.when(operationProtobuf.findRequestSerializer()).thenReturn(lWrapSchema);
+    Mockito.when(operationProtobuf.getRequestRootSerializer()).thenReturn(lWrapSchema);
     URIEndpointObject ep = Mockito.mock(URIEndpointObject.class);
     Mockito.when(lEndpoint.getAddress()).thenReturn(ep);
     Mockito.when(ep.getHostOrIp()).thenReturn("127.0.0.1");