6

アプリ サーバー (GlassFish 3.1) でさまざまなジョブをスケジュールするために、ServletContextListenerを実装しています。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
    }
}

sをキャンセルするとTimerTask、実行中のタスクが終了するのを待ってから続行するロジックを追加し、リソースをクリーンアップするときに何も実行されていないことを確認しました。

私の質問に行きます: アプリケーションをアンデプロイすると、GlassFish の出力に次の警告の 1 つまたは 2 つが表示されます。

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 は、タスクによってアクセスされている、Guava で作成されたコンピューティング マップの 1 つによって呼び出されたforInputStreamによって開かれた、明示的に閉じられなかった について不平を言っています。上記のスタック トレースは例外のスタック トレースではなく、実行中のタスクからストリームのインスタンス化までの実際のトレースであることに注意してください。ClassLoaderFinalizerMapMaker

私が助けを必要としているInputStreamのは、すべてのタスクが完了するのを待っているにもかかわらず、これが開いたままになっている理由と、そのクリーンアップをより適切に処理できるかどうかを理解することです. これは、スタック トレースで確認できる Guava のコンピューティング マップに特に関連しているようです。

更新:ScheduledThreadPoolExecutor代わりに使用すると、同じ警告が表示されますTimerTask

更新 2:タンブルウィード

4

1 に答える 1

1

おそらく新しいバージョンのライブラリを使用する必要があります。以下は guava Java docs からのものです。

FinalizableReferenceQueue() Deprecated.

FinalizableReferenceQueue は、参照をクリーンアップするための不健全なメカニズムです。(1) シングル スレッドは簡単にオーバーロードされる可能性があり、(2) バックグラウンド スレッドの実行に固執することは、特定の環境では問題となるからです。このクラスは 2012 年 12 月に削除される予定です。

于 2012-02-01T15:03:16.767 に答える