We have just upgraded our Camel project from the version 4.4.0 to the version 4.9.0. And we encountered this error when sending our JMS messages :
java.lang.IllegalArgumentException: Unrecognized Type: [null]
at com.fasterxml.jackson.databind.type.TypeFactory._fromAny(TypeFactory.java:1472)
at com.fasterxml.jackson.databind.type.TypeFactory.constructType(TypeFactory.java:778)
at com.fasterxml.jackson.databind.cfg.MapperConfig.constructType(MapperConfig.java:337)
at com.fasterxml.jackson.databind.ObjectReader.forType(ObjectReader.java:791)
at .apache.camelponent.jackson.AbstractJacksonDataFormat.unmarshal(AbstractJacksonDataFormat.java:203)
at .apache.camel.support.processor.UnmarshalProcessor.process(UnmarshalProcessor.java:85)
at .apache.camel.processor.errorhandler.RedeliveryErrorHandler$RedeliveryTask.doRun(RedeliveryErrorHandler.java:808)
at .apache.camel.processor.errorhandler.RedeliveryErrorHandler$RedeliveryTask.run(RedeliveryErrorHandler.java:714)
at .apache.camel.impl.engine.DefaultReactiveExecutor$Worker.doRun(DefaultReactiveExecutor.java:199)
at .apache.camel.impl.engine.DefaultReactiveExecutor$Worker.executeReactiveWork(DefaultReactiveExecutor.java:189)
at .apache.camel.impl.engine.DefaultReactiveExecutor$Worker.tryExecuteReactiveWork(DefaultReactiveExecutor.java:166)
at .apache.camel.impl.engine.DefaultReactiveExecutor$Worker.schedule(DefaultReactiveExecutor.java:148)
at .apache.camel.impl.engine.DefaultReactiveExecutor.scheduleSync(DefaultReactiveExecutor.java:64)
at .apache.camel.processor.MulticastProcessor.lambda$schedule$1(MulticastProcessor.java:388)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:833)
By debugging the EndpointMessageListener
class of Camel, I have noticed that a JMS header used to deserialize our messages was missing and was used to specify the Class to be used to unmarshall the data : the CamelJacksonUnmarshalType
header.
I've found out that this is due to the JmsHeaderFilterStrategy
class that sets its internal filters in its constructor to filter every JMS Headers beginning with "Camel". In comparison wit the older version 4.4.0 we were using, these filters were null and everything worked fine.
I've tried to change some options in the CamelContext
, but it did nothing.
I'll post in answer how I've overridden this strategy to solve my problem. But if you have a better solution to handle it, don't hesitate to share it.
We have just upgraded our Camel project from the version 4.4.0 to the version 4.9.0. And we encountered this error when sending our JMS messages :
java.lang.IllegalArgumentException: Unrecognized Type: [null]
at com.fasterxml.jackson.databind.type.TypeFactory._fromAny(TypeFactory.java:1472)
at com.fasterxml.jackson.databind.type.TypeFactory.constructType(TypeFactory.java:778)
at com.fasterxml.jackson.databind.cfg.MapperConfig.constructType(MapperConfig.java:337)
at com.fasterxml.jackson.databind.ObjectReader.forType(ObjectReader.java:791)
at .apache.camelponent.jackson.AbstractJacksonDataFormat.unmarshal(AbstractJacksonDataFormat.java:203)
at .apache.camel.support.processor.UnmarshalProcessor.process(UnmarshalProcessor.java:85)
at .apache.camel.processor.errorhandler.RedeliveryErrorHandler$RedeliveryTask.doRun(RedeliveryErrorHandler.java:808)
at .apache.camel.processor.errorhandler.RedeliveryErrorHandler$RedeliveryTask.run(RedeliveryErrorHandler.java:714)
at .apache.camel.impl.engine.DefaultReactiveExecutor$Worker.doRun(DefaultReactiveExecutor.java:199)
at .apache.camel.impl.engine.DefaultReactiveExecutor$Worker.executeReactiveWork(DefaultReactiveExecutor.java:189)
at .apache.camel.impl.engine.DefaultReactiveExecutor$Worker.tryExecuteReactiveWork(DefaultReactiveExecutor.java:166)
at .apache.camel.impl.engine.DefaultReactiveExecutor$Worker.schedule(DefaultReactiveExecutor.java:148)
at .apache.camel.impl.engine.DefaultReactiveExecutor.scheduleSync(DefaultReactiveExecutor.java:64)
at .apache.camel.processor.MulticastProcessor.lambda$schedule$1(MulticastProcessor.java:388)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:833)
By debugging the EndpointMessageListener
class of Camel, I have noticed that a JMS header used to deserialize our messages was missing and was used to specify the Class to be used to unmarshall the data : the CamelJacksonUnmarshalType
header.
I've found out that this is due to the JmsHeaderFilterStrategy
class that sets its internal filters in its constructor to filter every JMS Headers beginning with "Camel". In comparison wit the older version 4.4.0 we were using, these filters were null and everything worked fine.
I've tried to change some options in the CamelContext
, but it did nothing.
I'll post in answer how I've overridden this strategy to solve my problem. But if you have a better solution to handle it, don't hesitate to share it.
Share Improve this question asked Jan 29 at 10:26 AnthonyAtVIFAnthonyAtVIF 114 bronze badges1 Answer
Reset to default 0Here is one working solution I've found to solve my problem.
In my Spring configuration, I've overridden the header filter strategy.
public class ContextConfig extends CamelConfiguration {
@Override
protected void setupCamelContext(CamelContext camelContext) throws Exception {
super.setupCamelContext(camelContext);
var jmsComponent = (JmsComponent) camelContext.getComponent("jms", false, false);
// Override the default Jms Header filter strategy. See in the CustomHeaderFilterStrategy class why.
jmsComponent.setHeaderFilterStrategy(new CustomHeaderFilterStrategy());
}
}
And here is the CustomHeaderFilterStrategy
class :
/**
* Override of the default {@link JmsHeaderFilterStrategy} to avoid problems introduced between versions 4.5.0 and
* 4.9.0. In version 4.4.0, where everything worked well, the
* {@link .apache.camelponent.jms.EndpointMessageListener} was using its bindings to create the exchange object
* and its internal "in" attribute, which contains all the jms headers sent. When we upgraded to the version 4.9.0, we
* noticed that the "CamelJacksonUnmarshalType" header was missing after initializing the exchange object, and this was
* due to the new header filter strategy. In the In and Out filters, everything beginning with "Camel", "camel", or
* ".apache.camel" was filtered by default. See the constructor of {@link JmsHeaderFilterStrategy}, and the
* {@link .apache.camel.support.DefaultHeaderFilterStrategy}.CAMEL_FILTER_STARTS_WITH constant where these new
* filters are defined. For information, both inFilterStartsWith and outFilterStartsWith attributes were null in 4.4.0.
*/
public class CustomHeaderFilterStrategy extends JmsHeaderFilterStrategy {
public CustomHeaderFilterStrategy() {
this(false);
}
protected CustomHeaderFilterStrategy(boolean includeAllJMSXProperties) {
// We force these filters to be null to retrieve the behavior of the Camel version 4.4.0
String[] nullPattern = null;
this.setInFilterStartsWith(nullPattern); // cannot directly set to be null, otherwise it creates an array with null,
this.setOutFilterStartsWith(nullPattern); // and an array with null -> [null] would break the filter strategy !
if (!includeAllJMSXProperties) {
// We keep these default JMS filters, because they were there in the version 4.4.0 of Camel
this.initialize();
}
}
}
With that, we ensure the header CamelJacksonUnmarshalType
is kept during the creation of the Exchange
object in the EndpointMessageListener
, and our message is properly unmarshalled.