changeset 325:847e4e6d0e06

PR852: Classloader not being flushed after last applet from a site is closed
author Deepak Bhole <dbhole@redhat.com>
date Fri, 27 Jan 2012 16:20:22 -0500
parents 21183f821dd4
children 54cbfb3a5469
files ChangeLog NEWS netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java plugin/icedteanp/java/sun/applet/PluginAppletViewer.java
diffstat 4 files changed, 63 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Tue Jan 24 15:33:51 2012 -0500
+++ b/ChangeLog	Fri Jan 27 16:20:22 2012 -0500
@@ -1,3 +1,15 @@
+2012-01-27  Deepak Bhole <dbhole@redhat.com>
+
+	PR852: Classloader not being flushed after last applet from a site is closed
+	* netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java: Added variable
+	to count usage for a given ClassLoader instance.
+	(getInstance): Decrement use count for a loader after it is merged with
+	another. Increment loader use count before returning.
+	(incrementLoaderUseCount): New method. Increments loader use count.
+	(decrementLoaderUseCount): New method. Decrements loader use count.
+	* java/sun/applet/PluginAppletViewer.java (appletClose): Decrement loader
+	use count when applet is closed.
+
 2012-01-06  Danesh Dadachanji  <ddadacha@redhat.com>
 
 	Use the JNLP file's information section for the Name and
--- a/NEWS	Tue Jan 24 15:33:51 2012 -0500
+++ b/NEWS	Fri Jan 27 16:20:22 2012 -0500
@@ -22,6 +22,7 @@
   - PR749: sun.applet.PluginStreamHandler#handleMessage(String) really slow
   - PR782: Support building against npapi-sdk as well
   - PR838: IcedTea plugin crashes with chrome browser when javascript is executed
+  - PR852: Classloader not being flushed after last applet from a site is closed
   - RH586194: Unable to connect to connect with Juniper VPN client
   - RH718693: MindTerm SSH Applet doesn't work
 Common
--- a/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java	Tue Jan 24 15:33:51 2012 -0500
+++ b/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java	Fri Jan 27 16:20:22 2012 -0500
@@ -173,6 +173,11 @@
     private boolean foundMainJar= false;
 
     /**
+     * Variable to track how many times this loader is in use
+     */
+    private int useCount = 0;
+
+    /**
      * Create a new JNLPClassLoader from the specified file.
      *
      * @param file the JNLP file
@@ -321,6 +326,7 @@
                             throw new LaunchException(file, null, R("LSFatal"), R("LCClient"), R("LSignedAppJarUsingUnsignedJar"), R("LSignedAppJarUsingUnsignedJarInfo"));
 
                     loader.merge(extLoader);
+                    extLoader.decrementLoaderUseCount(); // loader urls have been merged, ext loader is no longer used
                 }
 
                 // loader is now current + ext. But we also need to think of
@@ -347,7 +353,11 @@
 
         // loaders are mapped to a unique key. Only extensions and parent
         // share a key, so it is safe to always share based on it
-        urlToLoader.put(uniqueKey, loader);
+        
+        loader.incrementLoaderUseCount();
+        synchronized(urlToLoader) {
+            urlToLoader.put(uniqueKey, loader);
+        }
 
         return loader;
     }
@@ -1762,6 +1772,42 @@
         }
         return result;
     }
+    
+    /**
+     * Increments loader use count by 1
+     * 
+     * @throws SecurityException if caller is not trusted
+     */
+    private synchronized void incrementLoaderUseCount() {
+        
+        // For use by trusted code only
+        if (System.getSecurityManager() != null)
+            System.getSecurityManager().checkPermission(new AllPermission());
+        
+        useCount++;
+    }
+
+    /**
+     * Decrements loader use count by 1
+     * 
+     * If count reaches 0, loader is removed from list of available loaders
+     * 
+     * @throws SecurityException if caller is not trusted
+     */
+    public synchronized void decrementLoaderUseCount() {
+
+        // For use by trusted code only
+        if (System.getSecurityManager() != null)
+            System.getSecurityManager().checkPermission(new AllPermission());
+
+        useCount--;
+
+        if (useCount <= 0) {
+            synchronized(urlToLoader) {
+                urlToLoader.remove(file.getUniqueKey());
+            }
+        }
+    }
 
     /*
      * Helper class to expose protected URLClassLoader methods.
--- a/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java	Tue Jan 24 15:33:51 2012 -0500
+++ b/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java	Fri Jan 27 16:20:22 2012 -0500
@@ -1625,6 +1625,9 @@
 
                 appletShutdown(p);
                 appletPanels.removeElement(p);
+                
+                // Mark classloader unusable
+                ((JNLPClassLoader) cl).decrementLoaderUseCount();
 
                 try {
                     SwingUtilities.invokeAndWait(new Runnable() {