[RFC] PR858

Thomas Meyer thomas at m3y3r.de
Sun Mar 18 04:31:07 PDT 2012


Am Dienstag, den 13.03.2012, 17:08 -0400 schrieb Deepak Bhole:

> This is odd. The code was added in that catch because at one point
> loadClassExt() was not automatically adding the index classes. Now it is
> :/
> 
> The best thing would be to somehow remove the index from the JarFile
> returned by CachedJarFileCallback, but entries cannot be removed without
> re-writing the JAR. I think given that, your logic of check for sd looks
> correct.
> 
> However, calling addJar means that the jar is now being downloaded twice
> -- once by URLClassLoader (which doesn't cache it) and once by
> JNLPClassLoader.
> 
> We could scan for INDEX.LIST beforhand and add those jars, but then that
> defeats lazy loading. Other suggestions?

I did implement the preloading. what do you think of this patch:

kind regards
thomas

# HG changeset patch
# User thomas at m3y3r.de
# Date 1332069949 -3600
# Node ID 540254dcb2b360f2cf8d343e2326b327e7a4177b
# Parent  fe27f172a7ae67230ac7864c7b1584569c22b482
Preload jar in the initial classpath to avoid a duplicate download in the URLClassLoader and fix PR858. The preloading will add a SecurityDesc to all jars in the initial classpath and thus return the correct getPermissions(CodeSource cs). Also prevent an NPE in getPermissions(CodeSource cs) and assign sandbox permissions in the case a CodeSource has no SecurityDesc yet.

diff -r fe27f172a7ae -r 540254dcb2b3 netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java
--- a/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java	Sun Mar 18 12:16:48 2012 +0100
+++ b/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java	Sun Mar 18 12:25:49 2012 +0100
@@ -206,10 +206,46 @@
         setSecurity();
 
         installShutdownHooks();
+        
+        makeClassPathAvailable();
 
     }
 
     /**
+     * Make jars in the classpath available and start downloading them.
+     * FIXME: only do this for applets?!
+     */
+    private void makeClassPathAvailable() {
+        
+        if(file instanceof PluginBridge) {
+
+            List<JARDesc> classPathJars = new ArrayList<JARDesc>();
+
+            //start downloading the jars                             
+            for (String classpath: classpaths) {
+                URL jarUrl;
+                try {
+                    jarUrl = new URL(file.getCodeBase(), classpath);
+                    JARDesc desc = new JARDesc(jarUrl, null, null, false, true, false, true);
+                    classPathJars.add(desc);
+                    addAvailable(desc);
+                } catch (MalformedURLException e) {
+                    // do nothing
+                }
+            }
+
+            // wait for download
+            waitForJars(classPathJars);
+
+            //add them
+            for(JARDesc jar: classPathJars) {
+                addNewJar(jar);
+            }
+        }
+        
+    }
+
+    /**
      * Install JVM shutdown hooks to clean up resources allocated by this
      * ClassLoader.
      */
@@ -448,16 +484,10 @@
 
         for (int i = 0; i < jars.length; i++) {
 
-            available.add(jars[i]);
+            addAvailable(jars[i]);
 
             if (jars[i].isEager())
                 initialJars.add(jars[i]); // regardless of part
-
-            tracker.addResource(jars[i].getLocation(),
-                                jars[i].getVersion(),
-                                getDownloadOptionsForJar(jars[i]),
-                                jars[i].isCacheable() ? JNLPRuntime.getDefaultUpdatePolicy() : UpdatePolicy.FORCE
-                               );
         }
         
         //If there are no eager jars, initialize the first jar
@@ -496,7 +526,7 @@
                 checkForMain(initialJars);
 
                 // If jar with main class was not found, check available resources
-                while (!foundMainJar && available != null && available.size() != 0) 
+                while (!foundMainJar && available != null) 
                     addNextResource();
 
                 // If jar with main class was not found and there are no more
@@ -576,6 +606,25 @@
     }
     
     /***
+     * Add jar to the list of available jars and start the tracker to download it
+     * 
+     * @param jarDesc jar to make available
+     */
+    private void addAvailable(JARDesc jarDesc) {
+
+        if(available.contains(jarDesc))
+            return;
+
+        available.add(jarDesc);
+
+        tracker.addResource(jarDesc.getLocation(),
+                            jarDesc.getVersion(),
+                            getDownloadOptionsForJar(jarDesc),
+                            jarDesc.isCacheable() ? JNLPRuntime.getDefaultUpdatePolicy() : UpdatePolicy.FORCE
+                           );
+    }
+
+    /***
      * Checks for the jar that contains the main class. If the main class was
      * found, it checks to see if the jar is signed and whether it contains a
      * signed JNLP file
@@ -908,15 +957,17 @@
 
             // set default perms
             PermissionCollection permissions = security.getSandBoxPermissions();
+            URL csUrl = cs.getLocation();
+            SecurityDesc sd = getCodeSourceSecurity(csUrl);
 
             // If more than default is needed:
             // 1. Code must be signed
             // 2. ALL or J2EE permissions must be requested (note: plugin requests ALL automatically)
-            if (cs.getCodeSigners() != null &&
-                    (getCodeSourceSecurity(cs.getLocation()).getSecurityType().equals(SecurityDesc.ALL_PERMISSIONS) ||
-                     getCodeSourceSecurity(cs.getLocation()).getSecurityType().equals(SecurityDesc.J2EE_PERMISSIONS))) {
+            if (cs.getCodeSigners() != null && sd != null &&
+                    (sd.getSecurityType().equals(SecurityDesc.ALL_PERMISSIONS) ||
+                     sd.getSecurityType().equals(SecurityDesc.J2EE_PERMISSIONS))) {
 
-                permissions = getCodeSourceSecurity(cs.getLocation()).getPermissions(cs);
+                permissions = sd.getPermissions(cs);
             }
 
             Enumeration<Permission> e = permissions.elements();
@@ -1263,11 +1314,11 @@
      *
      * @param jars the jars
      */
-    private void waitForJars(List jars) {
+    private void waitForJars(List<JARDesc> jars) {
         URL urls[] = new URL[jars.size()];
 
         for (int i = 0; i < jars.size(); i++) {
-            JARDesc jar = (JARDesc) jars.get(i);
+            JARDesc jar = jars.get(i);
 
             urls[i] = jar.getLocation();
         }
@@ -1340,30 +1391,7 @@
             try {
                 result = loadClassExt(name);
             } catch (ClassNotFoundException cnfe) {
-                // Not found in external loader either
-
-                // Look in 'Class-Path' as specified in the manifest file
-                try {
-                    for (String classpath: classpaths) {
-                        JARDesc desc;
-                        try {
-                            URL jarUrl = new URL(file.getCodeBase(), classpath);
-                            desc = new JARDesc(jarUrl, null, null, false, true, false, true);
-                        } catch (MalformedURLException mfe) {
-                            throw new ClassNotFoundException(name, mfe);
-                        }
-                        addNewJar(desc);
-                    }
-
-                    result = loadClassExt(name);
-                    return result;
-                } catch (ClassNotFoundException cnfe1) {
-                    if (JNLPRuntime.isDebug()) {
-                        cnfe1.printStackTrace();
-                    }
-                }
-
-                // As a last resort, look in any available indexes
+                // Not found in external loader either, look in any available indexes
 
                 // Currently this loads jars directly from the site. We cannot cache it because this
                 // call is initiated from within the applet, which does not have disk read/write permissions
@@ -1413,13 +1441,7 @@
      */
     private void addNewJar(final JARDesc desc) {
 
-        available.add(desc);
-
-        tracker.addResource(desc.getLocation(),
-                desc.getVersion(),
-                null,
-                JNLPRuntime.getDefaultUpdatePolicy()
-                );
+        addAvailable(desc);
 
         // Give read permissions to the cached jar file
         AccessController.doPrivileged(new PrivilegedAction<Void>() {








More information about the distro-pkg-dev mailing list