InputStream从TimerTask调用到Guava map保持打开状态; GlassFish抱怨取消部署

时间:2011-07-29 19:21:52

标签: java glassfish-3 guava timertask servlet-listeners

我正在实施ServletContextListener,以便在我的应用服务器上安排各种工作(GlassFish 3.1)。我正在使用contextInitialized()来安排重复性任务,并使用contextDestroyed()来调用清理方法,例如关闭c3p0:

public class JobScheduler implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        //schedule TimerTasks
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        //cancel TimerTasks
        //cleanup methods
    }
}

当我取消TimerTask时,我添加了在继续之前等待任何正在运行的任务完成的逻辑,以确保在清理资源时没有任何内容仍在执行。

回答我的问题:当我取消部署我的应用程序时,我看到GlassFish输出中显示了其中一个或两个警告:

WARNING: Input stream has been finalized or forced closed without being explicitly closed; stream instantiation reported in following stack trace
java.lang.Throwable
    at com.sun.enterprise.loader.ASURLClassLoader$SentinelInputStream.<init>(ASURLClassLoader.java:1230)
    at com.sun.enterprise.loader.ASURLClassLoader$InternalJarURLConnection.getInputStream(ASURLClassLoader.java:1338)
    at sun.misc.URLClassPath$Loader.getResource(URLClassPath.java:503)
    at sun.misc.URLClassPath.getResource(URLClassPath.java:169)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:194)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
    at com.google.common.base.FinalizableReferenceQueue$DecoupledLoader.loadFinalizer(FinalizableReferenceQueue.java:228)
    at com.google.common.base.FinalizableReferenceQueue.loadFinalizer(FinalizableReferenceQueue.java:155)
    at com.google.common.base.FinalizableReferenceQueue.<clinit>(FinalizableReferenceQueue.java:84)
    at com.google.common.collect.CustomConcurrentHashMap$QueueHolder.<clinit>(CustomConcurrentHashMap.java:651)
    at com.google.common.collect.CustomConcurrentHashMap$WeakValueReference.<init>(CustomConcurrentHashMap.java:1589)
    at com.google.common.collect.CustomConcurrentHashMap$Strength$3.referenceValue(CustomConcurrentHashMap.java:322)
    at com.google.common.collect.CustomConcurrentHashMap.newValueReference(CustomConcurrentHashMap.java:1731)
    at com.google.common.collect.CustomConcurrentHashMap$Segment.setValue(CustomConcurrentHashMap.java:2050)
    at com.google.common.collect.CustomConcurrentHashMap$Segment.put(CustomConcurrentHashMap.java:2430)
    at com.google.common.collect.CustomConcurrentHashMap.put(CustomConcurrentHashMap.java:3346)
    at MyProject.CacheEngine$MyCustomCache$1.apply(CacheEngine.java:244)
    at MyProject.CacheEngine$MyCustomCache$1.apply(CacheEngine.java:237)
    at com.google.common.collect.ComputingConcurrentHashMap$ComputingValueReference.compute(ComputingConcurrentHashMap.java:316)
    at com.google.common.collect.ComputingConcurrentHashMap$ComputingSegment.compute(ComputingConcurrentHashMap.java:140)
    at com.google.common.collect.ComputingConcurrentHashMap.apply(ComputingConcurrentHashMap.java:71)
    at com.google.common.collect.MapMaker$ComputingMapAdapter.get(MapMaker.java:848)

    //stacktrace of the Runnable called by TimerTask, leading up to a call to Guava ComputingMap

    at java.util.TimerThread.mainLoop(Timer.java:512)
    at java.util.TimerThread.run(Timer.java:462)

据我所知,GlassFish抱怨InputStream从未明确关闭过,ClassLoader为我的一个Guava Finalizer打开了MapMaker 1}} - 创建的计算地图,由任务访问。 请注意,上面的堆栈跟踪不是异常,而是从正在运行的任务到流的实例化的实际跟踪。

我需要帮助的是理解为什么这个InputStream保持开放,即使我等待所有任务完成,以及我是否可以更好地处理它的清理。它似乎与Guava的计算图特别相关,您可以在堆栈跟踪中看到它。

更新:如果我使用ScheduledThreadPoolExecutor代替TimerTask

,我仍会收到相同的警告

更新2: Tumbleweeded

1 个答案:

答案 0 :(得分:1)

可能需要使用更新版本的库,以下是来自guava java docs:

FinalizableReferenceQueue() Deprecated.
  

FinalizableReferenceQueue是一种用于清理引用的不健全机制,因为   (1)它的单线程可以很容易地重载,并且   (2)在某些环境中坚持运行后台线程是有问题的。该课程计划于2012年12月删除。