Skip to content

fix: add fail-fast validation to SolrConfigurationProperties - #104

Open
adityamparikh wants to merge 2 commits into
apache:mainfrom
adityamparikh:fix/solr-config-properties-validation
Open

fix: add fail-fast validation to SolrConfigurationProperties#104
adityamparikh wants to merge 2 commits into
apache:mainfrom
adityamparikh:fix/solr-config-properties-validation

Conversation

@adityamparikh

@adityamparikh adityamparikh commented Apr 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Fail-fast validation for solr.url, so a misconfigured deployment dies at startup with an actionable message instead of at first request with an opaque SolrJ error.

  • Add @Validated + @NotBlank to SolrConfigurationProperties.url
  • Add @SolrUrl, a Bean Validation constraint requiring an absolute http/https URL with a non-empty host, implemented with Spring's UriComponentsBuilder
  • Add the spring-boot-starter-validation dependency

Why @NotBlank alone isn't enough

@NotBlank rejects only null, "" and all-whitespace. solr.url=localhost:8983 — omitting the scheme is an easy mistake — binds successfully. java.net.URI parses it as scheme localhost with a null host, and SolrConfig normalizes it by pure string concatenation into localhost:8983/solr/ without ever noticing.

Accepted Rejected
http://localhost:8983 localhost:8983 (scheme localhost, no host)
http://localhost:8983/solr/ solr.example.com (not absolute)
https://solr.internal:8983/custom/solr/ ftp://…, file://… (SolrJ can't speak them)
/solr, not a url, http://

Null and blank remain @NotBlank's responsibility, so a single mistake produces a single message rather than two overlapping ones.

Test plan

Rebased onto main @ a84033b.

  • ./gradlew build passes (full Testcontainers suite)
  • ./gradlew nativeTest -Pnative242 successful, 0 failed
  • SolrUrlValidatorTest — 17 tests. Verified the suite actually detects the feature's absence: with the predicate neutered, exactly the 8 tests encoding the new behavior fail.
  • No SolrNativeHints change needed — Spring's BeanValidationBeanRegistrationAotProcessor registers SolrUrlValidator automatically, confirmed by the 15 constraint tests passing inside the native test binary.

Note for reviewers

The two ApplicationContextRunner tests are @DisabledInNativeImage. That runner builds its AssertableApplicationContext via java.lang.reflect.Proxy, which GraalVM cannot materialize without a build-time registration. This is a test-harness limitation, not a constraint limitation — registering that proxy in SolrNativeHints would push test-only scaffolding into the production image. The JVM build covers this path, and the constraint itself runs natively (15 passing, 2 skipped).

🤖 Generated with Claude Code

@adityamparikh
adityamparikh force-pushed the fix/solr-config-properties-validation branch from a3f6b1a to b2c8af9 Compare May 2, 2026 17:04
@adityamparikh
adityamparikh force-pushed the fix/solr-config-properties-validation branch from b2c8af9 to 184bdd3 Compare June 15, 2026 16:42
@adityamparikh
adityamparikh force-pushed the fix/solr-config-properties-validation branch from b4159ef to b1c961d Compare August 18, 2026 23:33
adityamparikh and others added 2 commits August 19, 2026 07:25
Add @validated and @notblank to SolrConfigurationProperties.url so that
missing or empty Solr URL is caught at startup instead of failing at
runtime. Add spring-boot-starter-validation dependency to enable Bean
Validation. The existing @NullMarked JSpecify annotation on the package
already covers the null-safety contract.

Signed-off-by: Aditya Parikh <aditya.m.parikh@gmail.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: adityamparikh <aditya.m.parikh@gmail.com>
@notblank rejects only null, empty and all-whitespace values, so
solr.url=localhost:8983 still binds successfully. java.net.URI parses
that as scheme "localhost" with a null host, and SolrConfig normalizes
it by pure string concatenation into localhost:8983/solr/ without
noticing, so the misconfiguration only surfaces later as an opaque
SolrJ connection error.

Add a @SolrUrl constraint that parses the value with Spring's
UriComponentsBuilder and requires an absolute URL whose scheme is http
or https and which carries a non-empty host -- exactly the set
HttpJdkSolrClient can talk to. Null and blank stay @notblank's
responsibility so a single mistake yields a single message.

The two ApplicationContextRunner tests are @DisabledInNativeImage:
that runner builds its AssertableApplicationContext through
java.lang.reflect.Proxy, which GraalVM cannot materialize without a
build-time registration. The constraint itself runs natively and is
covered there by the parameterized tests.

Verified: ./gradlew build passes; nativeTest -Pnative shows 68
failures both with and without this change (pre-existing on this
branch's base) with 15 added passing tests and no new failures.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Aditya Parikh <aditya.m.parikh@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant