GithubHelp home page GithubHelp logo

jprotobuf's People

Contributors

chinesejie avatar iohao avatar jhunters avatar qiunet avatar silencesu avatar xiemalin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jprotobuf's Issues

增加对jprotobuf动态生成的类文件的生成

该功能可以支持把jprotobuf动态生成的中间代码的类文件输出到指定目录,以方便后续只有jre环境使用jprotobuf的可行性。

使用示例:Codec codec = ProtobufProxy.create(AddressBookProtosPOJO.class, false, new File("D:/"));

会在d盘根目录下生成中间的类文件对象。下次只需要把这个类文件对象加入到classpath中,就不会再执行动态编译过程了

ProtobufIDLGenerator对List类型生成问题

String idl = ProtobufIDLGenerator.getIDL(RequrieRepeatedNumberTypePOJOClass2.class);
System.out.println(idl);

输出错误内容如下
package com.baidu.bjf.remoting.protobuf.simplerepeat;
option java_outer_classname = "RequrieRepeatedNumberTypePOJOClass2$$ByJProtobuf";
message RequrieRepeatedNumberTypePOJOClass2 {
optional int32 list1=1;
}

public class RequrieRepeatedNumberTypePOJOClass2 {

@Protobuf(fieldType = FieldType.INT32, order = 1, required = false)
public List<Integer> list1;

}

由.proto文件生成pojo对引用嵌套enum支持有问题

jprotobuf版本:1.9.4

执行

ProtobufIDLProxy.generateSource(protoFile, srcPath);

抛异常:

Exception in thread "main" java.lang.RuntimeException: Message 'DataStatus' depend on message 'DataInfo.DataVisibility' is missed
    at com.baidu.bjf.remoting.protobuf.ProtobufIDLProxy.hasDependency(ProtobufIDLProxy.java:513)
    at com.baidu.bjf.remoting.protobuf.ProtobufIDLProxy.createClass(ProtobufIDLProxy.java:419)

proto:

message DataInfo {
    enum DataVisibility {
    PUBLIC = 1;
    PRIVATE = 2;
    }
...
}

message DataStatus {
    optional DataInfo.DataVisibility visibility = 1;
}

使用@Protobuf方式,动态编译的POJO序列化反序列化效率非常低

版本1.9.8,使用@protobuf方式,序列化反序列化对象效率非常低。

在代码中调用API生成了POJO源代码(非预编译,是动态编译)
Codec simpleListCodec = ProtobufProxy.create(SimpleList.class, true);

发现生成的代码存在重复动态生成jprotobuf POJO源代码

public byte[] encode(SimpleList t) throws IOException {
    int size = 0;List f_2=null;
    if (!CodedConstant.isNull(t.getList())) {
        f_2=t.getList();
    }if (!CodedConstant.isNull(t.getList())){
        size += CodedConstant.computeListSize(2,f_2, FieldType.STRING,true,ProtobufProxy.OUTPUT_PATH.get());
    }
    if (f_2== null) {
        throw new UninitializedMessageException(CodedConstant.asList("list"));
    }
    final byte[] result = new byte[size];
    final CodedOutputStream output = CodedOutputStream.newInstance(result);
    writeTo(t, output);
    return result;
}

com.baidu.bjf.remoting.protobuf.CodedConstant#computeSize(int, java.lang.Object, com.baidu.bjf.remoting.protobuf.FieldType, boolean, boolean, java.io.File)

public static int computeSize(int order, Object o, FieldType type, boolean list, boolean debug, File path) {
        int size = 0;
        if (o == null) {
            return size;
        }
        if (type == FieldType.OBJECT) {
            Class cls = o.getClass();
            Codec target = ProtobufProxy.create(cls, debug, path);
            try {
                size = target.size(o);
                size = size + CodedOutputStream.computeRawVarint32Size(size);
                return size + CodedOutputStream.computeTagSize(order);
            } catch (IOException e) {
                throw new RuntimeException(e.getMessage(), e);
            }
        }
        if (type == FieldType.STRING) {
            size = CodedOutputStream.computeStringSizeNoTag(String.valueOf(o));
        } else if (type == FieldType.BOOL) {
            size = CodedOutputStream.computeBoolSizeNoTag(Boolean.valueOf(String.valueOf(o)));
        } else if (type == FieldType.BYTES) {
            byte[] bb = (byte[]) o;
            size = CodedOutputStream.computeBytesSizeNoTag(ByteString.copyFrom(bb));
        } else if (type == FieldType.DOUBLE) {
            size = CodedOutputStream.computeDoubleSizeNoTag(Double.valueOf(o.toString()));
        } else if (type == FieldType.FIXED32 || type == FieldType.INT32 || type == FieldType.SFIXED32
                || type == FieldType.SINT32 || type == FieldType.UINT32) {
            size = CodedOutputStream.computeInt32SizeNoTag(Integer.valueOf(o.toString()));
        } else if (type == FieldType.FIXED64 || type == FieldType.INT64 || type == FieldType.SFIXED64
                || type == FieldType.SINT64 || type == FieldType.UINT64) {
            size = CodedOutputStream.computeInt64SizeNoTag(Long.valueOf(o.toString()));
        } else if (type == FieldType.FLOAT) {
            size = CodedOutputStream.computeFloatSizeNoTag(Float.valueOf(o.toString()));
        } else if (type == FieldType.ENUM) {
            if (o instanceof EnumReadable) {
                size = CodedOutputStream.computeInt32SizeNoTag(((EnumReadable) o).value());
            } else if (o instanceof Enum) {
                size = CodedOutputStream.computeInt32SizeNoTag(((Enum) o).ordinal());
            }
        }

        return size;
    }

ProtobufProxy.create是没有缓存生成的对象的,每次调用都重新生成。

IDLGen.getIDL的问题

public class Test
{
@protobuf(fieldType = FieldType.INT32, order = 1, required = false)
private List list;
}

使用IDLGen.getIDL(Test.class);生成的描述文件不对:

message Test{
optional string list=1;
}
应该是repeated啊。。。

增加从注解的POJO类生成.proto描述文件

由于开发中使用注解方便了protobuf的开发,但目前这个功能仅对于java,如果要把注释开发功能,导出给其它语言使用,就需要单独编写.proto文件,需要额外的工作,所以加上自动生成.proto文件的功能可以简化这一部分工作

List<Integer>类型不支持

定义如下:
@protobuf
private List intList;

报错如下:
Class must has default constructor method with no parameters.

原始类型的数组或者list不支持?

增加对jprotobuf 复合类型数据用法

该特征将支持:
public class AddressBookProtosPOJO {

@Protobuf(fieldType = FieldType.OBJECT, order=1, required = false)
public PersonPOJO list;

/* (non-Javadoc)
 * @see java.lang.Object#toString()
 */
@Override
public String toString() {
    return "AddressBookProtosPOJO [list=" + list + "]";
}

}

public class PersonPOJO {

/* (non-Javadoc)
 * @see java.lang.Object#toString()
 */
@Override
public String toString() {
    return "PersonPOJO [name=" + name + ", id=" + id + ", email=" + email + "]";
}
@Protobuf(fieldType = FieldType.STRING, order=1, required = true)
public String name;
@Protobuf(fieldType = FieldType.INT32, order=2, required = true)
public int id;
@Protobuf(fieldType = FieldType.STRING, order=3, required = false)
public String email;

@Protobuf(fieldType = FieldType.DOUBLE, order=4, required = false)
public Double doubleF;


@Protobuf(fieldType = FieldType.FLOAT, order=5, required = false)
public Float floatF;

@Protobuf(fieldType = FieldType.BYTES, order=6, required = false)
public byte[] bytesF;

@Protobuf(fieldType=FieldType.BOOL, order=7, required=false)
public Boolean boolF;    

}

改进建议

@protobuf(fieldType = FieldType.STRING, order = 1, required = true)
private String name;

@protobuf(fieldType = FieldType.INT32, order = 2, required = false)
private int value;

这些都可以用使用的默认值吧,
如String => STRING, int => INT32, long => INT64
默认required = false, order按bean的field顺序
这样别人就不需要写这么多东西了

ProtobufIDLGenerator是否可以提供一个重载的getIDL(Class<?> cls)方法?

ProtobufIDLGenerator目前只有getIDL(Class cls)一个public方法,我们还是需要一个这样的方法: getIDL(Class cls,Set<Class> cachedTypes,Set> cachedEnumTypes) 因为有这个方法的话,就可以避免重复生成同一个类的idl;比如A类引用了B类,C类也引用了B类,当生成A的idl后其实已经生成了B的idl,再调用getIDL(Class cls)传入C的时候,又一次生成B, 所以把两个cache作为参数传入还是有意义的。我目前是在我们的项目里修改这个ProtobufIDLGenerator并提供这个getIDL(Class cls,Set<Class> cachedTypes,Set> cachedEnumTypes) 方法的。

关于属性默认值的问题

好像 如果属性配置了默认值,生成后的Class类没有配置这个值

optional string Language = 6 [default = "en-US"];

原生的会有这个配置

private java.lang.Object language_ = "en-US";

不兼容的类型: java.util.List无法转换为java.util.ArrayList<

--------------------------generate protobuf proxy code end--------------------------
Exception in thread "main" java.lang.IllegalStateException: Compilation failed. class: com.flhx.gate.player.bean.PlayerBaseInfo$$JProtoBufClass, diagnostics: [PlayerBaseInfo$$JProtoBufClass.java:101: 错误: 不兼容的类型: java.util.List无法转换为java.util.ArrayList<com.flhx.gate.player.bean.Building>
ret.setBuildings(__list);
^, PlayerBaseInfo$$JProtoBufClass.java:114: 错误: 不兼容的类型: java.util.List无法转换为java.util.ArrayList<com.flhx.gate.player.bean.Resource>
ret.setResources(__list);
^, PlayerBaseInfo$$JProtoBufClass.java:127: 错误: 不兼容的类型: java.util.List无法转换为java.util.ArrayList<com.flhx.gate.player.bean.Item>
ret.setItems(__list);

ProtobufIDLGenerator的bug

举个例子:
public class Test
{
@protobuf
private List bps;

public List getBps()
{
return bps;
}
public void setBps(List bps)
{
this.bps = bps;
}
}

这个类,调用ProtobufIDLGenerator的getIDL(Test.class,new HashSet<Class>(),new HashSet>(),true);
生成如下idl:

message Test
{
repeated String bps=1;
}
message String {
}

应该生成这样的吧:
message Test
{
repeated string bps=1;
}

Jprotobuf增加对枚举类型的支持

  1. @protobuf 注释支持枚举类型的支持
  2. ProtobufIDLGenerator 支持枚举类型的idl生成
  3. ProtobufIDLProxy支持包含枚举类型的idl动态代理支持,但目前不支持包含内部类与内部枚举类型方式

默认值会被encode

一个类有10个字段,如果只使用了其中1个字段,其他9个字段 "应该" 不会encode.

@Protobuf的order属性是否应该为必选?

在协议定义时,字段顺序通常是明确的,使用默认值时如果不小心在中间新加了一个字段,就会造成协议不兼容,是否可以考虑设置必选?

另外,是否可以考虑order不定义的话,忽略该字段?

java.lang.ExceptionInInitializerError

单独的测试方法中 没有问题

    public static void main(String[] args) {
        Codec<UserJProtoBufProtoClass> codec = ProtobufProxy.create(UserJProtoBufProtoClass.class);
        System.out.println(codec);
    }

但如果在servlet 方法中调用就会抱这个错误

java.lang.ExceptionInInitializerError
    at com.baidu.bjf.remoting.protobuf.ProtobufProxy.create(ProtobufProxy.java:201)
    at com.baidu.bjf.remoting.protobuf.ProtobufProxy.create(ProtobufProxy.java:106)
    at com.rekoe.protobuf.mobule.ProtobufMobule.test(ProtobufMobule.java:38)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.nutz.mvc.impl.processor.MethodInvokeProcessor.process(MethodInvokeProcessor.java:25)
    at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
    at org.nutz.mvc.impl.processor.AdaptorProcessor.process(AdaptorProcessor.java:33)
    at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
    at org.nutz.mvc.impl.processor.ActionFiltersProcessor.process(ActionFiltersProcessor.java:40)
    at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
    at org.nutz.mvc.impl.processor.ModuleProcessor.process(ModuleProcessor.java:113)
    at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
    at org.nutz.mvc.impl.processor.EncodingProcessor.process(EncodingProcessor.java:27)
    at org.nutz.mvc.impl.processor.AbstractProcessor.doNext(AbstractProcessor.java:44)
    at org.nutz.mvc.impl.processor.UpdateRequestAttributesProcessor.process(UpdateRequestAttributesProcessor.java:15)
    at org.nutz.mvc.impl.NutActionChain.doChain(NutActionChain.java:40)
    at org.nutz.mvc.impl.ActionInvoker.invoke(ActionInvoker.java:67)
    at org.nutz.mvc.ActionHandler.handle(ActionHandler.java:31)
    at org.nutz.mvc.NutFilter.doFilter(NutFilter.java:183)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
    at com.baidu.bjf.remoting.protobuf.utils.compiler.JdkCompiler.<init>(JdkCompiler.java:74)
    at com.baidu.bjf.remoting.protobuf.utils.JDKCompilerHelper.<clinit>(JDKCompilerHelper.java:31)
    ... 37 more
·``````

public class UserJProtoBufProtoClass {

@Protobuf(fieldType = FieldType.INT64, order = 1, required = false)
public Long id;
@Protobuf(fieldType = FieldType.STRING, order = 2, required = false)
public String name;
@Protobuf(fieldType = FieldType.OBJECT, order = 4)
public PhoneNumberJProtoBufProtoClass phone;

public static class PhoneNumberJProtoBufProtoClass {
    @Protobuf(fieldType = FieldType.STRING, order = 1, required = true)
    public String number;
}

}

CodedConstant.computeSize 错误?

CodedConstant.computeSize(int order, Object o, FieldType type, boolean list) 方法中
......

} else if (type == FieldType.FIXED32 || type == FieldType.INT32 || type == FieldType.SFIXED32
|| type == FieldType.SINT32 || type == FieldType.UINT32) {
size = CodedOutputStream.computeInt32SizeNoTag(Integer.valueOf(o.toString()));
} else if (type == FieldType.FIXED64 || type == FieldType.INT64 || type == FieldType.SFIXED64
|| type == FieldType.SINT64 || type == FieldType.UINT64) {
size = CodedOutputStream.computeInt64SizeNoTag(Long.valueOf(o.toString()));
}
.......
FieldType.FIXED32,FieldType.SFIXED32 size应该是固定值4
FieldType.FIXED64,FieldType.SFIXED64 size 应该是固定值8

proto生成jprotobuf Source代码:自循环引用无法生成代码

现在有个proto文件用
ProtobufIDLProxy.generateSource(fis, new File(source));
方法无法生成pojo文件 请问是不支持还是格式不对?
用原生的是可以生成的

package pkg;

option java_package = "org.nutz.plugins.protobuf.pojo";
option java_outer_classname = "JJFlyProtocol";
message MixedDataTypeTable
{
message BoolKVP
{
required string Key = 1;
required bool Value = 2;
}

message BoolArrayKVP
{
    required string Key = 1;
    repeated bool Values = 2;
}

message IntKVP
{
    required string Key = 1;
    required sint64 Value = 2;
}

message IntArrayKVP
{
    required string Key = 1;
    repeated sint64 Values = 2;
}

message FloatKVP
{
    required string Key = 1;
    required float Value = 2;
}

message FloatArrayKVP
{
    required string Key = 1;
    repeated float Values = 2;
}

message StringKVP
{
    required string Key = 1;
    required string Value = 2;
}

message StringArrayKVP
{
    required string Key = 1;
    repeated string Values = 2;
}

message MixedDataTypeTableKVP
{
    required string Key = 1;
    required MixedDataTypeTable Value = 2;
}

message MixedDataTypeTableArrayKVP
{
    required string Key = 1;
    repeated MixedDataTypeTable Values = 2;
}

repeated BoolKVP BoolKVPs = 1;
repeated BoolArrayKVP BoolArrayKVPs = 2;
repeated IntKVP IntKVPs = 3;
repeated IntArrayKVP IntArrayKVPs = 4;
repeated FloatKVP FloatKVPs = 5;
repeated FloatArrayKVP FloatArrayKVPs = 6;
repeated StringKVP StringKVPs = 7;
repeated StringArrayKVP StringArrayKVPs = 8;
repeated MixedDataTypeTableKVP MixedDataTypeTableKVPs = 9;
repeated MixedDataTypeTableArrayKVP MixedDataTypeTableArrayKVPs = 10;

}

message JJFlyMessageItem
{
required sint64 ID = 1;
required MixedDataTypeTable Value = 2;
}

message JJFlyMessageRequestBody
{
required sint64 BaseProtocolVersion = 1;
optional string AppID = 2;
optional sint64 ProtocolVersion = 3;
optional sint64 AppVersion = 4;
optional sint64 ResVersion = 5;
optional string Language = 6 [default = "en-US"];
optional string DistributionChannel = 7;
optional string SessionID = 8;
optional sint64 SessionSerialNumber = 9;
repeated JJFlyMessageItem JJFlyMessageItems = 15;
}

message JJFlyMessageResponseBody
{
optional string SessionID = 1;
optional sint64 SessionSerialNumber = 2;
repeated JJFlyMessageItem JJFlyMessageItems = 15;
}

proto文件依赖另一个proto文件,生成POJO的时候会报错

使用1.7.4 Jprotobuf
测试新功能 通过 .proto文件生成POJO类
发现如果 proto文件依赖另一个proto文件,生成带注解的POJO类时 就会报错
例如:
package com.base.research;

option java_package = "com.base.research.protobufMsg.test";
option java_outer_classname = "AddressBookProto";

import "person.proto";

message AddressBook {
repeated Person person = 1;
}

是不支持吗?

computeListSize 计算错误

public static int computeListSize(int order, List list, FieldType type) {
int size = 0;
if (list == null) {
return size;
}
for (Object object : list) {
size += computeSize(order, object, type, true);
}
if (type != FieldType.OBJECT) {
size += list.size();
}
return size;
}

.......

if (type != FieldType.OBJECT) {
//这里不能直接 += list.size ,因为只有 order < 16 的时候,tag占位才是1,
//应该是 += (list.size * CodedOutputStream.computeTagSize(order))
size += (list.size * CodedOutputStream.computeTagSize(order));
}

将测试用例中 List< String > 字段的 order 改为 >= 16 即可重现

有想法,谢谢分享!!!!
尊重别人的劳动!!!

嵌套对象支持

嵌套对象的支持是不是弄得太复杂了?
为了支持这个 codec 上多出了3方法
int size(T t)
void writeTo(T t, CodedOutputStream out)
T readFrom(CodedInputStream intput)

直接把对象 encode 然后直接按照 byte[] 处理效果应该是一样的吧?

关于servlet 响应数据问题

在servlet 返回中调用

OutputStream out = resp.getOutputStream();
codec.writeTo(obj, CodedOutputStream.newInstance(out));

返回的数据是空的

但调用客户端是可以得到返回值的

OutputStream out = resp.getOutputStream();    
out.write(codec.encode(obj));

是不是codec.writeTo 方法有问题?

框架能够做到支持泛型吗?

比如说
public EchoInfo<T> { @Protobuf(seeAlso={A.class, B.class, C.class}) T data; }
在使用的时候:
public EchoServiceImpl { @ProtobufRpcService EchoInfo<A> echo(String msg); }

或者干脆连seeAlso都不需要, 直接根据impl中的泛型的的typeInfer拿到具体的type,从而进行序列化反序列化。

List<Integer> 类型支持

集合不支持没有构造函数的对象类型,例如List,初始化时报错。

原生的protobuf是可以支持的:repeated int32 xxx = 1;

自定义错误处理情况下,可否支持范型?

错误处理

要定义一套错误处理,比如我定义一个范型的rpcresponse 对象。

@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class RPCResponse<T> {

  @Protobuf(required = true)
  private int status = RPCResponseUtil.OK_STATUS; // similar to httpStatus

  @Protobuf
  private T data;

  @Protobuf
  private Exception exception;

}

其范型T 的对象可以是

@Data
public class EchoInfo {

  @Protobuf
  public String message;
}
public class EchoRPCServiceImpl {
  @ProtobufRPCService(serviceName = "echoRPCService", methodName = "echo")
  public RPCResponse<EchoInfo> doEcho(String message) {
    RPCResponse<EchoInfo> ret = new RPCResponse();

    if (message.equals("hello")) {
      throw new UnknownException();
    }

    if (message.equals("jersey")) {
      throw new CustomException();
    }

    EchoInfo data = new EchoInfo();
    data.setMessage(message);
    ret.setData(data);
    return ret;
  }
}
public interface EchoRPCService {
  @ProtobufRPC(serviceName = "echoRPCService", onceTalkTimeout = 5000)
  RPCResponse<EchoInfo> echo(String message);
}
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class Exception {
  @Protobuf(required = true)
  private long timestamp;

  @Protobuf
  private int status;

  @Protobuf(required = true)
  private String errorCode;

  @Protobuf(required = true)
  private String errorMessage;

  @Protobuf(required = true)
  private String exception;

  @Protobuf
  private String path;
}

这样处理了, 好像总是报错。
目前不支持范型?
或者有没有更好的方式处理错误呢? 我目前知道的是用继承的方式,一个个属性写在基类里面。

错误堆栈信息

Caused by: java.lang.IllegalArgumentException: Invalid class [java.lang.String] no field use annotation @com.baidu.bjf.remoting.protobuf.annotation.Protobuf at class java.lang.String
    at com.baidu.bjf.remoting.protobuf.ProtobufProxy.getCodeGenerator(ProtobufProxy.java:103)
    at com.baidu.bjf.remoting.protobuf.ProtobufProxy.doCreate(ProtobufProxy.java:198)
    at com.baidu.bjf.remoting.protobuf.ProtobufProxy.create(ProtobufProxy.java:159)
    at com.baidu.bjf.remoting.protobuf.ProtobufProxy.create(ProtobufProxy.java:126)
    at com.baidu.jprotobuf.pbrpc.server.AnnotationRpcHandler.<init>(AnnotationRpcHandler.java:54)
    at com.baidu.jprotobuf.pbrpc.server.RpcServiceRegistry.doCreateRpcHandler(RpcServiceRegistry.java:119)
    at com.baidu.jprotobuf.pbrpc.server.RpcServiceRegistry.doRegiterService(RpcServiceRegistry.java:131)
    at com.baidu.jprotobuf.pbrpc.server.RpcServiceRegistry.access$000(RpcServiceRegistry.java:41)
    at com.baidu.jprotobuf.pbrpc.server.RpcServiceRegistry$1.doWith(RpcServiceRegistry.java:107)
    at com.baidu.jprotobuf.pbrpc.utils.ReflectionUtils.doWithMethods(ReflectionUtils.java:64)
    at com.baidu.jprotobuf.pbrpc.utils.ReflectionUtils.doWithMethods(ReflectionUtils.java:41)
    at com.baidu.jprotobuf.pbrpc.server.RpcServiceRegistry.registerService(RpcServiceRegistry.java:101)
    at com.baidu.jprotobuf.pbrpc.transport.RpcServer.registerService(RpcServer.java:172)

效率怎么样呢

相比于直接使用protobuf,使用jprotobuf效率上会降低多少?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.