aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorAndrew Azores <[email protected]>2013-10-16 13:13:19 -0400
committerAndrew Azores <[email protected]>2013-10-16 13:13:19 -0400
commita8d0fefc52c821169e1c9d7be41cdeb75456dd64 (patch)
tree584807bb03aa371bc3dd0d71e804cb4a77c5b70a /tests
parent76667d1d971e9fc9ac9840d64a38e7a06a6cfabb (diff)
Resolve multiple-applet deadlock issue in JNLPClassLoader
New lock used for synchronizing JNLPClassLoader#loadClass(String) to avoid deadlock condition when multiple applets are being loaded simultaneously. Regression test included. * netx/net/sourceforge/jnlp/runtime/JNLPClassLoader.java: (loadClassLock) private member for locking of loadClass method. (loadClass) synchronizes using new lock rather than instance intrinsic lock to avoid RH976833 deadlock * tests/reproducers/custom/JNLPClassLoaderDeadlock/testcases/JNLPClassLoaderDeadlockTest.java: new test for multiple applet deadlock condition * tests/reproducers/custom/JNLPClassLoaderDeadlock/resources/JNLPClassLoaderDeadlock.html: same * tests/reproducers/custom/JNLPClassLoaderDeadlock/srcs/JNLPClassLoaderDeadlock_1.java: same * tests/reproducers/custom/JNLPClassLoaderDeadlock/srcs/JNLPClassLoaderDeadlock_2.java: same * tests/reproducers/custom/JNLPClassLoaderDeadlock/srcs/Makefile: same
Diffstat (limited to 'tests')
-rw-r--r--tests/reproducers/custom/JNLPClassLoaderDeadlock/resources/JNLPClassLoaderDeadlock.html7
-rw-r--r--tests/reproducers/custom/JNLPClassLoaderDeadlock/srcs/JNLPClassLoaderDeadlock_1.java24
-rw-r--r--tests/reproducers/custom/JNLPClassLoaderDeadlock/srcs/JNLPClassLoaderDeadlock_2.java83
-rw-r--r--tests/reproducers/custom/JNLPClassLoaderDeadlock/srcs/Makefile30
-rw-r--r--tests/reproducers/custom/JNLPClassLoaderDeadlock/testcases/JNLPClassLoaderDeadlockTest.java70
5 files changed, 214 insertions, 0 deletions
diff --git a/tests/reproducers/custom/JNLPClassLoaderDeadlock/resources/JNLPClassLoaderDeadlock.html b/tests/reproducers/custom/JNLPClassLoaderDeadlock/resources/JNLPClassLoaderDeadlock.html
new file mode 100644
index 0000000..3020b30
--- /dev/null
+++ b/tests/reproducers/custom/JNLPClassLoaderDeadlock/resources/JNLPClassLoaderDeadlock.html
@@ -0,0 +1,7 @@
+<html>
+<head></head>
+<body>
+<p><applet code="JNLPClassLoaderDeadlock_1.class" codebase="." width="384" height="32"></applet></p>
+<p><applet code="JNLPClassLoaderDeadlock_2.class" codebase="." width="512" height="512"></applet></p>
+</body>
+</html>
diff --git a/tests/reproducers/custom/JNLPClassLoaderDeadlock/srcs/JNLPClassLoaderDeadlock_1.java b/tests/reproducers/custom/JNLPClassLoaderDeadlock/srcs/JNLPClassLoaderDeadlock_1.java
new file mode 100644
index 0000000..616e5d3
--- /dev/null
+++ b/tests/reproducers/custom/JNLPClassLoaderDeadlock/srcs/JNLPClassLoaderDeadlock_1.java
@@ -0,0 +1,24 @@
+import java.applet.Applet;
+import java.awt.*;
+
+public class JNLPClassLoaderDeadlock_1 extends Applet {
+
+ @Override
+ public void init() {
+ System.out.println("JNLPClassLoaderDeadlock_1 applet initialized");
+ final String version = System.getProperty("java.version") + " (" + System.getProperty("java.vm.version") + ")";
+ final String vendor = System.getProperty("java.vendor");
+ final TextField tf = new TextField(40);
+ tf.setText(version + " -- " + vendor);
+ tf.setEditable(false);
+ tf.setBackground(Color.white);
+ setBackground(Color.white);
+ add(tf);
+ System.out.println("JNLPClassLoaderDeadlock_1 applet finished");
+ System.out.println("*** APPLET FINISHED ***");
+ }
+
+ public static void main(String[] args) {
+ new JNLPClassLoaderDeadlock_1().init();
+ }
+}
diff --git a/tests/reproducers/custom/JNLPClassLoaderDeadlock/srcs/JNLPClassLoaderDeadlock_2.java b/tests/reproducers/custom/JNLPClassLoaderDeadlock/srcs/JNLPClassLoaderDeadlock_2.java
new file mode 100644
index 0000000..6def405
--- /dev/null
+++ b/tests/reproducers/custom/JNLPClassLoaderDeadlock/srcs/JNLPClassLoaderDeadlock_2.java
@@ -0,0 +1,83 @@
+import java.applet.Applet;
+import java.awt.*;
+
+import java.security.*;
+import java.util.PropertyPermission;
+
+public class JNLPClassLoaderDeadlock_2 extends Applet implements Runnable {
+
+ private static final String propertyNames[] = {
+ "java.version",
+ "java.vendor",
+ "java.vendor.url",
+ "java.home",
+ "java.vm.specification.version",
+ "java.vm.specification.vendor",
+ "java.vm.specification.name",
+ "java.vm.version",
+ "java.vm.name",
+ "java.vm.home",
+ "java.specification.version",
+ "java.specification.vendor",
+ "java.specification.name",
+ "java.class.version",
+ "java.class.path",
+ "os.name",
+ "os.arch",
+ "os.version",
+ "file.separator",
+ "path.separator",
+ "line.separator",
+ "user.home",
+ "user.name",
+ "user.dir",
+ };
+
+ private Label[] propertyValues;
+
+ @Override
+ public void init() {
+ System.out.println("JNLPClassLoaderDeadlock_2 applet initialized");
+ GridBagLayout gridbaglayout = new GridBagLayout();
+ setLayout(gridbaglayout);
+
+ GridBagConstraints leftColumn = new GridBagConstraints();
+ leftColumn.anchor = 20;
+ leftColumn.ipadx = 16;
+
+ GridBagConstraints rightColumn = new GridBagConstraints();
+ rightColumn.fill = 2;
+ rightColumn.gridwidth = 0;
+ rightColumn.weightx = 1.0D;
+
+ Label labels[] = new Label[propertyNames.length];
+ propertyValues = new Label[propertyNames.length];
+ final String preloadText = "...";
+
+ for (int i = 0; i < propertyNames.length; ++i) {
+ labels[i] = new Label(propertyNames[i]);
+ gridbaglayout.setConstraints(labels[i], leftColumn);
+ add(labels[i]);
+
+ propertyValues[i] = new Label(preloadText);
+ gridbaglayout.setConstraints(propertyValues[i], rightColumn);
+ add(propertyValues[i]);
+ }
+
+ Thread t = new Thread(this);
+ t.start();
+ }
+
+ @Override
+ public void run() {
+ for (int i = 0; i < propertyNames.length; ++i) {
+ try {
+ final String propertyValue = System.getProperty(propertyNames[i]);
+ propertyValues[i].setText(propertyValue);
+ } catch (SecurityException securityexception) {
+ }
+ }
+ System.out.println("JNLPClassLoaderDeadlock_2 applet finished");
+ System.out.println("*** APPLET FINISHED ***");
+ }
+}
diff --git a/tests/reproducers/custom/JNLPClassLoaderDeadlock/srcs/Makefile b/tests/reproducers/custom/JNLPClassLoaderDeadlock/srcs/Makefile
new file mode 100644
index 0000000..15657da
--- /dev/null
+++ b/tests/reproducers/custom/JNLPClassLoaderDeadlock/srcs/Makefile
@@ -0,0 +1,30 @@
+TESTNAME=JNLPClassLoaderDeadlock
+
+SRC_FILES=JNLPClassLoaderDeadlock_1.java JNLPClassLoaderDeadlock_2.java
+RESOURCE_FILES=JNLPClassLoaderDeadlock.html
+ENTRYPOINT_CLASSES=JNLPClassLoaderDeadlock_1 JNLPClassLoaderDeadlock_2
+
+JAVAC_CLASSPATH=$(TEST_EXTENSIONS_DIR):$(NETX_DIR)/lib/classes.jar
+JAVAC=$(BOOT_DIR)/bin/javac
+JAR=$(BOOT_DIR)/bin/jar
+
+TMPDIR:=$(shell mktemp -d)
+
+prepare-reproducer:
+ echo PREPARING REPRODUCER $(TESTNAME)
+
+ $(JAVAC) -d $(TMPDIR) -classpath $(JAVAC_CLASSPATH) $(SRC_FILES)
+
+ cd ../resources; \
+ cp $(RESOURCE_FILES) $(REPRODUCERS_TESTS_SERVER_DEPLOYDIR); \
+ cd -; \
+ for CLASS in $(ENTRYPOINT_CLASSES); \
+ do \
+ mv $(TMPDIR)/"$$CLASS.class" $(REPRODUCERS_TESTS_SERVER_DEPLOYDIR); \
+ done; \
+
+ echo PREPARED REPRODUCER $(TESTNAME), removing $(TMPDIR)
+ rm -rf $(TMPDIR)
+
+clean-reproducer:
+ echo NOTHING TO CLEAN FOR $(TESTNAME)
diff --git a/tests/reproducers/custom/JNLPClassLoaderDeadlock/testcases/JNLPClassLoaderDeadlockTest.java b/tests/reproducers/custom/JNLPClassLoaderDeadlock/testcases/JNLPClassLoaderDeadlockTest.java
new file mode 100644
index 0000000..84b93d8
--- /dev/null
+++ b/tests/reproducers/custom/JNLPClassLoaderDeadlock/testcases/JNLPClassLoaderDeadlockTest.java
@@ -0,0 +1,70 @@
+/* JNLPClassLoaderDeadlockTest.java
+Copyright (C) 2013 Red Hat, Inc.
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as published by
+the Free Software Foundation, version 2.
+
+IcedTea is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+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.
+ */
+
+import net.sourceforge.jnlp.ProcessResult;
+import net.sourceforge.jnlp.ServerAccess.AutoClose;
+import net.sourceforge.jnlp.annotations.Bug;
+import net.sourceforge.jnlp.annotations.KnownToFail;
+import net.sourceforge.jnlp.annotations.NeedsDisplay;
+import net.sourceforge.jnlp.annotations.TestInBrowsers;
+import net.sourceforge.jnlp.browsertesting.BrowserTest;
+import net.sourceforge.jnlp.browsertesting.Browsers;
+import net.sourceforge.jnlp.closinglisteners.AutoOkClosingListener;
+
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+
+public class JNLPClassLoaderDeadlockTest extends BrowserTest {
+
+ @NeedsDisplay
+ @Test
+ @TestInBrowsers(testIn={Browsers.one})
+ @Bug(id="RH976833")
+ public void testClassLoaderDeadlock() throws Exception {
+ ProcessResult pr = server.executeBrowser("JNLPClassLoaderDeadlock.html", AutoClose.CLOSE_ON_CORRECT_END);
+ assertTrue("First applet should have initialized",
+ pr.stdout.contains("JNLPClassLoaderDeadlock_1 applet initialized"));
+ assertTrue("Second applet should have initialized",
+ pr.stdout.contains("JNLPClassLoaderDeadlock_2 applet initialized"));
+
+ assertTrue("First applet should have finished",
+ pr.stdout.contains("JNLPClassLoaderDeadlock_1 applet finished"));
+ assertTrue("Second applet should have finished",
+ pr.stdout.contains("JNLPClassLoaderDeadlock_2 applet finished"));
+ }
+
+}