InputStream оставлен открытым после вызова TimerTask карты Guava; GlassFish жалуется на undeploy

Я использую 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 s, я добавил логику, которая ожидает завершения всех запущенных задач, прежде чем продолжить, чтобы убедиться, что ничего не выполняется, когда я очищаю ресурсы.

Переходя к моему вопросу: когда я отменяю развертывание приложения, я видя одно или два из этих предупреждений, отображаемых в выводе 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.(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.(FinalizableReferenceQueue.java:84)
    at com.google.common.collect.CustomConcurrentHashMap$QueueHolder.(CustomConcurrentHashMap.java:651)
    at com.google.common.collect.CustomConcurrentHashMap$WeakValueReference.(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 для Finalizer , вызываемого одной из моих компьютерных карт, созданных Guava MapMaker , к которым обращается задача. Обратите внимание, что приведенная выше трассировка стека - это не исключение, а фактическая трассировка от запущенной задачи до создания экземпляра потока.

Мне нужна помощь, так это понять, почему этот InputStream используется оставлен открытым, даже если я жду завершения всех задач, и могу ли я лучше справиться с его очисткой. Кажется, это конкретно связано с вычислительными картами Guava, которые вы можете увидеть в трассировке стека.

Обновление: Я все равно получаю те же предупреждения, если использую ScheduledThreadPoolExecutor вместо TimerTask

Обновление 2: Tumbleweeded

6
задан Paul Bellora 31 January 2012 в 15:13
поделиться