Programing

이름이 지정되지 않은 또 다른 CacheManager가 동일한 VM (ehCache 2.5)에 이미 있습니다.

lottogame 2020. 10. 24. 09:26
반응형

이름이 지정되지 않은 또 다른 CacheManager가 동일한 VM (ehCache 2.5)에 이미 있습니다.


이것은 내가 junit 테스트를 실행할 때 일어나는 일입니다.

Another CacheManager with same name 'cacheManager' already exists in the same VM. Please 
provide unique names for each CacheManager in the config or do one of following:
1. Use one of the CacheManager.create() static factory methods to reuse same
   CacheManager with same name or create one if necessary
2. Shutdown the earlier cacheManager before creating new one with same name.

The source of the existing CacheManager is: 
 DefaultConfigurationSource [ ehcache.xml or ehcache-failsafe.xml ]

예외의 이유는 무엇입니까? 동시에 실행되는 하나 이상의 cacheManager가있을 수 있습니까?

이것이 Sping 3.1.1을 사용하여 cachManager를 구성한 방법입니다. cacheManager의 범위를 "singleton"으로 명시 적으로 설정합니다.

<ehcache:annotation-driven />

<bean
    id="cacheManager"
    class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
    scope="singleton"
    />

ehcache.xml은 다음과 같습니다.

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
     updateCheck="false"
     maxBytesLocalHeap="100M" 
     name="cacheManager"
     >
 ....
 </ehcache>

마침내 내 수업

@Component
public class BookingCache implements CacheWrapper<String, BookingUIBean> {

     @Autowired
     private CacheManager ehCacheManager;
      ....
}

내 코드베이스에서 하나의 cacheManager 만 다루고 있다고 확신합니다. 다른 것이 아마도 n 번째 인스턴스를 실행하고있을 것입니다.


EhCacheManagerFactoryBean은 싱글 톤일 수 있지만 여러 CacheManager를 빌드하고 동일한 이름을 지정하려고합니다. 그것은 Ehcache 2.5 의미론을 위반 합니다.

버전 2.5 이전의 Ehcache 버전에서는 JVM에 동일한 이름 (동일한 구성 자원)을 가진 CacheManager가 얼마든지 존재할 수있었습니다.

Ehcache 2.5 이상에서는 동일한 JVM에 동일한 이름을 가진 여러 CacheManager가 존재하는 것을 허용하지 않습니다. 싱글 톤이 아닌 CacheManager를 생성하는 CacheManager () 생성자는이 규칙을 위반할 수 있습니다.

공유 특성을 true 로 설정하여 JVM에서 CacheManager의 공유 인스턴스를 작성하도록 팩토리 Bean에 지시하십시오 .

<bean id="cacheManager"
      class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
      p:shared="true"/>

JPA (2.0) + Hibernate (3.6.4) + Spring (3.2.4)을 사용하는 통합 테스트에서 동일한 문제가 발생했습니다. 이 문제는 다음 Hibernate 구성을 사용하여 해결되었습니다.

<property name="hibernate.cache.region.factory_class" value="net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory"/>

사용하는 대신

<property name="hibernate.cache.region.factory_class" value="net.sf.ehcache.hibernate.EhCacheRegionFactory"/>

문제는 Spring 테스트 프레임 워크에 빌드 된 컨텍스트 로딩 최적화입니다. Spring (기본값)은 테스트 클래스가 완료되면 컨텍스트를 파괴하지 않습니다. 다른 테스트 클래스가이를 재사용 할 수 있기를 바랍니다 (처음부터 생성하는 대신).

@DirtiesContext를 사용하여이 기본값을 재정의하거나 maven을 사용하는 경우 surefire forkMode를 "always"로 설정하고 테스트 클래스별로 새 VM을 만들 수 있습니다.


ehcache.xml 구성 (ehcache 요소에서)에 이름 "xxx"를 설정하려고 할 수도 있습니다.

내 앱의 모듈 중 하나에 또 다른 캐시 구성이 숨어 있다고 생각했기 때문에 그것은 나를 위해 트릭을했습니다.

공유 솔루션도 작동하지만 그에 대한 광범위한 의미를 모릅니다.


Hibernate 5로 업그레이드 한 후 다음을 사용해야했습니다.

<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory"/>

대신에:

<property name="hibernate.cache.region.factory_class" value="net.sf.ehcache.hibernate.SingletonEhCacheRegionFactory"/>

다른 패키지를 사용하지 마십시오.


더 나은 방법은 EhCacheManagerFactoryBean 의 "accept-existing"속성을 사용하는 입니다.


두 번째 수준 캐시가 아닌 비즈니스 서비스를 테스트하는 경우 스프링 구성 파일에서 두 번째 수준 구성을 제거 할 수 있으며 테스트가 성공적으로 실행됩니다. 두 번째 수준 구성이 있습니다.

 <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="persistenceUnitName" value="defaultPU" />
        <property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter" />
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">false</prop>
                <!-- <prop key="hibernate.hbm2ddl.auto">update</prop> -->
                <prop key="hibernate.cache.use_second_level_cache">false</prop>
                <prop key="hibernate.cache.use_query_cache">false</prop>
            </props>
        </property>
    </bean>

두 번째 수준 캐시 구성의 전체 구성으로 변경하면 실행 시간에 실제 웹 앱이 다음과 같이 사용됩니다.

    <bean id="entityManagerFactory"
            class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <property name="persistenceUnitName" value="defaultPU" />
            <property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter" />
            <property name="jpaProperties">
                <props>
                    <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                    <prop key="hibernate.show_sql">false</prop>
                    <!-- <prop key="hibernate.hbm2ddl.auto">update</prop> -->
                    <prop key="hibernate.cache.use_second_level_cache">true</prop>
                    <prop key="hibernate.cache.use_query_cache">true</prop>
                    <prop key="hibernate.cache.region.factory_class">net.sf.ehcache.hibernate.EhCacheRegionFactory</prop>               
                    <prop key="net.sf.ehcache.configurationResourceName">ehcache/ehcache-hibernate-local.xml</prop>
                </props>
            </property>
        </bean>

그런 다음 동일한 예외가 발생합니다. "이름이 지정되지 않은 다른 CacheManager가 이미 동일한 VM에 있습니다."


제 경우에는 빈으로 정의 된 커스텀 캐시 관리자가 있습니다. 또한 사용자 정의 응용 프로그램 컨텍스트이므로 스프링 junit 러너를 사용하지 않으므로 @DirtiesContext가 작동하지 않습니다.

트릭은 빈에서 캐시 인스턴스를 검색하고 해당 캐시에서 cacheManager (EHCache의 인스턴스)를 가져 오는 것입니다. 캐시 관리자에서 removeCache 메서드를 호출합니다.

이것을 @After 주석이 달린 메서드에 넣으면 각 테스트 후에 캐시가 VM에서 제거됩니다. 이렇게 :

@After
public void destroy() {
    MyCustomCacheManager customCacheManager = (MyCustomCacheManager) context.getBean("yourCustomCacheManagerBean");

    try {
        net.sf.ehcache.Cache cache = customCacheManager.getCache();
        net.sf.ehcache.CacheManager cacheManager = cache.getCacheManager();
        cacheManager.removeCache("nameOfYourCache");
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    }

    context.destroy();
    context = null;
}

resources.groovy에 다음을 추가하여 해결했습니다.

빈 = {... aclCacheManager (EhCacheManagerFactoryBean) {공유 = true} ...}


Spring Boot 2.0.2로 전환했을 때 저에게 일어났습니다 . 다음을 수행하여 문제를 해결했습니다.

application.yml에서 제거

spring.jpa.properties.hibernate.cache.region.factory_class: org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory

pom.xml에서 제거

<dependency>
    <groupId>net.sf.ehcache</groupId>
    <artifactId>ehcache</artifactId>
</dependency>

pom.xml에만 유지

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-ehcache</artifactId>
</dependency>

미래의 독자를 위해이 문제의 원인은 pom.xml 파일에서 hibernate-ehcache 라이브러리를 가져 왔기 때문입니다. libray.

독립 실행 형 앱 (예 : 명령 줄 유틸리티)으로 실행할 때 제대로 작동하는 것처럼 보였지만 바람둥이 서버에서 실행할 때 원래 게시물에 오류가 발생했습니다.

내 pom 파일 변경 :

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-ehcache</artifactId>
            <version>5.0.2.Final</version>
        </dependency>
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
            <version>2.7.4</version>
        </dependency>

에:

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-ehcache</artifactId>
            <version>5.0.2.Final</version>
        </dependency>
        <!-- ehcache dependency removed -->

문제를 해결했습니다. 누군가가 바람둥이 컨테이너에서 실행할 때만 문제가 나타나는 이유를 아는 사람이 있다면 알고 싶습니다 ..


나를 EhCacheManagerFactoryBean#shared위해 true하도록 설정합니다 .

를 설정 EhCacheManagerFactoryBean#acceptExisting하는 true나를 위해 작동하지 않았다.

import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;

@Configuration
public class EhCacheConfiguration {

    @Bean
    public EhCacheCacheManager ehCacheCacheManager() {

        return new EhCacheCacheManager(ehCacheManagerFactoryBean().getObject());
    }


    @Bean
    public EhCacheManagerFactoryBean ehCacheManagerFactoryBean() {

        EhCacheManagerFactoryBean cacheManagerFactoryBean = new EhCacheManagerFactoryBean();

        cacheManagerFactoryBean.setConfigLocation(new ClassPathResource("ehcache.xml"));
        cacheManagerFactoryBean.setShared(true);

        return cacheManagerFactoryBean;
    }
}

XML없이 Spring 4에서 EhCache 사용 에서 설명한대로


glassfish 3.0.1에서 IniShiroFilter가 두 번 초기화되는 문제를 추적했습니다.이 문제는 서버 시작 직후 동시 요청이 시작될 때 발생합니다. 다음은 두 개의 HTTP 요청에 해당하는 두 개의 서로 다른 스레드의 스택 추적입니다.

[#|2012-11-28T08:25:10.630-0800|SEVERE|glassfish3.0.1|javax.enterprise.system.std.com.sun.enterprise.v3.services.impl|_ThreadID=28;_ThreadName=Thread-1;|java.lang.Exception: Stack trace
        at java.lang.Thread.dumpStack(Thread.java:1249)
        at org.apache.shiro.web.servlet.IniShiroFilter.<init>(IniShiroFilter.java:124)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
        at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.createManagedObject(InjectionManagerImpl.java:303)
        at com.sun.enterprise.web.WebContainer.createFilterInstance(WebContainer.java:725)
        at com.sun.enterprise.web.WebModule.createFilterInstance(WebModule.java:1948)
        at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:248)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215)
        at com.sentilla.filter.DumpFilter.doFilter(DumpFilter.java:152)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:277)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)
        at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
        at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)
        at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:322)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:226)
        at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:239)
        at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791)
        at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693)
        at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954)
        at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)
        at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135)
        at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102)
        at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)
        at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
        at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
        at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
        at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
        at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)
        at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309)
        at java.lang.Thread.run(Thread.java:662)

다른 스레드

[#|2012-11-28T08:25:15.299-0800|SEVERE|glassfish3.0.1|javax.enterprise.system.std.com.sun.enterprise.v3.services.impl|_ThreadID=29;_ThreadName=Thread-1;|java.lang.Exception: Stack trace
        at java.lang.Thread.dumpStack(Thread.java:1249)
        at org.apache.shiro.web.servlet.IniShiroFilter.<init>(IniShiroFilter.java:124)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
        at com.sun.enterprise.container.common.impl.util.InjectionManagerImpl.createManagedObject(InjectionManagerImpl.java:303)
        at com.sun.enterprise.web.WebContainer.createFilterInstance(WebContainer.java:725)
        at com.sun.enterprise.web.WebModule.createFilterInstance(WebModule.java:1948)
        at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:248)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215)
        at com.sentilla.filter.DumpFilter.doFilter(DumpFilter.java:152)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:215)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:277)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)
        at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
        at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)
        at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)
        at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:322)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:226)
        at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:239)
        at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791)
        at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693)
        at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954)
        at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)
        at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135)
        at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102)
        at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)
        at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
        at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
        at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
        at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
        at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)
        at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309)
        at java.lang.Thread.run(Thread.java:662)

스택 추적을 보면 ApplicationFilterConfig.java:248이 범인이 될 수 있습니다. 또는 glassfish가 잘못된 컨텍스트에서 필터를 초기화하고 있습니다. 비교를 위해 Tomcat은 BootStrap 중에 필터를 초기화합니다.


제 경우에는 문제가 구성 요소 스캔 및 Java 구성입니다.

root-context.xml
<context:component-scan base-package="org.beansugar">

servlet-context.xml
<context:component-scan base-package="org.beansugar">

spring component-scan은 xml 파일에서 두 번 작동합니다. 런타임마다 SpringConfig.java 내부에 빈을 생성합니다. 그런 다음 중복 캐시 관리자가 작성되었습니다.

그래서 아래와 같이 변경했습니다.

root-context.xml
<context:component-scan base-package="org.beansugar">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

servlet-context.xml
<context:component-scan base-package="org.beansugar" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>

이 오류는 잘못된 매핑 파일에서도 발생합니다. 메시지는 끔찍하고 원인을 말하지 않습니다.


제 경우 구성은 다음과 같습니다.

<spring.boot.version>1.5.8.RELEASE</spring.boot.version>
<spring.boot.yarn.version>2.4.0.RELEASE</spring.boot.yarn.version>
<spring.version>4.3.7.RELEASE</spring.version>

<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-core</artifactId>
  <version>3.5.1-Final</version>
</dependency>
<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-ehcache</artifactId>
  <version>3.5.1-Final</version>
</dependency>

Changing the EHCache provider class did the job for me. I was using cache provider class as org.hibernate.cache.EhCacheProvider instead i changed this to: net.sf.ehcache.hibernate.SingletonEhCacheProvider


As of Spring Boot 2.1.2 the following configuration worked to resolve the issue. (Note, these are snippets of the overall config.)

Dependencies:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-core</artifactId>
  <version>5.2.8.Final</version>
</dependency>
<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-ehcache</artifactId>
  <version>5.2.8.Final</version>
</dependency>

application.yml config:

spring:
  jpa:
    open-in-view: false
    hibernate:
      ddl-auto: none
    show-sql: true
    properties:
      dialect: org.hibernate.dialect.MySQLDialect
      net:
        sf:
          ehcache:
            configurationResourceName: ehcache.xml
      hibernate:
        cache:
          use_second_level_cache: true
          region:
            factory_class: org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory

ehcache.xml configuration:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
  <!-- Required elements -->
  <diskStore path="java.io.tmpdir"/>
  <defaultCache
    maxElementsInMemory="10000"
    eternal="false"
    timeToIdleSeconds="120"
    timeToLiveSeconds="120"
    overflowToDisk="true"/>

  <!-- Cache settings per class -->
  <cache name="com.mystuff.component.services.example.Book"
    maxElementsInMemory="1000"
    eternal="false"
    timeToIdleSeconds="300"
    timeToLiveSeconds="600"
    overflowToDisk="true"/>
</ehcache>

The application I am working on slows down drastically without a working cache. So, to validate I simply ran the application and hit one of the read intense endpoints.

참고URL : https://stackoverflow.com/questions/10013288/another-unnamed-cachemanager-already-exists-in-the-same-vm-ehcache-2-5

반응형