Skip to content

ProtobufMessageConverter fails to parse JSON payload if byte array is used #27408

Closed
@white-sagittarius

Description

@white-sagittarius

Affects: org.springframework:spring-messaging:5.3.6


We are using org.springframework:spring-messaging:5.3.6 with com.google.protobuf:protobuf-java:3.13.0 and com.google.protobuf:protobuf-java-util:3.13.0 to send and receive protobuf messages as application/json.

static class ProtobufJavaUtilSupport implements ProtobufFormatSupport {
...
@Override
public void merge(org.springframework.messaging.Message<?> message, Charset charset,
		MimeType contentType, ExtensionRegistry extensionRegistry, Message.Builder builder)
		throws IOException, MessageConversionException {

	if (contentType.isCompatibleWith(APPLICATION_JSON)) {
		this.parser.merge(message.getPayload().toString(), builder);
	}
	else {
		throw new MessageConversionException(
				"protobuf-java-util does not support parsing " + contentType);
	}
}
...
}

message.getPayload() returns a byte array (GenericMessage [payload=byte[230], headers={...}]). Calling toString on a byte array produces a string similar to "[B@27fe3806".

Attempt to parse resulting string as JSON produces the following error:

com.google.protobuf.InvalidProtocolBufferException: java.io.EOFException: End of input at line 1 column 12 path $[1]
at com.google.protobuf.util.JsonFormat$ParserImpl.merge (JsonFormat.java:1347)
at com.google.protobuf.util.JsonFormat$Parser.merge (JsonFormat.java:477)
at org.springframework.messaging.converter.ProtobufMessageConverter$ProtobufJavaUtilSupport.merge (ProtobufMessageConverter.java:265)
at org.springframework.messaging.converter.ProtobufMessageConverter.convertFromInternal (ProtobufMessageConverter.java:150)

I assume that byte arrays need special handling so that we use String constructor instead of toString() call in order to get actual JSON content (i.e. something akin to new String(message.getPayload(), StandardCharsets.UTF_8)).

Activity

snicoll

snicoll commented on Sep 26, 2023

@snicoll
Member

I assume that byte arrays need special handling so that we use String constructor instead of toString() call in order to get actual JSON content

Yes although it looks a bit odd to me that the MimeType of the body is application/json and then the actual content of the body is not text. To make sure I am not missing anything, can you please share a small sample that we can run ourselves? You can do so by attaching a zip to this issue or pushing the code to a separate GitHub repository.

spring-projects-issues

spring-projects-issues commented on Oct 3, 2023

@spring-projects-issues
Collaborator

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

spring-projects-issues

spring-projects-issues commented on Oct 10, 2023

@spring-projects-issues
Collaborator

Closing due to lack of requested feedback. If you would like us to look at this issue, please provide the requested information and we will re-open the issue.

gnagy

gnagy commented on Apr 17, 2024

@gnagy
Contributor

Hi, I just ran into this exact same issue on a project. My use case is to read Protobuf messages from Kafka (has ByteArray native payload format) and ProtobufMessageConverter is the only converter configured.

Following the answer here https://stackoverflow.com/questions/70121156/how-to-use-org-springframework-messaging-converter-protobufmessageconverter have subclassed ProtobufMessageConverter.

This works OK for binary protobuf encoding, when content-type: application/x-protobuf is set. The same converter supports JSON encoding (by checking protobufFormatSupport field) when content-type: application/json is set, but fails with the exception described above.

Looking at other MessageConverters, they seem to support multiple payload types, therefore I believe in ProtobufMessageConverter it is a bug.

gnagy

gnagy commented on Apr 17, 2024

@gnagy
Contributor

Another related shortcoming:

If com.google.protobuf:protobuf-java-util is on the classpath, therefore ProtobufMessageConverter.protobufJsonFormatPresent is true, then ProtobufMessageConverter will try to handle content-type: application/json messages, preventing another JSON MessageConverter to handle those. This will fail for cases when protobuf binary and non-protobuf JSON topics are configured within the same app. There is no apparent way to configure the supported mime types in ProtobufMessageConverter.

siaavush

siaavush commented on Jun 25, 2024

@siaavush

I have the exact same problem here

self-assigned this
on Jun 25, 2024
added this to the 6.1.11 milestone on Jun 25, 2024
added a commit that references this issue on Jun 25, 2024
6dd5c85
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

in: messagingIssues in messaging modules (jms, messaging)type: bugA general bug

Type

No type

Projects

No projects

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @bclozel@rstoyanchev@snicoll@gnagy@spring-projects-issues

      Issue actions

        ProtobufMessageConverter fails to parse JSON payload if byte array is used · Issue #27408 · spring-projects/spring-framework