mayur mohan created CAMEL-24510:
-----------------------------------

             Summary: ExchangeHelper.convertToType throws NPE when 
CamelContext.getTypeConverter() is null during shutdown
                 Key: CAMEL-24510
                 URL: https://issues.apache.org/jira/browse/CAMEL-24510
             Project: Camel
          Issue Type: Bug
            Reporter: mayur mohan


h2. Problem

When a typed {{exchange.getProperty(name, Class)}} is called and the stored 
value requires type conversion, {{ExchangeHelper.convertToType()}} calls 
{{exchange.getContext().getTypeConverter().convertTo(...)}}. If 
{{getTypeConverter()}} returns {{null}} (e.g. during CamelContext shutdown, 
OSGi bundle refresh, or context not fully initialized), a bare 
{{NullPointerException}} is thrown with no actionable message.

h2. Root Cause

File: 
{{core/camel-support/src/main/java/org/apache/camel/support/ExchangeHelper.java}}

{code:java}
public static <T> T convertToType(Exchange exchange, Class<T> type, Object 
value)
        throws TypeConversionException {
    return exchange.getContext().getTypeConverter().convertTo(type, exchange, 
value);
}
{code}

No null check on the result of {{getTypeConverter()}}. Typical situations where 
{{getTypeConverter()}} is null:
* CamelContext stopping or restarting while a Quartz poll still runs
* OSGi / Blueprint bundle refresh
* Exchange created or copied without a fully initialized context
* Type converter registry already cleared during shutdown

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.ExchangeHelper.convertToType(ExchangeHelper.java:261)
    at 
org.apache.camel.support.AbstractExchange.getProperty(AbstractExchange.java:321)
    at 
org.apache.camel.support.DefaultExchange.getProperty(DefaultExchange.java:27)
    at 
com.sap.esb.camel.ftp.sap.sftp.component.SapSftpConsumer.isStopOnExceptionEnabled(SapSftpConsumer.java:189)
    at 
com.sap.esb.camel.ftp.sap.sftp.component.SapSftpConsumer.processBatch(SapSftpConsumer.java:172)
    at 
org.apache.camel.component.file.GenericFileConsumer.poll(GenericFileConsumer.java:206)
    at 
com.sap.esb.camel.ftp.sap.sftp.component.SapSftpConsumer.poll(SapSftpConsumer.java:134)
    at 
org.apache.camel.support.ScheduledPollConsumer.doRun(ScheduledPollConsumer.java:202)
    at 
org.apache.camel.support.ScheduledPollConsumer.run(ScheduledPollConsumer.java:116)
    at 
org.apache.camel.pollconsumer.quartz.QuartzScheduledPollConsumerJob.execute(QuartzScheduledPollConsumerJob.java:61)
    at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
    at 
org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
{noformat}

h2. Fix

Add null guards in both {{convertToType}} and {{convertToMandatoryType}}, 
throwing a descriptive {{IllegalStateException}} instead of a bare NPE:

{code:java}
public static <T> T convertToType(Exchange exchange, Class<T> type, Object 
value)
        throws TypeConversionException {
    if (value == null) { return null; }
    if (type != null && type.isInstance(value)) { return type.cast(value); }
    CamelContext ctx = exchange != null ? exchange.getContext() : null;
    TypeConverter converter = ctx != null ? ctx.getTypeConverter() : null;
    if (converter == null) {
        throw new IllegalStateException(
            "Cannot convert from " + value.getClass().getName() + " to " + 
type.getName()
            + " because CamelContext type converter is not available"
            + " (context not started, stopped, or not initialized)");
    }
    return converter.convertTo(type, exchange, value);
}
{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 from java.lang.String to 
java.lang.Boolean because CamelContext type converter is not available (context 
not started, stopped, or not initialized)
{noformat}

h2. PR

https://github.com/apache/camel/pull/TBD



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to