I am running ServletContextListener to schedule various jobs on my application server (GlassFish 3.1). I use contextInitialized() to schedule recurring tasks and contextDestroyed() to call cleanup methods such as turning off c3p0:
public class JobScheduler implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) {
When I cancel TimerTask s, I added logic that waited for all running tasks to complete before continuing, to ensure that nothing was being cleaned up.
To my question: when I deploy my application, I see one or two of these warnings displayed on GlassFish output:
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)
From what I can tell, GlassFish complains about an InputStream that has never been explicitly closed, which ClassLoader opened for a Finalizer , called by one of my configuration maps, the Guava MapMaker that the task is accessing. Please note that the stack trace above does not apply to the exception, but the actual trace of the task being performed to create the thread.
I need help understanding why this InputStream remains open, although I am waiting for all tasks to complete and can I better handle cleaning it. This seems to be specifically related to Guava compute cards, which you can see in the stack trace.
Update: I still get the same warnings if I use ScheduledThreadPoolExecutor instead of TimerTask
Update 2: Tumbleweeded
source share