1

내가 플레이 프레임 워크 기본 캐시 (EHCache는)와 함께 문제를 직면 존재한다. 오류가있는 핫 다시로드에 충돌 플레이 : EHCache는 인스턴스 이름을 '놀이'로 이미 비동기 <strong>couchdatabase</strong> 자바 드라이버로 작업 할 때

Error in custom provider, play.api.cache.EhCacheExistsException: An EhCache instance with name 'play' already exists. 

나는이 https://groups.google.com/forum/#!topic/pac4j-dev/2_EUOCrov7M처럼 couchdatabase 드라이버뿐만 아니라 다른 시나리오에서뿐만 아니라 수 발견했다.

답변

1

나는 stop-hook에서 솔루션 강제 종료를 알아 낸다. 그것은 같은 프로젝트에 존재하는 모듈 중 하나를 사용하여이를 수행 할 수 있습니다 :

특별 "수정"모듈뿐만 아니라 생성 될 수
lifecycle.addStopHook(() -> { 
    ... 
    CacheManager.getInstance().shutdown(); 
    ... 
}); 

:

package fixes; 

import java.util.concurrent.CompletableFuture; 

import javax.inject.Inject; 
import javax.inject.Singleton; 

import com.google.inject.AbstractModule; 

import net.sf.ehcache.CacheManager; 
import play.Logger; 
import play.Logger.ALogger; 
import play.inject.ApplicationLifecycle; 

/** 
* Fix for the hot reloading cache issue. 
* "Error in custom provider, play.api.cache.EhCacheExistsException: An EhCache instance with name 'play' already exists." 
* 
*/ 
public class CacheFix extends AbstractModule{ 
    @Override 
    protected void configure() { 
     bind(CacheFixInstance.class).asEagerSingleton();   
    } 
} 


/** 
* Only stop hook 
*/ 
@Singleton 
class CacheFixInstance {  
    private static ALogger logger = Logger.of(CacheFixInstance.class); 

    @Inject 
    public CacheFixInstance(ApplicationLifecycle lifecycle) { 
     lifecycle.addStopHook(() -> { 

      // Force cache to stop. 
      CacheManager.getInstance().shutdown(); 
      logger.debug("Cache has been shutdown"); 

      // Nothing to return. 
      return CompletableFuture.completedFuture(null); 
     }); 
    } 
} 

application.conf에서 :

enabled += fixes.CacheFix 
1

경우에 빠른 copypaste 수정 좀 봐 안드리 Kuba 대답에서 번역 된 스칼라 버전입니다

package utils 

import javax.inject.{Inject, Singleton} 

import com.google.inject.AbstractModule 
import net.sf.ehcache.CacheManager 
import play.api.Logger 
import play.api.inject.ApplicationLifecycle 

import scala.concurrent.{ExecutionContext, Future} 

/** 
    * Fix for the hot reloading cache issue. 
    * "Error in custom provider, play.api.cache.EhCacheExistsException: An EhCache instance with name 'play' already exists." 
    * 
    */ 
class CacheHotReloadFix extends AbstractModule { 
    override protected def configure(): Unit = { 
    bind(classOf[CacheHotReloadFixInstance]).asEagerSingleton() 
    } 
} 

@Singleton 
class CacheHotReloadFixInstance @Inject() (lifecycle: ApplicationLifecycle, implicit val executionContext: ExecutionContext) { 

    private val logger = Logger(this.getClass) 

    lifecycle.addStopHook {() => 
    logger.debug("Forching ehcach to stop before play reloads") 
    // Force cache to stop. 
    Future(CacheManager.getInstance().shutdown()) 
    } 
} 
+0

나는 이것을 연 2.6.3과 함께 시도했다. 오류를 수정하지 않았습니다. – nemoo

+0

@nemoo 테스트 케이스에 문제가있는 경우 아래 내 대답을 참조하십시오. –

0

(Applicaiton의 여러가있을 것입니다) 테스트 케이스를 실행하는 동안 문제가있는 경우, 당신은 SyncCacheApiAsyncCacheApi의 더미 구현을 가질 수 있고, ApplicationprovideApplication()를 통해

@Override 
    protected Application provideApplication() { 
Application application = new GuiceApplicationBuilder().configure(testConfig) 
         .disable(EhCacheModule.class) 
    .overrides(bind(SyncCacheApi.class).to(FakeSyncCacheApi.class)) 
         .bindings(new MyModule()) 
         .in(new File(".")).build(); 
    return application; 
} 
을 만드는 동안 바인딩을 오버라이드 (override)

@Singleton 
public class FakeSyncCacheApi implements SyncCacheApi { 

    private LRUMap cache = new LRUMap(); 

    @Override 
    public <T> T get(String key) { 
     return (T) cache.get(key); 
    } 

    @Override 
    public <T> T getOrElseUpdate(String key, Callable<T> block, int expiration) { 
     return getOrElseUpdate(key, block); 
    } 

    @Override 
    public <T> T getOrElseUpdate(String key, Callable<T> block) { 
     T value = (T) cache.get(key); 
     if (value == null) { 
      try { 
       value = block.call(); 
      } catch (Exception e) { 

      } 
      cache.put(key, value); 
     } 
     return value; 
    } 

    @Override 
    public void set(String key, Object value, int expiration) { 
     cache.put(key, value); 
    } 

    @Override 
    public void set(String key, Object value) { 
     cache.put(key, value); 
    } 

    @Override 
    public void remove(String key) { 
     cache.remove(key); 
    } 
} 
여기에 생각이

같은

샘플이 FakeSyncCacheApi 수있는 작품은 EhCache 모듈을 비활성화하고있다합니다 우리 자신의 더미 구현.