Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow for marshalling the messaging Message<T> payload with an user defined marshaller [SPR-12912] #17511

Closed
spring-issuemaster opened this issue Apr 15, 2015 · 11 comments

Comments

Projects
None yet
2 participants
@spring-issuemaster
Copy link
Collaborator

commented Apr 15, 2015

Stephan Oudmaijer opened SPR-12912 and commented

Sorry for changing this ticket a few times. Took me some time to figure out what I need ;-)

The MessagingMessageListenerAdapter does not allow for a user defined marshaller the the Message payload.

An example:

@JmsListener(destination = "someDestination")
@SendTo("someOtherDestination")
public Message<SomeObjectThatNeedsToBeMarshalledWithJaxb> onMessage(final IncomingMessage message) { ... } 

The SomeObjectThatNeedsToBeMarshalledWithJaxb needs to be marshalled using a MarshallingMessageConverter. Configuring a MessageConverter on the DefaultJmsListenerContainerFactory is not sufficient. Because the MessagingMessageListenerAdapter internally always uses the MessagingMessageConverterAdapter which uses the SimpleMessageConverter internally.


Affects: 4.1.4

Attachments:

Issue Links:

  • #17715 @SendTo does not get converter applied when returning Message

Referenced from: commits 72894b2

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Apr 16, 2015

Stéphane Nicoll commented

It's not clear to me what you're explicitly referring to.

If you configure a MessageConverter on the factory, it will be used by the MessagingMessageConverterAdapter since it simply delegates to the extractMessage method of the adapter. Since you obviously did some debugging yourself can you clarify what you tried (or better yet, provide a sample project that shows the issue).

That being said, I remember Thomas Demande asked something of the kind (i.e. looking at the type of the message to figure out how the converter should be applied). Maybe it's related?

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Apr 16, 2015

Stephan Oudmaijer commented

I have configured the DJLCF like this:

public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() {
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    factory.setMessageConverter(marshallingMessageConverter());
    factory.setDestinationResolver(new BeanFactoryDestinationResolver(applicationContext));
    ...

The DJLCF uses the marshaller just fine for the incoming message. But the result from my Listener is also an object that should be marshalled with the same MarshallingMessageConverter.

I attached a screenshot because (hopefully) it says more than 1000 words.

The screenshot also shows that the destinationResolver of the MessagingMessageListenerAdapter is always of the type DynamicDestinationResolver. Even if I configure a different one on the DJLCF.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Apr 16, 2015

Stéphane Nicoll commented

MessagingMessageConverterAdapter ignores the payload converter.

	/**
	 * Delegates payload extraction to {@link #extractMessage(javax.jms.Message)} to
	 * enforce backward compatibility.
	 */
	private class MessagingMessageConverterAdapter extends MessagingMessageConverter {

		@Override
		protected Object extractPayload(Message message) throws JMSException {
			return extractMessage(message);
		}
	}

I am not denying that you have a problem but it does not correspond to your analysis, that's what I am saying. If I could debug in your app myself that would help a lot.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Apr 17, 2015

Stephan Oudmaijer commented

Hi Stephane,

working on an example project, give me a few minute to put it on github.

Some more info, the actual problem starts in the MessagingMessageListenerAdapter. It calls AbstractAdaptableMessageListener.handleResult(result, jmsMessage, session); which internally calls buildMessage.

At spring-jms-4.1.6.RELEASE-sources.jar!/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java:272 it tries to convert the result to a message using the MessagingMessageConverter. See: 4.1.6.RELEASE/spring-jms-4.1.6.RELEASE-sources.jar!/org/springframework/jms/support/converter/MessagingMessageConverter.java:96

The payloadConverter is of type SimpleMessageConverter, not of type MarshallingMessageConverter. Therefore it fails.

HTH

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Apr 17, 2015

Stéphane Nicoll commented

aaah, gotcha now. It's broken in one way but not the other. Sorry about the back and forth.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Apr 17, 2015

Stephan Oudmaijer commented

Took me some time to actually pinpoint the problem as well :-)

I now also see the other issue in the MessagingMessageListenerAdapter. The MethodJmsListenerEndpoint does not set a destination resolver in the createMessageListener() method. Therefore it always uses the DynamicDestinationResolver defined at spring-jms-4.1.6.RELEASE-sources.jar!/org/springframework/jms/listener/adapter/AbstractAdaptableMessageListener.java:60

You already asked me to create a separate ticket for this issue. But jira was complaining about indexing failures.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Apr 17, 2015

Stéphane Nicoll commented

Yeah, we had some issues with our Jira instance yesterday. Could you please create that issue now so that we cover this as well?

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Apr 17, 2015

Stephan Oudmaijer commented

Done: #17520

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Apr 20, 2015

Stéphane Nicoll commented

This is now fixed and will be available in 4.2.0.BUILD-SNAPSHOT in a moment. Please give that a try.

Juergen Hoeller this is arguably a serious issue for those who are using the Message abstraction as there is no obvious way to work-around the issue (overriding MethodJmsEndpoint might be a way but it's definitely not something one would typically do). For those reasons, it would be great if you could review and consider a backport for 4.1.7. Thanks!

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Apr 20, 2015

Stephan Oudmaijer commented

Validated the fixes (#17510, #17511 and #17520) in the 4.2.0.BUILD-SNAPSHOT, works beautifully! Many thanks.

@spring-issuemaster

This comment has been minimized.

Copy link
Collaborator Author

commented Apr 20, 2015

Stéphane Nicoll commented

Awesome, thanks for testing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.