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 5d8105299db camel-jbang - Should export using lazy beans (#15575)
5d8105299db is described below

commit 5d8105299db092601be6fc9ecc77adfd79314ac6
Author: Claus Ibsen <[email protected]>
AuthorDate: Mon Sep 16 14:14:31 2024 +0200

    camel-jbang - Should export using lazy beans (#15575)
    
    * CAMEL-21138: camel-jbang - Export should use lazy bean. Only possible for 
factory method beans such as @Produces
    
    * Fixed test
---
 .../camel/spring/xml/CamelBeanPostProcessor.java   | 15 ++++++++
 .../management/SpringManagedSedaEndpointTest.java  |  2 +-
 .../camel/spring/spi/CamelBeanPostProcessor.java   | 13 +++++++
 .../apache/camel/spi/CamelBeanPostProcessor.java   | 12 +++++++
 .../impl/engine/DefaultCamelBeanPostProcessor.java | 29 +++++++++++++---
 .../ROOT/pages/camel-4x-upgrade-guide-4_9.adoc     |  4 +++
 .../camel/dsl/jbang/core/commands/Export.java      |  1 +
 .../dsl/jbang/core/commands/ExportBaseCommand.java |  7 +++-
 .../dsl/jbang/core/commands/ExportCamelMain.java   |  2 +-
 .../dsl/jbang/core/commands/ExportQuarkus.java     |  2 +-
 .../dsl/jbang/core/commands/ExportSpringBoot.java  |  2 +-
 .../apache/camel/dsl/jbang/core/commands/Run.java  |  9 +++++
 .../camel/dsl/jbang/core/commands/ExportTest.java  | 19 +++++++++-
 .../src/test/resources/LazyFoo.java                | 27 +++++++++++++++
 .../java/org/apache/camel/main/KameletMain.java    |  4 ++-
 .../injection/AnnotationDependencyInjection.java   | 40 ++++++++++++++++------
 16 files changed, 165 insertions(+), 23 deletions(-)

diff --git 
a/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/CamelBeanPostProcessor.java
 
b/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/CamelBeanPostProcessor.java
index af05b7ff10d..d8d298a5e47 100644
--- 
a/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/CamelBeanPostProcessor.java
+++ 
b/components/camel-spring-xml/src/main/java/org/apache/camel/spring/xml/CamelBeanPostProcessor.java
@@ -19,12 +19,14 @@ package org.apache.camel.spring.xml;
 import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Set;
+import java.util.function.Predicate;
 
 import jakarta.xml.bind.annotation.XmlAccessType;
 import jakarta.xml.bind.annotation.XmlAccessorType;
 import jakarta.xml.bind.annotation.XmlRootElement;
 import jakarta.xml.bind.annotation.XmlTransient;
 
+import org.apache.camel.BindToRegistry;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Endpoint;
 import org.apache.camel.Service;
@@ -65,6 +67,8 @@ public class CamelBeanPostProcessor
     private String camelId;
     @XmlTransient
     private boolean bindToRegistrySupported;
+    @XmlTransient
+    private Predicate<BindToRegistry> lazyBeanStrategy;
 
     // must use a delegate, as we cannot extend DefaultCamelBeanPostProcessor, 
as this will cause the
     // XSD schema generator to include the DefaultCamelBeanPostProcessor as a 
type, which we do not want to
@@ -234,4 +238,15 @@ public class CamelBeanPostProcessor
     public boolean isEnabled() {
         return delegate.isEnabled();
     }
+
+    @Override
+    public void setLazyBeanStrategy(Predicate<BindToRegistry> strategy) {
+        this.lazyBeanStrategy = strategy;
+    }
+
+    @Override
+    public Predicate<BindToRegistry> getLazyBeanStrategy() {
+        return lazyBeanStrategy;
+    }
+
 }
diff --git 
a/components/camel-spring-xml/src/test/java/org/apache/camel/spring/management/SpringManagedSedaEndpointTest.java
 
b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/management/SpringManagedSedaEndpointTest.java
index ef2f2210044..ec647abe60d 100644
--- 
a/components/camel-spring-xml/src/test/java/org/apache/camel/spring/management/SpringManagedSedaEndpointTest.java
+++ 
b/components/camel-spring-xml/src/test/java/org/apache/camel/spring/management/SpringManagedSedaEndpointTest.java
@@ -82,7 +82,7 @@ public class SpringManagedSedaEndpointTest extends 
SpringTestSupport {
         size = (Integer) mbeanServer.getAttribute(name, "CurrentQueueSize");
         assertEquals(1, size.intValue());
 
-        Long size2 = (Long) mbeanServer.invoke(name, "queueSize", null, null);
+        Integer size2 = (Integer) mbeanServer.invoke(name, "queueSize", null, 
null);
         assertEquals(1, size2.longValue());
 
         String out
diff --git 
a/components/camel-spring/src/main/java/org/apache/camel/spring/spi/CamelBeanPostProcessor.java
 
b/components/camel-spring/src/main/java/org/apache/camel/spring/spi/CamelBeanPostProcessor.java
index 3c50c04e5e3..a616c10f304 100644
--- 
a/components/camel-spring/src/main/java/org/apache/camel/spring/spi/CamelBeanPostProcessor.java
+++ 
b/components/camel-spring/src/main/java/org/apache/camel/spring/spi/CamelBeanPostProcessor.java
@@ -19,7 +19,9 @@ package org.apache.camel.spring.spi;
 import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Set;
+import java.util.function.Predicate;
 
+import org.apache.camel.BindToRegistry;
 import org.apache.camel.CamelContext;
 import org.apache.camel.CamelContextAware;
 import org.apache.camel.Endpoint;
@@ -53,6 +55,7 @@ public class CamelBeanPostProcessor
     private ApplicationContext applicationContext;
     private String camelId;
     private boolean bindToRegistrySupported;
+    private Predicate<BindToRegistry> lazyBeanStrategy;
 
     // must use a delegate, as we cannot extend DefaultCamelBeanPostProcessor, 
as this will cause the
     // XSD schema generator to include the DefaultCamelBeanPostProcessor as a 
type, which we do not want to
@@ -238,4 +241,14 @@ public class CamelBeanPostProcessor
     public boolean isEnabled() {
         return delegate.isEnabled();
     }
+
+    @Override
+    public void setLazyBeanStrategy(Predicate<BindToRegistry> strategy) {
+        this.lazyBeanStrategy = strategy;
+    }
+
+    @Override
+    public Predicate<BindToRegistry> getLazyBeanStrategy() {
+        return lazyBeanStrategy;
+    }
 }
diff --git 
a/core/camel-api/src/main/java/org/apache/camel/spi/CamelBeanPostProcessor.java 
b/core/camel-api/src/main/java/org/apache/camel/spi/CamelBeanPostProcessor.java
index 1fff61155a4..ce38b989e30 100644
--- 
a/core/camel-api/src/main/java/org/apache/camel/spi/CamelBeanPostProcessor.java
+++ 
b/core/camel-api/src/main/java/org/apache/camel/spi/CamelBeanPostProcessor.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.spi;
 
+import org.apache.camel.BindToRegistry;
+
 /**
  * Bean post processor.
  */
@@ -92,4 +94,14 @@ public interface CamelBeanPostProcessor {
         // noop
     }
 
+    /**
+     * Custom strategy for handling {@link BindToRegistry} beans and whether 
they are lazy or not.
+     */
+    void setLazyBeanStrategy(java.util.function.Predicate<BindToRegistry> 
strategy);
+
+    /**
+     * Custom strategy for handling {@link BindToRegistry} beans and whether 
they are lazy or not.
+     */
+    java.util.function.Predicate<BindToRegistry> getLazyBeanStrategy();
+
 }
diff --git 
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java
 
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java
index 7fd5cdbf967..4f5b7052ba9 100644
--- 
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java
+++ 
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultCamelBeanPostProcessor.java
@@ -23,6 +23,7 @@ import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.List;
 import java.util.function.Function;
+import java.util.function.Predicate;
 import java.util.function.Supplier;
 
 import org.apache.camel.BeanConfigInject;
@@ -70,6 +71,7 @@ public class DefaultCamelBeanPostProcessor implements 
CamelBeanPostProcessor, Ca
     protected CamelContext camelContext;
     protected boolean enabled = true;
     protected boolean unbindEnabled;
+    protected java.util.function.Predicate<BindToRegistry> lazyBeanStrategy;
 
     public DefaultCamelBeanPostProcessor() {
     }
@@ -108,6 +110,16 @@ public class DefaultCamelBeanPostProcessor implements 
CamelBeanPostProcessor, Ca
         this.unbindEnabled = unbindEnabled;
     }
 
+    @Override
+    public Predicate<BindToRegistry> getLazyBeanStrategy() {
+        return lazyBeanStrategy;
+    }
+
+    @Override
+    public void setLazyBeanStrategy(Predicate<BindToRegistry> 
lazyBeanStrategy) {
+        this.lazyBeanStrategy = lazyBeanStrategy;
+    }
+
     @Override
     public void addCamelBeanPostProjectInjector(CamelBeanPostProcessorInjector 
injector) {
         this.beanPostProcessorInjectors.add(injector);
@@ -405,9 +417,9 @@ public class DefaultCamelBeanPostProcessor implements 
CamelBeanPostProcessor, Ca
 
         // bind each method
         methods.forEach(method -> {
-            BindToRegistry bind = method.getAnnotation(BindToRegistry.class);
-            bindToRegistry(method, bind.value(), bean, beanName, 
bind.beanPostProcess(), bind.lazy(), bind.initMethod(),
-                    bind.destroyMethod());
+            BindToRegistry ann = method.getAnnotation(BindToRegistry.class);
+            bindToRegistry(method, ann.value(), bean, beanName, 
ann.beanPostProcess(), isLazyBean(ann), ann.initMethod(),
+                    ann.destroyMethod());
         });
     }
 
@@ -415,7 +427,7 @@ public class DefaultCamelBeanPostProcessor implements 
CamelBeanPostProcessor, Ca
         Class<?> clazz = bean.getClass();
         BindToRegistry ann = clazz.getAnnotation(BindToRegistry.class);
         if (ann != null) {
-            bindToRegistry(clazz, ann.value(), bean, beanName, 
ann.beanPostProcess(), ann.lazy(), ann.initMethod(),
+            bindToRegistry(clazz, ann.value(), bean, beanName, 
ann.beanPostProcess(), isLazyBean(ann), ann.initMethod(),
                     ann.destroyMethod());
         }
     }
@@ -425,7 +437,7 @@ public class DefaultCamelBeanPostProcessor implements 
CamelBeanPostProcessor, Ca
             BindToRegistry ann = clazz.getAnnotation(BindToRegistry.class);
             if (ann != null) {
                 // it is a nested class so we don't have a bean instance for it
-                bindToRegistry(clazz, ann.value(), null, null, 
ann.beanPostProcess(), ann.lazy(), ann.initMethod(),
+                bindToRegistry(clazz, ann.value(), null, null, 
ann.beanPostProcess(), isLazyBean(ann), ann.initMethod(),
                         ann.destroyMethod());
             }
         });
@@ -459,6 +471,13 @@ public class DefaultCamelBeanPostProcessor implements 
CamelBeanPostProcessor, Ca
         }
     }
 
+    protected boolean isLazyBean(BindToRegistry ann) {
+        if (lazyBeanStrategy == null) {
+            return ann.lazy();
+        }
+        return lazyBeanStrategy.test(ann);
+    }
+
     public void setterInjection(Method method, Object bean, String beanName, 
String endpointUri, String endpointProperty) {
         Class<?>[] parameterTypes = method.getParameterTypes();
         if (parameterTypes.length != 1) {
diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_9.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_9.adoc
index 867639fe171..dd7381688c2 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_9.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_9.adoc
@@ -6,6 +6,10 @@ from both 4.0 to 4.1 and 4.1 to 4.2.
 
 == Upgrading Camel 4.8 to 4.9
 
+=== camel-api
+
+Added `setLazyBeanStrategy`/`getLazyBeanStrategy` methods to 
`org.apache.camel.spi.CamelBeanPostProcessor`.
+
 === camel-management
 
 The `queueSize` attribute on endpoints which are `ManagedBrowseableEndpoint` 
is changed from returning a `Long` value
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Export.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Export.java
index 70adc51d5df..b12f1515499 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Export.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Export.java
@@ -147,6 +147,7 @@ public class Export extends ExportBaseCommand {
         cmd.packageName = this.packageName;
         cmd.excludes = this.excludes;
         cmd.ignoreLoadingError = this.ignoreLoadingError;
+        cmd.lazyBean = this.lazyBean;
         // run export
         return cmd.export();
     }
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportBaseCommand.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportBaseCommand.java
index c50b50ccf2d..0025b60493a 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportBaseCommand.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportBaseCommand.java
@@ -218,6 +218,10 @@ public abstract class ExportBaseCommand extends 
CamelCommand {
                         description = "Whether to ignore route loading and 
compilation errors (use this with care!)")
     protected boolean ignoreLoadingError;
 
+    @CommandLine.Option(names = { "--lazy-bean" },
+                        description = "Whether to use lazy bean initialization 
(can help with complex classloading issues")
+    protected boolean lazyBean;
+
     protected boolean symbolicLink;     // copy source files using symbolic 
link
 
     protected boolean javaLiveReload; // reload java codes in dev
@@ -296,7 +300,7 @@ public abstract class ExportBaseCommand extends 
CamelCommand {
         return null;
     }
 
-    protected Integer runSilently(boolean ignoreLoadingError) throws Exception 
{
+    protected Integer runSilently(boolean ignoreLoadingError, boolean 
lazyBean) throws Exception {
         Run run = new Run(getMain());
         // need to declare the profile to use for run
         run.dependencies = dependencies;
@@ -311,6 +315,7 @@ public abstract class ExportBaseCommand extends 
CamelCommand {
         run.kameletsVersion = kameletsVersion;
         run.localKameletDir = localKameletDir;
         run.ignoreLoadingError = ignoreLoadingError;
+        run.lazyBean = lazyBean;
         return run.runExport(ignoreLoadingError);
     }
 
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportCamelMain.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportCamelMain.java
index d47a5b35c1f..709552d1e10 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportCamelMain.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportCamelMain.java
@@ -65,7 +65,7 @@ class ExportCamelMain extends Export {
             if (!quiet && fresh) {
                 printer().println("Generating fresh run data");
             }
-            int silent = runSilently(ignoreLoadingError);
+            int silent = runSilently(ignoreLoadingError, lazyBean);
             if (silent != 0) {
                 return silent;
             }
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportQuarkus.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportQuarkus.java
index 4c2fa09585d..88914af1179 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportQuarkus.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportQuarkus.java
@@ -69,7 +69,7 @@ class ExportQuarkus extends Export {
             if (!quiet) {
                 printer().println("Generating fresh run data");
             }
-            int silent = runSilently(ignoreLoadingError);
+            int silent = runSilently(ignoreLoadingError, lazyBean);
             if (silent != 0) {
                 return silent;
             }
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportSpringBoot.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportSpringBoot.java
index 07cbe64ff9d..72979ac35b9 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportSpringBoot.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/ExportSpringBoot.java
@@ -67,7 +67,7 @@ class ExportSpringBoot extends Export {
             if (!quiet) {
                 printer().println("Generating fresh run data");
             }
-            int silent = runSilently(ignoreLoadingError);
+            int silent = runSilently(ignoreLoadingError, lazyBean);
             if (silent != 0) {
                 return silent;
             }
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java
index 02e49777bdd..8aa6b5c4d85 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java
@@ -283,6 +283,10 @@ public class Run extends CamelCommand {
             description = "Whether to ignore route loading and compilation 
errors (use this with care!)")
     protected boolean ignoreLoadingError;
 
+    @Option(names = { "--lazy-bean" },
+            description = "Whether to use lazy bean initialization (can help 
with complex classloading issues")
+    protected boolean lazyBean;
+
     @Option(names = { "--prompt" },
             description = "Allow user to type in required parameters in prompt 
if not present in application")
     boolean prompt;
@@ -529,6 +533,9 @@ public class Run extends CamelCommand {
         if (ignoreLoadingError) {
             writeSetting(main, profileProperties, 
"camel.jbang.ignoreLoadingError", "true");
         }
+        if (lazyBean) {
+            writeSetting(main, profileProperties, "camel.jbang.lazyBean", 
"true");
+        }
         if (prompt) {
             writeSetting(main, profileProperties, "camel.jbang.prompt", 
"true");
         }
@@ -892,6 +899,7 @@ public class Run extends CamelCommand {
         eq.logging = false;
         eq.loggingLevel = "off";
         eq.ignoreLoadingError = this.ignoreLoadingError;
+        eq.lazyBean = this.lazyBean;
 
         // run export
         int exit = eq.export();
@@ -966,6 +974,7 @@ public class Run extends CamelCommand {
         eq.logging = false;
         eq.loggingLevel = "off";
         eq.ignoreLoadingError = this.ignoreLoadingError;
+        eq.lazyBean = this.lazyBean;
 
         // run export
         int exit = eq.export();
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ExportTest.java
 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ExportTest.java
index 363451cce62..e0b5d672b7c 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ExportTest.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ExportTest.java
@@ -62,7 +62,7 @@ class ExportTest {
 
     @ParameterizedTest
     @MethodSource("runtimeProvider")
-    public void shouldGenerateSpringBootProject(RuntimeType rt) throws 
Exception {
+    public void shouldGenerateProject(RuntimeType rt) throws Exception {
         Export command = createCommand(rt, new String[] { 
"classpath:route.yaml" },
                 "--gav=examples:route:1.0.0", "--dir=" + workingDir, 
"--quiet");
         int exit = command.doCall();
@@ -120,10 +120,27 @@ class ExportTest {
         Export command = new ExportSpringBoot(new CamelJBangMain());
         CommandLine.populateCommand(command, "--gav=examples:route:1.0.0", 
"--dir=" + workingDir, "--quiet",
                 "--runtime=%s".formatted(rt.runtime()));
+        if (args != null) {
+            CommandLine.populateCommand(command, args);
+        }
         command.files = Arrays.asList(files);
         return command;
     }
 
+    @ParameterizedTest
+    @MethodSource("runtimeProvider")
+    public void shouldExportLazyBean(RuntimeType rt) throws Exception {
+        Export command = createCommand(rt, new String[] { 
"classpath:route.yaml", "file:src/test/resources/LazyFoo.java" },
+                "--gav=examples:route:1.0.0", "--dir=" + workingDir, 
"--quiet", "--lazy-bean");
+        int exit = command.doCall();
+
+        Assertions.assertEquals(0, exit);
+        Model model = readMavenModel();
+        Assertions.assertEquals("examples", model.getGroupId());
+        Assertions.assertEquals("route", model.getArtifactId());
+        Assertions.assertEquals("1.0.0", model.getVersion());
+    }
+
     private Model readMavenModel() throws Exception {
         File f = workingDir.toPath().resolve("pom.xml").toFile();
         Assertions.assertTrue(f.isFile(), "Not a pom.xml file: " + f);
diff --git a/dsl/camel-jbang/camel-jbang-core/src/test/resources/LazyFoo.java 
b/dsl/camel-jbang/camel-jbang-core/src/test/resources/LazyFoo.java
new file mode 100755
index 00000000000..88db2860f48
--- /dev/null
+++ b/dsl/camel-jbang/camel-jbang-core/src/test/resources/LazyFoo.java
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ */
+// use modeline to configure properties directly in the same source file
+// camel-k: language=java name=Cool property=period=1000
+import org.apache.camel.BindToRegistry;
+
+public class LazyFoo {
+
+  @BindToRegistry
+  public String myFoo() {
+      throw new IllegalArgumentException("Cannot load foo driver");
+  }
+}
diff --git 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
index f15786c1c65..75e5416ae1f 100644
--- 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
+++ 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/KameletMain.java
@@ -477,7 +477,9 @@ public class KameletMain extends MainCommandLineSupport {
         // load camel component and custom health-checks
         answer.setLoadHealthChecks(true);
         // annotation based dependency injection for camel/spring/quarkus 
annotations in DSLs and Java beans
-        
AnnotationDependencyInjection.initAnnotationBasedDependencyInjection(answer);
+
+        boolean lazyBean = 
"true".equals(getInitialProperties().get("camel.jbang.lazyBean"));
+        new AnnotationDependencyInjection(answer, lazyBean);
 
         if (!silent) {
             // silent should not include cli-connector
diff --git 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/injection/AnnotationDependencyInjection.java
 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/injection/AnnotationDependencyInjection.java
index 0479ba6d14b..07000bfa8aa 100644
--- 
a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/injection/AnnotationDependencyInjection.java
+++ 
b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/injection/AnnotationDependencyInjection.java
@@ -61,12 +61,17 @@ import org.springframework.stereotype.Service;
  */
 public final class AnnotationDependencyInjection {
 
-    private AnnotationDependencyInjection() {
-    }
+    private final boolean lazyBean;
+
+    public AnnotationDependencyInjection(CamelContext context, boolean 
lazyBean) {
+        this.lazyBean = lazyBean;
 
-    public static void initAnnotationBasedDependencyInjection(CamelContext 
context) {
         Registry registry = context.getRegistry();
         CamelBeanPostProcessor cbbp = 
PluginHelper.getBeanPostProcessor(context);
+        if (lazyBean) {
+            // force lazy beans
+            cbbp.setLazyBeanStrategy((ann) -> true);
+        }
 
         // camel / common
         registry.bind("CamelTypeConverterCompilePostProcessor", new 
TypeConverterCompilePostProcessor());
@@ -78,6 +83,7 @@ public final class AnnotationDependencyInjection {
         // quarkus
         registry.bind("QuarkusAnnotationCompilePostProcessor", new 
QuarkusAnnotationCompilePostProcessor());
         cbbp.addCamelBeanPostProjectInjector(new 
QuarkusBeanPostProcessorInjector(context));
+
     }
 
     private static class TypeConverterCompilePostProcessor implements 
CompilePostProcessor {
@@ -132,7 +138,7 @@ public final class AnnotationDependencyInjection {
         }
     }
 
-    private static class BindToRegistryCompilePostProcessor implements 
CompilePostProcessor {
+    private class BindToRegistryCompilePostProcessor implements 
CompilePostProcessor {
 
         @Override
         public void postCompile(CamelContext camelContext, String name, 
Class<?> clazz, byte[] byteCode, Object instance)
@@ -142,7 +148,7 @@ public final class AnnotationDependencyInjection {
             Configuration cfg = clazz.getAnnotation(Configuration.class);
 
             // special for lazy beans which we must create on-demand
-            if (instance == null && bir != null && bir.lazy()) {
+            if (instance == null && bir != null && (lazyBean || bir.lazy())) {
                 final String beanName = bir.value();
                 instance = (Supplier<Object>) () -> {
                     Object answer = 
camelContext.getInjector().newInstance(clazz);
@@ -189,7 +195,7 @@ public final class AnnotationDependencyInjection {
 
     }
 
-    private static class SpringAnnotationCompilePostProcessor implements 
CompilePostProcessor {
+    private class SpringAnnotationCompilePostProcessor implements 
CompilePostProcessor {
 
         @Override
         public void postCompile(CamelContext camelContext, String name, 
Class<?> clazz, byte[] byteCode, Object instance)
@@ -211,7 +217,7 @@ public final class AnnotationDependencyInjection {
         }
     }
 
-    private static class SpringBeanPostProcessorInjector implements 
CamelBeanPostProcessorInjector {
+    private class SpringBeanPostProcessorInjector implements 
CamelBeanPostProcessorInjector {
 
         private final CamelContext context;
         private final CamelPostProcessorHelper helper;
@@ -252,7 +258,13 @@ public final class AnnotationDependencyInjection {
         public void onMethodInject(Method method, Object bean, String 
beanName) {
             Bean bi = method.getAnnotation(Bean.class);
             if (bi != null) {
-                Object instance = helper.getInjectionBeanMethodValue(context, 
method, bean, beanName, "Bean");
+                Object instance;
+                if (lazyBean) {
+                    instance = (Supplier<Object>) () -> 
helper.getInjectionBeanMethodValue(context, method, bean, beanName,
+                            "Bean");
+                } else {
+                    instance = helper.getInjectionBeanMethodValue(context, 
method, bean, beanName, "Bean");
+                }
                 if (instance != null) {
                     String name = method.getName();
                     if (bi.name().length > 0) {
@@ -264,7 +276,7 @@ public final class AnnotationDependencyInjection {
         }
     }
 
-    private static class QuarkusAnnotationCompilePostProcessor implements 
CompilePostProcessor {
+    private class QuarkusAnnotationCompilePostProcessor implements 
CompilePostProcessor {
 
         @Override
         public void postCompile(CamelContext camelContext, String name, 
Class<?> clazz, byte[] byteCode, Object instance)
@@ -285,7 +297,7 @@ public final class AnnotationDependencyInjection {
         }
     }
 
-    private static class QuarkusBeanPostProcessorInjector implements 
CamelBeanPostProcessorInjector {
+    private class QuarkusBeanPostProcessorInjector implements 
CamelBeanPostProcessorInjector {
 
         private final CamelContext context;
         private final CamelPostProcessorHelper helper;
@@ -324,7 +336,13 @@ public final class AnnotationDependencyInjection {
             Produces produces = method.getAnnotation(Produces.class);
             Named bi = method.getAnnotation(Named.class);
             if (produces != null || bi != null) {
-                Object instance = helper.getInjectionBeanMethodValue(context, 
method, bean, beanName, "Produces");
+                Object instance;
+                if (lazyBean) {
+                    instance = (Supplier<Object>) () -> 
helper.getInjectionBeanMethodValue(context, method, bean, beanName,
+                            "Produces");
+                } else {
+                    instance = helper.getInjectionBeanMethodValue(context, 
method, bean, beanName, "Produces");
+                }
                 if (instance != null) {
                     String name = method.getName();
                     if (bi != null && !bi.value().isBlank()) {

Reply via email to