尝试删除所有缓存时,Ehcache异常

时间:2019-09-10 05:43:23

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

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

用作Cache的类是:

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调用时可以轻松删除:

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.

1 个答案:

答案 0 :(得分:1)

在调用clearAllCache方法之前,您创建了new CacheHelper()。因此,永远不会初始化此实例的cacheManager属性(只能在putInCacheFromDb方法中对其进行初始化)。
我猜想当您通过API调用它时,您有一个bean /单个实例被调用以填充缓存,然后再也不会销毁。因此必须使用此实例。

EDIT :回答为什么在构造函数中初始化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();