diff --git a/admin/broadleaf-open-admin-platform/src/main/java/org/broadleafcommerce/openadmin/server/service/persistence/validation/SkuNamePropertyValidator.java b/admin/broadleaf-open-admin-platform/src/main/java/org/broadleafcommerce/openadmin/server/service/persistence/validation/SkuNamePropertyValidator.java index 221d069330..601d4870bf 100644 --- a/admin/broadleaf-open-admin-platform/src/main/java/org/broadleafcommerce/openadmin/server/service/persistence/validation/SkuNamePropertyValidator.java +++ b/admin/broadleaf-open-admin-platform/src/main/java/org/broadleafcommerce/openadmin/server/service/persistence/validation/SkuNamePropertyValidator.java @@ -2,7 +2,7 @@ * #%L * BroadleafCommerce Open Admin Platform * %% - * Copyright (C) 2009 - 2025 Broadleaf Commerce + * Copyright (C) 2009 - 2026 Broadleaf Commerce * %% * Licensed under the Broadleaf Fair Use License Agreement, Version 1.0 * (the "Fair Use License" located at http://license.broadleafcommerce.org/fair_use_license-1.0.txt) @@ -74,4 +74,4 @@ protected static boolean getExploitProtection() { return BLCSystemProperty.resolveBooleanSystemProperty("exploitProtection.xssEnabled", false); } -} \ No newline at end of file +} diff --git a/common/pom.xml b/common/pom.xml index d511f5b9e0..fd1e81834b 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -142,11 +142,11 @@ - org.hibernate.orm - hibernate-core + org.hibernate + hibernate-core-jakarta - org.hibernate.orm + org.hibernate hibernate-jcache @@ -171,8 +171,8 @@ easymockclassextension - org.hibernate.orm - hibernate-envers + org.hibernate + hibernate-envers-jakarta jakarta.mail @@ -479,9 +479,9 @@ javassist - jakarta.cache - jakarta.cache-api - 3.0.0 + javax.cache + cache-api + 1.1.0 diff --git a/core/broadleaf-framework/pom.xml b/core/broadleaf-framework/pom.xml index 2c19a01d95..8ec6b8d0c3 100644 --- a/core/broadleaf-framework/pom.xml +++ b/core/broadleaf-framework/pom.xml @@ -77,6 +77,10 @@ org.apache.solr solr-solrj + + org.apache.solr + solr-solrj-jetty + org.apache.zookeeper zookeeper diff --git a/core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/search/service/solr/AbstractSolrSearchServiceExtensionHandler.java b/core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/search/service/solr/AbstractSolrSearchServiceExtensionHandler.java index bc9053481e..38ef20018c 100644 --- a/core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/search/service/solr/AbstractSolrSearchServiceExtensionHandler.java +++ b/core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/search/service/solr/AbstractSolrSearchServiceExtensionHandler.java @@ -17,7 +17,7 @@ */ package org.broadleafcommerce.core.search.service.solr; -import org.apache.solr.client.solrj.SolrQuery; +import org.apache.solr.client.solrj.request.SolrQuery; import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.common.SolrDocument; import org.broadleafcommerce.common.extension.AbstractExtensionHandler; diff --git a/core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/search/service/solr/DelegatingHttpSolrClient.java b/core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/search/service/solr/DelegatingHttpJettySolrClient.java similarity index 96% rename from core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/search/service/solr/DelegatingHttpSolrClient.java rename to core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/search/service/solr/DelegatingHttpJettySolrClient.java index b769efdc7e..e51f8921e7 100644 --- a/core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/search/service/solr/DelegatingHttpSolrClient.java +++ b/core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/search/service/solr/DelegatingHttpJettySolrClient.java @@ -22,9 +22,9 @@ import org.apache.solr.client.solrj.SolrRequest; import org.apache.solr.client.solrj.SolrRequest.METHOD; import org.apache.solr.client.solrj.SolrServerException; -import org.apache.solr.client.solrj.StreamingResponseCallback; import org.apache.solr.client.solrj.beans.DocumentObjectBinder; -import org.apache.solr.client.solrj.impl.HttpSolrClient; +import org.apache.solr.client.solrj.response.StreamingResponseCallback; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.client.solrj.response.SolrPingResponse; import org.apache.solr.client.solrj.response.UpdateResponse; @@ -42,35 +42,35 @@ import java.util.List; /** - * Wrapper implementation of Solr that delegates to an {@link HttpSolrClient}. With older versions of SolrJ, there was no ability to specify a - * a collection on an {@link HttpSolrClient}. As a result, you needed two different clients, one for each collection. For example, you might have + * Wrapper implementation of Solr that delegates to an {@link HttpJettySolrClient}. With older versions of SolrJ, there was no ability to specify a + * a collection on an {@link HttpJettySolrClient}. As a result, you needed two different clients, one for each collection. For example, you might have * a client with the base URL: http://localhost:8983/solr/catalogs and another with the base URL of http://localhost:8983/solr/catalogs_reindex. *

* What this class allows for is a "defaultCollection". If the base URL is http://localhost:8983/solr for example, and the default collection is "catalog", then a call - * to {@link DelegatingHttpSolrClient#query(new SolrQuery("foo:bar")} will search the "catalog" index, or http://localhost:8983/solr/catalogs. Alternatively, a call to - * {@link DelegatingHttpSolrClient#query("catalogs_reindex", new SolrQuery("foo:bar"))} will search the "catalogs_reindex" index, or http://localhost:8983/solr/catalogs_reindex. + * to {@link DelegatingHttpJettySolrClient#query(new SolrQuery("foo:bar")} will search the "catalog" index, or http://localhost:8983/solr/catalogs. Alternatively, a call to + * {@link DelegatingHttpJettySolrClient#query("catalogs_reindex", new SolrQuery("foo:bar"))} will search the "catalogs_reindex" index, or http://localhost:8983/solr/catalogs_reindex. *

* The same thing goes for writes. This class simply delegates to the delegate passed into the constructor. * * @author Kelly Tisdell */ -public class DelegatingHttpSolrClient extends SolrClient { +public class DelegatingHttpJettySolrClient extends SolrClient { @Serial private static final long serialVersionUID = 1L; - protected final HttpSolrClient delegate; + protected final HttpJettySolrClient delegate; protected final String defaultCollection; protected final String defaultCollectionPath; - public DelegatingHttpSolrClient(HttpSolrClient delegate) { + public DelegatingHttpJettySolrClient(HttpJettySolrClient delegate) { Assert.notNull(delegate, "SolrClient cannot be null."); this.delegate = delegate; this.defaultCollection = null; defaultCollectionPath = null; } - public DelegatingHttpSolrClient(HttpSolrClient delegate, String defaultCollection) { + public DelegatingHttpJettySolrClient(HttpJettySolrClient delegate, String defaultCollection) { Assert.notNull(delegate, "SolrClient cannot be null."); this.delegate = delegate; if (StringUtils.isNotBlank(defaultCollection)) { @@ -643,9 +643,8 @@ public SolrDocumentList getById(Collection ids, SolrParams params) throw } } - @Override public DocumentObjectBinder getBinder() { - return delegate.getBinder(); + return DocumentObjectBinder.INSTANCE; } @Override @@ -653,7 +652,7 @@ public void close() throws IOException { delegate.close(); } - public HttpSolrClient getDelegate() { + public HttpJettySolrClient getDelegate() { return delegate; } diff --git a/core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/search/service/solr/SolrConfiguration.java b/core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/search/service/solr/SolrConfiguration.java index cd5d1aa13f..7a8d621411 100644 --- a/core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/search/service/solr/SolrConfiguration.java +++ b/core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/search/service/solr/SolrConfiguration.java @@ -23,7 +23,7 @@ import org.apache.solr.client.solrj.SolrClient; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.impl.CloudSolrClient; -import org.apache.solr.client.solrj.impl.HttpSolrClient; +import org.apache.solr.client.solrj.jetty.HttpJettySolrClient; import org.apache.solr.client.solrj.request.CollectionAdminRequest; import org.broadleafcommerce.common.exception.ExceptionHelper; import org.broadleafcommerce.common.site.domain.Site; @@ -82,7 +82,7 @@ public class SolrConfiguration implements InitializingBean { /** * Sets up Solr using multiple clients, one primary, one for reindexing, and one admin to reduce down time during - * indexing. This constructor should be used when setting up HttpSolrClient since no collection names are + * indexing. This constructor should be used when setting up HttpJettySolrClient since no collection names are * being provided. *

* The adminServer is just a reference to a SolrClient component for connecting to Solr. In newer @@ -102,16 +102,16 @@ public class SolrConfiguration implements InitializingBean { public SolrConfiguration(SolrClient solrServer, SolrClient reindexServer, SolrClient adminServer) throws IllegalStateException { //get primary and reindex names from http urls - if (HttpSolrClient.class.isAssignableFrom(solrServer.getClass())) { - this.setPrimaryName(determineCoreName((HttpSolrClient) solrServer)); - } else if (DelegatingHttpSolrClient.class.isAssignableFrom(solrServer.getClass())) { - this.setPrimaryName(((DelegatingHttpSolrClient) solrServer).getDefaultCollection()); + if (HttpJettySolrClient.class.isAssignableFrom(solrServer.getClass())) { + this.setPrimaryName(determineCoreName((HttpJettySolrClient) solrServer)); + } else if (DelegatingHttpJettySolrClient.class.isAssignableFrom(solrServer.getClass())) { + this.setPrimaryName(((DelegatingHttpJettySolrClient) solrServer).getDefaultCollection()); } - if (HttpSolrClient.class.isAssignableFrom(reindexServer.getClass())) { - this.setReindexName(determineCoreName((HttpSolrClient) reindexServer)); - } else if (DelegatingHttpSolrClient.class.isAssignableFrom(reindexServer.getClass())) { - this.setReindexName(((DelegatingHttpSolrClient) reindexServer).getDefaultCollection()); + if (HttpJettySolrClient.class.isAssignableFrom(reindexServer.getClass())) { + this.setReindexName(determineCoreName((HttpJettySolrClient) reindexServer)); + } else if (DelegatingHttpJettySolrClient.class.isAssignableFrom(reindexServer.getClass())) { + this.setReindexName(((DelegatingHttpJettySolrClient) reindexServer).getDefaultCollection()); } this.setServer(solrServer); @@ -121,7 +121,7 @@ public SolrConfiguration(SolrClient solrServer, SolrClient reindexServer, SolrCl /** * Sets up Solr using multiple clients, one primary, one for reindexing, and one admin to reduce down time during - * indexing. This constructor should be used when setting up HttpSolrClient since no collection names are + * indexing. This constructor should be used when setting up HttpJettySolrClient since no collection names are * being provided. Namespace can be specified if managing multiple document sets within the same cores. *

* The adminServer is just a reference to a SolrClient component for connecting to Solr. In newer @@ -146,23 +146,23 @@ public SolrConfiguration( String namespace ) throws IllegalStateException { this.setNamespace(namespace); - if (HttpSolrClient.class.isAssignableFrom(solrServer.getClass())) { - this.setPrimaryName(determineCoreName((HttpSolrClient) solrServer)); - } else if (DelegatingHttpSolrClient.class.isAssignableFrom(solrServer.getClass())) { - if (((DelegatingHttpSolrClient) solrServer).getDefaultCollection() == null) { - this.setReindexName(determineCoreName(((DelegatingHttpSolrClient) solrServer).getDelegate())); + if (HttpJettySolrClient.class.isAssignableFrom(solrServer.getClass())) { + this.setPrimaryName(determineCoreName((HttpJettySolrClient) solrServer)); + } else if (DelegatingHttpJettySolrClient.class.isAssignableFrom(solrServer.getClass())) { + if (((DelegatingHttpJettySolrClient) solrServer).getDefaultCollection() == null) { + this.setReindexName(determineCoreName(((DelegatingHttpJettySolrClient) solrServer).getDelegate())); } else { - this.setReindexName(((DelegatingHttpSolrClient) solrServer).getDefaultCollection()); + this.setReindexName(((DelegatingHttpJettySolrClient) solrServer).getDefaultCollection()); } } - if (HttpSolrClient.class.isAssignableFrom(reindexServer.getClass())) { - this.setReindexName(determineCoreName((HttpSolrClient) reindexServer)); - } else if (DelegatingHttpSolrClient.class.isAssignableFrom(solrServer.getClass())) { - if (((DelegatingHttpSolrClient) reindexServer).getDefaultCollection() == null) { - this.setReindexName(determineCoreName(((DelegatingHttpSolrClient) reindexServer).getDelegate())); + if (HttpJettySolrClient.class.isAssignableFrom(reindexServer.getClass())) { + this.setReindexName(determineCoreName((HttpJettySolrClient) reindexServer)); + } else if (DelegatingHttpJettySolrClient.class.isAssignableFrom(solrServer.getClass())) { + if (((DelegatingHttpJettySolrClient) reindexServer).getDefaultCollection() == null) { + this.setReindexName(determineCoreName(((DelegatingHttpJettySolrClient) reindexServer).getDelegate())); } else { - this.setReindexName(((DelegatingHttpSolrClient) reindexServer).getDefaultCollection()); + this.setReindexName(((DelegatingHttpJettySolrClient) reindexServer).getDefaultCollection()); } } @@ -173,7 +173,7 @@ public SolrConfiguration( /** * Sets up Solr using multiple clients, one primary, one for reindexing, and one admin to reduce down time during - * indexing. This constructor should be used when setting up LBHttpSolrClients because primaryCoreName and + * indexing. This constructor should be used when setting up LBHttpJettySolrClients because primaryCoreName and * reindexCoreName need to be provided to SolrConfiguration. *

* The adminServer is just a reference to a SolrClient component for connecting to Solr. In newer @@ -208,7 +208,7 @@ public SolrConfiguration( /** * Sets up Solr using multiple clients, one primary, one for reindexing, and one admin to reduce down time during - * indexing. This constructor should be used when setting up LBHttpSolrClients because primaryCoreName and + * indexing. This constructor should be used when setting up LBHttpJettySolrClients because primaryCoreName and * reindexCoreName need to be provided to SolrConfiguration. Namespace can be specified if managing multiple * document sets within the same cores. *

@@ -431,8 +431,8 @@ public SolrClient getServer() { /** * Sets the primary SolrClient instance to communicate with Solr. This is typically one of the following: * org.apache.solr.client.solrj.embedded.EmbeddedSolrClient, - * org.apache.solr.client.solrj.impl.HttpSolrClient, - * org.apache.solr.client.solrj.impl.LBHttpSolrClient, + * org.apache.solr.client.solrj.impl.HttpJettySolrClient, + * org.apache.solr.client.solrj.impl.LBHttpJettySolrClient, * or org.apache.solr.client.solrj.impl.CloudSolrClient * * @param server SolrClient @@ -441,9 +441,8 @@ public SolrClient getServer() { public void setServer(SolrClient server) throws IllegalStateException { if (server != null && CloudSolrClient.class.isAssignableFrom(server.getClass())) { CloudSolrClient cs = (CloudSolrClient) server; - if (StringUtils.isBlank(cs.getDefaultCollection())) { - cs.setDefaultCollection(getPrimaryName()); - } + // Note: In Solr 10+, CloudSolrClient is immutable and defaultCollection must be set via builder + // We can only validate here, not set if (reindexServer != null) { //If we already have a reindex server set, make sure it's not the same instance as the primary @@ -491,9 +490,8 @@ public SolrClient getReindexServer() { public void setReindexServer(SolrClient server) throws IllegalStateException { if (server != null && CloudSolrClient.class.isAssignableFrom(server.getClass())) { CloudSolrClient cs = (CloudSolrClient) server; - if (StringUtils.isBlank(cs.getDefaultCollection())) { - cs.setDefaultCollection(getReindexName()); - } + // Note: In Solr 10+, CloudSolrClient is immutable and defaultCollection must be set via builder + // We can only validate here, not set if (primaryServer != null) { //If we already have a reindex server set, make sure it's not the same instance as the primary @@ -792,7 +790,7 @@ public String getReindexCollectionName() { return null; } - protected String determineCoreName(HttpSolrClient httpSolrClient) { + protected String determineCoreName(HttpJettySolrClient httpSolrClient) { String url = httpSolrClient.getBaseURL(); return url.substring(url.lastIndexOf('/') + 1); } diff --git a/core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/search/service/solr/SolrHelperService.java b/core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/search/service/solr/SolrHelperService.java index 263738a345..2d952e5b08 100644 --- a/core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/search/service/solr/SolrHelperService.java +++ b/core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/search/service/solr/SolrHelperService.java @@ -18,7 +18,7 @@ package org.broadleafcommerce.core.search.service.solr; import org.apache.solr.client.solrj.SolrClient; -import org.apache.solr.client.solrj.SolrQuery; +import org.apache.solr.client.solrj.request.SolrQuery; import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.common.SolrDocument; import org.apache.solr.common.SolrInputDocument; diff --git a/core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/search/service/solr/SolrHelperServiceImpl.java b/core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/search/service/solr/SolrHelperServiceImpl.java index a8656378bb..8001d8b74b 100644 --- a/core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/search/service/solr/SolrHelperServiceImpl.java +++ b/core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/search/service/solr/SolrHelperServiceImpl.java @@ -26,9 +26,9 @@ import org.apache.commons.logging.LogFactory; import org.apache.commons.text.StringEscapeUtils; import org.apache.solr.client.solrj.SolrClient; -import org.apache.solr.client.solrj.SolrQuery; -import org.apache.solr.client.solrj.SolrQuery.ORDER; -import org.apache.solr.client.solrj.SolrQuery.SortClause; +import org.apache.solr.client.solrj.request.SolrQuery; +import org.apache.solr.client.solrj.request.SolrQuery.ORDER; +import org.apache.solr.client.solrj.request.SolrQuery.SortClause; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.impl.CloudSolrClient; import org.apache.solr.client.solrj.request.CollectionAdminRequest; diff --git a/core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/search/service/solr/SolrSearchServiceExtensionHandler.java b/core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/search/service/solr/SolrSearchServiceExtensionHandler.java index 87afce7f3d..52b2ebd7b7 100644 --- a/core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/search/service/solr/SolrSearchServiceExtensionHandler.java +++ b/core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/search/service/solr/SolrSearchServiceExtensionHandler.java @@ -17,7 +17,7 @@ */ package org.broadleafcommerce.core.search.service.solr; -import org.apache.solr.client.solrj.SolrQuery; +import org.apache.solr.client.solrj.request.SolrQuery; import org.apache.solr.client.solrj.response.QueryResponse; import org.apache.solr.common.SolrDocument; import org.broadleafcommerce.common.extension.ExtensionHandler; diff --git a/core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/search/service/solr/SolrSearchServiceImpl.java b/core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/search/service/solr/SolrSearchServiceImpl.java index c643400661..33cf71450c 100644 --- a/core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/search/service/solr/SolrSearchServiceImpl.java +++ b/core/broadleaf-framework/src/main/java/org/broadleafcommerce/core/search/service/solr/SolrSearchServiceImpl.java @@ -22,7 +22,7 @@ import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.solr.client.solrj.SolrQuery; +import org.apache.solr.client.solrj.request.SolrQuery; import org.apache.solr.client.solrj.SolrRequest.METHOD; import org.apache.solr.client.solrj.SolrServerException; import org.apache.solr.client.solrj.response.QueryResponse; diff --git a/pom.xml b/pom.xml index df4e070753..9ef10c444d 100644 --- a/pom.xml +++ b/pom.xml @@ -644,6 +644,23 @@ + + + org.hibernate.orm + hibernate-core + ${hibernate.version} + + + org.hibernate.orm + hibernate-jcache + ${hibernate.version} + + + org.hibernate.orm + hibernate-envers + ${hibernate.version} + + commons-validator @@ -1020,7 +1037,7 @@ org.apache.solr solr-solrj - 9.9.0 + 10.0.0 org.slf4j @@ -1040,16 +1057,10 @@ - - org.eclipse.jetty.http2 - http2-parent - 11.0.26 - - - org.eclipse.jetty - jetty-io - 12.1.2 + org.apache.solr + solr-solrj-jetty + 10.0.0 io.netty