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.
322 lines
13 KiB
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);
|
|
|