You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
gentoo-overlay/dev-java/icedtea-web/files/fix-plugin-in-icedtea-7.patch

322 lines
13 KiB

# HG changeset patch
# User Denis Lila <dlila@redhat.com>
# Date 1304110685 14400
# Node ID 77640d74d21c2303b64bbc05583a3850db564894
# Parent f0647c9385358b4fc3fe747ba7b95b9117c2f681
Fix appcontext related plugin bugs.
diff -r f0647c938535 -r 77640d74d21c netx/net/sourceforge/jnlp/Launcher.java
--- a/netx/net/sourceforge/jnlp/Launcher.java Sat Jan 07 02:48:05 2012 -0500
+++ b/netx/net/sourceforge/jnlp/Launcher.java Fri Apr 29 16:58:05 2011 -0400
@@ -33,7 +33,6 @@
import net.sourceforge.jnlp.cache.CacheUtil;
import net.sourceforge.jnlp.cache.UpdatePolicy;
-import net.sourceforge.jnlp.runtime.AppThreadGroup;
import net.sourceforge.jnlp.runtime.AppletInstance;
import net.sourceforge.jnlp.runtime.ApplicationInstance;
import net.sourceforge.jnlp.runtime.JNLPClassLoader;
@@ -707,7 +706,7 @@
throw new ClassNotFoundException("Can't do a codebase look up and there are no jars. Failing sooner rather than later");
}
- AppThreadGroup group = (AppThreadGroup) Thread.currentThread().getThreadGroup();
+ ThreadGroup group = Thread.currentThread().getThreadGroup();
String appletName = file.getApplet().getMainClass();
@@ -723,7 +722,6 @@
else
appletInstance = new AppletInstance(file, group, loader, applet, cont);
- group.setApplication(appletInstance);
loader.setApplication(appletInstance);
setContextClassLoaderForAllThreads(appletInstance.getThreadGroup(), appletInstance.getClassLoader());
@@ -770,10 +768,9 @@
protected ApplicationInstance createApplication(JNLPFile file) throws LaunchException {
try {
JNLPClassLoader loader = JNLPClassLoader.getInstance(file, updatePolicy);
- AppThreadGroup group = (AppThreadGroup) Thread.currentThread().getThreadGroup();
+ ThreadGroup group = Thread.currentThread().getThreadGroup();
ApplicationInstance app = new ApplicationInstance(file, group, loader);
- group.setApplication(app);
loader.setApplication(app);
return app;
@@ -789,16 +786,16 @@
* then this method simply returns the existing ThreadGroup. The applet
* ThreadGroup has to be created at an earlier point in the applet code.
*/
- protected AppThreadGroup createThreadGroup(JNLPFile file) {
- AppThreadGroup appThreadGroup = null;
+ protected ThreadGroup createThreadGroup(JNLPFile file) {
+ ThreadGroup tg = null;
if (file instanceof PluginBridge) {
- appThreadGroup = (AppThreadGroup) Thread.currentThread().getThreadGroup();
+ tg = Thread.currentThread().getThreadGroup();
} else {
- appThreadGroup = new AppThreadGroup(mainGroup, file.getTitle());
+ tg = new ThreadGroup(mainGroup, file.getTitle());
}
- return appThreadGroup;
+ return tg;
}
/**
diff -r f0647c938535 -r 77640d74d21c netx/net/sourceforge/jnlp/NetxPanel.java
--- a/netx/net/sourceforge/jnlp/NetxPanel.java Sat Jan 07 02:48:05 2012 -0500
+++ b/netx/net/sourceforge/jnlp/NetxPanel.java Fri Apr 29 16:58:05 2011 -0400
@@ -23,12 +23,13 @@
package net.sourceforge.jnlp;
import net.sourceforge.jnlp.AppletLog;
-import net.sourceforge.jnlp.runtime.AppThreadGroup;
import net.sourceforge.jnlp.runtime.AppletInstance;
import net.sourceforge.jnlp.runtime.JNLPRuntime;
import java.net.URL;
import java.util.Hashtable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import sun.applet.AppletViewerPanel;
import sun.awt.SunToolkit;
@@ -44,9 +45,58 @@
private boolean exitOnFailure = true;
private AppletInstance appInst = null;
private boolean appletAlive;
+ private final String uKey;
+
+ // We use this so that we can create exactly one thread group
+ // for all panels with the same uKey.
+ private static final ConcurrentMap<String, ThreadGroup> uKeyToTG =
+ new ConcurrentHashMap<String, ThreadGroup>();
+
+ // This map is actually a set (unfortunately there is no ConcurrentSet
+ // in java.util.concurrent). If KEY is in this map, then we know that
+ // an app context has been created for the panel that has uKey.equals(KEY),
+ // so we avoid creating it a second time for panels with the same uKey.
+ // Because it's a set, only the keys matter. However, we can't insert
+ // null values in because if we did, we couldn't use null checks to see
+ // if a key was absent before a putIfAbsent.
+ private static final ConcurrentMap<String, Boolean> appContextCreated =
+ new ConcurrentHashMap<String, Boolean>();
public NetxPanel(URL documentURL, Hashtable<String, String> atts) {
super(documentURL, atts);
+
+ /* According to http://download.oracle.com/javase/6/docs/technotes/guides/deployment/deployment-guide/applet-compatibility.html,
+ * classloaders are shared iff these properties match:
+ * codebase, cache_archive, java_archive, archive
+ *
+ * To achieve this, we create the uniquekey based on those 4 values,
+ * always in the same order. The initial "<NAME>=" parts ensure a
+ * bad tag cannot trick the loader into getting shared with another.
+ */
+
+ // Firefox sometimes skips the codebase if it is default -- ".",
+ // so set it that way if absent
+ String codebaseAttr = atts.get("codebase") != null ?
+ atts.get("codebase") : ".";
+
+ String cache_archiveAttr = atts.get("cache_archive") != null ?
+ atts.get("cache_archive") : "";
+
+ String java_archiveAttr = atts.get("java_archive") != null ?
+ atts.get("java_archive") : "";
+
+ String archiveAttr = atts.get("archive") != null ?
+ atts.get("archive") : "";
+
+ this.uKey = "codebase=" + codebaseAttr +
+ "cache_archive=" + cache_archiveAttr +
+ "java_archive=" + java_archiveAttr +
+ "archive=" + archiveAttr;
+
+ // when this was being done (incorrectly) in Launcher, the call was
+ // new AppThreadGroup(mainGroup, file.getTitle());
+ ThreadGroup tg = new ThreadGroup(Launcher.mainGroup, this.documentURL.toString());
+ uKeyToTG.putIfAbsent(this.uKey, tg);
}
// overloaded constructor, called when initialized via plugin
@@ -58,18 +108,6 @@
}
@Override
- public void run() {
- /*
- * create an AppContext for this thread associated with this particular
- * plugin instance (which runs in a different thread group from the rest
- * of the plugin).
- */
- SunToolkit.createNewAppContext();
-
- super.run();
- }
-
- @Override
protected void showAppletException(Throwable t) {
/*
* Log any exceptions thrown while loading, initializing, starting,
@@ -78,7 +116,7 @@
AppletLog.log(t);
super.showAppletException(t);
}
-
+
//Overriding to use Netx classloader. You might need to relax visibility
//in sun.applet.AppletPanel for runLoader().
protected void runLoader() {
@@ -90,7 +128,7 @@
getCode(),
getWidth(),
getHeight(),
- atts);
+ atts, uKey);
doInit = true;
dispatchAppletEvent(APPLET_LOADING, null);
@@ -154,11 +192,7 @@
}
}
- // when this was being done (incorrectly) in Launcher, the call was
- // new AppThreadGroup(mainGroup, file.getTitle());
- ThreadGroup tg = new AppThreadGroup(Launcher.mainGroup,
- this.documentURL.toString());
- handler = new Thread(tg, this);
+ handler = new Thread(getThreadGroup(), this);
handler.start();
}
@@ -174,4 +208,19 @@
public boolean isAlive() {
return handler != null && handler.isAlive() && this.appletAlive;
}
+
+ public ThreadGroup getThreadGroup() {
+ return uKeyToTG.get(uKey);
+ }
+
+ public void createNewAppContext() {
+ if (Thread.currentThread().getThreadGroup() != getThreadGroup()) {
+ throw new RuntimeException("createNewAppContext called from the wrong thread.");
+ }
+ // only create a new context if one hasn't already been created for the
+ // applets with this unique key.
+ if (null == appContextCreated.putIfAbsent(uKey, Boolean.TRUE)) {
+ SunToolkit.createNewAppContext();
+ }
+ }
}
diff -r f0647c938535 -r 77640d74d21c netx/net/sourceforge/jnlp/PluginBridge.java
--- a/netx/net/sourceforge/jnlp/PluginBridge.java Sat Jan 07 02:48:05 2012 -0500
+++ b/netx/net/sourceforge/jnlp/PluginBridge.java Fri Apr 29 16:58:05 2011 -0400
@@ -44,7 +44,8 @@
private boolean codeBaseLookup;
public PluginBridge(URL codebase, URL documentBase, String jar, String main,
- int width, int height, Hashtable<String, String> atts)
+ int width, int height, Hashtable<String, String> atts,
+ String uKey)
throws Exception {
specVersion = new Version("1.0");
fileVersion = new Version("1.1");
@@ -132,34 +133,7 @@
else
security = null;
- /* According to http://download.oracle.com/javase/6/docs/technotes/guides/deployment/deployment-guide/applet-compatibility.html,
- * classloaders are shared iff these properties match:
- * codebase, cache_archive, java_archive, archive
- *
- * To achieve this, we create the uniquekey based on those 4 values,
- * always in the same order. The initial "<NAME>=" parts ensure a
- * bad tag cannot trick the loader into getting shared with another.
- */
-
- // Firefox sometimes skips the codebase if it is default -- ".",
- // so set it that way if absent
- String codebaseAttr = atts.get("codebase") != null ?
- atts.get("codebase") : ".";
-
- String cache_archiveAttr = atts.get("cache_archive") != null ?
- atts.get("cache_archive") : "";
-
- String java_archiveAttr = atts.get("java_archive") != null ?
- atts.get("java_archive") : "";
-
- String archiveAttr = atts.get("archive") != null ?
- atts.get("archive") : "";
-
- this.uniqueKey = "codebase=" + codebaseAttr +
- "cache_archive=" + cache_archiveAttr +
- "java_archive=" + java_archiveAttr +
- "archive=" + archiveAttr;
-
+ this.uniqueKey = uKey;
usePack = false;
useVersion = false;
String jargs = atts.get("java_arguments");
diff -r f0647c938535 -r 77640d74d21c plugin/icedteanp/java/sun/applet/PluginAppletViewer.java
--- a/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java Sat Jan 07 02:48:05 2012 -0500
+++ b/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java Fri Apr 29 16:58:05 2011 -0400
@@ -123,10 +123,10 @@
class PluginAppletPanelFactory {
public AppletPanel createPanel(PluginStreamHandler streamhandler,
- int identifier,
- long handle, int x, int y,
- final URL doc,
- final Hashtable<String, String> atts) {
+ final int identifier,
+ final long handle, int x, int y,
+ final URL doc,
+ final Hashtable<String, String> atts) {
final NetxPanel panel = AccessController.doPrivileged(new PrivilegedAction<NetxPanel>() {
public NetxPanel run() {
NetxPanel panel = new NetxPanel(doc, atts, false);
@@ -136,13 +136,29 @@
}
});
- // create the frame.
- PluginAppletViewer.framePanel(identifier, handle, panel);
+ // Framing the panel needs to happen in a thread whose thread group
+ // is the same as the threadgroup of the applet thread. If this
+ // isn't the case, the awt eventqueue thread's context classloader
+ // won't be set to a JNLPClassLoader, and when an applet class needs
+ // to be loaded from the awt eventqueue, it won't be found.
+ Thread panelInit = new Thread(panel.getThreadGroup(), new Runnable() {
+ @Override public void run() {
+ panel.createNewAppContext();
+ // create the frame.
+ PluginAppletViewer.framePanel(identifier, handle, panel);
+ panel.init();
+ // Start the applet
+ initEventQueue(panel);
+ }
+ }, "NetXPanel initializer");
- panel.init();
-
- // Start the applet
- initEventQueue(panel);
+ panelInit.start();
+ while(panelInit.isAlive()) {
+ try {
+ panelInit.join();
+ } catch (InterruptedException e) {
+ }
+ }
// Wait for the panel to initialize
PluginAppletViewer.waitForAppletInit(panel);