This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/main by this push:
     new 8a62b1441059 CAMEL-25410: camel-core-model - doTry keeps doCatch and 
doFinally in its outputs (#29772)
8a62b1441059 is described below

commit 8a62b14410599d9dec6e516e5a3b4042ba6f88b6
Author: Claus Ibsen <[email protected]>
AuthorDate: Fri Nov 13 08:03:41 2026 +0100

    CAMEL-25410: camel-core-model - doTry keeps doCatch and doFinally in its 
outputs (#29772)
    
    TryDefinition kept doCatch/doFinally both in its outputs and in transient
    fields, so walks of getOutputs() missed the YAML property-form clauses, and 
a
    clause removed from the outputs was still reified. The outputs are now the
    single source of truth:
    
    - setCatchClauses/setFinallyClause fold the clauses into the outputs
    - getCatchClauses, getFinallyClause and getOutputsWithoutCatches are derived
    - the copy constructor no longer copies the clause fields
    - TryDefinition.addOutput keeps steps before the clauses (YAML key order)
    - the CAMEL-25367 special case of the model writer templates is removed and
      the writers regenerated
    - 4.24 upgrade-guide note
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
 .../java/org/apache/camel/model/TryDefinition.java | 115 ++++++++++++----
 .../camel/model/TryDefinitionClausesTest.java      | 121 +++++++++++++++++
 .../interceptor/AdviceWithRemoveDoCatchTest.java   |  69 ++++++++++
 .../JaxbDumpModelAsXmlTryPropertyClausesTest.java  |  66 +++++++++
 .../apache/camel/java/out/JavaDslModelWriter.java  |  19 +--
 .../apache/camel/java/out/TryModelWriterTest.java  |  27 +++-
 .../java/org/apache/camel/xml/out/ModelWriter.java |  19 +--
 .../apache/camel/xml/out/TryModelWriterTest.java   |  27 +++-
 .../org/apache/camel/yaml/out/YamlModelWriter.java |  18 +--
 .../apache/camel/yaml/out/TryModelWriterTest.java  |  27 +++-
 .../ROOT/pages/camel-4x-upgrade-guide-4_24.adoc    |   9 ++
 .../camel/dsl/yaml/TryPropertyClausesTest.java     | 147 +++++++++++++++++++++
 .../resources/velocity/model-java-dsl-writer.vm    |  21 ---
 .../src/main/resources/velocity/model-writer.vm    |  21 ---
 .../main/resources/velocity/model-yaml-writer.vm   |  20 ---
 15 files changed, 585 insertions(+), 141 deletions(-)

diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/model/TryDefinition.java 
b/core/camel-core-model/src/main/java/org/apache/camel/model/TryDefinition.java
index 41f73f3d593a..f383c334462b 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/model/TryDefinition.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/model/TryDefinition.java
@@ -47,6 +47,9 @@ import org.apache.camel.spi.annotations.DslProperty;
            eipSteps = @BodyType(Carrier.UNCHANGED))
 public class TryDefinition extends OutputDefinition<TryDefinition> {
 
+    // the doCatch and doFinally clauses are kept in outputs (the single 
source of truth, CAMEL-25410): these fields
+    // are only the YAML DSL properties (doCatch and doFinally written as 
properties of doTry), and a cache derived
+    // from outputs by checkInitialized
     @DslProperty
     @XmlTransient
     private List<CatchDefinition> catchClauses;
@@ -64,9 +67,9 @@ public class TryDefinition extends 
OutputDefinition<TryDefinition> {
     }
 
     protected TryDefinition(TryDefinition source) {
+        // the clauses are in the outputs, which super copies: the cache 
fields are derived again from the copied outputs
+        // (copying them too would give the copy two instances of each clause)
         super(source);
-        this.catchClauses = 
ProcessorDefinitionHelper.deepCopyDefinitions(source.catchClauses);
-        this.finallyClause = source.finallyClause != null ? 
source.finallyClause.copyDefinition() : null;
     }
 
     @Override
@@ -162,34 +165,60 @@ public class TryDefinition extends 
OutputDefinition<TryDefinition> {
     // Properties
     // 
-------------------------------------------------------------------------
 
+    /**
+     * Adds the doCatch clauses to the outputs (before the doFinally, if any), 
where the clauses of a doTry are kept.
+     * Used by the YAML DSL for doCatch written as a property of doTry.
+     */
     @XmlTransient
     public void setCatchClauses(List<CatchDefinition> catchClauses) {
-        this.catchClauses = catchClauses;
+        if (catchClauses != null) {
+            for (CatchDefinition catchClause : catchClauses) {
+                if (!outputs.contains(catchClause)) {
+                    catchClause.setParent(this);
+                    configureChild(catchClause);
+                    outputs.add(indexOfFinally(), catchClause);
+                }
+            }
+        }
+        initialized = false;
     }
 
+    /**
+     * The doCatch clauses, in the order of the outputs where they are kept.
+     */
     public List<CatchDefinition> getCatchClauses() {
-        if (catchClauses == null) {
-            checkInitialized();
-        }
+        refresh();
         return catchClauses;
     }
 
+    /**
+     * Sets the doFinally clause in the outputs, where the clauses of a doTry 
are kept, replacing any other. Used by the
+     * YAML DSL for doFinally written as a property of doTry.
+     */
     @XmlTransient
     public void setFinallyClause(FinallyDefinition finallyClause) {
-        this.finallyClause = finallyClause;
+        outputs.removeIf(o -> o instanceof FinallyDefinition && o != 
finallyClause);
+        if (finallyClause != null && !outputs.contains(finallyClause)) {
+            finallyClause.setParent(this);
+            configureChild(finallyClause);
+            outputs.add(finallyClause);
+        }
+        initialized = false;
     }
 
+    /**
+     * The doFinally clause from the outputs, or null if there is none.
+     */
     public FinallyDefinition getFinallyClause() {
-        if (finallyClause == null) {
-            checkInitialized();
-        }
+        refresh();
         return finallyClause;
     }
 
+    /**
+     * The outputs that are the steps of the doTry block: all outputs except 
the doCatch and doFinally clauses.
+     */
     public List<ProcessorDefinition<?>> getOutputsWithoutCatches() {
-        if (outputsWithoutCatches == null) {
-            checkInitialized();
-        }
+        refresh();
         return outputsWithoutCatches;
     }
 
@@ -211,6 +240,18 @@ public class TryDefinition extends 
OutputDefinition<TryDefinition> {
         // reset end counter as we are adding some outputs
         endCounter = 0;
         super.addOutput(output);
+        // a step added to this doTry itself (not to the doCatch or doFinally 
the Java DSL is building, which takes it
+        // as its own output) after a clause, such as YAML steps after doCatch 
written as a property, goes before the
+        // clauses: the runtime takes the steps from anywhere in the outputs, 
and the outputs then read (and are dumped)
+        // as steps, doCatch and doFinally in this order
+        if (!(output instanceof CatchDefinition) && !(output instanceof 
FinallyDefinition)
+                && !outputs.isEmpty() && outputs.get(outputs.size() - 1) == 
output) {
+            int index = indexOfFirstClause();
+            if (index < outputs.size() - 1) {
+                outputs.remove(outputs.size() - 1);
+                outputs.add(index, output);
+            }
+        }
     }
 
     protected ProcessorDefinition<?> onEndDoTry() {
@@ -230,28 +271,56 @@ public class TryDefinition extends 
OutputDefinition<TryDefinition> {
     }
 
     /**
-     * Checks whether or not this object has been initialized
+     * Derives the clauses and the steps from the outputs again: the outputs 
can be changed directly (for example by
+     * advice-with), so a clause that is no longer in the outputs must not 
stay in the cache.
+     */
+    private void refresh() {
+        initialized = false;
+        checkInitialized();
+    }
+
+    private int indexOfFinally() {
+        for (int i = 0; i < outputs.size(); i++) {
+            if (outputs.get(i) instanceof FinallyDefinition) {
+                return i;
+            }
+        }
+        return outputs.size();
+    }
+
+    private int indexOfFirstClause() {
+        for (int i = 0; i < outputs.size(); i++) {
+            if (outputs.get(i) instanceof CatchDefinition || outputs.get(i) 
instanceof FinallyDefinition) {
+                return i;
+            }
+        }
+        return outputs.size();
+    }
+
+    /**
+     * Checks whether or not this object has been initialized, and derives the 
doCatch and doFinally clauses and the
+     * steps from the outputs if not.
      */
     protected void checkInitialized() {
         if (!initialized) {
             initialized = true;
-            outputsWithoutCatches = new ArrayList<>();
-            if (catchClauses == null) {
-                catchClauses = new ArrayList<>();
-            }
+            List<ProcessorDefinition<?>> steps = new ArrayList<>();
+            List<CatchDefinition> catches = new ArrayList<>();
+            FinallyDefinition doFinally = null;
             int doFinallyCounter = 0;
             for (ProcessorDefinition<?> output : outputs) {
                 if (output instanceof CatchDefinition catchDefinition) {
-                    if (!catchClauses.contains(output)) {
-                        catchClauses.add(catchDefinition);
-                    }
+                    catches.add(catchDefinition);
                 } else if (output instanceof FinallyDefinition 
finallyDefinition) {
                     ++doFinallyCounter;
-                    finallyClause = finallyDefinition;
+                    doFinally = finallyDefinition;
                 } else {
-                    outputsWithoutCatches.add(output);
+                    steps.add(output);
                 }
             }
+            outputsWithoutCatches = steps;
+            catchClauses = catches;
+            finallyClause = doFinally;
             if (doFinallyCounter > 1) {
                 throw new IllegalArgumentException(
                         "Multiple finally clauses added: " + doFinallyCounter);
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/model/TryDefinitionClausesTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/model/TryDefinitionClausesTest.java
new file mode 100644
index 000000000000..81c70981452b
--- /dev/null
+++ 
b/core/camel-core/src/test/java/org/apache/camel/model/TryDefinitionClausesTest.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.model;
+
+import java.util.List;
+
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * The doCatch and doFinally clauses of a doTry are kept in its outputs, also 
when they are set as properties (as the
+ * YAML DSL does), and the clause getters are derived from the outputs 
(CAMEL-25410).
+ */
+public class TryDefinitionClausesTest {
+
+    @Test
+    public void testClausesSetAsPropertiesAreInTheOutputs() {
+        TryDefinition doTry = new TryDefinition();
+        CatchDefinition doCatch = newCatch("mock:catch");
+        FinallyDefinition doFinally = newFinally("mock:finally");
+        doTry.setFinallyClause(doFinally);
+        doTry.setCatchClauses(List.of(doCatch));
+        // steps written after the clauses (as YAML with doCatch above steps) 
go before them
+        doTry.addOutput(new ToDefinition("mock:a"));
+        doTry.addOutput(new ToDefinition("mock:b"));
+
+        assertThat(doTry.getOutputs()).hasSize(4);
+        assertThat(((ToDefinition) 
doTry.getOutputs().get(0)).getUri()).isEqualTo("mock:a");
+        assertThat(((ToDefinition) 
doTry.getOutputs().get(1)).getUri()).isEqualTo("mock:b");
+        assertThat(doTry.getOutputs().get(2)).isSameAs(doCatch);
+        assertThat(doTry.getOutputs().get(3)).isSameAs(doFinally);
+
+        assertThat(doTry.getCatchClauses()).containsExactly(doCatch);
+        assertThat(doTry.getFinallyClause()).isSameAs(doFinally);
+        assertThat(doTry.getOutputsWithoutCatches()).hasSize(2);
+        assertThat(doCatch.getParent()).isSameAs(doTry);
+        assertThat(doFinally.getParent()).isSameAs(doTry);
+    }
+
+    @Test
+    public void testSettingTheClausesAgainDoesNotDuplicateThem() {
+        TryDefinition doTry = new TryDefinition();
+        doTry.addOutput(new ToDefinition("mock:a"));
+        CatchDefinition doCatch = newCatch("mock:catch");
+        doTry.setCatchClauses(List.of(doCatch));
+        doTry.setCatchClauses(List.of(doCatch));
+        FinallyDefinition first = newFinally("mock:first");
+        FinallyDefinition second = newFinally("mock:second");
+        doTry.setFinallyClause(first);
+        // a doTry has one doFinally: setting another replaces it
+        doTry.setFinallyClause(second);
+
+        assertThat(doTry.getOutputs()).hasSize(3);
+        assertThat(doTry.getCatchClauses()).containsExactly(doCatch);
+        assertThat(doTry.getFinallyClause()).isSameAs(second);
+        assertThat(doTry.getOutputs()).doesNotContain(first);
+    }
+
+    @Test
+    public void testClauseRemovedFromTheOutputsIsGone() {
+        TryDefinition doTry = new TryDefinition();
+        doTry.addOutput(new ToDefinition("mock:a"));
+        CatchDefinition doCatch = newCatch("mock:catch");
+        CatchDefinition other = newCatch("mock:other");
+        FinallyDefinition doFinally = newFinally("mock:finally");
+        doTry.setCatchClauses(List.of(doCatch, other));
+        doTry.setFinallyClause(doFinally);
+        assertThat(doTry.getCatchClauses()).containsExactly(doCatch, other);
+
+        // as advice-with does: the outputs are changed directly
+        doTry.getOutputs().remove(other);
+        doTry.getOutputs().remove(doFinally);
+
+        assertThat(doTry.getCatchClauses()).containsExactly(doCatch);
+        assertThat(doTry.getFinallyClause()).isNull();
+    }
+
+    @Test
+    public void testCopyHasOneInstanceOfEachClause() {
+        TryDefinition doTry = new TryDefinition();
+        doTry.addOutput(new ToDefinition("mock:a"));
+        doTry.setCatchClauses(List.of(newCatch("mock:catch")));
+        doTry.setFinallyClause(newFinally("mock:finally"));
+
+        TryDefinition copy = doTry.copyDefinition();
+
+        assertThat(copy.getOutputs()).hasSize(3);
+        assertThat(copy.getCatchClauses()).hasSize(1);
+        assertThat(copy.getOutputs()).contains(copy.getCatchClauses().get(0), 
copy.getFinallyClause());
+        
assertThat(copy.getCatchClauses().get(0)).isNotSameAs(doTry.getCatchClauses().get(0));
+        assertThat(copy.getCatchClauses().get(0).getParent()).isSameAs(copy);
+    }
+
+    private static CatchDefinition newCatch(String uri) {
+        CatchDefinition answer = new CatchDefinition();
+        answer.getExceptions().add("java.lang.Exception");
+        answer.addOutput(new ToDefinition(uri));
+        return answer;
+    }
+
+    private static FinallyDefinition newFinally(String uri) {
+        FinallyDefinition answer = new FinallyDefinition();
+        answer.addOutput(new ToDefinition(uri));
+        return answer;
+    }
+}
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/processor/interceptor/AdviceWithRemoveDoCatchTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/processor/interceptor/AdviceWithRemoveDoCatchTest.java
new file mode 100644
index 000000000000..3fa2e3136d43
--- /dev/null
+++ 
b/core/camel-core/src/test/java/org/apache/camel/processor/interceptor/AdviceWithRemoveDoCatchTest.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.processor.interceptor;
+
+import org.apache.camel.CamelExecutionException;
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.AdviceWith;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.model.CatchDefinition;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+/**
+ * A doCatch removed with advice-with from a route that has been started no 
longer runs (CAMEL-25410).
+ */
+public class AdviceWithRemoveDoCatchTest extends ContextTestSupport {
+
+    @Test
+    public void testRemovedDoCatchDoesNotRun() throws Exception {
+        // the route has been started, so its doTry has been reified once with 
the doCatch
+        getMockEndpoint("mock:catch").expectedMessageCount(1);
+        getMockEndpoint("mock:finally").expectedMessageCount(1);
+        template.sendBody("direct:start", "Hello");
+        assertMockEndpointsSatisfied();
+
+        AdviceWith.adviceWith(context, "myRoute", a -> 
a.weaveByType(CatchDefinition.class).remove());
+
+        resetMocks();
+        getMockEndpoint("mock:catch").expectedMessageCount(0);
+        getMockEndpoint("mock:finally").expectedMessageCount(1);
+        CamelExecutionException e
+                = assertThrows(CamelExecutionException.class, () -> 
template.sendBody("direct:start", "World"));
+        assertInstanceOf(IllegalArgumentException.class, e.getCause());
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                from("direct:start").routeId("myRoute")
+                        .doTry()
+                            .throwException(new 
IllegalArgumentException("Forced"))
+                        .doCatch(IllegalArgumentException.class)
+                            .to("mock:catch")
+                        .doFinally()
+                            .to("mock:finally")
+                        .end();
+            }
+        };
+    }
+}
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/util/JaxbDumpModelAsXmlTryPropertyClausesTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/util/JaxbDumpModelAsXmlTryPropertyClausesTest.java
new file mode 100644
index 000000000000..d64ee70a3acf
--- /dev/null
+++ 
b/core/camel-core/src/test/java/org/apache/camel/util/JaxbDumpModelAsXmlTryPropertyClausesTest.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.util;
+
+import java.util.List;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.model.CatchDefinition;
+import org.apache.camel.model.FinallyDefinition;
+import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.model.ToDefinition;
+import org.apache.camel.model.TryDefinition;
+import org.apache.camel.xml.jaxb.JaxbModelToXMLDumper;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * The JAXB dumper writes the doCatch and doFinally of a doTry also when they 
are set as properties, as the YAML DSL
+ * does (CAMEL-25410).
+ */
+public class JaxbDumpModelAsXmlTryPropertyClausesTest extends 
ContextTestSupport {
+
+    @Test
+    public void testDumpModelAsXml() throws Exception {
+        CatchDefinition doCatch = new CatchDefinition();
+        doCatch.getExceptions().add("java.lang.IllegalStateException");
+        doCatch.addOutput(new ToDefinition("mock:catch"));
+        FinallyDefinition doFinally = new FinallyDefinition();
+        doFinally.addOutput(new ToDefinition("mock:finally"));
+        TryDefinition doTry = new TryDefinition();
+        // as YAML with doCatch and doFinally written above the steps
+        doTry.setCatchClauses(List.of(doCatch));
+        doTry.setFinallyClause(doFinally);
+        doTry.addOutput(new ToDefinition("mock:try"));
+
+        RouteDefinition route = new RouteDefinition();
+        route.routeId("myRoute");
+        route.from("direct:start");
+        route.addOutput(doTry);
+
+        String xml = new JaxbModelToXMLDumper().dumpModelAsXml(context, route);
+        log.info(xml);
+
+        assertTrue(xml.contains("<doCatch"), xml);
+        assertTrue(xml.contains("<doFinally"), xml);
+        assertTrue(xml.indexOf("mock:try") < xml.indexOf("mock:catch"), xml);
+        assertTrue(xml.indexOf("mock:catch") < xml.indexOf("mock:finally"), 
xml);
+        assertEquals(xml.indexOf("mock:catch"), xml.lastIndexOf("mock:catch"), 
xml);
+    }
+}
diff --git 
a/core/camel-java-io/src/generated/java/org/apache/camel/java/out/JavaDslModelWriter.java
 
b/core/camel-java-io/src/generated/java/org/apache/camel/java/out/JavaDslModelWriter.java
index ca964c452a29..8ce8a9047761 100644
--- 
a/core/camel-java-io/src/generated/java/org/apache/camel/java/out/JavaDslModelWriter.java
+++ 
b/core/camel-java-io/src/generated/java/org/apache/camel/java/out/JavaDslModelWriter.java
@@ -20,7 +20,6 @@
  */
 package org.apache.camel.java.out;
 
-import java.util.ArrayList;
 import java.util.Base64;
 import java.util.List;
 import java.util.function.BiConsumer;
@@ -2707,23 +2706,7 @@ public class JavaDslModelWriter extends 
JavaDslModelWriterSupport {
     }
     protected void doWriteTryDefinition(StringBuilder sb, TryDefinition def) {
         doWriteProcessorDefinitionAttributes(sb, def);
-        List<ProcessorDefinition<?>> outputs = new 
ArrayList<>(def.getOutputs());
-        for (CatchDefinition clause : def.getCatchClauses()) {
-            if (!outputs.contains(clause)) {
-                int index = outputs.size();
-                for (int i = 0; i < outputs.size(); i++) {
-                    if (outputs.get(i) instanceof FinallyDefinition) {
-                        index = i;
-                        break;
-                    }
-                }
-                outputs.add(index, clause);
-            }
-        }
-        if (def.getFinallyClause() != null && 
!outputs.contains(def.getFinallyClause())) {
-            outputs.add(def.getFinallyClause());
-        }
-        doWriteOutputs(sb, outputs, this::doWriteProcessorDefinitionRef);
+        doWriteOutputs(sb, def.getOutputs(), 
this::doWriteProcessorDefinitionRef);
     }
     protected void doWriteUnmarshalDefinition(StringBuilder sb, 
UnmarshalDefinition def) {
         doWriteProcessorDefinitionAttributes(sb, def);
diff --git 
a/core/camel-java-io/src/test/java/org/apache/camel/java/out/TryModelWriterTest.java
 
b/core/camel-java-io/src/test/java/org/apache/camel/java/out/TryModelWriterTest.java
index aab120acefb9..28b0cabd5fdb 100644
--- 
a/core/camel-java-io/src/test/java/org/apache/camel/java/out/TryModelWriterTest.java
+++ 
b/core/camel-java-io/src/test/java/org/apache/camel/java/out/TryModelWriterTest.java
@@ -83,6 +83,26 @@ class TryModelWriterTest {
         Assertions.assertEquals(originalOutputs, def.getOutputs());
     }
 
+    @Test
+    void clausesSetBeforeTheStepsAreDumpedAfterThem() throws Exception {
+        // as the YAML DSL does when doCatch and doFinally are written above 
steps (CAMEL-25410)
+        TryDefinition def = new TryDefinition();
+        CatchDefinition clause = new CatchDefinition();
+        clause.getExceptions().add("java.lang.Exception");
+        clause.addOutput(new ToDefinition("mock:catch"));
+        FinallyDefinition finallyClause = new FinallyDefinition();
+        finallyClause.addOutput(new ToDefinition("mock:finally"));
+        def.setCatchClauses(List.of(clause));
+        def.setFinallyClause(finallyClause);
+        def.addOutput(new ToDefinition("mock:try1"));
+        def.addOutput(new ToDefinition("mock:try2"));
+        String output = dump(def);
+        Assertions.assertTrue(output.indexOf("mock:try1") < 
output.indexOf("mock:try2"), output);
+        Assertions.assertTrue(output.indexOf("mock:try2") < 
output.indexOf("mock:catch"), output);
+        Assertions.assertTrue(output.indexOf("mock:catch") < 
output.indexOf("mock:finally"), output);
+        Assertions.assertEquals(output.indexOf("mock:catch"), 
output.lastIndexOf("mock:catch"), output);
+    }
+
     @Test
     void dumpingAfterAddingOutputPreservesNewStepAndMixedClauses() throws 
Exception {
         TryDefinition def = new TryDefinition();
@@ -102,7 +122,12 @@ class TryModelWriterTest {
         Assertions.assertTrue(second.contains("mock:later"), second);
         Assertions.assertEquals(second.indexOf("mock:catch"), 
second.lastIndexOf("mock:catch"), second);
         Assertions.assertEquals(second.indexOf("mock:finally"), 
second.lastIndexOf("mock:finally"), second);
-        Assertions.assertEquals(3, def.getOutputs().size());
+        // the doCatch set as a property is kept in the outputs too 
(CAMEL-25410), and a step added later goes before
+        // the clauses: steps, doCatch, doFinally
+        Assertions.assertEquals(4, def.getOutputs().size());
+        Assertions.assertTrue(second.indexOf("mock:later") < 
second.indexOf("mock:catch"), second);
+        Assertions.assertSame(clause, def.getOutputs().get(2));
+        Assertions.assertSame(finallyClause, def.getOutputs().get(3));
     }
 
     private String dump(TryDefinition def) throws Exception {
diff --git 
a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
 
b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
index 4a1416e28d46..0eb472d59208 100644
--- 
a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
+++ 
b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
@@ -22,7 +22,6 @@ package org.apache.camel.xml.out;
 
 import java.io.IOException;
 import java.io.Writer;
-import java.util.ArrayList;
 import java.util.Base64;
 import java.util.List;
 import javax.annotation.processing.Generated;
@@ -1983,23 +1982,7 @@ public class ModelWriter extends BaseWriter {
     protected void doWriteTryDefinition(String name, TryDefinition def) throws 
IOException {
         startElement(name);
         doWriteProcessorDefinitionAttributes(def);
-        List<ProcessorDefinition<?>> outputs = new 
ArrayList<>(def.getOutputs());
-        for (CatchDefinition clause : def.getCatchClauses()) {
-            if (!outputs.contains(clause)) {
-                int index = outputs.size();
-                for (int i = 0; i < outputs.size(); i++) {
-                    if (outputs.get(i) instanceof FinallyDefinition) {
-                        index = i;
-                        break;
-                    }
-                }
-                outputs.add(index, clause);
-            }
-        }
-        if (def.getFinallyClause() != null && 
!outputs.contains(def.getFinallyClause())) {
-            outputs.add(def.getFinallyClause());
-        }
-        doWriteList(null, null, outputs, this::doWriteProcessorDefinitionRef);
+        doWriteList(null, null, def.getOutputs(), 
this::doWriteProcessorDefinitionRef);
         endElement(name);
     }
     protected void doWriteUnmarshalDefinition(String name, UnmarshalDefinition 
def) throws IOException {
diff --git 
a/core/camel-xml-io/src/test/java/org/apache/camel/xml/out/TryModelWriterTest.java
 
b/core/camel-xml-io/src/test/java/org/apache/camel/xml/out/TryModelWriterTest.java
index e00df9728617..0390efbf069b 100644
--- 
a/core/camel-xml-io/src/test/java/org/apache/camel/xml/out/TryModelWriterTest.java
+++ 
b/core/camel-xml-io/src/test/java/org/apache/camel/xml/out/TryModelWriterTest.java
@@ -84,6 +84,26 @@ class TryModelWriterTest {
         Assertions.assertEquals(originalOutputs, def.getOutputs());
     }
 
+    @Test
+    void clausesSetBeforeTheStepsAreDumpedAfterThem() throws Exception {
+        // as the YAML DSL does when doCatch and doFinally are written above 
steps (CAMEL-25410)
+        TryDefinition def = new TryDefinition();
+        CatchDefinition clause = new CatchDefinition();
+        clause.getExceptions().add("java.lang.Exception");
+        clause.addOutput(new ToDefinition("mock:catch"));
+        FinallyDefinition finallyClause = new FinallyDefinition();
+        finallyClause.addOutput(new ToDefinition("mock:finally"));
+        def.setCatchClauses(List.of(clause));
+        def.setFinallyClause(finallyClause);
+        def.addOutput(new ToDefinition("mock:try1"));
+        def.addOutput(new ToDefinition("mock:try2"));
+        String output = dump(def);
+        Assertions.assertTrue(output.indexOf("mock:try1") < 
output.indexOf("mock:try2"), output);
+        Assertions.assertTrue(output.indexOf("mock:try2") < 
output.indexOf("mock:catch"), output);
+        Assertions.assertTrue(output.indexOf("mock:catch") < 
output.indexOf("mock:finally"), output);
+        Assertions.assertEquals(output.indexOf("mock:catch"), 
output.lastIndexOf("mock:catch"), output);
+    }
+
     @Test
     void dumpingAfterAddingOutputPreservesNewStepAndMixedClauses() throws 
Exception {
         TryDefinition def = new TryDefinition();
@@ -103,7 +123,12 @@ class TryModelWriterTest {
         Assertions.assertTrue(second.contains("mock:later"), second);
         Assertions.assertEquals(second.indexOf("mock:catch"), 
second.lastIndexOf("mock:catch"), second);
         Assertions.assertEquals(second.indexOf("mock:finally"), 
second.lastIndexOf("mock:finally"), second);
-        Assertions.assertEquals(3, def.getOutputs().size());
+        // the doCatch set as a property is kept in the outputs too 
(CAMEL-25410), and a step added later goes before
+        // the clauses: steps, doCatch, doFinally
+        Assertions.assertEquals(4, def.getOutputs().size());
+        Assertions.assertTrue(second.indexOf("mock:later") < 
second.indexOf("mock:catch"), second);
+        Assertions.assertSame(clause, def.getOutputs().get(2));
+        Assertions.assertSame(finallyClause, def.getOutputs().get(3));
     }
 
     private String dump(TryDefinition def) throws Exception {
diff --git 
a/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/YamlModelWriter.java
 
b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/YamlModelWriter.java
index 730eb07f5578..fab0593590ec 100644
--- 
a/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/YamlModelWriter.java
+++ 
b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/YamlModelWriter.java
@@ -1982,23 +1982,7 @@ public class YamlModelWriter extends 
YamlModelWriterSupport {
     protected JsonObject doWriteTryDefinition(TryDefinition def) {
         JsonObject jo = new JsonObject();
         doWriteProcessorDefinitionAttributes(jo, def);
-        List<ProcessorDefinition<?>> outputs = new 
ArrayList<>(def.getOutputs());
-        for (CatchDefinition clause : def.getCatchClauses()) {
-            if (!outputs.contains(clause)) {
-                int index = outputs.size();
-                for (int i = 0; i < outputs.size(); i++) {
-                    if (outputs.get(i) instanceof FinallyDefinition) {
-                        index = i;
-                        break;
-                    }
-                }
-                outputs.add(index, clause);
-            }
-        }
-        if (def.getFinallyClause() != null && 
!outputs.contains(def.getFinallyClause())) {
-            outputs.add(def.getFinallyClause());
-        }
-        doWriteOutputs(jo, outputs, this::doWriteProcessorDefinitionRef);
+        doWriteOutputs(jo, def.getOutputs(), 
this::doWriteProcessorDefinitionRef);
         return jo;
     }
     protected JsonObject doWriteUnmarshalDefinition(UnmarshalDefinition def) {
diff --git 
a/core/camel-yaml-io/src/test/java/org/apache/camel/yaml/out/TryModelWriterTest.java
 
b/core/camel-yaml-io/src/test/java/org/apache/camel/yaml/out/TryModelWriterTest.java
index dff4a6e3ad73..cb1b710d44c8 100644
--- 
a/core/camel-yaml-io/src/test/java/org/apache/camel/yaml/out/TryModelWriterTest.java
+++ 
b/core/camel-yaml-io/src/test/java/org/apache/camel/yaml/out/TryModelWriterTest.java
@@ -83,6 +83,26 @@ class TryModelWriterTest {
         Assertions.assertEquals(originalOutputs, def.getOutputs());
     }
 
+    @Test
+    void clausesSetBeforeTheStepsAreDumpedAfterThem() throws Exception {
+        // as the YAML DSL does when doCatch and doFinally are written above 
steps (CAMEL-25410)
+        TryDefinition def = new TryDefinition();
+        CatchDefinition clause = new CatchDefinition();
+        clause.getExceptions().add("java.lang.Exception");
+        clause.addOutput(new ToDefinition("mock:catch"));
+        FinallyDefinition finallyClause = new FinallyDefinition();
+        finallyClause.addOutput(new ToDefinition("mock:finally"));
+        def.setCatchClauses(List.of(clause));
+        def.setFinallyClause(finallyClause);
+        def.addOutput(new ToDefinition("mock:try1"));
+        def.addOutput(new ToDefinition("mock:try2"));
+        String output = dump(def);
+        Assertions.assertTrue(output.indexOf("mock:try1") < 
output.indexOf("mock:try2"), output);
+        Assertions.assertTrue(output.indexOf("mock:try2") < 
output.indexOf("mock:catch"), output);
+        Assertions.assertTrue(output.indexOf("mock:catch") < 
output.indexOf("mock:finally"), output);
+        Assertions.assertEquals(output.indexOf("mock:catch"), 
output.lastIndexOf("mock:catch"), output);
+    }
+
     @Test
     void dumpingAfterAddingOutputPreservesNewStepAndMixedClauses() throws 
Exception {
         TryDefinition def = new TryDefinition();
@@ -102,7 +122,12 @@ class TryModelWriterTest {
         Assertions.assertTrue(second.contains("mock:later"), second);
         Assertions.assertEquals(second.indexOf("mock:catch"), 
second.lastIndexOf("mock:catch"), second);
         Assertions.assertEquals(second.indexOf("mock:finally"), 
second.lastIndexOf("mock:finally"), second);
-        Assertions.assertEquals(3, def.getOutputs().size());
+        // the doCatch set as a property is kept in the outputs too 
(CAMEL-25410), and a step added later goes before
+        // the clauses: steps, doCatch, doFinally
+        Assertions.assertEquals(4, def.getOutputs().size());
+        Assertions.assertTrue(second.indexOf("mock:later") < 
second.indexOf("mock:catch"), second);
+        Assertions.assertSame(clause, def.getOutputs().get(2));
+        Assertions.assertSame(finallyClause, def.getOutputs().get(3));
     }
 
     private String dump(TryDefinition def) throws Exception {
diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
index a6da958315b9..f73b33ada254 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
@@ -36,6 +36,15 @@ Starting in 4.24:
 * The Cache EIP stores keys directly without a namespace prefix, preserving 
documented cache invalidation recipes (`cache.delete(key)` and 
`cache.clear()`). Note that because cache keys are un-prefixed, calling 
`clear()` on a `KeyValueRepository` shared with the Cache EIP will clear all 
entries in that repository, including state-store entries. It is recommended to 
use a dedicated repository for the Cache EIP when co-located with state-store.
 * `KeyValueAggregationRepository` safely verifies entry types before 
unmarshalling, ignoring unexpected types gracefully instead of failing with a 
class cast exception.
 
+=== camel-core-model - doTry keeps doCatch and doFinally in its outputs
+
+`doCatch` and `doFinally` written as properties of `doTry` in the YAML DSL are 
now kept in the outputs of the
+`TryDefinition`, as the clauses of the Java and XML DSLs always were, after 
the steps whatever the order of the YAML
+keys. Code that walks `getOutputs()` (route dumps, tooling) now sees them, and 
`getCatchClauses()`,
+`getFinallyClause()` and `getOutputsWithoutCatches()` are derived from the 
outputs on each call: a clause removed from
+the outputs, for example with advice-with, is no longer used, and changing the 
list returned by `getCatchClauses()`
+no longer changes the doTry. Use `setCatchClauses` and `setFinallyClause`, or 
the outputs, instead.
+
 === camel-ehcache - shared CacheManager and changed defaults
 
 The following user-visible changes take effect in 4.24:
diff --git 
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/java/org/apache/camel/dsl/yaml/TryPropertyClausesTest.java
 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/java/org/apache/camel/dsl/yaml/TryPropertyClausesTest.java
new file mode 100644
index 000000000000..e9d9896d0986
--- /dev/null
+++ 
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/test/java/org/apache/camel/dsl/yaml/TryPropertyClausesTest.java
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.yaml;
+
+import java.util.concurrent.TimeUnit;
+
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.dsl.yaml.support.YamlTestSupport;
+import org.apache.camel.model.CatchDefinition;
+import org.apache.camel.model.FinallyDefinition;
+import org.apache.camel.model.ToDefinition;
+import org.apache.camel.model.TryDefinition;
+import org.apache.camel.yaml.LwModelToYAMLDumper;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * doCatch and doFinally written as properties of doTry are kept in its 
outputs, after the steps whatever the YAML key
+ * order (CAMEL-25410).
+ */
+class TryPropertyClausesTest extends YamlTestSupport {
+
+    private static final String CLAUSES_ABOVE_STEPS = """
+            - route:
+                id: clauses
+                from:
+                  uri: direct:start
+                  steps:
+                    - doTry:
+                        doCatch:
+                          - exception:
+                              - java.lang.IllegalStateException
+                            steps:
+                              - to: mock:catch
+                        doFinally:
+                          steps:
+                            - to: mock:finally
+                        steps:
+                          - to: mock:try
+                          - throwException:
+                              exceptionType: java.lang.IllegalStateException
+                              message: Forced
+            """;
+
+    @Test
+    void clausesAboveStepsAreAfterTheStepsInTheOutputs() throws Exception {
+        loadRoutes(CLAUSES_ABOVE_STEPS);
+
+        TryDefinition doTry = (TryDefinition) 
context.getRouteDefinition("clauses").getOutputs().get(0);
+        assertThat(doTry.getOutputs()).hasSize(4);
+        assertThat(doTry.getOutputs().get(0)).isInstanceOf(ToDefinition.class);
+        
assertThat(doTry.getOutputs().get(2)).isInstanceOf(CatchDefinition.class);
+        
assertThat(doTry.getOutputs().get(3)).isInstanceOf(FinallyDefinition.class);
+        assertThat(doTry.getCatchClauses()).containsExactly((CatchDefinition) 
doTry.getOutputs().get(2));
+        
assertThat(doTry.getFinallyClause()).isSameAs(doTry.getOutputs().get(3));
+
+        assertRuns();
+    }
+
+    @Test
+    void clausesAboveStepsSurviveDumpAndReload() throws Exception {
+        loadRoutes(CLAUSES_ABOVE_STEPS);
+        var route = context.getRouteDefinition("clauses");
+        String yaml = new LwModelToYAMLDumper().dumpModelAsYaml(context, 
route);
+        assertThat(yaml).contains("doCatch:", "doFinally:");
+        
assertThat(yaml.indexOf("mock:try")).isLessThan(yaml.indexOf("mock:catch"));
+        
assertThat(yaml.indexOf("mock:catch")).isLessThan(yaml.indexOf("mock:finally"));
+
+        context.removeRouteDefinition(route);
+        loadRoutes(yaml);
+
+        assertRuns();
+    }
+
+    @Test
+    void templatedRoutesRunEachClauseOnce() throws Exception {
+        loadRoutes("""
+                - routeTemplate:
+                    id: myTemplate
+                    from:
+                      uri: "direct:{{name}}"
+                      steps:
+                        - doTry:
+                            steps:
+                              - throwException:
+                                  exceptionType: 
java.lang.IllegalStateException
+                                  message: Forced
+                            doCatch:
+                              - exception:
+                                  - java.lang.IllegalStateException
+                                steps:
+                                  - to: "mock:catch-{{name}}"
+                            doFinally:
+                              steps:
+                                - to: "mock:finally-{{name}}"
+                - templatedRoute:
+                    routeId: one
+                    routeTemplateRef: myTemplate
+                    parameters:
+                      - name: name
+                        value: one
+                - templatedRoute:
+                    routeId: two
+                    routeTemplateRef: myTemplate
+                    parameters:
+                      - name: name
+                        value: two
+                """);
+
+        for (String name : new String[] { "one", "two" }) {
+            withMock("mock:catch-" + name, mock -> 
mock.expectedMessageCount(1));
+            withMock("mock:finally-" + name, mock -> 
mock.expectedMessageCount(1));
+        }
+        context.start();
+
+        withTemplate(t -> t.to("direct:one").withBody("Hello").send());
+        withTemplate(t -> t.to("direct:two").withBody("World").send());
+
+        MockEndpoint.assertIsSatisfied(context);
+        TryDefinition doTry = (TryDefinition) 
context.getRouteDefinition("one").getOutputs().get(0);
+        assertThat(doTry.getCatchClauses()).hasSize(1);
+    }
+
+    private void assertRuns() throws Exception {
+        withMock("mock:try", mock -> mock.expectedMessageCount(1));
+        withMock("mock:catch", mock -> mock.expectedMessageCount(1));
+        withMock("mock:finally", mock -> mock.expectedMessageCount(1));
+        context.start();
+        withTemplate(t -> t.to("direct:start").withBody("Hello").send());
+        MockEndpoint.assertIsSatisfied(context, 10, TimeUnit.SECONDS);
+    }
+}
diff --git 
a/tooling/maven/camel-package-maven-plugin/src/main/resources/velocity/model-java-dsl-writer.vm
 
b/tooling/maven/camel-package-maven-plugin/src/main/resources/velocity/model-java-dsl-writer.vm
index ce06ff42ae16..12dc6184d1c6 100644
--- 
a/tooling/maven/camel-package-maven-plugin/src/main/resources/velocity/model-java-dsl-writer.vm
+++ 
b/tooling/maven/camel-package-maven-plugin/src/main/resources/velocity/model-java-dsl-writer.vm
@@ -37,7 +37,6 @@
  */
 package ${package};
 
-import java.util.ArrayList;
 import java.util.Base64;
 import java.util.List;
 import java.util.function.BiConsumer;
@@ -151,27 +150,7 @@ public class JavaDslModelWriter extends 
JavaDslModelWriterSupport {
                         #set( $foo = $elementRefs.add($root) )
                         #if( $list )
                             #if( $member.name == "outputs" )
-                            #if( $clazz.simpleName == "TryDefinition" )
-        List<ProcessorDefinition<?>> outputs = new 
ArrayList<>(def.getOutputs());
-        for (CatchDefinition clause : def.getCatchClauses()) {
-            if (!outputs.contains(clause)) {
-                int index = outputs.size();
-                for (int i = 0; i < outputs.size(); i++) {
-                    if (outputs.get(i) instanceof FinallyDefinition) {
-                        index = i;
-                        break;
-                    }
-                }
-                outputs.add(index, clause);
-            }
-        }
-        if (def.getFinallyClause() != null && 
!outputs.contains(def.getFinallyClause())) {
-            outputs.add(def.getFinallyClause());
-        }
-        doWriteOutputs(sb, outputs, this::doWrite${root.simpleName}Ref);
-                            #else
         doWriteOutputs(sb, def.${member.getter}(), 
this::doWrite${root.simpleName}Ref);
-                            #end
                             #else
                                 #set( $refName = $member.xmlElementRef.name() )
                                 #if( $refName && $refName != $default && 
$refName != "" )
diff --git 
a/tooling/maven/camel-package-maven-plugin/src/main/resources/velocity/model-writer.vm
 
b/tooling/maven/camel-package-maven-plugin/src/main/resources/velocity/model-writer.vm
index 8fb03247d608..4b15a7fce29a 100644
--- 
a/tooling/maven/camel-package-maven-plugin/src/main/resources/velocity/model-writer.vm
+++ 
b/tooling/maven/camel-package-maven-plugin/src/main/resources/velocity/model-writer.vm
@@ -39,7 +39,6 @@ package ${package};
 
 import java.io.IOException;
 import java.io.Writer;
-import java.util.ArrayList;
 import java.util.Base64;
 import java.util.List;
 import javax.annotation.processing.Generated;
@@ -145,27 +144,7 @@ public class ModelWriter extends BaseWriter {
                     #elseif( $member.xmlElementRef )
                         #set( $foo = $elementRefs.add($root) )
                         #if( $list )
-                            #if( $clazz.simpleName == "TryDefinition" && 
$member.name == "outputs" )
-        List<ProcessorDefinition<?>> outputs = new 
ArrayList<>(def.getOutputs());
-        for (CatchDefinition clause : def.getCatchClauses()) {
-            if (!outputs.contains(clause)) {
-                int index = outputs.size();
-                for (int i = 0; i < outputs.size(); i++) {
-                    if (outputs.get(i) instanceof FinallyDefinition) {
-                        index = i;
-                        break;
-                    }
-                }
-                outputs.add(index, clause);
-            }
-        }
-        if (def.getFinallyClause() != null && 
!outputs.contains(def.getFinallyClause())) {
-            outputs.add(def.getFinallyClause());
-        }
-        doWriteList(null, null, outputs, this::doWrite${root.simpleName}Ref);
-                            #else
         doWriteList(null, null, def.${member.getter}(), 
this::doWrite${root.simpleName}Ref);
-                            #end
                         #else
         doWriteElement(null, def.${member.getter}(), 
this::doWrite${root.simpleName}Ref);
                         #end
diff --git 
a/tooling/maven/camel-package-maven-plugin/src/main/resources/velocity/model-yaml-writer.vm
 
b/tooling/maven/camel-package-maven-plugin/src/main/resources/velocity/model-yaml-writer.vm
index 8f294d11b62f..127b2be78341 100644
--- 
a/tooling/maven/camel-package-maven-plugin/src/main/resources/velocity/model-yaml-writer.vm
+++ 
b/tooling/maven/camel-package-maven-plugin/src/main/resources/velocity/model-yaml-writer.vm
@@ -148,27 +148,7 @@ public class YamlModelWriter extends 
YamlModelWriterSupport {
                         #if( $list )
                             #set( $yamlKey = 
$yamlKeys.get("${clazz.simpleName}.${member.name}") )
                             #if( $member.name == "outputs" )
-                            #if( $clazz.simpleName == "TryDefinition" )
-        List<ProcessorDefinition<?>> outputs = new 
ArrayList<>(def.getOutputs());
-        for (CatchDefinition clause : def.getCatchClauses()) {
-            if (!outputs.contains(clause)) {
-                int index = outputs.size();
-                for (int i = 0; i < outputs.size(); i++) {
-                    if (outputs.get(i) instanceof FinallyDefinition) {
-                        index = i;
-                        break;
-                    }
-                }
-                outputs.add(index, clause);
-            }
-        }
-        if (def.getFinallyClause() != null && 
!outputs.contains(def.getFinallyClause())) {
-            outputs.add(def.getFinallyClause());
-        }
-        doWriteOutputs(jo, outputs, this::doWrite${root.simpleName}Ref);
-                            #else
         doWriteOutputs(jo, def.${member.getter}(), 
this::doWrite${root.simpleName}Ref);
-                            #end
                             #elseif( $clazz.simpleName == "RestDefinition" && 
$member.name == "verbs" )
         doWriteVerbs(jo, def.${member.getter}(), 
this::doWrite${root.simpleName});
                             #elseif( $yamlKey )

Reply via email to