Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Ehcache磁盘存储未清理关闭_Java_Ehcache - Fatal编程技术网

Java Ehcache磁盘存储未清理关闭

Java Ehcache磁盘存储未清理关闭,java,ehcache,Java,Ehcache,我正在使用具有磁盘存储持久性的缓存。在随后重新运行应用程序时,我收到以下错误: net.sf.ehcache.store.DiskStore deleteIndexIfCorrupt WARNING: The index for data file MyCache.data is out of date, probably due to an unclean shutdown. Deleting index file MYCache.index 除了在应用程序中的某个地方显式调用net.sf.

我正在使用具有磁盘存储持久性的缓存。在随后重新运行应用程序时,我收到以下错误:

net.sf.ehcache.store.DiskStore deleteIndexIfCorrupt
WARNING: The index for data file MyCache.data is out of date,
probably due to an unclean shutdown. Deleting index file MYCache.index
除了在应用程序中的某个地方显式调用
net.sf.ehcache.CacheManager.shutdown()
之外,还有其他方法可以解决这个问题吗

缓存配置:

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="ehcache.xsd"
             updateCheck="true" monitoring="autodetect">

    <diskStore path="C:\work"/>

    <cacheManagerEventListenerFactory class="" properties=""/>

    <cacheManagerPeerProviderFactory
            class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
            properties="peerDiscovery=automatic,
                        multicastGroupAddress=230.0.0.1,
                        multicastGroupPort=4446, timeToLive=1"
            propertySeparator=","
            />

    <cacheManagerPeerListenerFactory
            class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"/>

    <defaultCache
            maxElementsInMemory="1"
            eternal="false"
            timeToIdleSeconds="0"
            timeToLiveSeconds="86400"
            overflowToDisk="true"
            diskSpoolBufferSizeMB="1"
            maxElementsOnDisk="10000"
            diskPersistent="true"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LFU"
            />

</ehcache>

复制问题的代码:

import java.util.ArrayList;
import java.util.List;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;

public class CacheTest {
    static CacheManager manager = new CacheManager(CacheTest.class
            .getResource("ehcache.xml"));
    static Cache cache;

    public static void main(String[] args) {

        // Get a default instance
        manager.addCache("test");
        cache = manager.getCache("test");

        // Generate some junk so that the
        // cache properly flushes to disk
        // as cache.flush() is not working
        List<String> t = new ArrayList<String>();
        for (int i = 0; i < 1000; i++)
            t.add(null);
        // Oddly enough fewer elements
        // do not persist to disk or give
        // an error
        for (int i = 0; i < 100000; i++) {
            cache.put(new Element(i, t));
        }
        cache.flush();

        if (cache.get("key1") == null) {
            System.out.println("key1 not found in cache!");
            cache.put(new Element("key1", "value1"));
        }

        System.out.println(cache.get("key1"));
    }
}
import java.util.ArrayList;
导入java.util.List;
导入net.sf.ehcache.Cache;
导入net.sf.ehcache.CacheManager;
导入net.sf.ehcache.Element;
公共类缓存测试{
静态缓存管理器=新缓存管理器(CacheTest.class
.getResource(“ehcache.xml”);
静态缓存;
公共静态void main(字符串[]args){
//获取默认实例
addCache(“测试”);
cache=manager.getCache(“测试”);
//生成一些垃圾,以便
//缓存正确地刷新到磁盘
//as cache.flush()不工作
List t=new ArrayList();
对于(int i=0;i<1000;i++)
t、 添加(空);
//奇怪的是,元素更少了
//不要持久保存到磁盘或放弃
//错误
对于(int i=0;i<100000;i++){
put(新元素(i,t));
}
cache.flush();
if(cache.get(“key1”)==null){
System.out.println(“在缓存中找不到键1!”);
cache.put(新元素(“key1”、“value1”);
}
System.out.println(cache.get(“key1”);
}
}

您如何停止应用程序

通过查看Ehcache代码,它注册了一个JVM关闭钩子
Runtime.getRuntime().addShutdownHook
,该钩子在JVM退出时关闭缓存。如果JVM被终止或崩溃,则不会调用关闭挂钩

更新您的评论:

以下是DiskStore方法的注释:

关闭磁盘存储以准备缓存关闭

如果发生VM崩溃,关闭挂钩将不会运行。数据文件和索引文件将不同步。初始化时,我们总是在读取元素后删除索引文件,使其长度为零。在脏重启时,它仍将有,数据文件将自动删除,从而保护安全


因此,如果您在不同的单元测试中重新创建缓存。由于shutdownHook不会运行,因此索引文件将为0。Ehcache认为索引已损坏。我会在每个单元测试中使用JUnit的@After注释关闭缓存。或者,在所有测试中共享缓存,但我猜这不会为您提供独立的测试。

尝试设置系统属性: net.sf.ehcache.enableShutdownHook=true

因此,您可以在程序的开头添加以下行:
System.setProperty(“net.sf.ehcache.enableShutdownHook”,“true”)

或者,从命令行传递属性:
java-Dnet.sf.ehcache.enableShutdownHook=true…

注意,ehcache网站在使用此关闭挂钩时确实提到了一些注意事项:

关闭挂钩何时运行,何时不运行

关闭挂钩在以下情况下运行:

  • 程序正常存在。e、 调用g.System.exit(),或者最后一个非守护进程线程退出
  • 虚拟机已终止。e、 g.CTRL-C。这对应于kill-SIGTERM pid或kill -15 Unix系统上的pid
在以下情况下,关机挂钩将不会运行:

  • 虚拟机中止
  • SIGKILL信号被发送到Unix系统上的虚拟机进程。e、 g.kill-SIGKILL pid或kill-9 pid
  • 在Windows系统上向进程发送TerminateProcess调用

希望它能工作:)

对于我们这些在Spring 3.1+和java config中使用Ehcache的人,您必须使用:

@Bean(destroyMethod = "shutdown")
public net.sf.ehcache.CacheManager ehCacheManager() { .. }
并且(假设您也在使用非web Spring应用程序上下文,请在那里启用关闭钩子以使bean正常销毁:

context = new AnnotationConfigApplicationContext(AppConfig.class);
((AbstractApplicationContext) context).registerShutdownHook();

有关更多信息,请参阅。

我正在将其作为Junit4测试的一部分运行。该错误将在随后的测试重新运行时显示。如果有帮助,我可以提供一个代码示例进行复制。不,即使在可运行的jar中从命令行运行,仍然会出现相同的错误。我猜一些示例代码可能会很好。您也可以尝试只运行一个test,并检查索引文件的大小。根据ehcache代码中的注释,它应该不是0。添加了一些代码以复制该问题。正确创建了.data文件,但.index保持为0。