[
https://issues.apache.org/jira/browse/CAMEL-24104?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Claus Ibsen resolved CAMEL-24104.
---------------------------------
Resolution: Fixed
> camel-bean: racy lazy Processor-adapter lookup in AbstractBeanProcessor
> (non-volatile fields, no retry on conversion failure)
> -----------------------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-24104
> URL: https://issues.apache.org/jira/browse/CAMEL-24104
> Project: Camel
> Issue Type: Bug
> Components: camel-bean
> Affects Versions: 4.21.0
> Reporter: Federico Mariani
> Assignee: Claus Ibsen
> Priority: Minor
> Fix For: 4.22.0
>
>
> {{AbstractBeanProcessor.getCustomAdapter()}} lazily resolves a custom
> {{Processor}} adapter for the bean via type conversion, guarded by:
> {code:java}
> private transient Processor processor;
> private transient boolean lookupProcessorDone;
> ...
> Processor target = getProcessor(); // plain read, no lock
> if (target == null) {
> if (allowCache) {
> if (!lookupProcessorDone) { // plain read, no lock
> lock.lock();
> try {
> lookupProcessorDone = true; // set BEFORE conversion
> target = ...tryConvertTo(Processor.class, exchange, beanTmp);
> processor = target;
> } finally { lock.unlock(); }
> }
> }
> {code}
> Two issues:
> # {{lookupProcessorDone}} and {{processor}} are *non-volatile* and read
> outside the lock. A racing thread can observe {{lookupProcessorDone == true}}
> while still reading a stale {{null}} {{processor}} → that exchange silently
> falls back to bean-binding method invocation instead of the custom
> {{Processor}} adapter (different invocation semantics for that message).
> There is also no double-check of {{lookupProcessorDone}} after acquiring the
> lock, so two threads racing before the flag is visible both perform the
> conversion (benign, but shows the guard is not doing its job).
> # {{lookupProcessorDone = true}} is set *before* {{tryConvertTo}}; if the
> conversion throws, the adapter lookup is permanently disabled without retry.
> Suggested fix: make both fields {{volatile}} (or do the whole
> check-and-populate under the lock with a re-check), and set the flag after
> the conversion succeeds.
> No test attached — the visibility race is not deterministically reproducible
> in a unit test; the defect is evident from the field declarations and access
> pattern in {{AbstractBeanProcessor.java}}.
> _This issue was found by an AI-assisted code review. Reported by Claude Code
> on behalf of [~fmariani] (GitHub: Croway)._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)