You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@thrift.apache.org by Andrew Watts <an...@gmail.com> on 2012/06/28 05:11:14 UTC

double serialization/deserialization issue in Java/Python

I'm writing a python client that needs to deserialize a thrift blob
that was serialized in a java server. Both sides use serializers and
the CompactProtocol from their respective libraries.  Java writes the
blob to a log file as a base64 encoded string, then python reads the
base64 encoded string from the log.  During development I discovered
double values were not being deserialized correctly.  However, when
using the Binary Protocol, the value is deserialized correctly.  Am I
doing something incorrectly or this there a possible bug in either the
python or java implementation of the compact protocol.

Below is a simple thrift definition, java program and python program
that demonstrate the problem.

Thanks.

- Andrew


» java -cp .:../lib/libthrift-0.8.0.jar:../lib/slf4j-api-1.6.4.jar ThriftTest
fooObj.bar: 3.456
base64String: F9nO91PjpQtAAA==

» python ../python/tdouble_test.py
base64 string:  F9nO91PjpQtAAA==
foo_obj.bar:  -4.09406819342e+124    # expect 3.456


Thrift Definition
================

struct FooObj {
    1: double bar
}


Java Code
=========

import org.apache.thrift.TException;
import org.apache.thrift.TSerializer;
import org.apache.thrift.protocol.TCompactProtocol;

import javax.xml.bind.DatatypeConverter;


public class ThriftTest {

    public static void main(String[] args) {

        final TSerializer serializer = new TSerializer(new
TCompactProtocol.Factory());

        // create a FooObj with double
        final FooObj fooObj = new FooObj(3.456);
        System.out.println("fooObj.bar: " + fooObj.bar);

        // serialize to bytes
        byte[] fooObjBlob = null;
        try {
            fooObjBlob = serializer.serialize(fooObj);
        } catch (TException e) {
            e.printStackTrace();
        }

        // encode to base64 string
        final String base64String =
DatatypeConverter.printBase64Binary(fooObjBlob);
        System.out.println("base64String: " + base64String);
    }

}


Python Code
===========

#!/bin/env python

import base64

from thrift.protocol import TCompactProtocol
from thrift.TSerialization import deserialize

from foo.ttypes import FooObj


def main():

    protocol_factory = TCompactProtocol.TCompactProtocolFactory
    base64_string = 'F9nO91PjpQtAAA=='

    print 'base64 string: ', base64_string

    # deserialize the string back into an object
    foo_blob = base64.urlsafe_b64decode(base64_string)
    foo_obj = FooObj()
    deserialize(foo_obj, foo_blob, protocol_factory=protocol_factory())
    print 'foo_obj.bar: ', foo_obj.bar

if __name__ == '__main__':
    main()

Re: double serialization/deserialization issue in Java/Python

Posted by Bryan Duxbury <br...@gmail.com>.
I suspect there's a mismatch in the serialization/deserialization between
the languages. Can you open a ticket?

On Wed, Jun 27, 2012 at 8:11 PM, Andrew Watts <an...@gmail.com> wrote:

> I'm writing a python client that needs to deserialize a thrift blob
> that was serialized in a java server. Both sides use serializers and
> the CompactProtocol from their respective libraries.  Java writes the
> blob to a log file as a base64 encoded string, then python reads the
> base64 encoded string from the log.  During development I discovered
> double values were not being deserialized correctly.  However, when
> using the Binary Protocol, the value is deserialized correctly.  Am I
> doing something incorrectly or this there a possible bug in either the
> python or java implementation of the compact protocol.
>
> Below is a simple thrift definition, java program and python program
> that demonstrate the problem.
>
> Thanks.
>
> - Andrew
>
>
> » java -cp .:../lib/libthrift-0.8.0.jar:../lib/slf4j-api-1.6.4.jar
> ThriftTest
> fooObj.bar: 3.456
> base64String: F9nO91PjpQtAAA==
>
> » python ../python/tdouble_test.py
> base64 string:  F9nO91PjpQtAAA==
> foo_obj.bar:  -4.09406819342e+124    # expect 3.456
>
>
> Thrift Definition
> ================
>
> struct FooObj {
>     1: double bar
> }
>
>
> Java Code
> =========
>
> import org.apache.thrift.TException;
> import org.apache.thrift.TSerializer;
> import org.apache.thrift.protocol.TCompactProtocol;
>
> import javax.xml.bind.DatatypeConverter;
>
>
> public class ThriftTest {
>
>    public static void main(String[] args) {
>
>        final TSerializer serializer = new TSerializer(new
> TCompactProtocol.Factory());
>
>        // create a FooObj with double
>        final FooObj fooObj = new FooObj(3.456);
>        System.out.println("fooObj.bar: " + fooObj.bar);
>
>        // serialize to bytes
>        byte[] fooObjBlob = null;
>        try {
>            fooObjBlob = serializer.serialize(fooObj);
>        } catch (TException e) {
>            e.printStackTrace();
>        }
>
>        // encode to base64 string
>        final String base64String =
> DatatypeConverter.printBase64Binary(fooObjBlob);
>        System.out.println("base64String: " + base64String);
>    }
>
> }
>
>
> Python Code
> ===========
>
> #!/bin/env python
>
> import base64
>
> from thrift.protocol import TCompactProtocol
> from thrift.TSerialization import deserialize
>
> from foo.ttypes import FooObj
>
>
> def main():
>
>    protocol_factory = TCompactProtocol.TCompactProtocolFactory
>    base64_string = 'F9nO91PjpQtAAA=='
>
>    print 'base64 string: ', base64_string
>
>    # deserialize the string back into an object
>    foo_blob = base64.urlsafe_b64decode(base64_string)
>    foo_obj = FooObj()
>    deserialize(foo_obj, foo_blob, protocol_factory=protocol_factory())
>    print 'foo_obj.bar: ', foo_obj.bar
>
> if __name__ == '__main__':
>    main()
>