GithubHelp home page GithubHelp logo

jprotobuf's Issues

List<Integer>类型不支持

定义如下:
@protobuf
private List intList;

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

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

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;
}

是不支持吗?

List<Integer> 类型支持

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

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

Jprotobuf增加对枚举类型的支持

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

改进建议

@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顺序
这样别人就不需要写这么多东西了

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啊。。。

效率怎么样呢

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

默认值会被encode

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

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 即可重现

增加对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;    

}

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

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

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

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

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;

}

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;
}

}

关于servlet 响应数据问题

在servlet 返回中调用

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

返回的数据是空的

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

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

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

嵌套对象支持

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

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

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) 方法的。

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

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

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

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

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;
}

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;
}

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

错误处理

要定义一套错误处理,比如我定义一个范型的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)

关于属性默认值的问题

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

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

原生的会有这个配置

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

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

比如说
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,从而进行序列化反序列化。

使用@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是没有缓存生成的对象的,每次调用都重新生成。

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

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

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

由.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;
}

不兼容的类型: 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);

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.