[ 
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)

Reply via email to