shashank created CAMEL-25292:
--------------------------------
Summary: camel-plc4x - a stopped triggered consumer keeps its
scraper running (exchanges after stop, duplicates after a restart), and the
triggered consumer cannot start without jackson-databind
Key: CAMEL-25292
URL: https://issues.apache.org/jira/browse/CAMEL-25292
Project: Camel
Issue Type: Bug
Reporter: shashank
h3. 1. The scraper is never stopped
With a {{trigger}}, {{Plc4XConsumer.doStart}} creates a
{{TriggerCollectorImpl}} and a {{TriggeredScraperImpl}}, starts them, and keeps
them only in local variables of {{startTriggered()}}. {{doStop}} only cancels
the future of the one-time (untriggered) read, so the scraper and the collector
keep running:
* after the route is stopped, the scraper keeps reading the PLC at the
configured period and sends the exchanges of every triggered read to the route;
* after the route is started again (a new consumer, a new scraper), the old and
the new scraper both run, so every triggered read is routed twice (once more
per restart), and the PLC gets the reads of every scraper.
The consumer also creates its own
{{Executors.newSingleThreadScheduledExecutor()}} per instance for the one-time
read and never shuts it down (one thread leaked per consumer, also for
triggered consumers, which do not use it).
h3. 2. The triggered consumer fails to start with camel-plc4x alone
{{camel-plc4x}} excludes {{jackson-databind}} from {{plc4j-scraper}}, but
{{ScraperConfigurationTriggeredImpl}} (built in {{getScraperConfig}}) needs it.
Without {{jackson-databind}} from another dependency, the triggered consumer
fails in {{doStart}}:
{noformat}
java.lang.NoClassDefFoundError:
com/fasterxml/jackson/databind/exc/MismatchedInputException
at
org.apache.camel.component.plc4x.Plc4XConsumer.getScraperConfig(Plc4XConsumer.java:153)
at
org.apache.camel.component.plc4x.Plc4XConsumer.startTriggered(Plc4XConsumer.java:124)
{noformat}
({{mvn dependency:tree}} of camel-plc4x has jackson-core and
jackson-annotations, not jackson-databind.) {{plc4j-scraper}} 0.13.1 declares
{{jackson-databind}} as a compile dependency. The exclusion came with the
import of the component (CAMEL-18655, 2022) without a comment or ticket;
nothing in camel-plc4x needs it. Applications that get {{jackson-databind}}
from another dependency (for example a Spring Boot web starter) do not see the
error. The existing test
{{Plc4XConsumerTest.shouldStartTriggeredScraperWhenTriggerPresent}} does not
catch it: it stubs {{getTrigger()}} after the consumer was created, so it runs
the untriggered path.
h3. Reproduction
{{Plc4XConsumerStopTest}} (new; {{TriggeredScraperImpl}} and
{{TriggerCollectorImpl}} replaced with Mockito {{mockConstruction}}): start and
stop a triggered consumer, the scraper and the collector must be stopped.
* main: {{NoClassDefFoundError:
com/fasterxml/jackson/databind/exc/MismatchedInputException}} at start;
* main with only the dependency fix: {{Wanted but not invoked:
triggeredScraperImpl.stop()}}.
h3. Proposed fix
Keep the scraper and the collector in fields and stop them in {{doStop}};
create the executor of the one-time read from the {{ExecutorServiceManager}}
when it is used and shut it down in {{doStop}}; remove the {{jackson-databind}}
exclusion from {{plc4j-scraper}} (the version is managed by Camel's Jackson
BOM: 2.22.3, as jackson-core). With the fix the test passes, and the module
suite passes (18 tests). Note: {{TriggeredScraperImpl.stop()}} cancels its
tasks but does not shut down the scraper's own thread pools (PLC4X library);
its idle threads remain.
Affected: 4.14.x, 4.18.x and main (same code).
Duplicate check (2026-10-03): JIRA text "plc4x" (10 issues: CAMEL-24171, 22491,
20871, 19199, 18861, ...): none about the scraper, the stop or
jackson-databind. GitHub pull requests "plc4x": none open about the component.
_Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)