【问题标题】:Exception in Ehcache when trying to remove all the caches尝试删除所有缓存时出现 Ehcache 异常
【发布时间】:2019-09-10 05:43:23
【问题描述】:

我已经搜索了解决方案,因为其他问题也发布了java.lang.NullPointerExcpetion。但我无法找到我的问题。我正在使用 Ehcache 3,并且我已经实例化了一个缓存,它将数据放入缓存中。

作为缓存工作的类是:

import org.ehcache.Cache;
import org.ehcache.CacheManager;
import org.ehcache.PersistentCacheManager;
import org.ehcache.config.ResourceType;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.CacheManagerBuilder;
import org.ehcache.config.builders.ResourcePoolsBuilder;
import org.ehcache.config.units.EntryUnit;
import org.ehcache.config.units.MemoryUnit;
import org.ehcache.expiry.Duration;
import org.ehcache.expiry.Expirations;

import javax.ejb.Stateless;
import javax.enterprise.inject.spi.CDI;
import java.io.File;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;


public class CacheHelper {

    private CacheManager cacheManager;

    private Cache<String,GenericClassForMap> mapPerson;


    private static Timer timer;

    public CacheHelper() {
        timer = new Timer();
        TimerTask task = new Helper();

        timer.schedule(task, 2, 5000);

    }

    //initialziing cache
    public void putInCacheFromDb() {
        System.getProperties().setProperty("java -Dnet.sf.ehcache.use.classic.lru", "true");
        cacheManager= CacheManagerBuilder
                .newCacheManagerBuilder().build();
        cacheManager.init();

        //for map
        mapPerson = cacheManager
                .createCache("cacheOfmap", CacheConfigurationBuilder
                        .newCacheConfigurationBuilder(
                                String.class,GenericClassForMap.class,
                                ResourcePoolsBuilder.heap(100000)).withExpiry(Expirations.timeToLiveExpiration(Duration.of(60000,
                                TimeUnit.SECONDS))));
        Map<Integer,Person> mp=new HashMap<>();
        mp.put(1,new Person(1,"om"));

        mapPerson.put(CACHE_MAP_PARAMETER,new GenericClassForMap(mp));

    }

    //method to clear the cache
    public void clearAllCache(){
        System.out.println("cache is being cleared........");
          cacheManager.close();
      }

}

当我运行程序时,数据被插入到缓存中并打印为:

 coming from map
[Person{id=1, name='om'}]

我正在为缓存设置计时器,并且需要在 15 秒内刷新缓存。所以,我尝试使用 Helper.java 类作为,

import com.cache.cachemanager.CacheHelper;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;


public class Helper extends TimerTask
{
    public static int i = 0;

    public void run()
    {
        System.out.println("Timer ran " + ++i);

        if(i==15){
            try {

                Thread.sleep(10000);
                System.out.println("system is sleeping");
                CacheHelper cacheHelper=new CacheHelper();
                cacheHelper.clearAllCache();
               cacheHelper.putInCacheFromDb();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }


        }
    }
}

我在以下位置收到空指针异常:

system is sleeping
 cache is being cleared........
Exception in thread "Timer-6" java.lang.NullPointerException
   at com.cache.cachemanager.CacheHelper.clearAllCache(CacheHelper.java:309)
  at com.cache.timer.Helper.run(Helper.java:25)

我尝试调试程序,发现空指针异常来自:

 cacheManager.close();

我的 cacheManager 为空。但是当我尝试从 API 请求中清除缓存时,它能够清除缓存。我没有使用 spring 框架。为什么我的cacheManager 为空但很容易被删除通过 API 调用时 Like:

http://localhost:8080/myresource/clearCache,我的缓存被清空了。

cache is being cleared........
11:19:31,154 INFO  [org.ehcache.core.EhcacheManager] (default task-8) Cache 'cacheOfmap' removed from EhcacheManager.

【问题讨论】:

    标签: java jakarta-ee nullpointerexception ehcache ehcache-3


    【解决方案1】:

    在调用clearAllCache 方法之前,您创建了一个new CacheHelper()。因此,此实例的 cacheManager 属性永远不会被初始化(您只能在 putInCacheFromDb 方法中初始化它)。
    我想当你通过 API 调用它时,你有一个 bean/singleton 实例被调用来填充你的缓存,然后永远不会被破坏。所以必须使用这个实例。

    编辑:回答为什么要在构造函数中初始化cacheManager
    您当前的代码运行如下:

        // CacheHelper constructor is called to initialize a new CacheHelper
        // => cacheManager attribute is not initialized
        CacheHelper cacheHelper = new CacheHelper();
        // This method will call cacheManager.close().
        // => cacheManager is currently null => NullPointerException
        cacheHelper.clearAllCache();
        // This method will initialize the cacheManager attribute
        // => Too late the Exception already occured
        // => So, need to initialize cacheManager attribute before calling clearAllCache()
        // => the constructor is the best place to do this here.
        cacheHelper.putInCacheFromDb();
    

    【讨论】:

    • 我什至尝试使用注入方法,它向我显示了空指针.. 我也尝试了@Inject private CacheHelper cacheHelper;
    • CacheHelper的构造函数中初始化cacheManager而不是putInCacheFromDb。延迟这个初始化是没有用的
    • 你只是节省了我的一天。但是你能告诉我为什么我需要放入构造函数中
    • 空指针异常已经消失,但缓存没有被清除,因为只有“缓存正在清除........”消息被打印
    • 从 EhcacheManager 中删除了类似 Cache 'cacheOfmap' 的消息。不露脸
    猜你喜欢
    • 2021-03-03
    • 2017-01-11
    • 2019-04-14
    • 1970-01-01
    • 2019-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多