3

I have a question/problem.

I'm sending messages from C++ to Java (Play framework) using RabbitMq. So, in C++ side I used SerializeToString function (also tried SerializeToArray with char* ). ParseFrom doesn't work in Java using String or byte [].

Detail: in my message, I send base64 images, over 500k characters as String. The error is:

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

Messages without base64 strings and other attributes, ParseFrom works ok.

Here the complete error:

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)
Igor Lima
  • 63
  • 1
  • 10
  • 1
    Please read [mcve] and enhance your question accordingly. Most likely, there is a bug in your code. Hard to say when we can't see the relevant parts of that code. – GhostCat May 02 '19 at 14:27

3 Answers3

2

Try testing the code with smaller images, like 50k characters, and see if it works. If the image is over 1 million characters, which is over 2 million bytes, would be an issue, since CodedInputStream$ArrayDecoder.pushLimit gets the first byte as overall number of bytes and int has a limit of positive 2147483647 before overflow, that overflow may be setting the size negative exception.

Leonardo Goes
  • 199
  • 1
  • 10
  • 1
    I tried with a image with 3k characateres, but I got that error: ```[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.]``` – Igor Lima May 02 '19 at 18:12
  • The problem lies on dynamicMethod from RequestOrResponse class, and the exception shows that the first byte of the array that indicate the array size is different from the actual array size. Without the full stacktrace and the piece of code that throws the error, this is as far as we can get. I'd put a breakpoint at line 1542 of RequestOrResponse and check all the variables. – Leonardo Goes May 02 '19 at 18:40
2

Try encode base64 on C++ side and decode in Java side, before ParseFrom.
Read more here

1

I solved the error.

The first thing I did was using a smaller image as @leonardo-goes said, but I got the error:

[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.]

After I tried encoding and deconding as @joão-pedro-bernardino said, and it worked.

Igor Lima
  • 63
  • 1
  • 10