From 3ed3d3eb36c4bce69c082c343152af54cdcdbb56 Mon Sep 17 00:00:00 2001 From: Chris Dennis Date: Sat, 26 Feb 2022 15:43:05 -0500 Subject: [PATCH] Restore Ehcache 3 Support See gh-30002 --- .../spring-boot-autoconfigure/build.gradle | 5 ++ .../EhCache3CacheAutoConfigurationTests.java | 67 +++++++++++++++++++ .../src/test/resources/ehcache3.xml | 4 +- .../spring-boot-dependencies/build.gradle | 13 ++++ .../src/docs/asciidoc/documentation/io.adoc | 2 +- .../src/docs/asciidoc/io/caching.adoc | 2 +- .../spring-boot-smoke-test-cache/build.gradle | 8 +++ 7 files changed, 97 insertions(+), 4 deletions(-) create mode 100644 spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/cache/EhCache3CacheAutoConfigurationTests.java diff --git a/spring-boot-project/spring-boot-autoconfigure/build.gradle b/spring-boot-project/spring-boot-autoconfigure/build.gradle index e252258320..83d557af77 100644 --- a/spring-boot-project/spring-boot-autoconfigure/build.gradle +++ b/spring-boot-project/spring-boot-autoconfigure/build.gradle @@ -88,6 +88,11 @@ dependencies { optional("org.eclipse.jetty.websocket:websocket-jetty-server") { exclude(group: "org.eclipse.jetty", module: "jetty-jndi") } + optional("org.ehcache:ehcache") { + artifact { + classifier = 'jakarta' + } + } optional("org.elasticsearch.client:elasticsearch-rest-client") { exclude group: "commons-logging", module: "commons-logging" } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/cache/EhCache3CacheAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/cache/EhCache3CacheAutoConfigurationTests.java new file mode 100644 index 0000000000..d3b0d56ec4 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/cache/EhCache3CacheAutoConfigurationTests.java @@ -0,0 +1,67 @@ +/* + * Copyright 2012-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.autoconfigure.cache; + +import org.ehcache.jsr107.EhcacheCachingProvider; +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.cache.CacheAutoConfigurationTests.DefaultCacheConfiguration; +import org.springframework.boot.testsupport.classpath.ClassPathExclusions; +import org.springframework.cache.jcache.JCacheCacheManager; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link CacheAutoConfiguration} with EhCache 3. + * + * @author Stephane Nicoll + * @author Andy Wilkinson + */ +@ClassPathExclusions("ehcache-2*.jar") +class EhCache3CacheAutoConfigurationTests extends AbstractCacheAutoConfigurationTests { + + @Test + void ehcache3AsJCacheWithCaches() { + String cachingProviderFqn = EhcacheCachingProvider.class.getName(); + this.contextRunner.withUserConfiguration(DefaultCacheConfiguration.class) + .withPropertyValues("spring.cache.type=jcache", "spring.cache.jcache.provider=" + cachingProviderFqn, + "spring.cache.cacheNames[0]=foo", "spring.cache.cacheNames[1]=bar") + .run((context) -> { + JCacheCacheManager cacheManager = getCacheManager(context, JCacheCacheManager.class); + assertThat(cacheManager.getCacheNames()).containsOnly("foo", "bar"); + }); + } + + @Test + void ehcache3AsJCacheWithConfig() { + String cachingProviderFqn = EhcacheCachingProvider.class.getName(); + String configLocation = "ehcache3.xml"; + this.contextRunner.withUserConfiguration(DefaultCacheConfiguration.class) + .withPropertyValues("spring.cache.type=jcache", "spring.cache.jcache.provider=" + cachingProviderFqn, + "spring.cache.jcache.config=" + configLocation) + .run((context) -> { + JCacheCacheManager cacheManager = getCacheManager(context, JCacheCacheManager.class); + + Resource configResource = new ClassPathResource(configLocation); + assertThat(cacheManager.getCacheManager().getURI()).isEqualTo(configResource.getURI()); + assertThat(cacheManager.getCacheNames()).containsOnly("foo", "bar"); + }); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/ehcache3.xml b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/ehcache3.xml index 575fd7cdbb..5f048f2186 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/ehcache3.xml +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/ehcache3.xml @@ -3,8 +3,8 @@ xmlns='http://www.ehcache.org/v3' xmlns:jsr107='http://www.ehcache.org/v3/jsr107' xsi:schemaLocation=" - http://www.ehcache.org/v3 https://www.ehcache.org/schema/ehcache-core-3.1.xsd - http://www.ehcache.org/v3/jsr107 https://www.ehcache.org/schema/ehcache-107-ext-3.1.xsd"> + http://www.ehcache.org/v3 https://www.ehcache.org/schema/ehcache-core-3.10.xsd + http://www.ehcache.org/v3/jsr107 https://www.ehcache.org/schema/ehcache-107-ext-3.10.xsd"> 200 diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle index 1510ed7c7f..9059a58e51 100644 --- a/spring-boot-project/spring-boot-dependencies/build.gradle +++ b/spring-boot-project/spring-boot-dependencies/build.gradle @@ -191,6 +191,19 @@ bom { ] } } + library("Ehcache3", "3.10.0") { + group("org.ehcache") { + modules = [ + "ehcache" { + classifier = 'jakarta' + }, + "ehcache-clustered", + "ehcache-transactions" { + classifier = 'jakarta' + } + ] + } + } library("Elasticsearch", "7.17.1") { group("org.elasticsearch") { modules = [ diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/documentation/io.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/documentation/io.adoc index 38e458d4b1..9a482440f3 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/documentation/io.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/documentation/io.adoc @@ -2,7 +2,7 @@ == IO If your application needs IO capabilities, see one or more of the following sections: -* *Caching:* <> +* *Caching:* <> * *Quartz:* <> * *Mail:* <> * *Validation:* <> diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/io/caching.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/io/caching.adoc index 31000819ca..06d9b1a764 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/io/caching.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/io/caching.adoc @@ -37,7 +37,7 @@ The cache abstraction does not provide an actual store and relies on abstraction If you have not defined a bean of type `CacheManager` or a `CacheResolver` named `cacheResolver` (see {spring-framework-api}/cache/annotation/CachingConfigurer.html[`CachingConfigurer`]), Spring Boot tries to detect the following providers (in the indicated order): . <> -. <> (Hazelcast and others) +. <> (EhCache 3, Hazelcast, and others) . <> . <> . <> diff --git a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-cache/build.gradle b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-cache/build.gradle index 9ea95627f4..e487a575c3 100644 --- a/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-cache/build.gradle +++ b/spring-boot-tests/spring-boot-smoke-tests/spring-boot-smoke-test-cache/build.gradle @@ -12,6 +12,14 @@ def caches = [ "couchbase": [ project(":spring-boot-project:spring-boot-starters:spring-boot-starter-data-couchbase") ], + "ehcache": [ + "javax.cache:cache-api", + dependencies.create("org.ehcache:ehcache") { + artifact { + classifier = 'jakarta' + } + } + ], "hazelcast": [ "com.hazelcast:hazelcast", "com.hazelcast:hazelcast-spring"