/hg/icedtea-web: - PR475, RH604061: Allow applets from the same ...
dbhole at icedtea.classpath.org
dbhole at icedtea.classpath.org
Fri Mar 4 14:31:39 PST 2011
changeset 5e62b3580dcc in /hg/icedtea-web
details: http://icedtea.classpath.org/hg/icedtea-web?cmd=changeset;node=5e62b3580dcc
author: Deepak Bhole <dbhole at redhat.com>
date: Fri Mar 04 17:34:32 2011 -0500
- PR475, RH604061: Allow applets from the same page to use the same
classloader
diffstat:
5 files changed, 23 insertions(+), 6 deletions(-)
ChangeLog | 15 ++++++++++++
netx/net/sourceforge/jnlp/PluginBridge.java | 3 --
netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java | 1
netx/net/sourceforge/jnlp/runtime/JNLPSecurityManager.java | 6 +++-
plugin/icedteanp/java/sun/applet/PluginAppletViewer.java | 4 ++-
diffs (309 lines):
diff -r 64b9d3a8239c -r 5e62b3580dcc ChangeLog
--- a/ChangeLog Thu Mar 03 17:56:00 2011 -0500
+++ b/ChangeLog Fri Mar 04 17:34:32 2011 -0500
@@ -1,3 +1,31 @@ 2011-03-03 Deepak Bhole <dbhole at redhat.
+2011-03-04 Deepak Bhole <dbhole at redhat.com>
+
+ * NEWS: Updated.
+ * netx/net/sourceforge/jnlp/PluginBridge.java (PluginBridge): Use
+ documentbase as a uniquekey so that the classloader may be shared by
+ applets from the same page.
+ * netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java: Added new
+ CodeBaseClassLoader class to load codebase (from path instead of a file)
+ classes.
+ (getInstance): Try to match file locations only for Web Start apps. For
+ plugin, merge the new loader into current one.
+ (enableCodeBase): Use the new addToCodeBaseLoader method.
+ (findLoadedClassAll): Search the codebase loader if the class was not
+ found in the file loaders.
+ (findClass): Likewise.
+ (getResource): Likewise.
+ (findResources): Likewise.
+ (merge): Merge codebase loaders.
+ (addToCodeBaseLoader): New method. Adds a given url to the codebase loader
+ if it is a path.
+ (CodeBaseClassLoader): New inner class. Extends URLClassLoader to expose
+ its protected methods like addURL.
+ * netx/net/sourceforge/jnlp/runtime/JNLPSecurityManager.java
+ (getApplication): Accomodate the fact that the classloader for a class may
+ be a CodeBaseClassLoader.
+ * plugin/icedteanp/java/sun/applet/PluginAppletViewer.java (run):
+ Likewise.
+
2011-03-03 Deepak Bhole <dbhole at redhat.com>
* plugin/icedteanp/IcedTeaNPPlugin.cc
diff -r 64b9d3a8239c -r 5e62b3580dcc NEWS
--- a/NEWS Thu Mar 03 17:56:00 2011 -0500
+++ b/NEWS Fri Mar 04 17:34:32 2011 -0500
@@ -21,6 +21,7 @@ New in release 1.1 (2011-XX-XX):
- Use Firefox's proxy settings if possible
- RH669942: javaws fails to download version/packed files (missing support for jnlp.packEnabled and jnlp.versionEnabled)
* Plugin
+ - PR475, RH604061: Allow applets from the same page to use the same classloader
- PR612: NetDania application ends on java.security.AccessControlException: access denied (java.util.PropertyPermission browser read)
New in release 1.0 (2010-XX-XX):
diff -r 64b9d3a8239c -r 5e62b3580dcc netx/net/sourceforge/jnlp/PluginBridge.java
--- a/netx/net/sourceforge/jnlp/PluginBridge.java Thu Mar 03 17:56:00 2011 -0500
+++ b/netx/net/sourceforge/jnlp/PluginBridge.java Fri Mar 04 17:34:32 2011 -0500
@@ -130,9 +130,10 @@ public class PluginBridge extends JNLPFi
else
security = null;
- this.uniqueKey = Calendar.getInstance().getTimeInMillis() + "-" +
- Math.abs(((new java.util.Random()).nextInt())) + "-" +
- documentBase;
+ // Plugin needs to share classloaders so that applet instances from
+ // same page can communicate (there are applets known to require
+ // such communication for proper functionality)
+ this.uniqueKey = documentBase.toString();
}
public String getTitle() {
diff -r 64b9d3a8239c -r 5e62b3580dcc netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java
--- a/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java Thu Mar 03 17:56:00 2011 -0500
+++ b/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java Fri Mar 04 17:34:32 2011 -0500
@@ -145,6 +145,9 @@ public class JNLPClassLoader extends URL
/** Map of specific codesources to securitydesc */
private HashMap<URL, SecurityDesc> jarLocationSecurityMap =
new HashMap<URL, SecurityDesc>();
+
+ /** Loader for codebase (which is a path, rather than a file) */
+ private CodeBaseClassLoader codeBaseLoader;
/**
* Create a new JNLPClassLoader from the specified file.
@@ -276,10 +279,12 @@ public class JNLPClassLoader extends URL
try {
- // If base loader is null, or the baseloader's file and this
- // file is different, initialize a new loader
+
+ // A null baseloader implies that no loader has been created
+ // for this codebase/jnlp yet. Create one.
if (baseLoader == null ||
- !baseLoader.getJNLPFile().getFileLocation().equals(file.getFileLocation())) {
+ (file.isApplication() &&
+ !baseLoader.getJNLPFile().getFileLocation().equals(file.getFileLocation()))) {
loader = new JNLPClassLoader(file, policy);
@@ -303,6 +308,13 @@ public class JNLPClassLoader extends URL
} else {
// if key is same and locations match, this is the loader we want
+ if (!file.isApplication()) {
+ // If this is an applet, we do need to consider its loader
+ loader = new JNLPClassLoader(file, policy);
+
+ if (baseLoader != null)
+ baseLoader.merge(loader);
+ }
loader = baseLoader;
}
@@ -529,7 +541,7 @@ public class JNLPClassLoader extends URL
* loaded from the codebase are not cached.
*/
public void enableCodeBase() {
- addURL(file.getCodeBase()); // nothing happens if called more that once?
+ addToCodeBaseLoader(file.getCodeBase());
}
/**
@@ -958,8 +970,13 @@ public class JNLPClassLoader extends URL
if (result != null)
return result;
}
-
- return null;
+
+ // Result is still null. Return what the codebaseloader
+ // has (which returns null if it is not loaded there either)
+ if (codeBaseLoader != null)
+ return codeBaseLoader.findLoadedClassFromParent(name);
+ else
+ return null;
}
/**
@@ -1067,6 +1084,11 @@ public class JNLPClassLoader extends URL
}
}
+ // Try codebase loader
+ if (codeBaseLoader != null)
+ return codeBaseLoader.findClass(name);
+
+ // All else failed. Throw CNFE
throw new ClassNotFoundException(name);
}
@@ -1109,6 +1131,10 @@ public class JNLPClassLoader extends URL
for (int i = 1; i < loaders.length; i++)
if (result == null)
result = loaders[i].getResource(name);
+
+ // If result is still null, look in the codebase loader
+ if (result == null && codeBaseLoader != null)
+ result = codeBaseLoader.getResource(name);
return result;
}
@@ -1120,15 +1146,23 @@ public class JNLPClassLoader extends URL
@Override
public Enumeration<URL> findResources(String name) throws IOException {
Vector<URL> resources = new Vector<URL>();
+ Enumeration<URL> e;
for (int i = 0; i < loaders.length; i++) {
- Enumeration<URL> e;
if (loaders[i] == this)
e = super.findResources(name);
else
e = loaders[i].findResources(name);
+ while (e.hasMoreElements())
+ resources.add(e.nextElement());
+ }
+
+ // Add resources from codebase (only if nothing was found above,
+ // otherwise the server will get hammered)
+ if (resources.isEmpty() && codeBaseLoader != null) {
+ e = codeBaseLoader.findResources(name);
while (e.hasMoreElements())
resources.add(e.nextElement());
}
@@ -1250,6 +1284,9 @@ public class JNLPClassLoader extends URL
// jars
for (URL u : extLoader.getURLs())
addURL(u);
+
+ // Codebase
+ addToCodeBaseLoader(extLoader.file.getCodeBase());
// native search paths
for (File nativeDirectory : extLoader.getNativeDirectories())
@@ -1258,6 +1295,28 @@ public class JNLPClassLoader extends URL
// security descriptors
for (URL key : extLoader.jarLocationSecurityMap.keySet()) {
jarLocationSecurityMap.put(key, extLoader.jarLocationSecurityMap.get(key));
+ }
+ }
+
+ /**
+ * Adds the given path to the path loader
+ *
+ * @param URL the path to add
+ * @throws IllegalArgumentException If the given url is not a path
+ */
+ private void addToCodeBaseLoader(URL u) {
+
+ // Only paths may be added
+ if (!u.getFile().endsWith("/")) {
+ throw new IllegalArgumentException("addToPathLoader only accepts path based URLs");
+ }
+
+ // If there is no loader yet, create one, else add it to the
+ // existing one (happens when called from merge())
+ if (codeBaseLoader == null) {
+ codeBaseLoader = new CodeBaseClassLoader(new URL[] { u }, this);
+ } else {
+ codeBaseLoader.addURL(u);
}
}
@@ -1283,4 +1342,49 @@ public class JNLPClassLoader extends URL
return new DownloadOptions(usePack, useVersion);
}
+ /*
+ * Helper class to expose protected URLClassLoader methods.
+ */
+
+ public class CodeBaseClassLoader extends URLClassLoader {
+
+ JNLPClassLoader parentJNLPClassLoader;
+
+ public CodeBaseClassLoader(URL[] urls, JNLPClassLoader cl) {
+ super(urls);
+ parentJNLPClassLoader = cl;
+ }
+
+ @Override
+ public void addURL(URL url) {
+ super.addURL(url);
+ }
+
+ @Override
+ public Class<?> findClass(String name) throws ClassNotFoundException {
+ return super.findClass(name);
+ }
+
+ /**
+ * Returns the output of super.findLoadedClass().
+ *
+ * The method is renamed because ClassLoader.findLoadedClass() is final
+ *
+ * @param name The name of the class to find
+ * @return Output of ClassLoader.findLoadedClass() which is the class if found, null otherwise
+ * @see java.lang.ClassLoader#findLoadedClass(String)
+ */
+ public Class<?> findLoadedClassFromParent(String name) {
+ return findLoadedClass(name);
+ }
+
+ /**
+ * Returns JNLPClassLoader that encompasses this loader
+ *
+ * @return parent JNLPClassLoader
+ */
+ public JNLPClassLoader getParentJNLPClassLoader() {
+ return parentJNLPClassLoader;
+ }
+ }
}
diff -r 64b9d3a8239c -r 5e62b3580dcc netx/net/sourceforge/jnlp/runtime/JNLPSecurityManager.java
--- a/netx/net/sourceforge/jnlp/runtime/JNLPSecurityManager.java Thu Mar 03 17:56:00 2011 -0500
+++ b/netx/net/sourceforge/jnlp/runtime/JNLPSecurityManager.java Fri Mar 04 17:34:32 2011 -0500
@@ -199,8 +199,16 @@ class JNLPSecurityManager extends AWTSec
// this needs to be tightened up
for (int i = 0; i < stack.length && i < maxDepth; i++) {
- if (stack[i].getClassLoader() instanceof JNLPClassLoader) {
- JNLPClassLoader loader = (JNLPClassLoader) stack[i].getClassLoader();
+ 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();
+
+ if (cl instanceof JNLPClassLoader) {
+
+ JNLPClassLoader loader = (JNLPClassLoader) cl;
if (loader != null && loader.getApplication() != null) {
return loader.getApplication();
diff -r 64b9d3a8239c -r 5e62b3580dcc plugin/icedteanp/java/sun/applet/PluginAppletViewer.java
--- a/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java Thu Mar 03 17:56:00 2011 -0500
+++ b/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java Fri Mar 04 17:34:32 2011 -0500
@@ -1646,7 +1646,14 @@ public class PluginAppletViewer extends
{
public void run()
{
- ThreadGroup tg = ((JNLPClassLoader) p.applet.getClass().getClassLoader()).getApplication().getThreadGroup();
+ ClassLoader cl = p.applet.getClass().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();
+
+ ThreadGroup tg = ((JNLPClassLoader) cl).getApplication().getThreadGroup();
appletShutdown(p);
appletPanels.removeElement(p);
More information about the distro-pkg-dev
mailing list