1

So I have a small problem:

A message is sent using MQTT, it consists of a series of serialized objects using protobuf-net in C# (I can't modify this code, but I have access to the source). At the other end i receive the serialized objects in Java, the problem is I can't seem to be able to deserialize the objects using protobuf, if anyone ever had this problem and solved it, please help :)

Example of object from C#:

using ProtoBuf;

namespace Concentrator.Services
{
[ProtoContract]
public class MeterID
{
    private byte[] _id;

    [ProtoMember(1)]
    public byte[] ID
    {
        get { return _id; }
        set { _id = value.Length == 16 ? value : null; }
    }

    [ProtoMember(2)] public string MeterType;
}
}

My attempt at recreating the same object in Java (the .proto file):

syntax = "proto2";

 package mqtt.entity;

 option java_package = "mqtt.entity";
 option java_outer_classname = "ProtoMeter";
 message Meter {
    optional bytes ID = 1;
     optional string MeterType = 2;
  }

  message MeterID {
     repeated Meter mid = 1;
 }

A solution to this example would be a huge help, Thanks a lot.

The code where the object is deserialized in C#:

var ms = new MemoryStream(data, 7, data.Length - 9)
var res = Serializer.Deserialize<List<MeterID>>(ms);

this works in C#, I'm trying to achieve the same thing in java

cosmin.danisor
  • 943
  • 1
  • 12
  • 29

2 Answers2

3

The message in your C# code matches just:

message MeterID {
    optional bytes ID = 1;
    optional string MeterType = 2;
}

There is no need for a 2-level model (unless you're using *WithLengthPrefix in the C# code). You can also get that output by using:

var proto = Serializer.GetProto<MeterID>();

With your edit, a List<MeterID> could be mapped as

message List_MeterID {
    repeated MeterID items = 1;
}

to be used in combination with the previous MeterID fragment. Which is what you have in the question. So it comes down to "what currently happens?".

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • I'm trying to deserialize in java, the objects comes in a list, I'll update the first post to add the code where they are deserialized in C# – cosmin.danisor Apr 08 '13 at 13:09
  • @cdanisor you didn't mention the `List` :p With that, the .proto from your original question is fine. So that then prompts the question - what happens now? what doesn't work? do you get an exception...? or...? – Marc Gravell Apr 08 '13 at 13:32
  • There is another problem now :) Exception in thread "MQTT Client Callback" java.lang.VerifyError: class mqtt.entity.ProtoMeter$MeterID overrides final method getUnknownFields.()Lcom/google/protobuf/UnknownFieldSet; at java.lang.ClassLoader.defineClass1(Native Method) The class generated by protoc seems to be bugged, it overrides a final method. – cosmin.danisor Apr 08 '13 at 13:37
  • 2
    @cdanisor first check you have the current build of the google protobuf (not protobuf-net) package; if `protoc` still emits illegal java, then I would suggest to report it on the [protobuf list](https://groups.google.com/forum/?fromgroups#!forum/protobuf) or on the protobuf (not protobuf-net) [issue tracker](https://code.google.com/p/protobuf/issues/list) – Marc Gravell Apr 08 '13 at 13:42
  • You were right, I used a wrong version of protoc, different from the jar, it works flawlessly now. Thanks a lot. – cosmin.danisor Apr 08 '13 at 13:59
  • Hi Cosmin, i am trying to achieve the same thing, trying to de-serialize the .bin file created in C# to object in JAVA.How have you achieved ? – Aada Aug 05 '13 at 11:58
  • @Aada it should *just work*. What problems have you encountered? – Marc Gravell Aug 05 '13 at 12:03
1

try regenerate proto-file by GetProto<T>

burning_LEGION
  • 13,246
  • 8
  • 40
  • 52