[
https://issues.apache.org/jira/browse/CAMEL-24515?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
mayur mohan updated CAMEL-24515:
--------------------------------
Superseded by CAMEL-24516 / https://github.com/apache/camel/pull/25775 which
fixes the root cause at source rather than at individual call sites.
> AbstractExchange.getIn(Class) and getOut(Class) throw NPE when
> CamelContext.getTypeConverter() is null during shutdown
> ----------------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-24515
> URL: https://issues.apache.org/jira/browse/CAMEL-24515
> Project: Camel
> Issue Type: Bug
> Reporter: mayur mohan
> Priority: Minor
> Labels: camel-support, diagnostic
>
> h2. Problem
> {{AbstractExchange.getIn(Class<T>)}} and
> {{AbstractExchange.getOut(Class<T>)}} call
> {{context.getTypeConverter().convertTo(...)}} directly without a null guard.
> When {{CamelContext}} is shutting down,
> {{DefaultCamelContextExtension.resetTypeConverter()}} sets the type converter
> to {{null}} during {{forceStopLazyInitialization()}}. Any thread that calls
> these methods during that window gets a bare {{NullPointerException}} with no
> actionable message.
> This is the same race condition as CAMEL-24510 (fixed in
> {{ExchangeHelper.convertToType}}), but affecting two additional call sites in
> {{AbstractExchange}} that bypass {{ExchangeHelper}} entirely.
> h2. Root Cause
> File:
> {{core/camel-support/src/main/java/org/apache/camel/support/AbstractExchange.java}}
> Line ~499 (getIn):
> {code:java}
> return context.getTypeConverter().convertTo(type, this, in);
> {code}
> Line ~553 (getOut):
> {code:java}
> return context.getTypeConverter().convertTo(type, this, out);
> {code}
> Note: {{getOut(Class<T>)}} is called from {{getMessage(Class<T>)}} which is
> used broadly by Camel processors and scripts.
> h2. Stack Trace
> {noformat}
> java.lang.NullPointerException: Cannot invoke
> "org.apache.camel.TypeConverter.convertTo(java.lang.Class,
> org.apache.camel.Exchange, Object)"
> because the return value of
> "org.apache.camel.CamelContext.getTypeConverter()" is null
> at
> org.apache.camel.support.AbstractExchange.getOut(AbstractExchange.java:548)
> at
> org.apache.camel.support.DefaultExchange.getOut(DefaultExchange.java:27)
> at
> org.apache.camel.support.AbstractExchange.getMessage(AbstractExchange.java:569)
> at
> org.apache.camel.support.DefaultExchange.getMessage(DefaultExchange.java:27)
> at
> com.sap.gateway.ip.core.customdev.processor.IGWScriptProcessor.setAllAttachments(IGWScriptProcessor.java:595)
> at
> com.sap.gateway.ip.core.customdev.processor.IGWScriptProcessor.process(IGWScriptProcessor.java:305)
> at jdk.internal.reflect.GeneratedMethodAccessor3818.invoke(Unknown Source)
> at
> java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> at java.base/java.lang.reflect.Method.invoke(Method.java:569)
> at
> org.apache.camel.support.ObjectHelper.invokeMethodSafe(ObjectHelper.java:403)
> at org.apache.camel.component.bean.MethodInfo.invoke(MethodInfo.java:494)
> at
> org.apache.camel.component.bean.MethodInfo$1.doProceed(MethodInfo.java:316)
> at
> org.apache.camel.component.bean.MethodInfo$1.proceed(MethodInfo.java:286)
> at
> org.apache.camel.component.bean.AbstractBeanProcessor.process(AbstractBeanProcessor.java:146)
> at
> org.apache.camel.component.bean.BeanProcessor.process(BeanProcessor.java:81)
> at
> org.apache.camel.support.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:104)
> at
> com.sap.it.op.agent.collector.camel.MplInterceptor$MplAsyncProcessor.process(MplInterceptor.java:290)
> at
> org.apache.camel.support.processor.DelegateAsyncProcessor.process(DelegateAsyncProcessor.java:104)
> at
> org.apache.camel.processor.errorhandler.RedeliveryErrorHandler$SimpleTask.run(RedeliveryErrorHandler.java:477)
> at
> org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.executeFromQueue(DefaultReactiveExecutor.java:224)
> at
> org.apache.camel.impl.engine.DefaultReactiveExecutor.executeFromQueue(DefaultReactiveExecutor.java:82)
> at
> org.apache.camel.impl.engine.DefaultAsyncProcessorAwaitManager.await(DefaultAsyncProcessorAwaitManager.java:96)
> at
> org.apache.camel.impl.engine.DefaultAsyncProcessorAwaitManager.process(DefaultAsyncProcessorAwaitManager.java:85)
> at
> org.apache.camel.processor.MulticastProcessor$MulticastReactiveTask.lambda$run$1(MulticastProcessor.java:664)
> at
> org.apache.camel.util.concurrent.AsyncCompletionService$Task.run(AsyncCompletionService.java:162)
> at
> org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.schedule(DefaultReactiveExecutor.java:193)
> at
> org.apache.camel.impl.engine.DefaultReactiveExecutor.schedule(DefaultReactiveExecutor.java:59)
> at
> org.apache.camel.processor.MulticastProcessor.lambda$schedule$1(MulticastProcessor.java:392)
> 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:840)
> {noformat}
> h2. Fix
> Add null guard on the {{TypeConverter}} in both methods, throwing
> {{IllegalStateException}} with a descriptive message instead of bare NPE:
> {code:java}
> TypeConverter tc = context.getTypeConverter();
> if (tc == null) {
> throw new IllegalStateException(
> "Cannot convert message body to " + type.getName()
> + " because CamelContext type converter is not available"
> + " (context not started, stopped, or not initialized)");
> }
> return tc.convertTo(type, this, in);
> {code}
> h2. Before / After
> *Before:*
> {noformat}
> NullPointerException: Cannot invoke "TypeConverter.convertTo(...)" because
> the return value of "CamelContext.getTypeConverter()" is null
> {noformat}
> *After:*
> {noformat}
> IllegalStateException: Cannot convert message body to java.lang.String
> because CamelContext type converter is not available (context not started,
> stopped, or not initialized)
> {noformat}
> h2. Related
> CAMEL-24510 / PR #25760 -- same fix for {{ExchangeHelper.convertToType()}}
> and {{convertToMandatoryType()}}
> h2. PR
> https://github.com/apache/camel/pull/25771
--
This message was sent by Atlassian Jira
(v8.20.10#820010)