simple-spring-memcached icon indicating copy to clipboard operation
simple-spring-memcached copied to clipboard

The cache with name or alias 'default' is no defined | Spring Boot 2.7.0

Open 90K2 opened this issue 1 year ago • 4 comments

I have default and working setup

	implementation("com.google.code.simple-spring-memcached:spring-cache:4.1.3")
	implementation("com.google.code.simple-spring-memcached:xmemcached-provider:4.1.3")

with config :

@Configuration
@EnableCaching
class LocalSSMConfiguration : AbstractSSMConfiguration() {

    @Value("\${app.settings.cache.memcache-endpoint}")
    private val memCacheConnection: String = ""

    @Bean
    override fun defaultMemcachedClient(): CacheFactory? {
        val conf = CacheConfiguration()
        conf.isConsistentHashing = true
        val cf = CacheFactory()
        cf.cacheClientFactory = MemcacheClientFactoryImpl()
        cf.addressProvider = DefaultAddressProvider(memCacheConnection)
        cf.configuration = conf

        return cf
    }
}

but when bump Spring version 2.3.4 to 2.7.0 default cache bean stop creating on startup. Previously startup logs print success info

:: Spring Boot :: (v2.3.4.RELEASE)

2022-10-13 18:01:22.268 INFO 2660 --- [ task-1] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] 2022-10-13 18:01:22.316 INFO 2660 --- [ task-1] org.hibernate.Version : HHH000412: Hibernate ORM core version 5.4.21.Final 2022-10-13 18:01:22.471 INFO 2660 --- [ task-1] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.1.0.Final} 2022-10-13 18:01:22.607 INFO 2660 --- [ task-1] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.PostgreSQLDialect 2022-10-13 18:01:23.259 INFO 2660 --- [ task-1] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform] 2022-10-13 18:01:23.266 INFO 2660 --- [ task-1] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' 2022-10-13 18:01:23.360 INFO 2660 --- [ main] c.g.c.ssm.config.DefaultAddressProvider : Defined values 127.0.0.1:11211 will be used as memcached addresses 2022-10-13 18:01:23.378 INFO 2660 --- [ main] net.rubyeye.xmemcached.XMemcachedClient : XMemcachedClient is using Text protocol 2022-10-13 18:01:23.397 INFO 2660 --- [ main] c.g.c.yanf4j.nio.impl.SelectorManager : Creating 8 reactors... 2022-10-13 18:01:23.412 INFO 2660 --- [ main] c.g.c.y.core.impl.AbstractController : The Controller started at localhost/127.0.0.1:0 ... 2022-10-13 18:01:23.425 INFO 2660 --- [ached-Reactor-0] c.g.c.y.core.impl.AbstractController : Add a session: 127.0.0.1:11211 2022-10-13 18:01:24.258 INFO 2660 --- [ main] .s.s.UserDetailsServiceAutoConfiguration :

and everything working fine while 2.7.0 does not create memcached connection during startup and CacheBase.afterPropertiesSet() collect zero cashe beans

90K2 avatar Oct 13 '22 15:10 90K2

@ragnor Hello

So it seems that CacheBase.afterPropertiesSet is calling earler than Cache class appears in context. I like annotation approach and this library, so I have to make this dirty hack for Spring Boot 2.7.0

    @PostConstruct
    fun initCache() {
        val beanRegistry = context.autowireCapableBeanFactory as DefaultListableBeanFactory
        beanRegistry.removeBeanDefinition("cacheBase")
        context.getBeansOfType(Cache::class.java).values
        beanRegistry.registerBeanDefinition("cacheBase", RootBeanDefinition(CacheBase::class.java))
    }

note: this method must be placed in config class differ than local implementation of AbstractSSMConfiguration

90K2 avatar Oct 14 '22 11:10 90K2

Hi @90K2 Thank you for your report. Do you have by any chance a sample simple project that reproduce the issue? In spring-cache-integration-test module I have a few tests, all pass on spring 5.3.23 (the newest one) but xml configuration is used.

ragnor avatar Oct 14 '22 16:10 ragnor

@ragnor thanks a lot for answer. In attached file I've placed small runnable app (kotlin).

build.gradle.kts: 

plugins {
    id("org.springframework.boot") version "2.3.4.RELEASE"
//    id("org.springframework.boot") version "2.7.0"
	id("io.spring.dependency-management") version "1.0.11.RELEASE"
	kotlin("jvm") version "1.3.72"
//	kotlin("jvm") version "1.7.0-RC2"
	kotlin("plugin.spring") version "1.3.72"
//	kotlin("plugin.spring") version "1.7.0-RC2"
}

So if we use uncommented set of versions, everything is well: beans creating on startup and XMemcachedClient open connect. But if you change this set to commented-out , (springboot + jvm + spring) beans will not be prepared in right way.

sample

90K2 avatar Oct 14 '22 17:10 90K2

Thank you very much @90K2 for the sample. I've reproduced the issue. Looks like to main problem is some kind of circular dependencies in SSM:

  • CacheBase looks for Cache beans
  • Cache beans are created by CacheFactory that has CacheBase field autowired

I have to break it by removing CacheBase from CacheFactory and replacing by Settings. It is final solution that will go with next version. In the mean time you can use workaround, set spring.main.allow-circular-references: true

ragnor avatar Oct 14 '22 21:10 ragnor