[icedtea-web] RFC: fix L&F issues with swing applications
Deepak Bhole
dbhole at redhat.com
Thu Mar 1 13:18:47 PST 2012
* Omair Majid <omajid at redhat.com> [2012-03-01 16:07]:
> Hi,
>
> The attached patch fixes a regression in icedtea-web 1.2 that occurs
> with some jnlp applications (such as
> http://www.soapui.org/jnlp/soapui.jnlp) where they are unable to set the
> look and feel for dialogs.
>
> The actual problem was not just limited to that. It turns out that we
> were not setting the right classloader for EventQueue - this classloader
> is used by EventQueue to obtain Look-and-Feel related classes (among
> other things). The only time to set this classloader is when the
> EventQueue is being created. And the EventQueue is created when a new
> AppContext is created, and the current context classloader of the thread
> is used.
>
> The attached patch (I have tried to keep it minimal) tires to fix this
> problem by creating the JNLPClassLoader as early as possible and then
> sets it as the context ClassLoader for jnlp applications.
>
> I suspect applets may be affected by similar issues, but I don't have a
> reproducer showing a problem and this patch doesn't change anything for
> them.
>
I am not sure how we could reproduce the problems with applets either. I
think we can overlook that situation for now.
The patch looks good to me. Assuming you have tested it, please push to
1.2 and HEAD.
Thanks!
Deepak
> Thoughts? Comments?
>
> Thanks,
> Omair
>
> diff --git a/netx/net/sourceforge/jnlp/Launcher.java b/netx/net/sourceforge/jnlp/Launcher.java
> --- a/netx/net/sourceforge/jnlp/Launcher.java
> +++ b/netx/net/sourceforge/jnlp/Launcher.java
> @@ -527,7 +527,7 @@
> * Launches a JNLP application. This method should be called
> * from a thread in the application's thread group.
> */
> - protected ApplicationInstance launchApplication(JNLPFile file) throws LaunchException {
> + protected ApplicationInstance launchApplication(JNLPClassLoader classLoader, JNLPFile file) throws LaunchException {
> if (!file.isApplication())
> throw launchError(new LaunchException(file, null, R("LSFatal"), R("LCClient"), R("LNotApplication"), R("LNotApplicationInfo")));
>
> @@ -549,7 +549,7 @@
>
> handler.launchInitialized(file);
>
> - ApplicationInstance app = createApplication(file);
> + ApplicationInstance app = createApplication(classLoader, file);
> app.initialize();
>
> String mainName = file.getApplication().getMainClass();
> @@ -600,7 +600,6 @@
> throw launchError(new LaunchException(file, ex, R("LSFatal"), R("LCLaunching"), R("LCouldNotLaunch"), R("LCouldNotLaunchInfo")));
> }
> }
> -
> /**
> * Set the classloader as the context classloader for all threads in
> * the given threadgroup. This is required to make some applications
> @@ -648,12 +647,12 @@
> * @param file the JNLP file
> * @param enableCodeBase whether to add the codebase URL to the classloader
> */
> - protected ApplicationInstance launchApplet(JNLPFile file, boolean enableCodeBase, Container cont) throws LaunchException {
> + protected ApplicationInstance launchApplet(JNLPClassLoader classLoader, JNLPFile file, boolean enableCodeBase, Container cont) throws LaunchException {
> if (!file.isApplet())
> throw launchError(new LaunchException(file, null, R("LSFatal"), R("LCClient"), R("LNotApplet"), R("LNotAppletInfo")));
>
> try {
> - AppletInstance applet = createApplet(file, enableCodeBase, cont);
> + AppletInstance applet = createApplet(classLoader, file, enableCodeBase, cont);
> applet.initialize();
>
> applet.getAppletEnvironment().startApplet(); // this should be a direct call to applet instance
> @@ -668,12 +667,12 @@
> /**
> * Gets an ApplicationInstance, but does not launch the applet.
> */
> - protected ApplicationInstance getApplet(JNLPFile file, boolean enableCodeBase, Container cont) throws LaunchException {
> + protected ApplicationInstance getApplet(JNLPClassLoader classLoader, JNLPFile file, boolean enableCodeBase, Container cont) throws LaunchException {
> if (!file.isApplet())
> throw launchError(new LaunchException(file, null, R("LSFatal"), R("LCClient"), R("LNotApplet"), R("LNotAppletInfo")));
>
> try {
> - AppletInstance applet = createApplet(file, enableCodeBase, cont);
> + AppletInstance applet = createApplet(classLoader, file, enableCodeBase, cont);
> applet.initialize();
> return applet;
> } catch (LaunchException lex) {
> @@ -687,7 +686,7 @@
> * Launches a JNLP installer. This method should be called from
> * a thread in the application's thread group.
> */
> - protected ApplicationInstance launchInstaller(JNLPFile file) throws LaunchException {
> + protected ApplicationInstance launchInstaller(JNLPClassLoader classLoader, JNLPFile file) throws LaunchException {
> throw launchError(new LaunchException(file, null, R("LSFatal"), R("LCNotSupported"), R("LNoInstallers"), R("LNoInstallersInfo")));
> }
>
> @@ -696,9 +695,9 @@
> *
> * @param enableCodeBase whether to add the code base URL to the classloader
> */
> - protected AppletInstance createApplet(JNLPFile file, boolean enableCodeBase, Container cont) throws LaunchException {
> + protected AppletInstance createApplet(JNLPClassLoader classLoader, JNLPFile file, boolean enableCodeBase, Container cont) throws LaunchException {
> try {
> - JNLPClassLoader loader = JNLPClassLoader.getInstance(file, updatePolicy);
> + JNLPClassLoader loader = classLoader;
>
> if (enableCodeBase) {
> loader.enableCodeBase();
> @@ -742,9 +741,9 @@
> * @param file the PluginBridge to be used.
> * @param enableCodeBase whether to add the code base URL to the classloader.
> */
> - protected Applet createAppletObject(JNLPFile file, boolean enableCodeBase, Container cont) throws LaunchException {
> + protected Applet createAppletObject(JNLPClassLoader classLoader, JNLPFile file, boolean enableCodeBase, Container cont) throws LaunchException {
> try {
> - JNLPClassLoader loader = JNLPClassLoader.getInstance(file, updatePolicy);
> + JNLPClassLoader loader = classLoader;
>
> if (enableCodeBase) {
> loader.enableCodeBase();
> @@ -765,9 +764,9 @@
> /**
> * Creates an Application.
> */
> - protected ApplicationInstance createApplication(JNLPFile file) throws LaunchException {
> + protected ApplicationInstance createApplication(JNLPClassLoader classLoader, JNLPFile file) throws LaunchException {
> try {
> - JNLPClassLoader loader = JNLPClassLoader.getInstance(file, updatePolicy);
> + JNLPClassLoader loader = classLoader;
> ThreadGroup group = Thread.currentThread().getThreadGroup();
>
> ApplicationInstance app = new ApplicationInstance(file, group, loader);
> @@ -873,24 +872,31 @@
>
> public void run() {
> try {
> + if (isPlugin) {
> + // Do not display download indicators if we're using gcjwebplugin.
> + JNLPRuntime.setDefaultDownloadIndicator(null);
> + }
> +
> + JNLPClassLoader classLoader = JNLPClassLoader.getInstance(file, updatePolicy);
> +
> // Do not create new AppContext if we're using NetX and icedteaplugin.
> // The plugin needs an AppContext too, but it has to be created earlier.
> - if (context && !isPlugin)
> + if (context && !isPlugin) {
> + setContextClassLoader(classLoader);
> SunToolkit.createNewAppContext();
> + }
>
> doPerApplicationAppContextHacks();
>
> if (isPlugin) {
> - // Do not display download indicators if we're using gcjwebplugin.
> - JNLPRuntime.setDefaultDownloadIndicator(null);
> - application = getApplet(file, ((PluginBridge)file).codeBaseLookup(), cont);
> + application = getApplet(classLoader, file, ((PluginBridge)file).codeBaseLookup(), cont);
> } else {
> if (file.isApplication())
> - application = launchApplication(file);
> + application = launchApplication(classLoader, file);
> else if (file.isApplet())
> - application = launchApplet(file, true, cont); // enable applet code base
> + application = launchApplet(classLoader, file, true, cont); // enable applet code base
> else if (file.isInstaller())
> - application = launchInstaller(file);
> + application = launchInstaller(classLoader, file);
> else
> throw launchError(new LaunchException(file, null,
> R("LSFatal"), R("LCClient"), R("LNotLaunchable"),
More information about the distro-pkg-dev
mailing list