thiagoelg opened a new pull request, #7107: URL: https://github.com/apache/incubator-kie/pull/7107
**Thank you for submitting this pull request** **NOTE!:** Double-check the target branch for this PR. The default is `main`. **Ports** If a forward-port or a backport is needed, paste the forward port PR here * n/a **Issue**: _(please edit the GitHub Issues link if it exists)_ * https://github.com/apache/incubator-kie/issues/7106 **Referenced Pull Requests**: _(please edit the URLs of referenced pull requests if they exist)_ * https://github.com/apache/incubator-kie-kogito-runtimes/pull/3870 (context only — see "Relationship to #3870" below) --- ## What this fixes `KogitoBeanProducer` produced the CDI `UnitOfWorkManager` bean by returning the JVM-wide static singleton `StaticUnitOfWorkManger.staticUnitOfWorkManager()`. That class comes from a dependency JAR, so Quarkus loads it with the base runtime ClassLoader, which a dev-mode live reload does not recreate. The manager — and the `BaseEventManager` inside it — therefore outlives the application it belongs to. Every restart, `AbstractProcessConfig` registers the new generation's `EventPublisher`s and `UnitOfWorkEventListener`s on that same manager, and both `addPublisher` and `register` are add-only. The publisher set grows by one per reload, and `publish()` then calls publishers belonging to applications that were shut down long ago. Those hold an `EntityManagerFactory` that was closed on their own shutdown, which surfaces as `IllegalStateException: EntityManagerFactory is closed`. Measured across five consecutive dev-mode generations — `Application` is correctly recreated each time, the manager never is, and the publisher count grows monotonically: | Start | `Application` | `UnitOfWorkManager` | `BaseEventManager` | Publishers | |---|---|---|---|---| | restart no:0 | `@2b15af5c` | `DefaultUnitOfWorkManager@135ba` | `@78f53ca9` | 1 | | restart no:1 | `@41d76578` | `DefaultUnitOfWorkManager@135ba` | `@78f53ca9` | 2 | | restart no:2 | `@266a08bf` | `DefaultUnitOfWorkManager@135ba` | `@78f53ca9` | 3 | | restart no:3 | `@6637bbb9` | `DefaultUnitOfWorkManager@135ba` | `@78f53ca9` | 4 | | restart no:4 | `@72a2ae1f` | `DefaultUnitOfWorkManager@135ba` | `@78f53ca9` | 5 | The fix scopes the producer to the application with `@Singleton` and returns a new `DefaultUnitOfWorkManager`. Reproducer (public dependencies only, plus the full analysis): https://github.com/thiagoelg/quarkus-dev-mode-emf-closed-repro ## Relationship to #3870 — this is not a revert This changes the line that dcaca447 ([`[Fix #3869] Using the same work and event manager`](https://github.com/apache/incubator-kie-kogito-runtimes/pull/3870)) introduced, so it needs saying explicitly. Before dcaca447 the producer was a bare `@Produces`, i.e. `@Dependent`, so **every injection point received its own manager** and only `ProcessConfig`'s carried the publishers. That is [#3869](https://github.com/apache/incubator-kie-kogito-runtimes/issues/3869): a path resolving the manager from any other injection point published into a manager nobody listened to. The defect in #3869 was the **missing scope**. dcaca447 obtained sharing through a JVM static; this PR obtains the same sharing through the container. dcaca447's invariant is preserved, its lifetime defect is not. `@Singleton` rather than `@ApplicationScoped` so injection points hold the instance directly, leaving the unit-of-work path free of a client proxy. This is also why dcaca447 only touched Quarkus: Spring `@Bean` methods are singleton-scoped by default, so Spring Boot never had #3869 and its producer already reads `new DefaultUnitOfWorkManager(new CollectingUnitOfWorkFactory())`. `LightProcessRuntimeServiceProvider` is deliberately left exactly as dcaca447 set it. ## Regression test for #3869 PR #3870 shipped no test, so nothing in CI guarded against this. This PR adds one, in `kogito-addons-quarkus-data-index-jpa/integration-tests-process`: `timerResume` parks on an intermediate timer, so the instance is persisted and resumed by the job scheduler rather than the request thread, and the test asserts the data index observes the completion. It was proven to fail before it was used to pass: | Build | `UnitOfWorkManager` identities | Test | |---|---|---| | Pre-dcaca447 (reverse-applied) | config `@3c11533` (1 publisher), fresh lookup `@7fd0231` — a **different object** — static `@4c1a14df` (0 publishers) | **Fails** (`ConditionTimeoutException`, instance holds `ACTIVE`) | | `main` | all one object, 1 publisher | Passes | | This PR | config == fresh, 1 publisher | Passes | ## Validation - Dev-mode reproducer: unpatched fails from reload #2 and never recovers; patched gives 11/11 clean starts with zero `EntityManagerFactory is closed`. - Data index actually receives events (a fix that merely disconnected the publishers would also look clean): 5 instances started across 5 generations → exactly 5 indexed, all `COMPLETED`. - `kogito-quarkus-processes-integration-test` (10 tests), `integration-tests-quarkus-usertasks` (22 tests), `kogito-addons-quarkus-data-index-jpa/integration-tests-process` (4 tests) all pass. The user-task module matters most: `UserTaskConfig` shares the `UnitOfWorkManager` bean with `ProcessConfig`, so a wrong scope shows up there. ## Note on the second commit `[NO-ISSUE] chore: fix the jobs-service IT shared/ ignore rule...` is unrelated to #7106. The `.gitignore` rule for the generated `src/main/resources/shared` directories still pointed at `apps-integration-tests/...`, the pre-merge path, so it has matched nothing since `kogito-apps` was merged in, and a built working copy shows 24 generated files as untracked. Happy to split it into its own PR if preferred. -- 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] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
