2017-03-17 27 views
0

我試圖使用EHCache緩存我的應用程序使用的(遠程)映像文件。Ehcache key ...從StoreAccessException中恢復:NullPointerException:空值

我以下列方式初始化緩存:

poolsBuilder = ResourcePoolsBuilder.newResourcePoolsBuilder() 
     .heap(1024, MemoryUnit.MB) 
     .disk(50, MemoryUnit.GB); 

     configurationBuilder = CacheConfigurationBuilder 
     .newCacheConfigurationBuilder(ImageFileKey.class, BufferedImage.class, poolsBuilder) 
     .withValueSerializer(new BufferedImageSerializer()) 
     ; 

     cacheManager = (PersistentCacheManager) CacheManagerBuilder.newCacheManagerBuilder() 

     .with(new CacheManagerPersistenceConfiguration(TempDirectory)) 
     .withCache("BufferedImageCache", configurationBuilder) 
     .build(true); 

     cache = cacheManager 
     .getCache("BufferedImageCache", ImageFileKey.class, BufferedImage.class); 

ImageFileKey包含文件名和我使用額外的圖像過濾信息。

顯然緩存工作,但在下面的方法

public BufferedImage getImage(ImageFileKey imageFileKey) { 
     BufferedImage ans = cache.get(imageFileKey); 
     if(ans == null) { 
     try { 
      ans = loadImage(imageFileKey.getImageFile(), imageFileKey.getImageFilter()); 
      cache.put(imageFileKey, ans); 
     } catch (IOException e) { 
      throw new RuntimeException(e); 
     } 

     } 
     return ans; 
    } 

當我運行BufferedImage ans = cache.get(imageFileKey)並返回null,我看到控制檯錯誤打印:

org.ehcache.core.spi.store.StoreAccessException: java.lang.NullPointerException: null value 
    at org.ehcache.impl.internal.store.heap.OnHeapStore.resolveFault(OnHeapStore.java:810) ~[ehcache-3.3.0.jar:3.3.0 fa4b4a8afb003e55eb74a2da228cacbbd2038073] 
    at org.ehcache.impl.internal.store.heap.OnHeapStore.getOrComputeIfAbsent(OnHeapStore.java:733) ~[ehcache-3.3.0.jar:3.3.0 fa4b4a8afb003e55eb74a2da228cacbbd2038073] 
    at org.ehcache.impl.internal.store.tiering.TieredStore.get(TieredStore.java:99) ~[ehcache-3.3.0.jar:3.3.0 fa4b4a8afb003e55eb74a2da228cacbbd2038073] 
    at org.ehcache.core.Ehcache.get(Ehcache.java:169) ~[ehcache-3.3.0.jar:3.3.0 fa4b4a8afb003e55eb74a2da228cacbbd2038073] 
    at com.cireca.overlaywidget.ehcache.BufferedImageCache.getImage(BufferedImageCache.java:99) [main/:na] 
    at com.cireca.overlaywidget.ehcache.BufferedImageCache.getImage(BufferedImageCache.java:113) [main/:na] 
    at com.cireca.overlaywidget.piccolo2d.PCachedImage.paint(PCachedImage.java:225) [main/:na] 
... 
Caused by: java.lang.NullPointerException: null value 
    at org.ehcache.impl.internal.store.heap.holders.CopiedOnHeapValueHolder.<init>(CopiedOnHeapValueHolder.java:57) ~[ehcache-3.3.0.jar:3.3.0 fa4b4a8afb003e55eb74a2da228cacbbd2038073] 
    at org.ehcache.impl.internal.store.heap.OnHeapStore.cloneValueHolder(OnHeapStore.java:1514) ~[ehcache-3.3.0.jar:3.3.0 fa4b4a8afb003e55eb74a2da228cacbbd2038073] 
    at org.ehcache.impl.internal.store.heap.OnHeapStore.importValueFromLowerTier(OnHeapStore.java:1492) ~[ehcache-3.3.0.jar:3.3.0 fa4b4a8afb003e55eb74a2da228cacbbd2038073] 
    at org.ehcache.impl.internal.store.heap.OnHeapStore.resolveFault(OnHeapStore.java:763) ~[ehcache-3.3.0.jar:3.3.0 fa4b4a8afb003e55eb74a2da228cacbbd2038073] 

我在想,如果這由設計行爲,還是我忘了提供類似複印機的東西?

UPDATE

看起來這發生在代碼的一部分,負責從內部組件failers恢復緩存。不幸的是,我既不能推斷出哪些組件失敗,也不能禁用這些打印輸出。

例如,我不能用LoggingRobustResilienceStrategy代替RobustResilienceStrategy

更新2

的價值本身不是null,我已經檢查。空值出現在更深的地方。還請注意,當我從緩存中讀取時,會發生該消息。另外請注意,它不是一個例外,它是一個標準輸出。如果我將null作爲一個值,我會得到意外的異常。

更新3個

我後來inverstigations(未完成)表明,該問題可能是與層之間的複製有關。此外,它會導致一些密鑰永遠不可能寫入緩存(緩存似乎不會在放置後立即包含它們)。如果我禁用磁盤層,問題就會消失。

回答

1

基於Caused by: java.lang.NullPointerException: null value,看起來像你試圖放入緩存的值是null ...? 可以loadImage(imageFileKey.getImageFile(), imageFileKey.getImageFilter());返回null

這會修復嗎? if (ans != null) cache.put(imageFileKey, ans);

或者你真的需要緩存缺少的東西嗎?如果是這種情況,我認爲你必須使用專用魔術值(null除外)

+0

該值絕對不爲空。空值出現在更深的地方。 – Dims

+0

如果確實如此,看起來您可能發現了一個錯誤。您可能希望將一個可重複使用的小型測試案例放在一起,揭露該問題並將其分享到ehcache3 github bug跟蹤器中。 –