fix(config): reject a solr.url SolrJ cannot connect to at bind time - #104
Open
adityamparikh wants to merge 1 commit into
Open
fix(config): reject a solr.url SolrJ cannot connect to at bind time#104adityamparikh wants to merge 1 commit into
adityamparikh wants to merge 1 commit into
Conversation
adityamparikh
force-pushed
the
fix/solr-config-properties-validation
branch
from
May 2, 2026 17:04
a3f6b1a to
b2c8af9
Compare
adityamparikh
force-pushed
the
fix/solr-config-properties-validation
branch
from
June 15, 2026 16:42
b2c8af9 to
184bdd3
Compare
adityamparikh
force-pushed
the
fix/solr-config-properties-validation
branch
2 times, most recently
from
August 19, 2026 11:58
b1c961d to
0f3e043
Compare
Contributor
Author
|
Heads-up: this branch carries |
adityamparikh
force-pushed
the
fix/solr-config-properties-validation
branch
from
September 12, 2026 16:03
777168e to
b4ffe18
Compare
A solr.url without a scheme (localhost:8983) binds cleanly: java.net.URI parses it as scheme "localhost" with no host, SolrConfig normalizes the path by concatenation without noticing, and the deployment fails at first request with an opaque SolrJ error instead of at startup. The record's compact constructor now requires an absolute http or https URL with a host and reports the property name, an example and the offending value; Boot's bind failure analyzer surfaces that at startup. No Bean Validation: Hibernate Validator is not on the classpath and a custom constraint would cost a dependency and two classes for one field. The binder invokes the constructor reflectively and passes null when the property is absent, so the hasText check here is the guard for that boundary. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wh7SJkZhL1uuK7pYc3SLk8 Signed-off-by: Aditya Parikh <aditya.m.parikh@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
solr.urlis bound into a record and handed to SolrJ. Nothing checks that it is a URL SolrJ can actually use, so a misconfigured deployment starts cleanly and fails at first request with an opaque client error. The easy mistake is omitting the scheme:Change
SolrConfigurationPropertiesgets a compact constructor that rejects anything but an absolutehttp/httpsURL with a host, with a message that names the property, shows an example and echoes the offending value:http://localhost:8983localhost:8983(schemelocalhost, no host)http://localhost:8983/solr/solr.example.com,/solr(not absolute)https://solr.internal:8983/custom/solr/ftp://…,file://…(SolrJ cannot speak them)http://solr:8983/solr/not a url,http://, empty, blank, absentBoot surfaces the
IllegalArgumentExceptionthrough its bind failure analyzer, so startup prints Failed to bind properties under 'solr' with the reason, rather than a stack trace at first request.Why the constructor and not Bean Validation.
@Validated+ constraints is the Boot idiom when Hibernate Validator is already present. Here it is not: adding it for one field means a new runtime dependency in the native image plus two extra classes for a custom constraint, and@NotBlank/@URLalone cannot express "http(s) with a host" (Hibernate's@URLacceptsftp://andfile://). A record's compact constructor is the plain-Java place for an invariant, and it is also where JSpecify's boundary argument applies: the binder invokes it reflectively and will passnullwhen the property is absent, so the onehasTextcheck here is the guard for that boundary, not a redundant one.Path normalization (appending
/solr/) is unchanged and still lives inSolrConfig.Verification
SolrConfigurationPropertiesTest(19 cases: 7 accepted URLs, 9 rejected values, absent value, and twoApplicationContextRunnerbind tests) was written before the change and run againstmain: all 11 rejection cases fail, all acceptance cases pass. The two context-runner tests are@DisabledInNativeImagebecause that runner builds its context through a JDK dynamic proxy; the constructor itself is plain Java and runs natively.SolrConfigUrlNormalizationTestandSolrConfigAuthTestunchanged and green../gradlew buildon JDK 25 againstmain@b4ffe18, run twice. First run: green. Second run, in a clean worktree: 6 failures, allDistributedTracingTest, root causeSolrClientUtilsException: Http Call Status: 404while Testcontainers startedsolr:9.9-slim— a container startup flake unrelated to this change; the class passes 6/6 on rerun in the same worktree.🤖 Generated with Claude Code
https://claude.ai/code/session_01Wh7SJkZhL1uuK7pYc3SLk8