You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@camel.apache.org by "Federico Mariani (Jira)" <ji...@apache.org> on 2026/07/16 13:20:00 UTC

[jira] [Created] (CAMEL-24184) camel-cxf - Umbrella: medium-severity findings from July 2026 code review

Federico Mariani created CAMEL-24184:
----------------------------------------

             Summary: camel-cxf - Umbrella: medium-severity findings from July 2026 code review
                 Key: CAMEL-24184
                 URL: https://issues.apache.org/jira/browse/CAMEL-24184
             Project: Camel
          Issue Type: Task
          Components: camel-cxf
            Reporter: Federico Mariani
            Assignee: Federico Mariani


Umbrella tracking the *medium-severity* findings from the July 2026 AI-assisted code review of the {{components/camel-cxf/}} component family. The high-severity findings are filed as separate linked issues. Each item below has been verified against current source and git history; items marked *[verified]* were additionally re-read line-by-line on {{main}}.

h2. camel-cxf-soap / camel-cxf-common
# *replaceMultiPartContentType strips 5 extra characters* _[verified]_ - {{DefaultCxfBinding.java:~869}}: for an unquoted {{type=}} parameter the value has {{type=}} removed, then {{substring(5)}} is applied again, so {{type=text/xml}} becomes {{xml}}. Corrupts the propagated {{Content-Type}} for unquoted MTOM/multipart responses. Fix: {{result = part;}} in the else branch.
# *CxfClientCallback NPE when out message absent* - {{CxfClientCallback.java:~88-97}}: with a failover {{ConduitSelector}} and a transport error before the out message exists, {{cxfExchange.getOutMessage().getContent(..)}} NPEs and replaces the real exception. Fix: null-guard the out message.
# *populateCxfHeaderFromCamelExchangeBeforeCheckError is a no-op* - {{DefaultCxfBinding.java:~456-479}}: called before the out message is created, so its guarded {{put}} is skipped and response protocol headers are never propagated onto a fault response. Fix: create/lookup the out (or fault) message first, or move propagation into the fault path.
# *Unsynchronized lazy Bus creation* - {{CxfEndpoint.java:~1015-1047}}: the {{bus}} field is non-volatile; concurrent producer/consumer {{doStart}} can each create a Bus and leak one. Fix: volatile + double-checked locking, or init in {{doInit}}.

h2. camel-cxf-rest
# *Void.class vs Void.TYPE in CxfRsInvoker* _[verified]_ - {{CxfRsInvoker.java:~165}}: {{method.getReturnType() == Void.class}} is false for {{void}} methods ({{void.class}}), so {{InOnly}} is never selected; a {{void}} resource method's route result leaks back as a response body. Fix: test {{Void.TYPE || Void.class}} (verify the MEP change before shipping).
# *Void.class confusion in SubResourceClassInvocationHandler* - {{SubResourceClassInvocationHandler.java:~33}}: {{void}} methods fall into {{findResourceConstructor(void.class)}} -> NPE instead of returning null. Fix: {{returnType != Void.TYPE && returnType != Void.class}}.
# *Async http-API leaks the JAX-RS Response for InOnly exchanges* - {{CxfRsProducer.java:~708-710}}: the sync path closes the {{Response}} for non-out-capable exchanges; the async {{completed()}} returns without closing, pinning connections under keep-alive. Fix: {{response.close()}} in the InOnly branch.
# *Multi-valued Camel headers flattened via toString()* - {{CxfHeaderHelper.java:~105}} (via {{DefaultCxfRsBinding.bindCamelHeadersToRequestHeaders}}): a {{List}}-valued header is serialized as the literal {{"[a, b]"}}. The sibling {{propagateCamelToCxf}} handles {{List}} correctly. Fix: add each list element to the multivalued map.
# *Inbound protocol headers keep only the first value* - {{DefaultCxfRsBinding.java:~333}}; producer error headers {{CxfRsProducer.java:~655}}: {{get(0)}} drops repeated headers (e.g. multiple {{Set-Cookie}}) into {{CxfOperationException.headers}} and the consumer header map. Fix: reuse {{convertCxfProtocolHeaderValues}}.
# *setProtocolHeaders NPE when CXF out message absent* - {{DefaultCxfRsBinding.java:~127-146}}: the null-guard covers only the {{putIfAbsent}}; the following {{getOutMessage().get(..)}} is unguarded (oneway/fault paths). Also {{ObjectHelper.isEmpty(cxfExchange)}} tests map-emptiness, not nullness. Fix: hoist a single out-message null check.
# *CxfConverter fallback NPEs on a Response with null entity* - {{CxfConverter.java:~221-232}}: {{entity.getClass()}} with no null check; a 204/empty {{Response}} throws inside the type converter. Separately, {{toStreamCache}} ({{~135}}) never closes the {{Response}} -> connection held until GC. Fix: null-check entity -> return {{MISS_VALUE}}; close the {{Response}} after caching.

h2. camel-cxf-transport
# *CamelConduit producer leak / use-after-stop race* - {{CamelConduit.java:~77-84,108-117}}: the producer is created+started in the constructor, stopped only in {{close()}}; an abandoned conduit leaks it, and an in-flight {{asyncInvokeFromWorkQueue}} can call {{producer.process}} after {{close()}} stopped it. Fix: guard against use-after-stop; consider lazy producer acquisition.
# *asyncInvokeFromWorkQueue NPE when no fault observer* - {{CamelOutputStream.java:~133-140}}: if both {{getFaultObserver()}} and {{exchange.get(MessageObserver.class)}} are null, {{mo.onMessage}} NPEs on a work-queue thread and loses the original exception; the chain is also cast to {{PhaseInterceptorChain}} without a null check. Fix: null-check both.
# *getBasePath regex fallback is fragile* - {{DefaultCxfMessageMapper.java:~149-159}}: the second {{replaceFirst}} can never fire after the first; non-HTTP front endpoints ({{direct:}}, {{jms:}}) leave the raw Camel URI as the SOAP BASE_PATH, breaking {{convertPathInfo}} path stripping. Fix: only rewrite when the URI is actually http(s).

h2. camel-cxf-spring-*
# *CAMEL-18528 graceful bus shutdown is dead code in the standard XML path* - {{CxfSpringEndpoint.java:~285-299}}: {{enableSpringBusShutdownGracefully}} is only reachable from {{getBus()}}'s {{bus == null}} branch, but {{setApplicationContext}} always assigns the bus first, so it never runs on the first lifecycle; in-flight SOAP calls still fail on abrupt bus shutdown - the exact scenario CAMEL-18528 claims to fix.
# *enableSpringBusShutdownGracefully removes an arbitrary listener and spawns a thread per event* - {{CxfSpringEndpoint.java:~310-359}}: keeps the last matching {{SpringBus}} listener, so with multiple buses it can unhook a different bus (leak) and double-fire this one; also starts {{new Thread()}} for every {{ApplicationEvent}}. Fix: match by bus identity; only spawn for {{ContextClosedEvent}}.
# *performInvocation not propagated to SpringJAXRSServerFactoryBean* - {{SpringJAXRSServerFactoryBean.java:~119-133}}: the bean reads its own always-false field, not the endpoint's, so interface-model resources aren't filtered in the Spring variant. Fix: propagate {{isPerformInvocation()}} before server creation.
# *SpringJAXRSServerFactoryBean missing the setProperties merge override* - {{SpringJAXRSServerFactoryBean.java:~110-117}}: the client bean merges, the server bean uses CXF's replace-semantics, so a {{<cxf:properties>}} element wipes the {{NullFaultListener}} installed by {{skipFaultLogging="true"}}. Fix: add the same merging override.
# *CxfRsSpringEndpoint hard-casts CamelContext to SpringCamelContext* - {{CxfRsSpringEndpoint.java:~51}} (selection in {{CxfRsComponent.java:~130-139}}): a camel-main/{{DefaultCamelContext}} app with the module on the classpath gets a {{ClassCastException}} instead of falling back to the default factory. Fix: gate the Spring factory on {{instanceof SpringCamelContext}}.

----
Note: two additional security-flavoured findings from the same review (an inbound header-filter prefix gap and a transport header-map bypass) are being handled through the ASF private security process and are intentionally not listed here.

----
_Filed by Claude Code (Claude Fable) on behalf of Federico Mariani (GitHub: Croway). Findings from an AI-assisted code review of the camel-cxf component family; each item was verified against the current source and git history. Items marked *[reproducer attached]* include a failing JUnit test that demonstrates the defect._



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