[ 
https://issues.apache.org/jira/browse/CAMEL-25506?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Work on CAMEL-25506 started by shashank.
----------------------------------------
> camel-lucene - concurrent queries can get another query's hits, and queries 
> fail after the route is restarted
> -------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-25506
>                 URL: https://issues.apache.org/jira/browse/CAMEL-25506
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-lucene
>            Reporter: shashank
>            Assignee: shashank
>            Priority: Major
>
> {{LuceneQueryProducer}} creates one {{LuceneSearcher}} in {{doStart()}} and 
> uses it for every exchange (Camel producers are shared by concurrent 
> exchanges). {{LuceneSearcher}} keeps the state of a query in fields (main 
> c578a42a776d): {{open()}} assigns {{indexReader}} and {{indexSearcher}} 
> (lines 47-51) and {{doSearch()}} assigns {{hits}} (line 94), which 
> {{search()}} then iterates (line 71). So:
> * two exchanges querying at the same time can get each other's results: one 
> exchange assigns {{hits}} between the other's search and its loop over 
> {{hits}}. In the test below, 27 to 48 of 20000 queries (8 threads, two terms) 
> returned the hits of the other term on main;
> * every query opens a new {{DirectoryReader}} and only the one in the field 
> when the producer stops is closed; the others are left to the garbage 
> collector;
> * {{LuceneQueryProducer.doStop()}} calls {{LuceneSearcher.close()}}, which 
> closes the endpoint's {{Analyzer}} (the configured bean or the endpoint's 
> default). After the route is stopped and started again, every query fails 
> with {{org.apache.lucene.store.AlreadyClosedException: this Analyzer is 
> closed}} until the CamelContext is restarted; when the route had not run a 
> query yet, the stop fails with a {{NullPointerException}} ({{indexReader}} is 
> null), logged as a WARN by the shutdown strategy.
> {{LuceneQueryProcessor}} has the same reader handling (a new searcher in a 
> shared field per exchange, never closed).
> h3. Reproduction
> New {{LuceneQueryProducerLifecycleTest}} (an index of 20 "alpha" and 20 
> "beta" documents built in {{@BeforeEach}}, a route {{direct:query}} to 
> {{lucene:queryIndex:query}}):
> * {{queryWorksAfterRouteRestart}} (deterministic): on main {{a query after 
> the route was restarted must succeed ==> expected: <null> but was: 
> <org.apache.lucene.store.AlreadyClosedException: this Analyzer is closed>}}.
> * {{concurrentQueriesGetTheirOwnHits}} (20000 queries on 8 threads, about 2 
> s; it cannot force the interleaving, it makes it very likely): on main {{each 
> query must get the hits of its own query, but 39 of 20000 did not, e.g. 
> [alpha: got hit 'beta document 0', ...]}}; it failed in all six runs on main 
> (27 to 48 wrong answers) and passed in every run with the fix.
> h3. Proposed fix
> Each exchange uses its own {{LuceneSearcher}} ({{open}}, {{search}}, 
> {{close}} in a {{finally}}); the producer no longer keeps one, so 
> {{doStart}}/{{doStop}} are gone. {{LuceneSearcher.close()}} closes only its 
> reader (null-safe), not the analyzer, which belongs to the endpoint or the 
> registry. {{LuceneQueryProcessor}} does the same (no dedicated test; 
> {{LuceneQueryProcessorIT}} passes). Code that calls {{LuceneSearcher}} 
> directly now has to close its analyzer itself. The {{Hits}} hold the stored 
> values (and the {{Document}} when requested), so closing the reader after 
> building them is safe; the existing ITs still pass. camel-lucene tests with 
> the fix: {{LuceneQueryProducerLifecycleTest}} 2, 
> {{LuceneIndexAndQueryProducerIT}} 4, {{LuceneQueryProcessorIT}} 2, 0 failures.
> Found with a TLA+ model of the producer and searcher (one action per field 
> read/write: open reader, create searcher, collect hits, iterate hits; route 
> stop/start): "every answer holds the hits of its own query" is violated in 7 
> steps with two threads, "no reader is left open after the stop" in 12 steps 
> with one thread and two queries, and "no query runs on a closed analyzer" in 
> 9 steps (query, stop, start, query). With the fix all properties hold for 2 
> and 3 threads and a restart. Then confirmed with the real component as above.
> Affected: main, camel-4.22.x, camel-4.18.x, camel-4.14.x (same code, GitHub 
> contents API; unchanged since 2.x).
> Duplicate check (2026-10-09): JIRA component camel-lucene (8 issues, all 
> upgrades or naming), text "LuceneSearcher" (4, upgrades), "this Analyzer is 
> closed" (none); GitHub pull requests "camel-lucene": none about the producers.
> _Filed with Claude Code on behalf of allthingssecurity._



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

Reply via email to