changeset 224:6528c988d538

PR687: BasicService.getCodeBase() returns null for IcedTea6 1.9.7 + OSGI The patch modifies how we try to find the JNLPClassLoader (from which we find the ApplicationInstance). We first search the Context ClassLoader (and it's parents) and then we search the ClassLoader for the classes on the stack (and their parents). The Launcher always sets the Context ClassLoader of the applications/applets it launches.
author Omair Majid <omajid@redhat.com>
date Wed, 20 Apr 2011 15:34:10 -0400
parents a3cbdab9bd7a
children 6abf7a788f4e
files ChangeLog netx/net/sourceforge/jnlp/runtime/JNLPSecurityManager.java
diffstat 2 files changed, 49 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Apr 20 15:23:49 2011 -0400
+++ b/ChangeLog	Wed Apr 20 15:34:10 2011 -0400
@@ -1,3 +1,12 @@
+2011-04-20  Omair Majid  <omajid@redhat.com>
+
+	* netx/net/sourceforge/jnlp/runtime/JNLPSecurityManager.java
+	(getApplication(Class[],int)): Renamed to ...
+	(getApplication(Thread,Class[],int)): New method. Check the thread's
+	context ClassLoader as well as parents of the classloader.
+	(getJnlpClassLoader): New method.
+	(getApplication, checkExit): Update to work with new method signatures.
+
 2011-04-20  Omair Majid  <omajid@redhat.com>
 
 	* plugin/icedteanp/java/sun/applet/PluginAppletSecurityContext.java
--- a/netx/net/sourceforge/jnlp/runtime/JNLPSecurityManager.java	Wed Apr 20 15:23:49 2011 -0400
+++ b/netx/net/sourceforge/jnlp/runtime/JNLPSecurityManager.java	Wed Apr 20 15:34:10 2011 -0400
@@ -165,7 +165,7 @@
      * determined.
      */
     protected ApplicationInstance getApplication() {
-        return getApplication(getClassContext(), 0);
+        return getApplication(Thread.currentThread(), getClassContext(), 0);
     }
 
     /**
@@ -190,27 +190,51 @@
     /**
      * Return the current Application, or null.
      */
-    protected ApplicationInstance getApplication(Class stack[], int maxDepth) {
+    protected ApplicationInstance getApplication(Thread thread, Class<?> stack[], int maxDepth) {
+        ClassLoader cl;
+        JNLPClassLoader jnlpCl;
+
+        cl = thread.getContextClassLoader();
+        while (cl != null) {
+            jnlpCl = getJnlpClassLoader(cl);
+            if (jnlpCl != null && jnlpCl.getApplication() != null) {
+                return jnlpCl.getApplication();
+            }
+            cl = cl.getParent();
+        }
+
         if (maxDepth <= 0)
             maxDepth = stack.length;
 
         // this needs to be tightened up
         for (int i = 0; i < stack.length && i < maxDepth; i++) {
-            ClassLoader cl = stack[i].getClassLoader();
-            
-            // Since we want to deal with JNLPClassLoader, extract it if this 
-            // is a codebase loader
-            if (cl instanceof JNLPClassLoader.CodeBaseClassLoader)
-                cl = ((JNLPClassLoader.CodeBaseClassLoader) cl).getParentJNLPClassLoader();
+            cl = stack[i].getClassLoader();
+            while (cl != null) {
+                jnlpCl = getJnlpClassLoader(cl);
+                if (jnlpCl != null && jnlpCl.getApplication() != null) {
+                    return jnlpCl.getApplication();
+                }
+                cl = cl.getParent();
+            }
+        }
+        return null;
+    }
 
-            if (cl instanceof JNLPClassLoader) {
-
-                JNLPClassLoader loader = (JNLPClassLoader) cl;
+    /**
+     * Returns the JNLPClassLoader associated with the given ClassLoader, or
+     * null.
+     * @param cl a ClassLoader
+     * @return JNLPClassLoader or null
+     */
+    private JNLPClassLoader getJnlpClassLoader(ClassLoader cl) {
+        // Since we want to deal with JNLPClassLoader, extract it if this
+        // is a codebase loader
+        if (cl instanceof JNLPClassLoader.CodeBaseClassLoader)
+            cl = ((JNLPClassLoader.CodeBaseClassLoader) cl).getParentJNLPClassLoader();
 
-                if (loader != null && loader.getApplication() != null) {
-                    return loader.getApplication();
-                }
-            }
+        if (cl instanceof JNLPClassLoader) {
+            JNLPClassLoader loader = (JNLPClassLoader) cl;
+            return loader;
         }
 
         return null;
@@ -444,7 +468,7 @@
         }
 
         // but when they really call, stop only the app instead of the JVM
-        ApplicationInstance app = getApplication(stack, 0);
+        ApplicationInstance app = getApplication(Thread.currentThread(), stack, 0);
         if (app == null) {
             throw new SecurityException(R("RExitNoApp"));
         }