【问题标题】:Failing ParseFrom messages in java from C++来自 C++ 的 java 中的 ParseFrom 消息失败
【发布时间】:2019-05-02 14:24:01
【问题描述】:

我有一个问题/问题。

我正在使用 RabbitMq 从 C++ 向 Java(Play 框架)发送消息。因此,在 C++ 方面,我使用了 SerializeToString 函数(也尝试了 SerializeToArraychar* )。 ParseFrom 在使用 Stringbyte [] 的 Java 中不起作用。

详细信息:在我的消息中,我发送 base64 图像,超过 500k 个字符为String。错误是:

CodedInputStream encountered an embedded string or message which claimed to have negative size

没有 base64 字符串和其他属性的消息,ParseFrom 工作正常。

这里是完整的错误:

play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[InvalidProtocolBufferException: CodedInputStream encountered an embedded string or message which claimed to have negative size.]]
    at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:323)
    at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:243)
    at play.core.server.AkkaHttpServer$$anonfun$1.applyOrElse(AkkaHttpServer.scala:382)
    at play.core.server.AkkaHttpServer$$anonfun$1.applyOrElse(AkkaHttpServer.scala:380)
    at scala.concurrent.Future.$anonfun$recoverWith$1(Future.scala:417)
    at scala.concurrent.impl.Promise.$anonfun$transformWith$1(Promise.scala:41)
    at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:64)
    at akka.dispatch.BatchingExecutor$AbstractBatch.processBatch(BatchingExecutor.scala:55)
    at akka.dispatch.BatchingExecutor$BlockableBatch.$anonfun$run$1(BatchingExecutor.scala:91)
    at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23)
Caused by: com.google.protobuf.InvalidProtocolBufferException: CodedInputStream encountered an embedded string or message which claimed to have negative size.
    at com.google.protobuf.InvalidProtocolBufferException.negativeSize(InvalidProtocolBufferException.java:92)
    at com.google.protobuf.CodedInputStream$ArrayDecoder.pushLimit(CodedInputStream.java:1179)
    at com.google.protobuf.CodedInputStream$ArrayDecoder.readMessage(CodedInputStream.java:881)
    at model.RequestOrResponse$Response.dynamicMethod(RequestOrResponse.java:1542)
    at com.google.protobuf.GeneratedMessageLite.parsePartialFrom(GeneratedMessageLite.java:1597)
    at com.google.protobuf.GeneratedMessageLite.parsePartialFrom(GeneratedMessageLite.java:1630)
    at com.google.protobuf.GeneratedMessageLite.parseFrom(GeneratedMessageLite.java:1746)
    at model.RequestOrResponse$Response.parseFrom(RequestOrResponse.java:1232)
    at controllers.SubjectController.get(SubjectController.java:195)
    at router.Routes$$anonfun$routes$1.$anonfun$applyOrElse$14(Routes.scala:187)

【问题讨论】:

  • 请阅读minimal reproducible example 并相应地增强您的问题。很可能,您的代码中存在错误。很难说我们什么时候看不到该代码的相关部分。

标签: java c++ rabbitmq base64 protocol-buffers


【解决方案1】:

ParseFrom之前尝试在C++端编码base64并在Java端解码。
阅读更多here

【讨论】:

    【解决方案2】:

    尝试使用较小的图像(例如 50k 个字符)测试代码,看看它是否有效。如果图像超过 100 万个字符,即超过 200 万个字节,这将是一个问题,因为 CodedInputStream$ArrayDecoder.pushLimit 将第一个字节作为总字节数,而 int 在溢出前的限制为正 2147483647,则该溢出可能设置大小负异常。

    【讨论】:

    • 我尝试使用具有 3k 个字符的图像,但我得到了那个错误:[InvalidProtocolBufferException: While parsing a protocol message, the input ended unexpectedly in the middle of a field. This could mean either that the input has been truncated or that an embedded message misreported its own length.]
    • 问题出在RequestOrResponse类的dynamicMethod上,异常显示表示数组大小的数组第一个字节与实际数组大小不同。如果没有完整的堆栈跟踪和抛出错误的代码,这是我们所能得到的。我会在 RequestOrResponse 的第 1542 行放置一个断点并检查所有变量。
    【解决方案3】:

    我解决了这个错误。

    正如@leonardo-goes 所说,我做的第一件事是使用较小的图像,但我得到了错误:

    [InvalidProtocolBufferException: While parsing a protocol message, the input ended unexpectedly in the middle of a field. This could mean either that the input has been truncated or that an embedded message misreported its own length.]

    在我按照@joão-pedro-bernardino 所说的那样尝试编码和解码之后,它奏效了。

    【讨论】:

      猜你喜欢
      • 2019-08-29
      • 2013-12-04
      • 2016-12-23
      • 1970-01-01
      • 2019-08-03
      • 2016-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多