changeset 508:5c8f7941fb07

Fixed long term failing unit-test, fixed NPE from ClassLoader * netx/net/sourceforge/jnlp/NullJnlpFileException.java: new class to distinguish plain NPE from null jnlp file. * netx/net/sourceforge/jnlp/SecurityDesc.java: (getSandBoxPermissions) added throw of NullJnlpFileException in case of null jnlp file. * netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java: (findClass) added Override annotation, add catch of NullJnlpFileException and re-throw of CNF exception. * tests/netx/unit/net/sourceforge/jnlp/runtime/CodeBaseClassLoaderTest.java: (testResourceLoadSuccessCaching) (testResourceLoadFailureCaching) (testParentClassLoaderIsAskedForClasses) - internal JNLPFile's (getSecurity) null in SecurityDesc constructorrepalced by this. (testNullFileSecurityDesc) new test to ensure NPE in null JNLPFile case.
author Jiri Vanek <jvanek@redhat.com>
date Mon, 27 Aug 2012 12:50:29 +0200
parents 4eda8f1766b0
children e591c793683a
files ChangeLog netx/net/sourceforge/jnlp/NullJnlpFileException.java netx/net/sourceforge/jnlp/SecurityDesc.java netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java tests/netx/unit/net/sourceforge/jnlp/runtime/CodeBaseClassLoaderTest.java
diffstat 5 files changed, 311 insertions(+), 115 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Aug 23 09:23:23 2012 +0200
+++ b/ChangeLog	Mon Aug 27 12:50:29 2012 +0200
@@ -1,3 +1,19 @@
+2012-08-27  Jiri Vanek  <jvanek@redhat.com>
+
+	Fixed long term failing unit-test, fixed NPE from ClassLoader
+	* netx/net/sourceforge/jnlp/NullJnlpFileException.java: new class to
+	distinguish plain NPE from null jnlp file.
+	* netx/net/sourceforge/jnlp/SecurityDesc.java: (getSandBoxPermissions) 
+	added throw of NullJnlpFileException in case of null jnlp file.
+	* netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java: (findClass)
+	added Override annotation,  add catch of NullJnlpFileException and 
+	re-throw of  CNF exception.
+	* tests/netx/unit/net/sourceforge/jnlp/runtime/CodeBaseClassLoaderTest.java:
+	(testResourceLoadSuccessCaching) (testResourceLoadFailureCaching)
+	(testParentClassLoaderIsAskedForClasses) - internal JNLPFile's
+	(getSecurity) null in SecurityDesc constructorrepalced by this.
+	(testNullFileSecurityDesc) new test to ensure NPE in null JNLPFile case. 
+
 2012-08-22  Jiri Vanek  <jvanek@redhat.com>
 
 	Added tests for PR905 - parameters in jnlp/html application/applet resources
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/netx/net/sourceforge/jnlp/NullJnlpFileException.java	Mon Aug 27 12:50:29 2012 +0200
@@ -0,0 +1,22 @@
+package net.sourceforge.jnlp;
+
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+/**
+ *
+ * @author jvanek
+ */
+public class NullJnlpFileException extends NullPointerException {
+
+    public NullJnlpFileException() {
+        super();
+    }
+
+    public NullJnlpFileException(String s) {
+        super(s);
+    }
+
+}
--- a/netx/net/sourceforge/jnlp/SecurityDesc.java	Thu Aug 23 09:23:23 2012 +0200
+++ b/netx/net/sourceforge/jnlp/SecurityDesc.java	Mon Aug 27 12:50:29 2012 +0200
@@ -233,10 +233,16 @@
         if (grantAwtPermissions) {
             permissions.add(new AWTPermission("showWindowWithoutWarningBanner"));
         }
-
-        if (file.isApplication())
-            for (int i = 0; i < jnlpRIAPermissions.length; i++)
-                permissions.add(jnlpRIAPermissions[i]);
+        if (JNLPRuntime.isWebstartApplication()) {
+            if (file == null) {
+                throw new NullJnlpFileException("Can not return sandbox permissions, file is null");
+            }
+            if (file.isApplication()) {
+                for (int i = 0; i < jnlpRIAPermissions.length; i++) {
+                    permissions.add(jnlpRIAPermissions[i]);
+                }
+            }
+        }
 
         if (downloadHost != null && downloadHost.length() > 0)
             permissions.add(new SocketPermission(downloadHost,
--- a/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java	Thu Aug 23 09:23:23 2012 +0200
+++ b/netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java	Mon Aug 27 12:50:29 2012 +0200
@@ -69,6 +69,7 @@
 import net.sourceforge.jnlp.JNLPMatcherException;
 import net.sourceforge.jnlp.LaunchDesc;
 import net.sourceforge.jnlp.LaunchException;
+import net.sourceforge.jnlp.NullJnlpFileException;
 import net.sourceforge.jnlp.ParseException;
 import net.sourceforge.jnlp.PluginBridge;
 import net.sourceforge.jnlp.ResourcesDesc;
@@ -1701,6 +1702,7 @@
     /**
      * Find the class in this loader or any of its extension loaders.
      */
+    @Override
     protected Class findClass(String name) throws ClassNotFoundException {
         for (int i = 0; i < loaders.length; i++) {
             try {
@@ -1718,6 +1720,8 @@
             } catch (ClassNotFoundException ex) {
             } catch (ClassFormatError cfe) {
             } catch (PrivilegedActionException pae) {
+            } catch (NullJnlpFileException ex) {
+                throw new ClassNotFoundException(this.mainClass + " in main classloader ", ex);
             }
         }
 
@@ -2233,7 +2237,10 @@
                         }, parentJNLPClassLoader.getAccessControlContextForClassLoading());
             } catch (PrivilegedActionException pae) {
                 notFoundResources.put(name, super.getURLs());
-                throw new ClassNotFoundException("Could not find class " + name);
+                throw new ClassNotFoundException("Could not find class " + name, pae);
+            } catch (NullJnlpFileException njf) {
+                notFoundResources.put(name, super.getURLs());
+                throw new ClassNotFoundException("Could not find class " + name, njf);
             }
         }
 
@@ -2297,7 +2304,7 @@
                                 }
                             }, parentJNLPClassLoader.getAccessControlContextForClassLoading());
                 } catch (PrivilegedActionException pae) {
-                }
+                } 
 
                 if (url == null) {
                     notFoundResources.put(name, super.getURLs());
--- a/tests/netx/unit/net/sourceforge/jnlp/runtime/CodeBaseClassLoaderTest.java	Thu Aug 23 09:23:23 2012 +0200
+++ b/tests/netx/unit/net/sourceforge/jnlp/runtime/CodeBaseClassLoaderTest.java	Mon Aug 27 12:50:29 2012 +0200
@@ -1,5 +1,5 @@
 /* CodeBaseClassLoaderTest.java
-   Copyright (C) 2012 Red Hat, Inc.
+Copyright (C) 2012 Red Hat, Inc.
 
 This file is part of IcedTea.
 
@@ -33,41 +33,237 @@
 this exception to your version of the library, but you are not
 obligated to do so.  If you do not wish to do so, delete this
 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.lang.reflect.Field;
 import java.net.URL;
 import java.util.Locale;
 
 import net.sourceforge.jnlp.JNLPFile;
-import net.sourceforge.jnlp.LaunchException;
-import net.sourceforge.jnlp.ParseException;
+import net.sourceforge.jnlp.NullJnlpFileException;
 import net.sourceforge.jnlp.ResourcesDesc;
 import net.sourceforge.jnlp.SecurityDesc;
 import net.sourceforge.jnlp.ServerAccess;
-import net.sourceforge.jnlp.runtime.JNLPClassLoader;
 import net.sourceforge.jnlp.runtime.JNLPClassLoader.CodeBaseClassLoader;
 import net.sourceforge.jnlp.annotations.Bug;
+import org.junit.AfterClass;
+import org.junit.Assert;
 
 import org.junit.Test;
 
 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"})
+    private static final URL JAR_URL;
+    private static final URL CODEBASE_URL;
+
+    static {
+        try {
+            JAR_URL = new URL("http://icedtea.classpath.org/netx/about.jar");
+            CODEBASE_URL = new URL("http://icedtea.classpath.org/netx/");
+        } catch (Exception ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+    private static final String isWSA = "isWebstartApplication";
+
+    static void setStaticField(Field field, Object newValue) throws Exception {
+        field.setAccessible(true);
+        field.set(null, newValue);
+    }
+
+    private void setWSA() throws Exception {
+        setStaticField(JNLPRuntime.class.getDeclaredField(isWSA), true);
+    }
+
+    private void setApplet() throws Exception {
+        setStaticField(JNLPRuntime.class.getDeclaredField(isWSA), false);
+    }
+
+    @AfterClass
+    public static void tearDown() throws Exception {
+        setStaticField(JNLPRuntime.class.getDeclaredField(isWSA), false);
+
+
+    }
+
+    @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 testResourceLoadSuccessCachingApplication() throws Exception {
+        setWSA();
+        //we are testing new resource not in cache
+        testResourceLoadSuccessCaching("Main.class");
+    }
+
+    @Test
+    public void testResourceLoadSuccessCachingApplet() throws Exception {
+        setApplet();
+        //so new resource again not in cache
+        testResourceLoadSuccessCaching("HTMLPanel.java");
+    }
+
+    public void testResourceLoadSuccessCaching(String r) throws Exception {
+        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(this, SecurityDesc.SANDBOX_PERMISSIONS, null);
+            }
+        };
+        JNLPClassLoader parent = new JNLPClassLoader(dummyJnlpFile, null);
+        CodeBaseClassLoader classLoader = new CodeBaseClassLoader(new URL[] { JAR_URL, CODEBASE_URL }, parent);
+
+        long startTime, stopTime;
+
+        startTime = System.nanoTime();
+        classLoader.findResource("net/sourceforge/jnlp/about/"+r);
+        stopTime = System.nanoTime();
+        long timeOnFirstTry = stopTime - startTime;
+        ServerAccess.logErrorReprint("" + timeOnFirstTry);
+
+        startTime = System.nanoTime();
+        classLoader.findResource("net/sourceforge/jnlp/about/"+r);
+        stopTime = System.nanoTime();
+        long timeOnSecondTry = stopTime - startTime;
+        ServerAccess.logErrorReprint("" + timeOnSecondTry);
+
+        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 testResourceLoadFailureCachingApplication() throws Exception {
+        setWSA();
+        testResourceLoadFailureCaching();
+    }
+
     @Test
-    public void testResourceLoadSuccessCaching() throws LaunchException, ClassNotFoundException, IOException, ParseException {
-        final URL JAR_URL = new URL("http://icedtea.classpath.org/netx/about.jar");
-        final URL CODEBASE_URL = new URL("http://icedtea.classpath.org/netx/");
+    public void testResourceLoadFailureCachingApplet() throws Exception {
+        setApplet();
+        testResourceLoadFailureCaching();
+    }
+
+    public void testResourceLoadFailureCaching() throws Exception {
+        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(this, SecurityDesc.SANDBOX_PERMISSIONS, null);
+            }
+        };
+
+        JNLPClassLoader parent = new JNLPClassLoader(dummyJnlpFile, null);
+        CodeBaseClassLoader classLoader = new CodeBaseClassLoader(new URL[] { JAR_URL, CODEBASE_URL }, parent);
+
+        long startTime, stopTime;
+
+        startTime = System.nanoTime();
+        classLoader.findResource("net/sourceforge/jnlp/about/Main_FOO_.class");
+        stopTime = System.nanoTime();
+        long timeOnFirstTry = stopTime - startTime;
+        ServerAccess.logErrorReprint("" + timeOnFirstTry);
+
+        startTime = System.nanoTime();
+        classLoader.findResource("net/sourceforge/jnlp/about/Main_FOO_.class");
+        stopTime = System.nanoTime();
+        long timeOnSecondTry = stopTime - startTime;
+        ServerAccess.logErrorReprint("" + timeOnSecondTry);
+
+        assertTrue(timeOnSecondTry < (timeOnFirstTry / 10));
+    }
+
+    @Test
+    public void testParentClassLoaderIsAskedForClassesApplication() throws Exception {
+        setWSA();
+        testParentClassLoaderIsAskedForClasses();
+    }
 
+    @Test
+    public void testParentClassLoaderIsAskedForClassesApplet() throws Exception {
+        setApplet();
+        testResourceLoadFailureCaching();
+    }
+
+    public void testParentClassLoaderIsAskedForClasses() throws Exception {
         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(this, 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]);
+    }
+
+    @Test
+    public void testNullFileSecurityDescApplication() throws Exception {
+        setWSA();
+        testNullFileSecurityDesc();
+    }
+
+    @Test
+    public void testNullFileSecurityDescApplet() throws Exception {
+        setApplet();
+        testNullFileSecurityDesc();
+    }
+
+    public void testNullFileSecurityDesc() throws Exception {
+        JNLPFile dummyJnlpFile = new JNLPFile() {
+
             @Override
             public ResourcesDesc getResources() {
                 return new ResourcesDesc(null, new Locale[0], new String[0], new String[0]);
@@ -87,105 +283,54 @@
         JNLPClassLoader parent = new JNLPClassLoader(dummyJnlpFile, null);
         CodeBaseClassLoader classLoader = new CodeBaseClassLoader(new URL[] { JAR_URL, CODEBASE_URL }, parent);
 
-        long startTime, stopTime;
+        Exception ex = null;
+        try {
+            classLoader.findClass("foo");
+        } catch (Exception exx) {
+            ex = exx;
+            ServerAccess.logException(ex);
+        }
+        Assert.assertNotNull(ex);
+        Assert.assertTrue(ex instanceof ClassNotFoundException);
 
-        startTime = System.nanoTime();
-        classLoader.findResource("net/sourceforge/jnlp/about/Main.class");
-        stopTime = System.nanoTime();
-        long timeOnFirstTry = stopTime - startTime;
-        ServerAccess.logErrorReprint(""+timeOnFirstTry);
 
-        startTime = System.nanoTime();
-        classLoader.findResource("net/sourceforge/jnlp/about/Main.class");
-        stopTime = System.nanoTime();
-        long timeOnSecondTry = stopTime - startTime;
-        ServerAccess.logErrorReprint(""+timeOnSecondTry);
+        //search dor resources is not relvant to null jnlp file for applets
+        ex = null;
+        URL res=null;
+        try {
+            //not cached
+            res=classLoader.findResource("net/sourceforge/jnlp/about/resources/notes.html");
+        } catch (Exception exx) {
+            ex = exx;
+            ServerAccess.logException(ex);
+        }
+        if (JNLPRuntime.isWebstartApplication()) {
+            Assert.assertNull(res);
+            Assert.assertNotNull(ex);
+            Assert.assertTrue(ex instanceof NullJnlpFileException);
+        } else {
+            Assert.assertNull(ex);
+            Assert.assertNotNull(res);
+        }
 
-        assertTrue(timeOnSecondTry < (timeOnFirstTry / 10));
+        ex = null;
+        res=null;
+        try {
+            //now cached
+            res=classLoader.findResource("net/sourceforge/jnlp/about/resources/notes.html");
+        } catch (Exception exx) {
+            ex = exx;
+            ServerAccess.logException(ex);
+        }
+        if (JNLPRuntime.isWebstartApplication()) {
+            Assert.assertNotNull(ex);
+            Assert.assertTrue(ex instanceof NullJnlpFileException);
+            Assert.assertNull(res);
+        } else {
+            Assert.assertNull(ex);
+            Assert.assertNotNull(res);
+        }
     }
 
-    @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");
-        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);
-            }
-        };
-
-        JNLPClassLoader parent = new JNLPClassLoader(dummyJnlpFile, null);
-        CodeBaseClassLoader classLoader = new CodeBaseClassLoader(new URL[] { JAR_URL, CODEBASE_URL }, parent);
-
-        long startTime, stopTime;
-
-        startTime = System.nanoTime();
-        classLoader.findResource("net/sourceforge/jnlp/about/Main_FOO_.class");
-        stopTime = System.nanoTime();
-        long timeOnFirstTry = stopTime - startTime;
-        ServerAccess.logErrorReprint(""+timeOnFirstTry);
-
-        startTime = System.nanoTime();
-        classLoader.findResource("net/sourceforge/jnlp/about/Main_FOO_.class");
-        stopTime = System.nanoTime();
-        long timeOnSecondTry = stopTime - startTime;
-        ServerAccess.logErrorReprint(""+timeOnSecondTry);
-
-        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]);
-    }
 }