[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