Andrea Cosentino created CAMEL-24501:
----------------------------------------
Summary: camel-spring-boot-generator-maven-plugin - generated
configuration binding drops values silently in three places
Key: CAMEL-24501
URL: https://issues.apache.org/jira/browse/CAMEL-24501
Project: Camel
Issue Type: Improvement
Components: tooling
Reporter: Andrea Cosentino
Assignee: Andrea Cosentino
Three related spots in {{SpringBootAutoConfigurationMojo}} generate code that
discards configuration instead of reporting it. All three regenerate into the
~425 starters.
*1. Converters return null for unresolved references (line 1488)*
{code:java}
sb.append("String ref = source.toString();\n");
sb.append("if (!ref.startsWith(\"#\")) {\n");
sb.append(" return null;\n");
sb.append("}\n");
{code}
A configured value that does not start with {{#}} converts to null, as does one
whose target type is not in the generated switch. For options holding objects
such as {{sslContextParameters}}, a typo in the property value yields a null
rather than an error, and the component starts with the option unset.
*2. Catalog defaults emitted as literal field initializers (line 747)*
{code:java}
if (!isBlank(option.getDefaultValue())) {
if ("java.lang.String".equals(option.getJavaType())) {
prop.getField().setStringInitializer(option.getDefaultValue().toString());
} else if ...
prop.getField().setLiteralInitializer(option.getDefaultValue().toString());
{code}
Every defaulted catalog option becomes a non-null field on the configuration
class. The generated customizer then copies the whole configuration onto the
component, so a value set programmatically before the customizer runs is
overwritten by the materialised default. The wrapper-type/null-sentinel design
elsewhere suggests defaults were meant to live in
{{spring-configuration-metadata}} {{defaultValue}} for IDE display only.
*3. Customizer bodies bind with failIfNotSet=false (line 1825)*
{{createComponentBody}} emits {{CamelPropertiesHelper.copyProperties(...)}},
which calls {{setCamelProperties(..., failIfNotSet=false)}}. An option that
cannot be bound is dropped without a log line. The generated {{camel.rest.*}}
path uses {{true}} for the same operation, so the two disagree.
*Proposal*
- Make the converter throw {{IllegalArgumentException}} naming the option and
the expected {{#bean:}} syntax when a non-null value does not resolve, and make
the generated converters {{ConditionalGenericConverter}} instances that match
only {{camel.*}} property sources.
- Stop emitting literal initializers for defaulted options, or have the
customizer skip values equal to the catalog default.
- Use {{failIfNotSet=true}} in the generated customizer bodies, or at minimum
log at WARN with the option name when a bind is missed.
These are best done as one change followed by a regeneration pass, since the
third will surface any latent generator or catalog drift as startup failures -
which is the intent.
----
_This issue was drafted by Claude Code on behalf of Andrea Cosentino._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)