This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch loading-error in repository https://gitbox.apache.org/repos/asf/camel.git
commit 9837c682c81c35381a1c29357a9e1dffba19497b Author: Claus Ibsen <[email protected]> AuthorDate: Thu Sep 28 12:52:54 2023 +0200 CAMEL-19917: camel-main/camel-jbang - Add option to ignore loading/compilation errors that tooling needs --- .../main/camel-main-configuration-metadata.json | 1 + .../java/org/apache/camel/spi/RoutesLoader.java | 10 ++++ .../camel/impl/engine/DefaultRoutesLoader.java | 63 +++++++++++++++++++--- .../MainConfigurationPropertiesConfigurer.java | 6 +++ .../camel-main-configuration-metadata.json | 1 + core/camel-main/src/main/docs/main.adoc | 3 +- .../org/apache/camel/main/BaseMainSupport.java | 6 ++- .../camel/main/DefaultConfigurationProperties.java | 24 +++++++++ .../apache/camel/main/DefaultRoutesCollector.java | 18 ++++++- .../org/apache/camel/main/RoutesCollector.java | 10 ++++ .../org/apache/camel/main/RoutesConfigurer.java | 30 ++++++++++- .../modules/ROOT/pages/camel-jbang.adoc | 3 ++ .../camel/dsl/jbang/core/commands/Export.java | 1 + .../dsl/jbang/core/commands/ExportBaseCommand.java | 8 ++- .../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 | 17 ++++-- .../camel/dsl/jbang/core/commands/Transform.java | 2 +- .../java/org/apache/camel/main/KameletMain.java | 5 +- .../main/download/CamelCustomClassLoader.java | 4 +- 21 files changed, 193 insertions(+), 25 deletions(-) diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json index 1ccdccd98d9..237e996e769 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json @@ -94,6 +94,7 @@ { "name": "camel.main.routesBuilderClasses", "description": "Sets classes names that implement RoutesBuilder .", "sourceType": "org.apache.camel.main.MainConfigurationProperties", "type": "string", "javaType": "java.lang.String" }, { "name": "camel.main.routesBuilders", "description": "Sets the RoutesBuilder instances.", "sourceType": "org.apache.camel.main.MainConfigurationProperties", "type": "object", "javaType": "java.util.List" }, { "name": "camel.main.routesCollectorEnabled", "description": "Whether the routes collector is enabled or not. When enabled Camel will auto-discover routes (RouteBuilder instances from the registry and also load additional routes from the file system). The routes collector is default enabled.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true }, + { "name": "camel.main.routesCollectorIgnoreLoadingError", "description": "Whether the routes collector should ignore any errors during loading and compiling routes. This is only intended for development or tooling.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" }, { "name": "camel.main.routesExcludePattern", "description": "Used for exclusive filtering of routes from directories. The exclusive filtering takes precedence over inclusive filtering. The pattern is using Ant-path style pattern. Multiple patterns can be specified separated by comma, as example, to exclude all the routes from a directory whose name contains foo use: **\/foo.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": [...] { "name": "camel.main.routesIncludePattern", "description": "Used for inclusive filtering of routes from directories. The exclusive filtering takes precedence over inclusive filtering. The pattern is using Ant-path style pattern. Multiple patterns can be specified separated by comma, as example, to include all the routes from a directory whose name contains foo use: **\/foo.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": [...] { "name": "camel.main.routesReloadDirectory", "description": "Directory to scan for route changes. Camel cannot scan the classpath, so this must be configured to a file directory. Development with Maven as build tool, you can configure the directory to be src\/main\/resources to scan for Camel routes in XML or YAML files.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": "java.lang.String", "defaultValue": "src\/main\/resources\/camel" }, diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/RoutesLoader.java b/core/camel-api/src/main/java/org/apache/camel/spi/RoutesLoader.java index 0bc6deb2fd5..59694f32742 100644 --- a/core/camel-api/src/main/java/org/apache/camel/spi/RoutesLoader.java +++ b/core/camel-api/src/main/java/org/apache/camel/spi/RoutesLoader.java @@ -34,6 +34,16 @@ public interface RoutesLoader extends CamelContextAware { */ String FACTORY = "routes-loader"; + /** + * Whether to ignore route loading and compilation errors (use this with care!) + */ + boolean isIgnoreLoadingError(); + + /** + * Whether to ignore route loading and compilation errors (use this with care!) + */ + void setIgnoreLoadingError(boolean ignoreLoadingError); + /** * Looks up a {@link RoutesBuilderLoader} in the registry or fallback to a factory finder mechanism if none found. * diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultRoutesLoader.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultRoutesLoader.java index 37196f50993..71b366cd684 100644 --- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultRoutesLoader.java +++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultRoutesLoader.java @@ -42,12 +42,16 @@ import org.apache.camel.support.service.ServiceHelper; import org.apache.camel.support.service.ServiceSupport; import org.apache.camel.util.FileUtil; import org.apache.camel.util.ObjectHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Default {@link RoutesLoader}. */ public class DefaultRoutesLoader extends ServiceSupport implements RoutesLoader, StaticService { + private static final Logger LOG = LoggerFactory.getLogger(DefaultRoutesLoader.class); + /** * Prefix to use for looking up existing {@link RoutesLoader} from the {@link org.apache.camel.spi.Registry}. */ @@ -56,6 +60,7 @@ public class DefaultRoutesLoader extends ServiceSupport implements RoutesLoader, private final Map<String, RoutesBuilderLoader> loaders; private CamelContext camelContext; + private boolean ignoreLoadingError; public DefaultRoutesLoader() { this(null); @@ -83,6 +88,14 @@ public class DefaultRoutesLoader extends ServiceSupport implements RoutesLoader, this.camelContext = camelContext; } + public boolean isIgnoreLoadingError() { + return ignoreLoadingError; + } + + public void setIgnoreLoadingError(boolean ignoreLoadingError) { + this.ignoreLoadingError = ignoreLoadingError; + } + @Override public Collection<RoutesBuilder> findRoutesBuilders(Collection<Resource> resources) throws Exception { return findRoutesBuilders(resources, false); @@ -134,10 +147,27 @@ public class DefaultRoutesLoader extends ServiceSupport implements RoutesLoader, // extended loader can load all resources ine one unit ExtendedRoutesBuilderLoader extLoader = (ExtendedRoutesBuilderLoader) loader; // pre-parse before loading - extLoader.preParseRoutes(entry.getValue()); + List<Resource> files = entry.getValue(); + try { + extLoader.preParseRoutes(files); + } catch (Exception e) { + if (isIgnoreLoadingError()) { + LOG.warn("Loading resources error: {} due to: {}. This exception is ignored.", files, e.getMessage()); + } else { + throw e; + } + } } else { for (Resource resource : entry.getValue()) { - loader.preParseRoute(resource); + try { + loader.preParseRoute(resource); + } catch (Exception e) { + if (isIgnoreLoadingError()) { + LOG.warn("Loading resources error: {} due to: {}. This exception is ignored.", resource, e.getMessage()); + } else { + throw e; + } + } } } } @@ -148,15 +178,32 @@ public class DefaultRoutesLoader extends ServiceSupport implements RoutesLoader, if (loader instanceof ExtendedRoutesBuilderLoader) { // extended loader can load all resources ine one unit ExtendedRoutesBuilderLoader extLoader = (ExtendedRoutesBuilderLoader) loader; - Collection<RoutesBuilder> builders = extLoader.loadRoutesBuilders(entry.getValue()); - if (builders != null) { - answer.addAll(builders); + List<Resource> files = entry.getValue(); + try { + Collection<RoutesBuilder> builders = extLoader.loadRoutesBuilders(files); + if (builders != null) { + answer.addAll(builders); + } + } catch (Exception e) { + if (isIgnoreLoadingError()) { + LOG.warn("Loading resources error: {} due to: {}. This exception is ignored.", files, e.getMessage()); + } else { + throw e; + } } } else { for (Resource resource : entry.getValue()) { - RoutesBuilder builder = loader.loadRoutesBuilder(resource); - if (builder != null) { - answer.add(builder); + try { + RoutesBuilder builder = loader.loadRoutesBuilder(resource); + if (builder != null) { + answer.add(builder); + } + } catch (Exception e) { + if (isIgnoreLoadingError()) { + LOG.warn("Loading resources error: {} due to: {}. This exception is ignored.", resource, e.getMessage()); + } else { + throw e; + } } } } diff --git a/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java b/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java index c8a783e0e9e..776094acb67 100644 --- a/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java +++ b/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java @@ -183,6 +183,8 @@ public class MainConfigurationPropertiesConfigurer extends org.apache.camel.supp case "RoutesBuilders": target.setRoutesBuilders(property(camelContext, java.util.List.class, value)); return true; case "routescollectorenabled": case "RoutesCollectorEnabled": target.setRoutesCollectorEnabled(property(camelContext, boolean.class, value)); return true; + case "routescollectorignoreloadingerror": + case "RoutesCollectorIgnoreLoadingError": target.setRoutesCollectorIgnoreLoadingError(property(camelContext, boolean.class, value)); return true; case "routesexcludepattern": case "RoutesExcludePattern": target.setRoutesExcludePattern(property(camelContext, java.lang.String.class, value)); return true; case "routesincludepattern": @@ -442,6 +444,8 @@ public class MainConfigurationPropertiesConfigurer extends org.apache.camel.supp case "RoutesBuilders": return java.util.List.class; case "routescollectorenabled": case "RoutesCollectorEnabled": return boolean.class; + case "routescollectorignoreloadingerror": + case "RoutesCollectorIgnoreLoadingError": return boolean.class; case "routesexcludepattern": case "RoutesExcludePattern": return java.lang.String.class; case "routesincludepattern": @@ -702,6 +706,8 @@ public class MainConfigurationPropertiesConfigurer extends org.apache.camel.supp case "RoutesBuilders": return target.getRoutesBuilders(); case "routescollectorenabled": case "RoutesCollectorEnabled": return target.isRoutesCollectorEnabled(); + case "routescollectorignoreloadingerror": + case "RoutesCollectorIgnoreLoadingError": return target.isRoutesCollectorIgnoreLoadingError(); case "routesexcludepattern": case "RoutesExcludePattern": return target.getRoutesExcludePattern(); case "routesincludepattern": diff --git a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json index 1ccdccd98d9..237e996e769 100644 --- a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json +++ b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json @@ -94,6 +94,7 @@ { "name": "camel.main.routesBuilderClasses", "description": "Sets classes names that implement RoutesBuilder .", "sourceType": "org.apache.camel.main.MainConfigurationProperties", "type": "string", "javaType": "java.lang.String" }, { "name": "camel.main.routesBuilders", "description": "Sets the RoutesBuilder instances.", "sourceType": "org.apache.camel.main.MainConfigurationProperties", "type": "object", "javaType": "java.util.List" }, { "name": "camel.main.routesCollectorEnabled", "description": "Whether the routes collector is enabled or not. When enabled Camel will auto-discover routes (RouteBuilder instances from the registry and also load additional routes from the file system). The routes collector is default enabled.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true }, + { "name": "camel.main.routesCollectorIgnoreLoadingError", "description": "Whether the routes collector should ignore any errors during loading and compiling routes. This is only intended for development or tooling.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" }, { "name": "camel.main.routesExcludePattern", "description": "Used for exclusive filtering of routes from directories. The exclusive filtering takes precedence over inclusive filtering. The pattern is using Ant-path style pattern. Multiple patterns can be specified separated by comma, as example, to exclude all the routes from a directory whose name contains foo use: **\/foo.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": [...] { "name": "camel.main.routesIncludePattern", "description": "Used for inclusive filtering of routes from directories. The exclusive filtering takes precedence over inclusive filtering. The pattern is using Ant-path style pattern. Multiple patterns can be specified separated by comma, as example, to include all the routes from a directory whose name contains foo use: **\/foo.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": [...] { "name": "camel.main.routesReloadDirectory", "description": "Directory to scan for route changes. Camel cannot scan the classpath, so this must be configured to a file directory. Development with Maven as build tool, you can configure the directory to be src\/main\/resources to scan for Camel routes in XML or YAML files.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": "java.lang.String", "defaultValue": "src\/main\/resources\/camel" }, diff --git a/core/camel-main/src/main/docs/main.adoc b/core/camel-main/src/main/docs/main.adoc index 0020c4572ac..aefdf771bcb 100644 --- a/core/camel-main/src/main/docs/main.adoc +++ b/core/camel-main/src/main/docs/main.adoc @@ -19,7 +19,7 @@ The following tables lists all the options: // main options: START === Camel Main configurations -The camel.main supports 126 options, which are listed below. +The camel.main supports 127 options, which are listed below. [width="100%",cols="2,5,^1,2",options="header"] |=== @@ -105,6 +105,7 @@ The camel.main supports 126 options, which are listed below. | *camel.main.routesBuilder{zwsp}Classes* | Sets classes names that implement RoutesBuilder . | | String | *camel.main.routesBuilders* | Sets the RoutesBuilder instances. | | List | *camel.main.routesCollector{zwsp}Enabled* | Whether the routes collector is enabled or not. When enabled Camel will auto-discover routes (RouteBuilder instances from the registry and also load additional routes from the file system). The routes collector is default enabled. | true | boolean +| *camel.main.routesCollector{zwsp}IgnoreLoadingError* | Whether the routes collector should ignore any errors during loading and compiling routes. This is only intended for development or tooling. | false | boolean | *camel.main.routesExclude{zwsp}Pattern* | Used for exclusive filtering of routes from directories. The exclusive filtering takes precedence over inclusive filtering. The pattern is using Ant-path style pattern. Multiple patterns can be specified separated by comma, as example, to exclude all the routes from a directory whose name contains foo use: **/foo. | | String | *camel.main.routesInclude{zwsp}Pattern* | Used for inclusive filtering of routes from directories. The exclusive filtering takes precedence over inclusive filtering. The pattern is using Ant-path style pattern. Multiple patterns can be specified separated by comma, as example, to include all the routes from a directory whose name contains foo use: **/foo. | classpath:camel/*,classpath:camel-template/*,classpath:camel-rest/* | String | *camel.main.routesReload{zwsp}Directory* | Directory to scan for route changes. Camel cannot scan the classpath, so this must be configured to a file directory. Development with Maven as build tool, you can configure the directory to be src/main/resources to scan for Camel routes in XML or YAML files. | src/main/resources/camel | String diff --git a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java index fa1f087dee3..b2906c2bda9 100644 --- a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java +++ b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java @@ -549,7 +549,9 @@ public abstract class BaseMainSupport extends BaseService { protected void configureRoutesLoader(CamelContext camelContext) { // use main based routes loader - camelContext.getCamelContextExtension().addContextPlugin(RoutesLoader.class, new DefaultRoutesLoader()); + RoutesLoader loader = new DefaultRoutesLoader(); + loader.setIgnoreLoadingError(mainConfigurationProperties.isRoutesCollectorIgnoreLoadingError()); + camelContext.getCamelContextExtension().addContextPlugin(RoutesLoader.class, loader); } protected void modelineRoutes(CamelContext camelContext) throws Exception { @@ -569,8 +571,10 @@ public abstract class BaseMainSupport extends BaseService { // then configure and add the routes RoutesConfigurer configurer = new RoutesConfigurer(); + routesCollector.setIgnoreLoadingError(mainConfigurationProperties.isRoutesCollectorIgnoreLoadingError()); if (mainConfigurationProperties.isRoutesCollectorEnabled()) { configurer.setRoutesCollector(routesCollector); + configurer.setIgnoreLoadingError(mainConfigurationProperties.isRoutesCollectorIgnoreLoadingError()); } configurer.setBeanPostProcessor(PluginHelper.getBeanPostProcessor(camelContext)); diff --git a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java index 9ef65ba9ce4..83af6a7d6e1 100644 --- a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java +++ b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java @@ -112,6 +112,7 @@ public abstract class DefaultConfigurationProperties<T> { private LoggingLevel beanIntrospectionLoggingLevel; private boolean contextReloadEnabled; private boolean routesCollectorEnabled = true; + private boolean routesCollectorIgnoreLoadingError; private String javaRoutesIncludePattern; private String javaRoutesExcludePattern; private String routesIncludePattern = "classpath:camel/*,classpath:camel-template/*,classpath:camel-rest/*"; @@ -1166,6 +1167,19 @@ public abstract class DefaultConfigurationProperties<T> { this.routesCollectorEnabled = routesCollectorEnabled; } + public boolean isRoutesCollectorIgnoreLoadingError() { + return routesCollectorIgnoreLoadingError; + } + + /** + * Whether the routes collector should ignore any errors during loading and compiling routes. + * + * This is only intended for development or tooling. + */ + public void setRoutesCollectorIgnoreLoadingError(boolean routesCollectorIgnoreLoadingError) { + this.routesCollectorIgnoreLoadingError = routesCollectorIgnoreLoadingError; + } + public String getJavaRoutesIncludePattern() { return javaRoutesIncludePattern; } @@ -2482,6 +2496,16 @@ public abstract class DefaultConfigurationProperties<T> { return (T) this; } + /** + * Whether the routes collector should ignore any errors during loading and compiling routes. + * + * This is only intended for development or tooling. + */ + public T withRoutesCollectorIgnoreLoadingError(boolean routesCollectorIgnoreLoadingError) { + this.routesCollectorIgnoreLoadingError = routesCollectorIgnoreLoadingError; + return (T) this; + } + /** * Used for inclusive filtering component scanning of RouteBuilder classes with @Component annotation. The exclusive * filtering takes precedence over inclusive filtering. The pattern is using Ant-path style pattern. diff --git a/core/camel-main/src/main/java/org/apache/camel/main/DefaultRoutesCollector.java b/core/camel-main/src/main/java/org/apache/camel/main/DefaultRoutesCollector.java index ffefd06891b..7df07acd9a5 100644 --- a/core/camel-main/src/main/java/org/apache/camel/main/DefaultRoutesCollector.java +++ b/core/camel-main/src/main/java/org/apache/camel/main/DefaultRoutesCollector.java @@ -44,6 +44,18 @@ public class DefaultRoutesCollector implements RoutesCollector { protected final Logger log = LoggerFactory.getLogger(getClass()); + private boolean ignoreLoadingError; + + @Override + public boolean isIgnoreLoadingError() { + return ignoreLoadingError; + } + + @Override + public void setIgnoreLoadingError(boolean ignoreLoadingError) { + this.ignoreLoadingError = ignoreLoadingError; + } + @Override public Collection<RoutesBuilder> collectRoutesFromRegistry( CamelContext camelContext, @@ -194,7 +206,11 @@ public class DefaultRoutesCollector implements RoutesCollector { builders.addAll(found); } } catch (Exception e) { - throw RuntimeCamelException.wrapRuntimeException(e); + if (isIgnoreLoadingError()) { + log.warn("Loading resources error: {} due to: {}. This exception is ignored.", accepted, e.getMessage()); + } else { + throw RuntimeCamelException.wrapRuntimeException(e); + } } } diff --git a/core/camel-main/src/main/java/org/apache/camel/main/RoutesCollector.java b/core/camel-main/src/main/java/org/apache/camel/main/RoutesCollector.java index e7954d6610e..43abbd26a43 100644 --- a/core/camel-main/src/main/java/org/apache/camel/main/RoutesCollector.java +++ b/core/camel-main/src/main/java/org/apache/camel/main/RoutesCollector.java @@ -28,6 +28,16 @@ import org.apache.camel.spi.Resource; */ public interface RoutesCollector { + /** + * Whether to ignore route loading and compilation errors (use this with care!) + */ + boolean isIgnoreLoadingError(); + + /** + * Whether to ignore route loading and compilation errors (use this with care!) + */ + void setIgnoreLoadingError(boolean ignoreLoadingError); + /** * Collects the {@link RoutesBuilder} instances which was discovered from the {@link org.apache.camel.spi.Registry} * such as Spring or CDI bean containers. diff --git a/core/camel-main/src/main/java/org/apache/camel/main/RoutesConfigurer.java b/core/camel-main/src/main/java/org/apache/camel/main/RoutesConfigurer.java index c7ec97675fa..4038a4539c2 100644 --- a/core/camel-main/src/main/java/org/apache/camel/main/RoutesConfigurer.java +++ b/core/camel-main/src/main/java/org/apache/camel/main/RoutesConfigurer.java @@ -50,6 +50,7 @@ public class RoutesConfigurer { private static final Logger LOG = LoggerFactory.getLogger(RoutesConfigurer.class); private RoutesCollector routesCollector; + private boolean ignoreLoadingError; private CamelBeanPostProcessor beanPostProcessor; private List<RoutesBuilder> routesBuilders; private String basePackageScan; @@ -60,6 +61,14 @@ public class RoutesConfigurer { private String routesIncludePattern; private String routesSourceDir; + public boolean isIgnoreLoadingError() { + return ignoreLoadingError; + } + + public void setIgnoreLoadingError(boolean ignoreLoadingError) { + this.ignoreLoadingError = ignoreLoadingError; + } + public List<RoutesBuilder> getRoutesBuilders() { return routesBuilders; } @@ -349,10 +358,27 @@ public class RoutesConfigurer { if (loader instanceof ExtendedRoutesBuilderLoader) { // extended loader can pre-parse all resources ine one unit ExtendedRoutesBuilderLoader extLoader = (ExtendedRoutesBuilderLoader) loader; - extLoader.preParseRoutes(entry.getValue()); + List<Resource> files = entry.getValue(); + try { + extLoader.preParseRoutes(files); + } catch (Exception e) { + if (ignoreLoadingError) { + LOG.warn("Loading resources error: {} due to: {}. This exception is ignored.", files, e.getMessage()); + } else { + throw e; + } + } } else { for (Resource resource : entry.getValue()) { - loader.preParseRoute(resource); + try { + loader.preParseRoute(resource); + } catch (Exception e) { + if (ignoreLoadingError) { + LOG.warn("Loading resources error: {} due to: {}. This exception is ignored.", resource, e.getMessage()); + } else { + throw e; + } + } } } } diff --git a/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc b/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc index 6000e2ff3a6..250b93cc90b 100644 --- a/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc +++ b/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc @@ -2484,6 +2484,9 @@ The follow options related to _exporting_, can be configured in `application.pro |`camel.jbang.health` | Health check at /q/health on local HTTP server (port 8080 by default) when running standalone Camel +|`camel.jbang.ignoreLoadingError` +| Whether to ignore route loading and compilation errors (use this with care!) + |=== NOTE: These are options from the export command, so you can see mor details and default values using `camel export --help`. 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 31712c38eab..d17194baac2 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 @@ -128,6 +128,7 @@ public class Export extends ExportBaseCommand { cmd.openapi = this.openapi; cmd.packageName = this.packageName; cmd.exclude = this.exclude; + cmd.ignoreLoadingError = this.ignoreLoadingError; // 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 1decab8b5d2..3fb36852eb1 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 @@ -199,6 +199,10 @@ abstract class ExportBaseCommand extends CamelCommand { description = "Will be quiet, only print when error occurs") boolean quiet; + @CommandLine.Option(names = { "--ignore-loading-error" }, + description = "Whether to ignore route loading and compilation errors (use this with care!)") + protected boolean ignoreLoadingError; + public ExportBaseCommand(CamelJBangMain main) { super(main); } @@ -271,7 +275,7 @@ abstract class ExportBaseCommand extends CamelCommand { return null; } - protected Integer runSilently() throws Exception { + protected Integer runSilently(boolean ignoreLoadingError) throws Exception { Run run = new Run(getMain()); // need to declare the profile to use for run run.profile = profile; @@ -280,7 +284,7 @@ abstract class ExportBaseCommand extends CamelCommand { run.files = files; run.exclude = exclude; run.openapi = openapi; - return run.runSilent(); + return run.runSilent(ignoreLoadingError); } protected Set<String> resolveDependencies(File settings, File profile) throws Exception { 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 1b1d7079f01..8daaccca061 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 @@ -63,7 +63,7 @@ class ExportCamelMain extends Export { if (!quiet && fresh) { System.out.println("Generating fresh run data"); } - int silent = runSilently(); + int silent = runSilently(ignoreLoadingError); 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 14babc4717b..9e4c9dc9f7d 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 @@ -66,7 +66,7 @@ class ExportQuarkus extends Export { if (!quiet) { System.out.println("Generating fresh run data"); } - int silent = runSilently(); + int silent = runSilently(ignoreLoadingError); 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 4555cb9cf6d..08c3e4a6ad2 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) { System.out.println("Generating fresh run data"); } - int silent = runSilently(); + int silent = runSilently(ignoreLoadingError); 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 9805aa5bcf6..306610aed4d 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 @@ -251,6 +251,10 @@ public class Run extends CamelCommand { @Option(names = { "--verbose" }, description = "Verbose output of startup activity (dependency resolution and downloading") boolean verbose; + @Option(names = { "--ignore-loading-error" }, + description = "Whether to ignore route loading and compilation errors (use this with care!)") + protected boolean ignoreLoadingError; + public Run(CamelJBangMain main) { super(main); } @@ -274,14 +278,19 @@ public class Run extends CamelCommand { } protected Integer runSilent() throws Exception { + return runSilent(false); + } + + protected Integer runSilent(boolean ignoreLoadingError) throws Exception { // just boot silently and exit - silentRun = true; + this.silentRun = true; + this.ignoreLoadingError = ignoreLoadingError; return run(); } protected Integer runTransform() throws Exception { // just boot silently and exit - transformRun = true; + this.transformRun = true; return run(); } @@ -422,6 +431,9 @@ public class Run extends CamelCommand { if (modeline) { writeSetting(main, profileProperties, "camel.main.modeline", "true"); } + if (ignoreLoadingError) { + writeSetting(main, profileProperties, "camel.jbang.ignoreLoadingError", "true"); + } if (gav != null) { writeSetting(main, profileProperties, "camel.jbang.gav", gav); @@ -472,7 +484,6 @@ public class Run extends CamelCommand { // do not run for very long in silent run main.addInitialProperty("camel.main.autoStartup", "false"); main.addInitialProperty("camel.main.durationMaxSeconds", "1"); - main.addInitialProperty("camel.main.durationMaxSeconds", "1"); } else if (scriptRun) { // auto terminate if being idle main.addInitialProperty("camel.main.durationMaxIdleSeconds", "1"); diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Transform.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Transform.java index ac6a79c8528..310dd31fd61 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Transform.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Transform.java @@ -82,7 +82,7 @@ public class Transform extends CamelCommand { }; run.files = files; run.maxSeconds = 1; - Integer exit = run.runSilent(); + Integer exit = run.runTransform(); if (exit != null && exit != 0) { return exit; } 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 39a4793b899..7c8d684e7d4 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 @@ -447,12 +447,15 @@ public class KameletMain extends MainCommandLineSupport { if (tracing) { configure().withBacklogTracing(true); } - boolean health = "true".equals(getInitialProperties().get("camel.jbang.health")); if (health) { configure().httpServer().withEnabled(true); configure().httpServer().withHealthCheckEnabled(true); } + boolean ignoreLoading = "true".equals(getInitialProperties().get("camel.jbang.ignoreLoadingError")); + if (ignoreLoading) { + configure().withRoutesCollectorIgnoreLoadingError(true); + } if (silent) { // silent should not include http server configure().httpServer().withEnabled(false); diff --git a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/CamelCustomClassLoader.java b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/CamelCustomClassLoader.java index 5018b9818b3..c69e5c64fd2 100644 --- a/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/CamelCustomClassLoader.java +++ b/dsl/camel-kamelet-main/src/main/java/org/apache/camel/main/download/CamelCustomClassLoader.java @@ -19,8 +19,8 @@ package org.apache.camel.main.download; import org.apache.camel.CamelContext; /** - * ClassLoader loading from any custom class loaders that may - * have been added to Camel {@link org.apache.camel.spi.ClassResolver}. + * ClassLoader loading from any custom class loaders that may have been added to Camel + * {@link org.apache.camel.spi.ClassResolver}. */ public class CamelCustomClassLoader extends ClassLoader {
