Skip to content

Commit 96eb6c3

Browse files
adityamparikhclaude
andcommitted
feat(deps): upgrade solr-solrj from 9.9.0 to 10.0.0
- Bump solr version to 10.0.0 in libs.versions.toml - Remove Jetty BOM alignment (Solr 10 uses Jetty 12; no longer needed) - Remove Apache HttpComponents exclusion (SolrJ 10 no longer uses it) - Replace Http2SolrClient with HttpJdkSolrClient (new JDK HTTP client) - Move SolrQuery import: solrj → solrj.request package - Move ResponseParser import: solrj → solrj.response package - Adapt ResponseParser: getContentType() → getContentTypes() returning Collection<String>; remove processResponse(Reader) (no longer abstract) - Fix CoreAdminResponse.getCoreStatus(): now returns Map<String, SingleCoreData> instead of NamedList — update listCollections() and CollectionServiceTest accordingly All unit and Testcontainers integration tests pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Signed-off-by: adityamparikh <aditya.m.parikh@gmail.com>
1 parent a75f28f commit 96eb6c3

11 files changed

Lines changed: 32 additions & 52 deletions

File tree

build.gradle.kts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,7 @@ dependencies {
9696
implementation(libs.spring.boot.starter.web)
9797
implementation(libs.spring.boot.starter.actuator)
9898
implementation(libs.spring.ai.starter.mcp.server.webmvc)
99-
implementation(libs.solr.solrj) {
100-
exclude(group = "org.apache.httpcomponents")
101-
}
99+
implementation(libs.solr.solrj)
102100
implementation(libs.commons.csv)
103101
// JSpecify for nullability annotations
104102
implementation(libs.jspecify)
@@ -119,8 +117,6 @@ dependencies {
119117
dependencyManagement {
120118
imports {
121119
mavenBom("org.springframework.ai:spring-ai-bom:${libs.versions.spring.ai.get()}")
122-
// Align Jetty family to 10.x compatible with SolrJ 9.x
123-
mavenBom("org.eclipse.jetty:jetty-bom:${libs.versions.jetty.get()}")
124120
}
125121
}
126122

gradle/libs.versions.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ spotless = "7.0.2"
88

99
# Main dependencies
1010
spring-ai = "1.1.2"
11-
solr = "9.9.0"
11+
solr = "10.0.0"
1212
commons-csv = "1.10.0"
1313
jspecify = "1.0.0"
1414
mcp-server-security = "0.0.4"
@@ -17,8 +17,6 @@ mcp-server-security = "0.0.4"
1717
errorprone-core = "2.38.0"
1818
nullaway = "0.12.7"
1919

20-
# Jetty BOM version
21-
jetty = "10.0.22"
2220

2321
# Test dependencies
2422
testcontainers = "1.21.3"

src/main/java/org/apache/solr/mcp/server/config/JsonResponseParser.java

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@
2020
import com.fasterxml.jackson.databind.ObjectMapper;
2121
import java.io.IOException;
2222
import java.io.InputStream;
23-
import java.io.Reader;
2423
import java.util.ArrayList;
24+
import java.util.Collection;
2525
import java.util.List;
26-
import org.apache.solr.client.solrj.ResponseParser;
26+
import org.apache.solr.client.solrj.response.ResponseParser;
2727
import org.apache.solr.common.SolrDocument;
2828
import org.apache.solr.common.SolrDocumentList;
2929
import org.apache.solr.common.SolrException;
@@ -80,8 +80,8 @@ public String getWriterType() {
8080
}
8181

8282
@Override
83-
public String getContentType() {
84-
return MediaType.APPLICATION_JSON_VALUE;
83+
public Collection<String> getContentTypes() {
84+
return List.of(MediaType.APPLICATION_JSON_VALUE);
8585
}
8686

8787
@Override
@@ -93,15 +93,6 @@ public NamedList<Object> processResponse(InputStream body, String encoding) {
9393
}
9494
}
9595

96-
@Override
97-
public NamedList<Object> processResponse(Reader reader) {
98-
try {
99-
return toNamedList(mapper.readTree(reader));
100-
} catch (IOException e) {
101-
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Failed to parse Solr JSON response", e);
102-
}
103-
}
104-
10596
private SimpleOrderedMap<Object> toNamedList(JsonNode objectNode) {
10697
SimpleOrderedMap<Object> result = new SimpleOrderedMap<>();
10798
objectNode.fields().forEachRemaining(entry -> result.add(entry.getKey(), convertValue(entry.getValue())));

src/main/java/org/apache/solr/mcp/server/config/SolrConfig.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import com.fasterxml.jackson.databind.ObjectMapper;
2020
import java.util.concurrent.TimeUnit;
2121
import org.apache.solr.client.solrj.SolrClient;
22-
import org.apache.solr.client.solrj.impl.Http2SolrClient;
22+
import org.apache.solr.client.solrj.impl.HttpJdkSolrClient;
2323
import org.springframework.boot.context.properties.EnableConfigurationProperties;
2424
import org.springframework.context.annotation.Bean;
2525
import org.springframework.context.annotation.Configuration;
@@ -96,7 +96,7 @@
9696
* @version 1.0.0
9797
* @since 1.0.0
9898
* @see SolrConfigurationProperties
99-
* @see Http2SolrClient
99+
* @see HttpJdkSolrClient
100100
* @see org.springframework.boot.context.properties.EnableConfigurationProperties
101101
*/
102102
@Configuration
@@ -165,7 +165,7 @@ public class SolrConfig {
165165
* the injected Solr configuration properties containing connection
166166
* URL
167167
* @return configured SolrClient instance ready for use in application services
168-
* @see Http2SolrClient.Builder
168+
* @see HttpJdkSolrClient.Builder
169169
* @see SolrConfigurationProperties#url()
170170
*/
171171
@Bean
@@ -193,7 +193,7 @@ SolrClient solrClient(SolrConfigurationProperties properties, JsonResponseParser
193193
}
194194

195195
// Use with explicit base URL; JSON wire format replaces the JavaBin default
196-
return new Http2SolrClient.Builder(url).withConnectionTimeout(CONNECTION_TIMEOUT_MS, TimeUnit.MILLISECONDS)
196+
return new HttpJdkSolrClient.Builder(url).withConnectionTimeout(CONNECTION_TIMEOUT_MS, TimeUnit.MILLISECONDS)
197197
.withIdleTimeout(SOCKET_TIMEOUT_MS, TimeUnit.MILLISECONDS).withResponseParser(jsonResponseParser)
198198
.build();
199199
}

src/main/java/org/apache/solr/mcp/server/metadata/CollectionService.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@
2727
import java.util.Date;
2828
import java.util.List;
2929
import org.apache.solr.client.solrj.SolrClient;
30-
import org.apache.solr.client.solrj.SolrQuery;
3130
import org.apache.solr.client.solrj.SolrRequest;
3231
import org.apache.solr.client.solrj.SolrServerException;
3332
import org.apache.solr.client.solrj.impl.CloudSolrClient;
3433
import org.apache.solr.client.solrj.request.CollectionAdminRequest;
3534
import org.apache.solr.client.solrj.request.CoreAdminRequest;
3635
import org.apache.solr.client.solrj.request.GenericSolrRequest;
3736
import org.apache.solr.client.solrj.request.LukeRequest;
37+
import org.apache.solr.client.solrj.request.SolrQuery;
3838
import org.apache.solr.client.solrj.response.CollectionAdminResponse;
3939
import org.apache.solr.client.solrj.response.CoreAdminResponse;
4040
import org.apache.solr.client.solrj.response.LukeResponse;
@@ -359,12 +359,7 @@ public List<String> listCollections() {
359359
coreAdminRequest.setAction(CoreAdminParams.CoreAdminAction.STATUS);
360360
CoreAdminResponse coreResponse = coreAdminRequest.process(solrClient);
361361

362-
List<String> cores = new ArrayList<>();
363-
NamedList<NamedList<Object>> coreStatus = coreResponse.getCoreStatus();
364-
for (int i = 0; i < coreStatus.size(); i++) {
365-
cores.add(coreStatus.getName(i));
366-
}
367-
return cores;
362+
return new ArrayList<>(coreResponse.getCoreStatus().keySet());
368363
}
369364
} catch (SolrServerException | IOException e) {
370365
return new ArrayList<>();

src/main/java/org/apache/solr/mcp/server/search/SearchService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@
2222
import java.util.List;
2323
import java.util.Map;
2424
import org.apache.solr.client.solrj.SolrClient;
25-
import org.apache.solr.client.solrj.SolrQuery;
2625
import org.apache.solr.client.solrj.SolrServerException;
26+
import org.apache.solr.client.solrj.request.SolrQuery;
2727
import org.apache.solr.client.solrj.response.FacetField;
2828
import org.apache.solr.client.solrj.response.QueryResponse;
2929
import org.apache.solr.common.SolrDocument;

src/test/java/org/apache/solr/mcp/server/config/SolrConfigTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import static org.junit.jupiter.api.Assertions.*;
2020

2121
import org.apache.solr.client.solrj.SolrClient;
22-
import org.apache.solr.client.solrj.impl.Http2SolrClient;
22+
import org.apache.solr.client.solrj.impl.HttpJdkSolrClient;
2323
import org.apache.solr.mcp.server.TestcontainersConfiguration;
2424
import org.junit.jupiter.api.Test;
2525
import org.springframework.beans.factory.annotation.Autowired;
@@ -49,9 +49,9 @@ void testSolrClientConfiguration() {
4949

5050
// Verify that the SolrClient is using the correct URL
5151
// Note: SolrConfig normalizes the URL to have trailing slash, but
52-
// Http2SolrClient removes
52+
// HttpJdkSolrClient removes
5353
// it
54-
var httpSolrClient = assertInstanceOf(Http2SolrClient.class, solrClient);
54+
var httpSolrClient = assertInstanceOf(HttpJdkSolrClient.class, solrClient);
5555
String expectedUrl = "http://" + solrContainer.getHost() + ":" + solrContainer.getMappedPort(8983) + "/solr";
5656
assertEquals(expectedUrl, httpSolrClient.getBaseURL());
5757
}

src/test/java/org/apache/solr/mcp/server/config/SolrConfigUrlNormalizationTest.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
import com.fasterxml.jackson.databind.ObjectMapper;
2222
import org.apache.solr.client.solrj.SolrClient;
23-
import org.apache.solr.client.solrj.impl.Http2SolrClient;
23+
import org.apache.solr.client.solrj.impl.HttpJdkSolrClient;
2424
import org.junit.jupiter.api.Test;
2525
import org.junit.jupiter.params.ParameterizedTest;
2626
import org.junit.jupiter.params.provider.CsvSource;
@@ -46,7 +46,7 @@ void testUrlNormalization(String inputUrl, String expectedUrl) {
4646
SolrClient client = solrConfig.solrClient(testProperties, new JsonResponseParser(objectMapper));
4747
assertNotNull(client);
4848

49-
var httpClient = assertInstanceOf(Http2SolrClient.class, client);
49+
var httpClient = assertInstanceOf(HttpJdkSolrClient.class, client);
5050
assertEquals(expectedUrl, httpClient.getBaseURL());
5151

5252
try {
@@ -62,7 +62,7 @@ void testUrlWithoutTrailingSlash() {
6262
SolrConfig solrConfig = new SolrConfig();
6363

6464
SolrClient client = solrConfig.solrClient(testProperties, new JsonResponseParser(objectMapper));
65-
Http2SolrClient httpClient = (Http2SolrClient) client;
65+
HttpJdkSolrClient httpClient = (HttpJdkSolrClient) client;
6666

6767
assertEquals("http://localhost:8983/solr", httpClient.getBaseURL());
6868

@@ -79,7 +79,7 @@ void testUrlWithTrailingSlashButNoSolrPath() {
7979
SolrConfig solrConfig = new SolrConfig();
8080

8181
SolrClient client = solrConfig.solrClient(testProperties, new JsonResponseParser(objectMapper));
82-
Http2SolrClient httpClient = (Http2SolrClient) client;
82+
HttpJdkSolrClient httpClient = (HttpJdkSolrClient) client;
8383

8484
assertEquals("http://localhost:8983/solr", httpClient.getBaseURL());
8585

@@ -96,7 +96,7 @@ void testUrlWithSolrPathButNoTrailingSlash() {
9696
SolrConfig solrConfig = new SolrConfig();
9797

9898
SolrClient client = solrConfig.solrClient(testProperties, new JsonResponseParser(objectMapper));
99-
Http2SolrClient httpClient = (Http2SolrClient) client;
99+
HttpJdkSolrClient httpClient = (HttpJdkSolrClient) client;
100100

101101
assertEquals("http://localhost:8983/solr", httpClient.getBaseURL());
102102

@@ -113,7 +113,7 @@ void testUrlAlreadyProperlyFormatted() {
113113
SolrConfig solrConfig = new SolrConfig();
114114

115115
SolrClient client = solrConfig.solrClient(testProperties, new JsonResponseParser(objectMapper));
116-
Http2SolrClient httpClient = (Http2SolrClient) client;
116+
HttpJdkSolrClient httpClient = (HttpJdkSolrClient) client;
117117

118118
assertEquals("http://localhost:8983/solr", httpClient.getBaseURL());
119119

src/test/java/org/apache/solr/mcp/server/metadata/CollectionServiceTest.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
import java.lang.reflect.Method;
2727
import java.util.Arrays;
2828
import java.util.Collections;
29+
import java.util.HashMap;
2930
import java.util.List;
31+
import java.util.Map;
3032
import org.apache.solr.client.solrj.SolrClient;
3133
import org.apache.solr.client.solrj.SolrRequest;
3234
import org.apache.solr.client.solrj.SolrServerException;
@@ -744,15 +746,13 @@ void listCollections_CloudClient_Error() throws Exception {
744746

745747
@Test
746748
void listCollections_NonCloudClient_Success() throws Exception {
747-
// Create a NamedList to represent the core status response
749+
// Create a NamedList to represent the core status response.
750+
// The "status" value must be a Map so SolrJ 10 can use Jackson convertValue
751+
// to produce Map<String, SingleCoreData>.
748752
NamedList<Object> response = new NamedList<>();
749-
NamedList<Object> status = new NamedList<>();
750-
751-
NamedList<Object> core1Status = new NamedList<>();
752-
NamedList<Object> core2Status = new NamedList<>();
753-
754-
status.add("core1", core1Status);
755-
status.add("core2", core2Status);
753+
Map<String, Object> status = new HashMap<>();
754+
status.put("core1", new HashMap<>());
755+
status.put("core2", new HashMap<>());
756756
response.add("status", status);
757757

758758
// Mock the solrClient request to return the response

src/test/java/org/apache/solr/mcp/server/search/SearchServiceDirectTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
import java.util.List;
2727
import java.util.Map;
2828
import org.apache.solr.client.solrj.SolrClient;
29-
import org.apache.solr.client.solrj.SolrQuery;
3029
import org.apache.solr.client.solrj.SolrServerException;
30+
import org.apache.solr.client.solrj.request.SolrQuery;
3131
import org.apache.solr.client.solrj.response.FacetField;
3232
import org.apache.solr.client.solrj.response.QueryResponse;
3333
import org.apache.solr.common.SolrDocument;

0 commit comments

Comments
 (0)