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

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

commit 0eedf3f2fbe996b08c2e2ab89a8eeafea0d9ea3c
Author: Claus Ibsen <[email protected]>
AuthorDate: Wed Jan 7 15:28:04 2026 +0100

    CAMEL-22818: camel-core - AdviceWith should pin point to same resource so 
route coverage can correlate
---
 .../camel-spring-parent/camel-spring-xml/pom.xml   |   4 +
 .../spring/DumpModelAsXmlPlaceholdersTest.java     |   2 +-
 .../SpringDumpRouteCoverageAdviceWithTest.java     |  84 ++++++++++++++++
 .../XmlIoDumpRouteCoverageAdviceWithTest.java      | 109 +++++++++++++++++++++
 .../SpringDumpRouteCoverageAdviceWithTest.xml      |  36 +++++++
 .../XmlIoDumpRouteCoverageAdviceWithTest.xml       |  27 +++++
 .../java/org/apache/camel/builder/AdviceWith.java  |   8 ++
 .../org/apache/camel/builder/AdviceWithTasks.java  |  27 ++---
 .../camel/issues/AdviceWithWeaveByIdTest.java      |  56 +++++++++++
 .../management/mbean/ManagedCamelContext.java      |   2 +-
 .../org/apache/camel/xml/LwModelToXMLDumper.java   |   4 +-
 11 files changed, 345 insertions(+), 14 deletions(-)

diff --git a/components/camel-spring-parent/camel-spring-xml/pom.xml 
b/components/camel-spring-parent/camel-spring-xml/pom.xml
index b538df65a13d..d680e7e818fa 100644
--- a/components/camel-spring-parent/camel-spring-xml/pom.xml
+++ b/components/camel-spring-parent/camel-spring-xml/pom.xml
@@ -48,6 +48,10 @@
             <groupId>org.apache.camel</groupId>
             <artifactId>camel-spring</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-xml-io</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.apache.camel</groupId>
             <artifactId>camel-xml-jaxb</artifactId>
diff --git 
a/components/camel-spring-parent/camel-spring-xml/src/test/java/org/apache/camel/spring/DumpModelAsXmlPlaceholdersTest.java
 
b/components/camel-spring-parent/camel-spring-xml/src/test/java/org/apache/camel/spring/DumpModelAsXmlPlaceholdersTest.java
index 8234b73068f5..94c1a60fa2f1 100644
--- 
a/components/camel-spring-parent/camel-spring-xml/src/test/java/org/apache/camel/spring/DumpModelAsXmlPlaceholdersTest.java
+++ 
b/components/camel-spring-parent/camel-spring-xml/src/test/java/org/apache/camel/spring/DumpModelAsXmlPlaceholdersTest.java
@@ -42,7 +42,7 @@ public class DumpModelAsXmlPlaceholdersTest extends 
SpringTestSupport {
         assertNotNull(xml);
         log.info(xml);
 
-        assertTrue(xml.contains("<route 
xmlns=\"http://camel.apache.org/schema/spring\"; id=\"Gouda\">"));
+        assertTrue(xml.contains("id=\"Gouda\">"));
         assertTrue(xml.contains("\"direct:start-{{cheese.type}}\""));
         assertTrue(xml.contains("\"direct:end-{{cheese.type}}\""));
     }
diff --git 
a/components/camel-spring-parent/camel-spring-xml/src/test/java/org/apache/camel/spring/management/SpringDumpRouteCoverageAdviceWithTest.java
 
b/components/camel-spring-parent/camel-spring-xml/src/test/java/org/apache/camel/spring/management/SpringDumpRouteCoverageAdviceWithTest.java
new file mode 100644
index 000000000000..887f45e527ee
--- /dev/null
+++ 
b/components/camel-spring-parent/camel-spring-xml/src/test/java/org/apache/camel/spring/management/SpringDumpRouteCoverageAdviceWithTest.java
@@ -0,0 +1,84 @@
+/*
+ * 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.spring.management;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import org.w3c.dom.Document;
+
+import org.apache.camel.builder.AdviceWith;
+import org.apache.camel.spring.SpringTestSupport;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.DisabledOnOs;
+import org.junit.jupiter.api.condition.OS;
+import org.springframework.context.support.AbstractXmlApplicationContext;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@DisabledOnOs(OS.AIX)
+public class SpringDumpRouteCoverageAdviceWithTest extends SpringTestSupport {
+
+    @Override
+    protected boolean useJmx() {
+        return true;
+    }
+
+    @Override
+    public boolean isUseAdviceWith() {
+        return true;
+    }
+
+    @Override
+    protected AbstractXmlApplicationContext createApplicationContext() {
+        return new ClassPathXmlApplicationContext(
+                
"org/apache/camel/spring/management/SpringDumpRouteCoverageAdviceWithTest.xml");
+    }
+
+    protected MBeanServer getMBeanServer() {
+        return 
context.getManagementStrategy().getManagementAgent().getMBeanServer();
+    }
+
+    @Test
+    public void testDumpRouteCoverage() throws Exception {
+        AdviceWith.adviceWith(context, "hello-process-pipeline", advice -> {
+            
advice.weaveById("target-id").replace().to("mock:hello").id("target-id");
+        });
+
+        context.start();
+
+        // get the stats for the route
+        MBeanServer mbeanServer = getMBeanServer();
+        ObjectName on = getContextObjectName();
+
+        getMockEndpoint("mock:hello").expectedMessageCount(1);
+        template.sendBody("direct:hello-process", "Hello World");
+        assertMockEndpointsSatisfied();
+
+        String xml = (String) mbeanServer.invoke(on, 
"dumpRoutesCoverageAsXml", null, null);
+        log.info(xml);
+
+        assertTrue(xml.contains("exchangesTotal=\"1\""));
+
+        // should be valid XML
+        Document doc = context.getTypeConverter().convertTo(Document.class, 
xml);
+        assertNotNull(doc);
+    }
+
+}
diff --git 
a/components/camel-spring-parent/camel-spring-xml/src/test/java/org/apache/camel/spring/management/XmlIoDumpRouteCoverageAdviceWithTest.java
 
b/components/camel-spring-parent/camel-spring-xml/src/test/java/org/apache/camel/spring/management/XmlIoDumpRouteCoverageAdviceWithTest.java
new file mode 100644
index 000000000000..839976cc3ec4
--- /dev/null
+++ 
b/components/camel-spring-parent/camel-spring-xml/src/test/java/org/apache/camel/spring/management/XmlIoDumpRouteCoverageAdviceWithTest.java
@@ -0,0 +1,109 @@
+/*
+ * 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.spring.management;
+
+import java.io.InputStream;
+
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+
+import org.w3c.dom.Document;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.AdviceWith;
+import org.apache.camel.model.RoutesDefinition;
+import org.apache.camel.util.IOHelper;
+import org.apache.camel.xml.LwModelHelper;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.condition.DisabledOnOs;
+import org.junit.jupiter.api.condition.OS;
+
+import static 
org.apache.camel.management.DefaultManagementAgent.DEFAULT_DOMAIN;
+import static 
org.apache.camel.management.DefaultManagementObjectNameStrategy.KEY_CONTEXT;
+import static 
org.apache.camel.management.DefaultManagementObjectNameStrategy.KEY_NAME;
+import static 
org.apache.camel.management.DefaultManagementObjectNameStrategy.KEY_TYPE;
+import static 
org.apache.camel.management.DefaultManagementObjectNameStrategy.TYPE_CONTEXT;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+@DisabledOnOs(OS.AIX)
+public class XmlIoDumpRouteCoverageAdviceWithTest extends ContextTestSupport {
+
+    @Override
+    protected boolean useJmx() {
+        return true;
+    }
+
+    @Override
+    public boolean isUseAdviceWith() {
+        return true;
+    }
+
+    protected MBeanServer getMBeanServer() {
+        return 
context.getManagementStrategy().getManagementAgent().getMBeanServer();
+    }
+
+    @Test
+    public void testDumpRouteCoverage() throws Exception {
+        InputStream is = this.getClass()
+                
.getResourceAsStream("XmlIoDumpRouteCoverageAdviceWithTest.xml");
+        RoutesDefinition routes = LwModelHelper.loadRoutesDefinition(is);
+        context.addRouteDefinition(routes.getRoutes().get(0));
+        IOHelper.close(is);
+
+        AdviceWith.adviceWith(context, "hello-process-pipeline", advice -> {
+            advice.weaveById("target-id").replace().to("mock:hello");
+        });
+
+        context.start();
+
+        // get the stats for the route
+        MBeanServer mbeanServer = getMBeanServer();
+        ObjectName on = getContextObjectName();
+
+        getMockEndpoint("mock:hello").expectedMessageCount(1);
+        template.sendBody("direct:hello-process", "Hello World");
+        assertMockEndpointsSatisfied();
+
+        String xml = (String) mbeanServer.invoke(on, 
"dumpRoutesCoverageAsXml", null, null);
+        log.info(xml);
+
+        // advice replaced <log> -> <to> which we should find in the XML dump
+        assertTrue(xml.contains("<to exchangesTotal=\"1\""));
+        assertTrue(xml.contains("uri=\"mock:hello\""));
+        assertTrue(xml.contains("sourceLineNumber=\"24\""));
+
+        // should be valid XML
+        Document doc = context.getTypeConverter().convertTo(Document.class, 
xml);
+        assertNotNull(doc);
+    }
+
+    private ObjectName getContextObjectName() throws 
MalformedObjectNameException {
+        return getCamelObjectName(TYPE_CONTEXT, context.getName());
+    }
+
+    private ObjectName getCamelObjectName(String type, String name) throws 
MalformedObjectNameException {
+        String quote = "\"";
+        String on = DEFAULT_DOMAIN + ":"
+                    + KEY_CONTEXT + "=" + context.getManagementName() + ","
+                    + KEY_TYPE + "=" + type + ","
+                    + KEY_NAME + "=" + quote + name + quote;
+        return ObjectName.getInstance(on);
+    }
+
+}
diff --git 
a/components/camel-spring-parent/camel-spring-xml/src/test/resources/org/apache/camel/spring/management/SpringDumpRouteCoverageAdviceWithTest.xml
 
b/components/camel-spring-parent/camel-spring-xml/src/test/resources/org/apache/camel/spring/management/SpringDumpRouteCoverageAdviceWithTest.xml
new file mode 100644
index 000000000000..339b3b2ad7c5
--- /dev/null
+++ 
b/components/camel-spring-parent/camel-spring-xml/src/test/resources/org/apache/camel/spring/management/SpringDumpRouteCoverageAdviceWithTest.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans";
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+       xsi:schemaLocation="
+       http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd
+       http://camel.apache.org/schema/spring 
http://camel.apache.org/schema/spring/camel-spring.xsd
+    ">
+
+    <camelContext xmlns="http://camel.apache.org/schema/spring";>
+        <route id="hello-process-pipeline">
+            <from uri="direct:hello-process"/>
+            <log message="hello-process Start"/>
+            <log message="some message" id="target-id"/>
+            <log message="hello-process Done"/>
+        </route>
+    </camelContext>
+
+</beans>
diff --git 
a/components/camel-spring-parent/camel-spring-xml/src/test/resources/org/apache/camel/spring/management/XmlIoDumpRouteCoverageAdviceWithTest.xml
 
b/components/camel-spring-parent/camel-spring-xml/src/test/resources/org/apache/camel/spring/management/XmlIoDumpRouteCoverageAdviceWithTest.xml
new file mode 100644
index 000000000000..d0aa2e3475f7
--- /dev/null
+++ 
b/components/camel-spring-parent/camel-spring-xml/src/test/resources/org/apache/camel/spring/management/XmlIoDumpRouteCoverageAdviceWithTest.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<routes xmlns="http://camel.apache.org/schema/xml-io";>
+    <route id="hello-process-pipeline">
+        <from uri="direct:hello-process"/>
+        <log message="hello-process Start"/>
+        <log message="some message" id="target-id"/>
+        <log message="hello-process Done"/>
+    </route>
+</routes>
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/builder/AdviceWith.java 
b/core/camel-core-model/src/main/java/org/apache/camel/builder/AdviceWith.java
index d21ae501fc8e..4dd8af70b4b1 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/builder/AdviceWith.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/builder/AdviceWith.java
@@ -202,6 +202,14 @@ public final class AdviceWith {
         ExtendedCamelContext ecc = camelContext.getCamelContextExtension();
         Model model = 
camelContext.getCamelContextExtension().getContextPlugin(Model.class);
 
+        // before we can advice then the input route must be prepared
+        if (!definition.isPrepared()) {
+            RoutesDefinition routes = new RoutesDefinition();
+            routes.setCamelContext(camelContext);
+            routes.setResource(definition.getResource());
+            routes.prepareRoute(definition);
+        }
+
         // inject this route into the advice route builder so it can access 
this route
         // and offer features to manipulate the route directly
         if (builder instanceof AdviceWithRouteBuilder arb) {
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/builder/AdviceWithTasks.java
 
b/core/camel-core-model/src/main/java/org/apache/camel/builder/AdviceWithTasks.java
index b7a00aa91094..5aaff2c3a22f 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/builder/AdviceWithTasks.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/builder/AdviceWithTasks.java
@@ -22,6 +22,7 @@ import java.util.Iterator;
 import java.util.List;
 
 import org.apache.camel.Endpoint;
+import org.apache.camel.LineNumberAware;
 import org.apache.camel.model.AdviceWithDefinition;
 import org.apache.camel.model.ChoiceDefinition;
 import org.apache.camel.model.EndpointRequiredDefinition;
@@ -223,14 +224,14 @@ public final class AdviceWithTasks {
                             int index = outputs.indexOf(output);
                             if (index != -1) {
                                 match = true;
+                                ProcessorDefinition existing = 
outputs.remove(index);
                                 // flattern as replace uses a pipeline as 
temporary holder
-                                ProcessorDefinition<?> flattern = 
flatternOutput(replace);
-                                outputs.add(index + 1, flattern);
-                                Object old = outputs.remove(index);
+                                ProcessorDefinition<?> flattern = 
flatternOutput(replace, existing);
+                                outputs.add(index, flattern);
                                 // must set parent on the node we added in the 
route
                                 ProcessorDefinition<?> parent = 
output.getParent() != null ? output.getParent() : route;
                                 flattern.setParent(parent);
-                                LOG.info("AdviceWith ({}) : [{}] --> replace 
[{}]", matchBy.getId(), old, flattern);
+                                LOG.info("AdviceWith ({}) : [{}] --> replace 
[{}]", matchBy.getId(), existing, flattern);
                             }
                         }
                     }
@@ -355,9 +356,9 @@ public final class AdviceWithTasks {
                             int index = outputs.indexOf(output);
                             if (index != -1) {
                                 match = true;
+                                ProcessorDefinition existing = 
outputs.get(index);
                                 // flattern as before uses a pipeline as 
temporary holder
-                                ProcessorDefinition<?> flattern = 
flatternOutput(before);
-                                Object existing = outputs.get(index);
+                                ProcessorDefinition<?> flattern = 
flatternOutput(before, existing);
                                 outputs.add(index, flattern);
                                 // must set parent on the node we added in the 
route
                                 ProcessorDefinition<?> parent = 
output.getParent() != null ? output.getParent() : route;
@@ -425,9 +426,9 @@ public final class AdviceWithTasks {
                             int index = outputs.indexOf(output);
                             if (index != -1) {
                                 match = true;
+                                ProcessorDefinition existing = 
outputs.get(index);
                                 // flattern as after uses a pipeline as 
temporary holder
-                                ProcessorDefinition<?> flattern = 
flatternOutput(after);
-                                Object existing = outputs.get(index);
+                                ProcessorDefinition<?> flattern = 
flatternOutput(after, existing);
                                 outputs.add(index + 1, flattern);
                                 // must set parent on the node we added in the 
route
                                 ProcessorDefinition<?> parent = 
output.getParent() != null ? output.getParent() : route;
@@ -635,17 +636,21 @@ public final class AdviceWithTasks {
         };
     }
 
-    private static ProcessorDefinition<?> 
flatternOutput(ProcessorDefinition<?> output) {
+    private static ProcessorDefinition<?> 
flatternOutput(ProcessorDefinition<?> output, LineNumberAware source) {
         if (output instanceof AdviceWithDefinition advice) {
+            // copy over location from source so the advised nodes also have 
same location
+            advice.getOutputs().forEach(o -> 
LineNumberAware.trySetLineNumberAware(o, source));
             if (advice.getOutputs().size() == 1) {
-                return advice.getOutputs().get(0);
+                output = advice.getOutputs().get(0);
             } else {
                 // it should be a pipeline
                 PipelineDefinition pipe = new PipelineDefinition();
                 pipe.setOutputs(advice.getOutputs());
-                return pipe;
+                output = pipe;
             }
         }
+        // copy over location from source so the advised nodes also have same 
location
+        LineNumberAware.trySetLineNumberAware(output, source);
         return output;
     }
 
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/issues/AdviceWithWeaveByIdTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/issues/AdviceWithWeaveByIdTest.java
new file mode 100644
index 000000000000..6b4c822cccbd
--- /dev/null
+++ 
b/core/camel-core/src/test/java/org/apache/camel/issues/AdviceWithWeaveByIdTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.issues;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.AdviceWith;
+import org.apache.camel.builder.AdviceWithRouteBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.junit.jupiter.api.Test;
+
+public class AdviceWithWeaveByIdTest extends ContextTestSupport {
+
+    @Test
+    public void testWeaveByType() throws Exception {
+        AdviceWith.adviceWith(context.getRouteDefinitions().get(0), context, 
new AdviceWithRouteBuilder() {
+            @Override
+            public void configure() {
+                weaveById("target-id").replace().to("mock:baz");
+            }
+        });
+
+        getMockEndpoint("mock:baz").expectedMessageCount(1);
+
+        template.sendBody("direct:start", "World");
+
+        assertMockEndpointsSatisfied();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                from("direct:start")
+                        .log("a")
+                        .log("b").id("target-id")
+                        .log("c");
+            }
+        };
+    }
+
+}
diff --git 
a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
 
b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
index 6b88d05205a0..cfd2bb3d7693 100644
--- 
a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
+++ 
b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
@@ -894,7 +894,7 @@ public class ManagedCamelContext extends 
ManagedPerformanceCounter implements Ti
                         getExchangesTotal(), getTotalProcessingTime()))
                 .append(">\n");
 
-        String xml = dumpRoutesAsXml(false, true);
+        String xml = dumpRoutesAsXml(false, true, true);
         if (xml != null) {
             // use the coverage xml parser to dump the routes and enrich with 
coverage stats
             Document dom = RouteCoverageXmlParser.parseXml(context, new 
ByteArrayInputStream(xml.getBytes()));
diff --git 
a/core/camel-xml-io/src/main/java/org/apache/camel/xml/LwModelToXMLDumper.java 
b/core/camel-xml-io/src/main/java/org/apache/camel/xml/LwModelToXMLDumper.java
index f009c7803570..eb0edb17e547 100644
--- 
a/core/camel-xml-io/src/main/java/org/apache/camel/xml/LwModelToXMLDumper.java
+++ 
b/core/camel-xml-io/src/main/java/org/apache/camel/xml/LwModelToXMLDumper.java
@@ -104,10 +104,12 @@ public class LwModelToXMLDumper implements 
ModelToXMLDumper {
                 }
                 // write location information
                 if (sourceLocation || context.isDebugging()) {
-                    String loc = (def instanceof RouteDefinition ? 
((RouteDefinition) def).getInput() : def).getLocation();
                     int line = (def instanceof RouteDefinition ? 
((RouteDefinition) def).getInput() : def).getLineNumber();
                     if (line != -1) {
                         writer.addAttribute("sourceLineNumber", 
Integer.toString(line));
+                    }
+                    String loc = (def instanceof RouteDefinition ? 
((RouteDefinition) def).getInput() : def).getLocation();
+                    if (loc != null) {
                         writer.addAttribute("sourceLocation", loc);
                     }
                 }

Reply via email to