diff options
author | Omair Majid <[email protected]> | 2012-06-28 14:53:07 -0400 |
---|---|---|
committer | Omair Majid <[email protected]> | 2012-06-28 14:53:07 -0400 |
commit | 16f2e7d40c05927c5d911380a24d11dec4f31263 (patch) | |
tree | b93ac79d7ad4225bd28c6df06a93074b62ca774b | |
parent | 40f30149bcd80661a1df5ec0570d1b7c0124c3c3 (diff) |
Fix problem in resolving classes
The bug manifests when the following sequence of steps happen:
1. An applet with both a codebase and a jar (archive) is loaded
2. A class Foo is loaded using the codebase classloader
3. The Foo class tries to load a class Bar that is specified in the jar
archive. The Bar class is not found.
The following applet reproduces the problem:
http://javadjvu.foxtrottechnologies.com/cgi-bin/djvuapplet.pl/examples/deer.djvu?zoom=page
The fix addresses the problem by ensuring that the codebase classloader
asks the classloader that knows about the jar archive to resolve
classes too.
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java | 16 | ||||
-rw-r--r-- | tests/netx/unit/net/sourceforge/jnlp/runtime/CodeBaseClassLoaderTest.java | 48 |
3 files changed, 71 insertions, 3 deletions
@@ -1,3 +1,13 @@ +2012-06-28 Omair Majid <[email protected]> + + * netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java + (findClass): Invoke CodeBaseClassLoader.findClass with a flag to avoid + infinite recursion. + (CodeBaseClassLoader.findClass(String)): Delegate to ... + (CodeBaseClassLoader.findClass(String,boolean)): New method. + * tests/netx/unit/net/sourceforge/jnlp/runtime/CodeBaseClassLoaderTest.java + (testParentClassLoaderIsAskedForClasses): New method. + 2012-06-28 Jiri Vanek <[email protected]> Correctly backup all log files re-writable by emma during code-coverage diff --git a/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java b/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java index e487cb6..abdba94 100644 --- a/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java +++ b/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java @@ -1577,8 +1577,8 @@ public class JNLPClassLoader extends URLClassLoader { // Try codebase loader if (codeBaseLoader != null) - return codeBaseLoader.findClass(name); - + return codeBaseLoader.findClass(name, true); + // All else failed. Throw CNFE throw new ClassNotFoundException(name); } @@ -2060,6 +2060,18 @@ public class JNLPClassLoader extends URLClassLoader { @Override public Class<?> findClass(String name) throws ClassNotFoundException { + return findClass(name, false); + } + + public Class<?> findClass(String name, boolean recursivelyInvoked) throws ClassNotFoundException { + + if (!recursivelyInvoked) { + try { + return parentJNLPClassLoader.findClass(name); + } catch (ClassNotFoundException cnfe) { + // continue + } + } // If we have searched this path before, don't try again if (Arrays.equals(super.getURLs(), notFoundResources.get(name))) diff --git a/tests/netx/unit/net/sourceforge/jnlp/runtime/CodeBaseClassLoaderTest.java b/tests/netx/unit/net/sourceforge/jnlp/runtime/CodeBaseClassLoaderTest.java index 5f3d566..4839013 100644 --- a/tests/netx/unit/net/sourceforge/jnlp/runtime/CodeBaseClassLoaderTest.java +++ b/tests/netx/unit/net/sourceforge/jnlp/runtime/CodeBaseClassLoaderTest.java @@ -37,9 +37,11 @@ exception statement from your version. package net.sourceforge.jnlp.runtime; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.io.IOException; +import java.net.MalformedURLException; import java.net.URL; import java.util.Locale; @@ -55,9 +57,11 @@ import net.sourceforge.jnlp.annotations.Bug; import org.junit.Test; -@Bug(id={"PR895","http://mail.openjdk.java.net/pipermail/distro-pkg-dev/2012-March/017626.html","http://mail.openjdk.java.net/pipermail/distro-pkg-dev/2012-March/017667.html"}) public class CodeBaseClassLoaderTest { + @Bug(id={"PR895", + "http://mail.openjdk.java.net/pipermail/distro-pkg-dev/2012-March/017626.html", + "http://mail.openjdk.java.net/pipermail/distro-pkg-dev/2012-March/017667.html"}) @Test public void testResourceLoadSuccessCaching() throws LaunchException, ClassNotFoundException, IOException, ParseException { final URL JAR_URL = new URL("http://icedtea.classpath.org/netx/about.jar"); @@ -100,6 +104,9 @@ public class CodeBaseClassLoaderTest { assertTrue(timeOnSecondTry < (timeOnFirstTry / 10)); } + @Bug(id={"PR895", + "http://mail.openjdk.java.net/pipermail/distro-pkg-dev/2012-March/017626.html", + "http://mail.openjdk.java.net/pipermail/distro-pkg-dev/2012-March/017667.html"}) @Test public void testResourceLoadFailureCaching() throws LaunchException, ClassNotFoundException, IOException, ParseException { final URL JAR_URL = new URL("http://icedtea.classpath.org/netx/about.jar"); @@ -142,4 +149,43 @@ public class CodeBaseClassLoaderTest { assertTrue(timeOnSecondTry < (timeOnFirstTry / 10)); } + @Test + public void testParentClassLoaderIsAskedForClasses() throws MalformedURLException, LaunchException { + final URL JAR_URL = new URL("http://icedtea.classpath.org/netx/about.jar"); + final URL CODEBASE_URL = new URL("http://icedtea.classpath.org/netx/"); + + JNLPFile dummyJnlpFile = new JNLPFile() { + @Override + public ResourcesDesc getResources() { + return new ResourcesDesc(null, new Locale[0], new String[0], new String[0]); + } + + @Override + public URL getCodeBase() { + return CODEBASE_URL; + } + + @Override + public SecurityDesc getSecurity() { + return new SecurityDesc(null, SecurityDesc.SANDBOX_PERMISSIONS, null); + } + }; + + final boolean[] parentWasInvoked = new boolean[1]; + + JNLPClassLoader parent = new JNLPClassLoader(dummyJnlpFile, null) { + @Override + protected Class<?> findClass(String name) throws ClassNotFoundException { + parentWasInvoked[0] = true; + throw new ClassNotFoundException(name); + } + }; + CodeBaseClassLoader classLoader = new CodeBaseClassLoader(new URL[] { JAR_URL, CODEBASE_URL }, parent); + try { + classLoader.findClass("foo"); + assertFalse("should not happen", true); + } catch (ClassNotFoundException cnfe) { /* ignore */ } + + assertTrue(parentWasInvoked[0]); + } } |