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

Claus Ibsen updated CAMEL-25427:
--------------------------------
    Fix Version/s: 4.24.0

> camel-support - on-demand route reload fails with FileNotFoundException after 
> a route file is removed from the source dir
> -------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-25427
>                 URL: https://issues.apache.org/jira/browse/CAMEL-25427
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-core, camel-jbang
>    Affects Versions: 4.22.1
>         Environment: Camel JBang 4.22.1, JBang 0.139.3, Java 25.0.4, macOS
>            Reporter: Serdar Gökay
>            Priority: Minor
>             Fix For: 4.24.0
>
>
> On-demand route reload fails when one of several route files has been removed 
> from the source directory, for example after a route file was renamed. The 
> reload removes all routes and then fails with a FileNotFoundException for the 
> removed file. Afterwards no route runs, including the routes of files that 
> did not change, and every later on-demand reload fails the same way until the 
> JVM is restarted.
> h3. Reproduce
> Camel JBang 4.22.1 with two route files in a {{src}} directory:
> {noformat}
> # src/a.camel.yaml
> - route:
>     id: a
>     from:
>       uri: timer:a?period=10000
>       steps:
>         - log: tick a
> # src/b.camel.yaml
> - route:
>     id: b
>     from:
>       uri: timer:b?period=10000
>       steps:
>         - log: tick b
> {noformat}
> {noformat}
> camel run --source-dir=src --console --port=18761 --management-port=18762
> # routes a and b start
> rm src/b.camel.yaml
> curl 'http://localhost:18762/q/dev/reload?reload=true'
> curl -H 'Accept: application/json' http://localhost:18762/q/dev/route   # no 
> routes left, a is gone too
> curl 'http://localhost:18762/q/dev/reload?reload=true'                  # 
> fails again
> {noformat}
> Expected: route {{b}} is removed and route {{a}} is reloaded and keeps 
> running.
> Actual: both routes are gone, and each reload logs:
> {noformat}
> WARN  RouteOnDemandReloadStrategy : Error reloading routes due to 
> java.io.FileNotFoundException: Resource not found: file:src/b.camel.yaml. 
> This exception is ignored.
> org.apache.camel.RuntimeCamelException: java.io.FileNotFoundException: 
> Resource not found: file:src/b.camel.yaml
>     at 
> org.apache.camel.support.RouteWatcherReloadStrategy.onRouteReload(RouteWatcherReloadStrategy.java:388)
>     at 
> org.apache.camel.support.RouteOnDemandReloadStrategy.doOnReload(RouteOnDemandReloadStrategy.java:120)
>     at 
> org.apache.camel.support.RouteOnDemandReloadStrategy.onReload(RouteOnDemandReloadStrategy.java:75)
>     at 
> org.apache.camel.impl.console.ReloadDevConsole.lambda$doCallText$0(ReloadDevConsole.java:62)
> Caused by: java.io.FileNotFoundException: Resource not found: 
> file:src/b.camel.yaml
>     at 
> org.apache.camel.dsl.yaml.YamlRoutesBuilderLoader.preParseRoute(YamlRoutesBuilderLoader.java:667)
>     at 
> org.apache.camel.impl.engine.DefaultRoutesLoader.findRoutesBuilders(DefaultRoutesLoader.java:165)
>     at 
> org.apache.camel.impl.engine.DefaultRoutesLoader.updateRoutes(DefaultRoutesLoader.java:295)
>     at 
> org.apache.camel.support.RouteWatcherReloadStrategy.onRouteReload(RouteWatcherReloadStrategy.java:319)
> {noformat}
> After the two reloads the reload dev console reports 
> {{"reloaded":0,"failed":2}}.
> h3. Cause
> {{RouteOnDemandReloadStrategy.findReloadedResources}} lists the files that 
> exist in the source directory, so a removed file is never passed to 
> {{onRouteReload}}. With {{removeAllRoutes}} (the default), 
> {{RouteWatcherReloadStrategy.onRouteReload}} then adds the source resource of 
> every current route that is not among the passed resources, without checking 
> that it still exists, and {{DefaultRoutesLoader.updateRoutes}} fails on the 
> removed file. The passed resources already get a {{Files.exists}} check; the 
> sources of the current routes do not. After the failure the attempted list is 
> kept in {{previousSources}} and added again on the next reload, so the 
> failure repeats.
> The case where every route file is removed works, because 
> {{removeEverything}} clears the list before loading.
> Code: [RouteWatcherReloadStrategy, 
> 4.22.1|https://github.com/apache/camel/blob/camel-4.22.1/core/camel-support/src/main/java/org/apache/camel/support/RouteWatcherReloadStrategy.java#L258-L295].
>  The same logic is on main: [RouteWatcherReloadStrategy, 
> main|https://github.com/apache/camel/blob/main/core/camel-support/src/main/java/org/apache/camel/support/RouteWatcherReloadStrategy.java#L340-L380].
> h3. Proposed change
> When collecting the sources of the current routes and the remembered previous 
> sources, skip a source whose file no longer exists, with the same 
> {{Files.exists}} check the passed resources get. The routes of a removed file 
> are then removed like those of a changed file, and the other routes reload.
> h3. Classification
> Filed as a Bug because the reload fails on an ordinary edit (removing or 
> renaming a route file). We were not sure whether it should rather be an 
> Improvement, since on-demand reload only scans the files that exist. Please 
> reclassify it if Improvement fits better.
> We came across this when a project was reloaded on demand after a Git pull 
> that had renamed one of its route files.



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

Reply via email to