当前位置: 首页 > 知识库问答 >
问题:

Apache节俭C GLib->Java反序列化问题

蒋昊天
2023-03-14

我不能在使用C Glib序列化的Java节俭对象中反序列化。我的序列化代码如下(我在这里提出问题后提出的解决方案):

ThriftMemoryBuffer* tbuffer = g_object_new(THRIFT_TYPE_MEMORY_BUFFER,
    "buf_size", 2048, NULL);
ThriftTransport *transport = NULL;
ThriftProtocol* protocol = NULL;
GError* error = NULL;

if (tbuffer) {
    transport = THRIFT_TRANSPORT(tbuffer);
    thrift_transport_open(transport, &error);

    protocol =
    THRIFT_PROTOCOL(
        g_object_new(THRIFT_TYPE_BINARY_PROTOCOL, "transport", transport, NULL));

    if (protocol) {
        ExceptionData* exception_data = g_object_new(TYPE_EXCEPTION_DATA, "ex_sign",
            exception_signature, "cl_sign", class_signature, "caught",
            catch_method != NULL,
            NULL);

        if (exception_data) {
            ThriftStructClass* cls = THRIFT_STRUCT_CLASS(EXCEPTION_DATA_GET_CLASS(exception_data));
            int write_len = cls->write(exception_data, protocol, &error);

            if(tbuffer->buf != NULL) {

                printf("Write len %i bytes\n", write_len);
                printf("Data sending: %s, %s, %b \n", exception_data->ex_sign, exception_data->cl_sign, exception_data->caught);

                send_kafka_message((const void *)tbuffer->buf, write_len);
            }

            g_object_unref(exception_data);
        }

        g_object_unref(protocol);
    }

    if (thrift_transport_is_open(transport)) {
        thrift_transport_close(transport, &error);
    }

    g_object_unref(tbuffer);
}
TDeserializer deserializer = new TDeserializer();
ExceptionData ex = new ExceptionData();

try {
    byte[] binData = tuple.getBinary(0);

    _logger.info("Bin data length: " + binData.length);
    _logger.info("HEX data: " + DatatypeConverter.printHexBinary(binData));

    deserializer.deserialize(ex, binData);
} catch (TException e) {
    _logger.error(e);
}

_logger.info("Deserialized object: " + ex);
org.apache.thrift.protocol.TProtocolException: Required field 'caught' was not found in serialized data!
struct ExceptionData {
    1: required string ex_sign, // exception signature
    2: required string cl_sign, // class signature where exception was thrown
    3: required bool caught // whether exception was caught or not
}

发送和接收的消息长度相同。但不知何故,在Java端,我不能复制对象。

可能有人面临过类似的问题?

UPD:

ExceptionData("Ljava/lang/ClassNotFoundException;", "Ljava/net/URLClassLoader;", true)
HEX data: 40890DE0297F00004C000000800000000100000000000000010000000000000000000000000000000000000000000000007E0DE0297F00000100000000000000000000000000000090D900E0
HEX data(1): 00880D109D7F00004E000000800000000100000000000000010000000000000000000000000000000000000000000000007E0D109D7F000001000000000000000000000000000000507F0D109D7F
HEX data(2): 00880D4CF57F00004E000000800000000100000000000000010000000000000000000000000000000000000000000000007E0D4CF57F000001000000000000000000000000000000507F0D4CF57F
    null
ExceptionData("Ljava/lang/ClassNotFoundException;", "Ljava/net/URLClassLoader;", true)
HEX data: 0B0001000000224C6A6176612F6C616E672F436C6173734E6F74466F756E64457863657074696F6E3B0B0002000000194C6A6176612F6E65742F55524C436C6173734C6F616465723B0200030100

在发送到Kafka之前,对相同的tbuffer->buf连续进行了两次十六进制转储。看起来缓冲区在发送前包含错误的数据:

call 1 buf:
  0000  00 88 0d 2c ce 7f 00 00 4e 00 00 00 80 00 00 00  ...,....N.......
  0010  01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00  ................
  0020  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  0030  00 7e 0d 2c ce 7f 00 00 01 00 00 00 00 00 00 00  .~.,............
  0040  00 00 00 00 00 00 00 00 50 e2 00 2c ce 7f        ........P..,..


call 2 buf:
  0000  80 88 0d b8 08 7f 00 00 4e 00 00 00 80 00 00 00  ........N.......
  0010  01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00  ................
  0020  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  0030  00 e1 00 b8 08 7f 00 00 01 00 00 00 00 00 00 00  ................
  0040  00 00 00 00 00 00 00 00 20 88 0d b8 08 7f        ........ .....

共有1个答案

万俟靖
2023-03-14

最后我发现了错误所在。序列化数据存储在tbuffer->buf->data中,而不是tbuffer->buf中。缓冲区lenght存储在tbuffer->buf->len中。

所以,最终的工作代码是:

ThriftMemoryBuffer* tbuffer = g_object_new(THRIFT_TYPE_MEMORY_BUFFER,
    "buf_size", 2048, NULL);
ThriftTransport *transport = NULL;
ThriftProtocol* protocol = NULL;
GError* error = NULL;

if (tbuffer) {
    transport = THRIFT_TRANSPORT(tbuffer);
    thrift_transport_open(transport, &error);

    protocol =
    THRIFT_PROTOCOL(
        g_object_new(THRIFT_TYPE_BINARY_PROTOCOL, "transport", transport, NULL));

    if (protocol) {
        ExceptionData* exception_data = g_object_new(TYPE_EXCEPTION_DATA, "ex_sign",
            exception_signature, "cl_sign", class_signature, "caught",
            catch_method != NULL,
            NULL);

        if (exception_data) {
            ThriftStructClass* cls = THRIFT_STRUCT_CLASS(EXCEPTION_DATA_GET_CLASS(exception_data));
            cls->write(exception_data, protocol, &error);

            if(tbuffer->buf != NULL) {

                printf("Buffer length %i bytes\n", tbuffer->buf->len);

                send_kafka_message((const void *)tbuffer->buf->data, tbuffer->buf->len);
            }

            g_object_unref(exception_data);
        }

        g_object_unref(protocol);
    }

    if (thrift_transport_is_open(transport)) {
        thrift_transport_close(transport, &error);
    }

    g_object_unref(tbuffer);
}
 类似资料:
  • 好的,我做了更改,下面是我得到的JSON响应 它现在导致一个嵌套异常是java.lang.IllegalArgumentException:参数类型不匹配 NestedServletException:请求处理失败;嵌套异常是java.lang.IllegalArgumentException:参数类型不匹配org.springframework.web.servlet.framework.ser

  • 问题内容: 每当我尝试序列化文件时,都会收到错误消息:FileNotFound。不知道为什么。这是我的FileHelper代码: 问题答案:

  • 问题内容: 我尝试过在Java和Android之间实现跨平台序列化。我使用了Serializable,并将我的代码在Android中与台式机Java放在同一软件包中。 来源:java-desktop序列化 资料来源:Android-反序列化 学生是一类,实现了Serializable。在桌面上,我将学生实例序列化为“ thestudent.dat”。我将此文件放在Android设备上的SD卡上,并

  • 主要内容:1 Java序列化和反序列化,2 Java序列化的优点,3 java.io.Serializable接口,4 Java ObjectOutputStream,5 Java ObjectInputStream,6 Java序列化的例子,7 Java反序列化的例子1 Java序列化和反序列化 Java中的序列化是一种将对象状态写入字节流的机制。它主要用于Hibernate,RMI,JPA,EJB和JMS技术。 序列化的反向操作称为反序列化,其中字节流被转换为对象。序列化和反序列化过程与平台

  • 上一小节我们学习了 Java 的输入输出流,有了这些前置知识点,我们就可以学习 Java 的序列化了。本小节将介绍什么是序列化、什么是反序列化、序列化有什么作用,Serializable 接口以及 Externalizable 接口,常用序列化工具介绍等内容。 1. 序列化与反序列化 序列化在计算机科学的数据处理中,是指将数据结构或对象状态转换成可取用格式,以留待后续在相同或另一台计算机环境中,能

  • 目前,我正在使用Avro1.8.0序列化/反序列化对象,但面临一些问题,特别是java.util.Map对象。不面临其他类型对象的问题。 这里的示例代码- 在deserialize方法中,我试图根据输入数据获取模式,但avro抛出错误- 多谢了。