3
votes

Échec des messages ParseFrom en java à partir de C ++

J'ai une question / un problème.

J'envoie des messages de C ++ vers Java (framework Play) en utilisant RabbitMq. Donc, côté C ++, j'ai utilisé la fonction SerializeToString (j'ai également essayé SerializeToArray avec char * ). ParseFrom ne fonctionne pas en Java en utilisant String ou byte [] .

Détail: dans mon message, j'envoie des images base64 de plus de 500k caractères comme Chaîne . L'erreur est:

CodedInputStream a rencontré une chaîne ou un message incorporé qui prétendait avoir une taille négative

Messages sans chaînes base64 et autres attributs, ParseFrom fonctionne bien.

Voici l'erreur complète:

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)


1 commentaires

Veuillez lire exemple minimal reproductible et enrichir votre question en conséquence. Très probablement, il y a un bogue dans votre code. Difficile à dire quand nous ne pouvons pas voir les parties pertinentes de ce code.


3 Réponses :


2
votes

Essayez de tester le code avec des images plus petites, comme 50 000 caractères, et voyez si cela fonctionne. Si l'image contient plus d'un million de caractères, soit plus de 2 millions d'octets, cela poserait un problème, car CodedInputStream $ ArrayDecoder.pushLimit obtient le premier octet en tant que nombre total d'octets et int a une limite positive de 2147483647 avant le dépassement, ce dépassement peut définir l'exception de taille négative.


2 commentaires

J'ai essayé avec une image avec des caractères 3k, mais j'ai eu cette erreur: [InvalidProtocolBufferException: Lors de l'analyse d'un message de protocole, l'entrée s'est terminée de manière inattendue au milieu d'un champ. Cela peut signifier que l'entrée a été tronquée ou qu'un message intégré a mal rapporté sa propre longueur.]


Le problème réside dans dynamicMethod de la classe RequestOrResponse, et l'exception montre que le premier octet du tableau qui indique la taille du tableau est différent de la taille réelle du tableau. Sans le stacktrace complet et le morceau de code qui génère l'erreur, c'est tout ce que nous pouvons obtenir. Je mettrais un point d'arrêt à la ligne 1542 de RequestOrResponse et vérifierais toutes les variables.



2
votes

Essayez d'encoder base64 côté C ++ et de décoder côté Java, avant ParseFrom .
En savoir plus ici


0 commentaires

1
votes

J'ai résolu l'erreur.

La première chose que j'ai faite a été d'utiliser une image plus petite comme @ leonardo-go l'a dit, mais j'ai eu l'erreur:

[InvalidProtocolBufferException: Lors de l'analyse d'un message de protocole, l'entrée s'est terminée de manière inattendue au milieu d'un champ. Cela peut signifier que l'entrée a été tronquée ou qu'un message incorporé a mal signalé sa propre longueur.]

Après avoir essayé d'encoder et de décoller comme l'a dit @ joão-pedro-bernardino, et cela a fonctionné.


0 commentaires