首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >名为“play”的EhCache实例已经存在

名为“play”的EhCache实例已经存在
EN

Stack Overflow用户
提问于 2017-04-05 23:34:50
回答 6查看 3.1K关注 0票数 2

我在使用异步 couchdatabase java驱动程序时,遇到了Play framework默认缓存(EHCache)的问题。在热重新加载时播放崩溃,错误如下:

代码语言:javascript
运行
复制
Error in custom provider, play.api.cache.EhCacheExistsException: An EhCache instance with name 'play' already exists.

我发现这可能不仅适用于couchdatabase驱动程序,而且也适用于其他一些场景,比如EUOCrov7M

EN

回答 6

Stack Overflow用户

发布于 2017-04-05 23:34:50

我想出了一个解决方案-强制停止钩上的高速缓存关闭。它可以在项目中的一个现有模块中完成,例如:

代码语言:javascript
运行
复制
lifecycle.addStopHook(() -> {
  ...
  CacheManager.getInstance().shutdown();
  ...
});

还可以创建特殊的“修复”模块:

代码语言:javascript
运行
复制
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中:

代码语言:javascript
运行
复制
enabled += fixes.CacheFix
票数 4
EN

Stack Overflow用户

发布于 2017-07-27 14:49:51

如果有些人看了一下快速的复制修复,这里是我从Andriy的答案翻译出来的scala版本。

代码语言:javascript
运行
复制
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())
  }
}
票数 1
EN

Stack Overflow用户

发布于 2018-01-05 20:08:44

如果在运行测试用例时遇到问题(其中将有多个Applicaiton),则可以使用SyncCacheApiAsyncCacheApi的虚拟实现,并在通过provideApplication()创建Application时覆盖绑定。

代码语言:javascript
运行
复制
    @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;
}

而样本FakeSyncCacheApi应该类似于

代码语言:javascript
运行
复制
@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);
    }
}

这里的想法是禁用EhCache模块并拥有我们自己的虚拟实现。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43243293

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档