Ehcache integration in Spring Boot application fails

2.5k Views Asked by At

I try to integrate Ehcache 3 into a Spring Boot 2.7.7 application, but during startup, the application fails with the following error message:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cacheAutoConfigurationValidator' defined in class path resource [org/springframework/boot/autoconfigure/cache/CacheAutoConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: No cache manager could be auto-configured, check your configuration (caching type is 'EHCACHE') ... Caused by: java.lang.IllegalArgumentException: No cache manager could be auto-configured, check your configuration (caching type is 'EHCACHE')

According the documentation it should be enough to add Ehcache to the classpath/dependencies, and to provide a ehcache.xml file.

My (relevant) dependencies looks like this:

<dependency>
    <groupId>javax.cache</groupId>
    <artifactId>cache-api</artifactId>
</dependency>
<dependency>
    <groupId>org.ehcache</groupId>
    <artifactId>ehcache</artifactId>
</dependency>

My application.properties contains the following chache related entry:

spring.cache.type=ehcache

Any idea what might be missing?

2

There are 2 best solutions below

1
On

The error was the wrong value for spring.cache.type. Changing the value of the property to jcache solved the issue.

spring.cache.type=jcache

It is also possible to leave this property out.

1
On

Encountering the same problem as Oliver, with the same exception, I'd like to submit my own work when upgrading to SpringBoot 3.0.5

Old configurations:

<!-- in POM.xml -->
<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache</artifactId>
    <version>2.10.3</version>
</dependency>
## in application.properties:
spring.cache.type=ehcache
spring.cache.ehcache.config=classpath:ehcache.xml
<!-- ehcache.xml example -->
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="ehcache.xsd"
         updateCheck="true"
         monitoring="autodetect"
         dynamicConfig="true">

<cache name="myCustomCache"
           maxEntriesLocalHeap="1000"
           eternal="false"
           timeToIdleSeconds="3600"
           timeToLiveSeconds="0"
           overflowToDisk="false"
           memoryStoreEvictionPolicy="LRU"
/>
</ehcache>
/*
 * regular call in a @RestController annotated class
 */
@GetMapping(value = "/users/{myParam}", produces = "application/xml")
@Cacheable(value = "myCustomCache", key = "#myParam")
public String findActiveUser(@PathVariable("myParam") String myParam) {
        // call to service

        // returning desired String
        return "answerFromService";
}
@Configuration
@EnableCaching
public class CacheConfig {

}

New configurations:

<!-- in POM.xml -->
<dependency>
    <groupId>org.ehcache</groupId>
    <artifactId>ehcache</artifactId>
    <version>3.10.6</version>
</dependency>
<dependency>
    <groupId>javax.cache</groupId>
    <artifactId>cache-api</artifactId>
    <version>1.1.1</version>
</dependency>
## in application.properties:
spring.cache.type=jcache
import org.ehcache.config.CacheConfiguration;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.ExpiryPolicyBuilder;
import org.ehcache.config.builders.ResourcePoolsBuilder;
import org.ehcache.jsr107.Eh107Configuration;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.cache.CacheManager;
import javax.cache.Caching;
import javax.cache.spi.CachingProvider;
import java.time.Duration;

@Configuration
@EnableCaching
public class CacheConfig {

    @Bean
    public CacheManager createCacheWithinManager() {
        // creation of cache configuration
        CacheConfiguration<String, String> cacheConfiguration = CacheConfigurationBuilder
                .newCacheConfigurationBuilder(
                        String.class, String.class,
                        ResourcePoolsBuilder.heap(1000).build()
                )
                .withExpiry(ExpiryPolicyBuilder
                        .timeToIdleExpiration(Duration.ofSeconds(3600))
                ).build();

        // fetching cacheManager
        CachingProvider cachingProvider = Caching.getCachingProvider();
        CacheManager cacheManager = cachingProvider.getCacheManager();

        // parsing ehcache configuration to something SpringBoot will understand
        javax.cache.configuration.Configuration<String, String> configuration = Eh107Configuration.fromEhcacheCacheConfiguration(cacheConfiguration);

        // creating as many caches as you want
        cacheManager.createCache("myCustomCache", configuration);

        // add shutdown hook to close cacheManager
        Runtime.getRuntime().addShutdownHook(new Thread(cacheManager::close));

        // return Bean
        return cacheManager;
    }
}

The xml configuration is now obsolete and the Controller-method can remain unchanged! Take note: the cache is picked up by it's name.

Sources