mayurbm opened a new pull request, #25775:
URL: https://github.com/apache/camel/pull/25775

   ## JIRA
   
   - https://issues.apache.org/jira/browse/CAMEL-24510
   - https://issues.apache.org/jira/browse/CAMEL-24515
   
   ## Supersedes
   
   - PR #25760 (ExchangeHelper per-call-site null guards)
   - PR #25771 (AbstractExchange StoppedTypeConverter sentinel)
   
   ## Problem
   
   `AbstractCamelContext.forceStopLazyInitialization()` set `typeConverter`, 
`typeConverterRegistry` and `injector` to `null` at the tail of `doStop()`. Any 
async work still running on the reactive executor at that point — e.g. a 
Multicast continuation dispatched via `DefaultReactiveExecutor`, a parallel 
Splitter task, or a Quartz SFTP poll — would hit a bare `NullPointerException` 
at one of the ~200 unguarded `getTypeConverter()` call sites across `core/`.
   
   `DefaultReactiveExecutor.doStop()` does no draining (no `awaitTermination`, 
no wait on `getRunningWorkers()`), so async continuations are not guaranteed to 
have finished when the tail of `doStop()` runs — even when graceful route 
shutdown reports success.
   
   ## Fix
   
   Move the three null-and-recreate calls from `forceStopLazyInitialization()` 
to the start of `forceLazyInitialization()`, guarded by `firstStartDone`:
   
   ```java
   protected void forceLazyInitialization() {
       if (firstStartDone) {
           // on restart, null the lazy fields so they are re-created fresh on 
this start
           camelContextExtension.resetInjector();
           camelContextExtension.resetTypeConverterRegistry();
           camelContextExtension.resetTypeConverter();
       }
       // ... existing initialization ...
   }
   
   protected void forceStopLazyInitialization() {
       // intentionally left empty: fields kept alive after stop
       // for in-flight async work; nulled at start of next doStart()
   }
   ```
   
   The fields are now nulled synchronously at the beginning of the **next** 
`doStart()` instead of at the end of `doStop()`:
   - `getTypeConverter()` is never `null` during the stopped/idle window — all 
~200 call sites are fixed at once
   - Restart-in-place (`stop()`/`start()` on the same instance) still works: 
`firstStartDone` ensures resets only run on a genuine restart, not on the first 
start
   - No null-check, guard, or sentinel is needed anywhere
   
   ## Changes
   
   - `AbstractCamelContext.java` — move resets from 
`forceStopLazyInitialization()` to `forceLazyInitialization()` guarded by 
`firstStartDone`
   - `TypeConverterNotNullAfterStopTest.java` — 2 tests: converter non-null 
after stop, restart-in-place works
   
   ## Test plan
   
   - [x] `mvn test -pl core/camel-core 
-Dtest=TypeConverterNotNullAfterStopTest` — Tests run: 2, Failures: 0
   - [x] `mvn formatter:format impsort:sort` — no changes needed
   
   > AI-assisted contribution. Co-authored-by: Claude <[email protected]>


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to