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 ce2d847d55f2 CAMEL-25327: camel-jbang - the source validator finds the 
project's classes under src/main/java (#27349)
ce2d847d55f2 is described below

commit ce2d847d55f295b0b988072e4c3a8cda29eb4b87
Author: Claus Ibsen <[email protected]>
AuthorDate: Mon Oct 5 07:39:08 2026 +0200

    CAMEL-25327: camel-jbang - the source validator finds the project's classes 
under src/main/java (#27349)
    
    A bean whose class is in the Maven layout (src/main/java/camel/example/
    OrderNumber.java) was refused as "class camel.example.OrderNumber was not
    found", although camel run --source-dir compiles and runs that layout: the
    scan of the project listed only the files directly in the directory. It now
    reads the .java files under src/main/java too, and the hint names that 
place.
    
    
    Claude-Session: https://claude.ai/code/session_01STT6whBgK1AqsSsUKrnE8m
    
    Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
---
 .../dsl/jbang/core/commands/ai/BeanRefChecks.java  |  2 +-
 .../jbang/core/commands/ai/SourceValidator.java    | 12 ++++++++-
 .../commands/ai/SourceValidatorBeanRefsTest.java   | 30 ++++++++++++++++++++++
 3 files changed, 42 insertions(+), 2 deletions(-)

diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ai/BeanRefChecks.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ai/BeanRefChecks.java
index 6d29cd936d0b..d92d0ce65886 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ai/BeanRefChecks.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ai/BeanRefChecks.java
@@ -507,7 +507,7 @@ final class BeanRefChecks {
             }
         }
         if (hint.isEmpty()) {
-            hint = " (check the package name; a class of your own goes in a 
.java file next to the route; a class from"
+            hint = " (check the package name; a class of your own goes in a 
.java file next to the route or under src/main/java; a class from"
                    + " another library needs its dependency declared, 
camel.jbang.dependencies=<groupId>:<artifactId>:<version>"
                    + " in application.properties or --dep on camel run)";
         }
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ai/SourceValidator.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ai/SourceValidator.java
index aef6616b292a..3d572d282043 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ai/SourceValidator.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ai/SourceValidator.java
@@ -357,7 +357,17 @@ public final class SourceValidator {
                 return NONE;
             }
             try (var stream = Files.list(directory)) {
-                for (Path p : stream.filter(Files::isRegularFile).toList()) {
+                List<Path> files = new 
ArrayList<>(stream.filter(Files::isRegularFile).toList());
+                // a class of the project may also sit in the Maven layout, 
src/main/java/<package>/<Class>.java, which
+                // camel run --source-dir compiles too: without it a bean of 
that class was refused as not found
+                Path mavenSources = directory.resolve("src/main/java");
+                if (Files.isDirectory(mavenSources)) {
+                    try (var walk = Files.walk(mavenSources)) {
+                        walk.filter(Files::isRegularFile).filter(q -> 
q.getFileName().toString().endsWith(".java"))
+                                .forEach(files::add);
+                    }
+                }
+                for (Path p : files) {
                     String fn = p.getFileName().toString();
                     if (fn.equals(excludeFile)) {
                         continue;
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ai/SourceValidatorBeanRefsTest.java
 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ai/SourceValidatorBeanRefsTest.java
index aa5a2dbcb8a6..9fae923e1f89 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ai/SourceValidatorBeanRefsTest.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ai/SourceValidatorBeanRefsTest.java
@@ -97,6 +97,36 @@ public class SourceValidatorBeanRefsTest {
                 .isEmpty();
     }
 
+    @Test
+    void aClassOfTheProjectInTheMavenLayoutIsFound(@TempDir Path dir) throws 
IOException {
+        // camel run --source-dir compiles 
src/main/java/<package>/<Class>.java too, so a bean of that class is no error
+        // another class of the project, so the directory is known and the 
check judges; a name that is not on the test
+        // classpath (camel.example.OrderNumber is, for the bundled example 
tests)
+        Files.writeString(dir.resolve("Other.java"), "public class Other 
{}\n");
+        String beans = """
+                - beans:
+                  - name: shipmentNumber
+                    type: "#class:com.acme.shop.ShipmentNumber"
+                """;
+        assertThat(
+                SourceValidator.validate("beans.yaml", beans, CATALOG, null, 
dir))
+                .anyMatch(m -> m.contains("class com.acme.shop.ShipmentNumber 
was not found"));
+
+        Path pkg = 
Files.createDirectories(dir.resolve("src/main/java/com/acme/shop"));
+        Files.writeString(pkg.resolve("ShipmentNumber.java"), """
+                package com.acme.shop;
+
+                public class ShipmentNumber {
+                    public String next() {
+                        return "ORD-1001";
+                    }
+                }
+                """);
+        assertThat(
+                SourceValidator.validate("beans.yaml", beans, CATALOG, null, 
dir))
+                .isEmpty();
+    }
+
     @Test
     void classReferencesPlaceholdersAndUnknownDirectoryAreLeftAlone(@TempDir 
Path dir) {
         String yaml = ROUTE.replace("aggregationStrategy: myAggregator",

Reply via email to