| SWT in Java WebStart App stopped working on OSX after upgrading to Java 7 [message #957764] |
Thu, 25 October 2012 09:21  |
Christian Niessner Messages: 5 Registered: October 2012 |
Junior Member |
|
|
Hi Forum-Readers,
i'm maintaining a JavaWS application using SWT for our company for quite a while now. I have reports that it stopped to work on Apple OSX computers, so i started digging into it.
It seems Apple has dropped their own Java 1.6 implementation and Oracle's Java 7 is now installed by default. An here the misery begins...
My app started to report the known "***WARNING: Display must be created on main thread due to Cocoa restrictions. / org.eclipse.swt.SWTException: Invalid thread access" issue. Okay, it seems that -XstartOnFirstThread works for Apple's 1.6 but not for Oracle's java 7?
After digging into it i found out that Oracle's implementation didn't do a restart with -XstartOnFirstThread during javaws init. The cause was that i've dropped signing the application's jnlp file due to some issues on the Microsoft platform. Don't care, i signed it again and next try - and i got one step further:
Java is now restarted with -XstartOnFirstThread, but then everything freezes up. It seems there is a massive problem bringing up the AWT/Swing subsystem because javaws launcher is sitting on the main thread and AWT also want's the main thread because of the same cause we want it for SWT...
My next try was to add an additional -Djava.awt.headless=true parameter, and at least everything comes up into my app - but i'm dying on the "Invalid thread access" issue again. I think the javaws starter or maybe AWT is still fooling around with the threads...
BTW: i just tried it with swt-4.2.1.
Anyone out there having the same issue or idea's what else i can try?
Thanks & Bye,
Chris
|
|
|
|
|
|
|
|
|
|
|
|
| Re: SWT in Java WebStart App stopped working on OSX after upgrading to Java 7 [message #982056 is a reply to message #977694] |
Mon, 12 November 2012 17:47   |
Dylan McReynolds Messages: 9 Registered: June 2011 |
Junior Member |
|
|
I have made some progress in my RCP application. Inside my implementation of IApplication.start(), I have (ignore the sloppy error handling for now):
if (SystemHelpers.isOSMac()) {
private boolean isDisplayBuilt = false;
try {
try {
Class<?> comAppleConcurrentDispatch = Class.forName("com.apple.concurrent.Dispatch");
Method getInstance = comAppleConcurrentDispatch.getMethod("getInstance", (Class<?>[]) null);
Object dispatchInstance = getInstance.invoke(null, (Object[]) null);
Method getNonBlockingMainQueueExecutor = dispatchInstance.getClass().getMethod("getNonBlockingMainQueueExecutor",(Class<?>[]) null);
Executor executor = (Executor) getNonBlockingMainQueueExecutor.invoke(dispatchInstance, (Object[]) null);
executor.execute(new Runnable() {
public void run() {
try {
if (display == null) {
display = PlatformUI.createDisplay();
PlatformUI.createAndRunWorkbench(display,
new MyWorkbenchAdvisor()); //my implementation of WorkbenchAdvisor
isDisplayBuilt = true;
}
} catch (Throwable t) {
//log error
}
}
});
} catch (Throwable t) {
//log error
}
SwingUtilities.invokeAndWait(new Runnable() {
@Override
public void run() {
while (isDisplayBuilt == false) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
//log error
}
}
}
});
} catch (Throwable t) {
//log error
}
Putting the AWT EventQueue thread to sleep was a pretty brutal way to go, but it was the only way I could figure out to wait to get the Display object initialized and b) get the non-blocking main queue executor to actually fire the run method.
But now I'm up against the next issue, which is that my application also uses the AWT_SWT bridge. The first time I try and get an AWT/Swing class running, I get the following:
(AppKit Thread) A org.eclipse.swt.SWTError object with a message of:
org.eclipse.swt.SWTError: Not implemented (java.lang.ClassNotFoundException: apple.awt.CEmbeddedFrame)
was generated in the following call stack:
at org.eclipse.swt.SWT.error(SWT.java:4109)
at org.eclipse.swt.SWT.error(SWT.java:3998)
at org.eclipse.swt.awt.SWT_AWT.new_Frame(SWT_AWT.java:145)
at com.lspeed.workbench.AstoriaNavigatorWindowAdvisor.prepareModalFrame(AstoriaNavigatorWindowAdvisor.java:416)
at com.lspeed.workbench.AstoriaNavigatorWindowAdvisor.createWindowContents(AstoriaNavigatorWindowAdvisor.java:325)
at org.eclipse.ui.internal.WorkbenchWindow.createContents(WorkbenchWindow.java:1016)
at org.eclipse.jface.window.Window.create(Window.java:431)
at org.eclipse.ui.internal.Workbench$22.runWithException(Workbench.java:1208)
at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:134)
at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3593)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3286)
at org.eclipse.ui.application.WorkbenchAdvisor.openWindows(WorkbenchAdvisor.java:803)
at org.eclipse.ui.internal.Workbench$31.runWithException(Workbench.java:1567)
at org.eclipse.ui.internal.StartupThreading$StartupRunnable.run(StartupThreading.java:31)
at org.eclipse.swt.widgets.Synchronizer.syncExec(Synchronizer.java:179)
at org.eclipse.ui.internal.UISynchronizer.syncExec(UISynchronizer.java:150)
at org.eclipse.swt.widgets.Display.syncExec(Display.java:4240)
at org.eclipse.ui.internal.StartupThreading.runWithoutExceptions(StartupThreading.java:94)
at org.eclipse.ui.internal.Workbench.init(Workbench.java:1562)
at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2567)
at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2438)
at org.eclipse.ui.internal.Workbench$7.run(Workbench.java:671)
at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332)
at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:664)
at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
at com.lspeed.workbench.AstoriaNavigatorApp$1.run(AstoriaNavigatorApp.java:84)
Caused by: java.lang.ClassNotFoundException: apple.awt.CEmbeddedFrame
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at org.eclipse.swt.awt.SWT_AWT.new_Frame(SWT_AWT.java:140)
... 25 more
due to the following cause:
This appears to come down to the reported bug in OpenJDK: http://www.java.net/forum/topic/jdk/java-se-snapshots-project-feedback/eclipse-swtawt-bridge-broken-mac-os-x-openjdk-7u4ea
I think I'm stuck there.
|
|
|
| Re: SWT in Java WebStart App stopped working on OSX after upgrading to Java 7 [message #986215 is a reply to message #982056] |
Mon, 19 November 2012 08:45   |
Christian Niessner Messages: 5 Registered: October 2012 |
Junior Member |
|
|
Dear Dylan,
sorry for the late reply, it seems i've missed the notification about your post.
I also had the issue with not starting the main thread via com.apple.concurrent.Dispatch as long as the JRE was not relaunched during JavaWS-Initialization. I enabled 'tracing' and 'logging' from java preferences and when it works right, you'll find two trace files in Library/Application Support/Oracle/Java/Deployment/log/javaws....trace for each application launch. The first one only tells that JRE is restarted and the second one does the 'real work'.
Look for lines like:
basic: DefaultMatchJRE:
JREDesc: JREDesc[version 0+, heap=-1--1, args=null, sel=true, com.sun.javaws.jnl.ResourcesDesc@5956ca9f, null]
JREInfo: JREInfo for index 0:
platform is: 1.7
product is: 1.7.0_09
location is: ht tp:// java.sun.com/products/autodl/j2se
path is: /Library/Internet Plug-ins/JavaAppletPlugin.plugin/Contents/Home/bin/java
args is: null
native platform is: Mac OS X, x86_64 [ x86_64, 64bit ]
JavaFX runtime is: JavaFX 2.2.3 found at /Library/Internet Plug-ins/JavaAppletPlugin.plugin/Contents/Home/
enabled is: true
registered is: true
system is: true
Init Heap: -1
Max Heap: 67108864
Satisfying: false, true
SatisfyingVersion: true
SatisfyingJVMArgs: false, true
SatisfyingSecure: false
Selected JVMParam: [JVMParameters: isSecure: false, args: -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true]
Running JVMParam: [JVMParameters: isSecure: true, args: ]
temp: Convert image: /Volumes/data/marvin/Library/Application Support/Oracle/Java/Deployment/cache/6.0/1/1dee1481-26720c99->/Volumes/data/user/Library/Application Support/Oracle/Java/Deployment/cache/6.0/1/1dee1481-26720c99.icns
basic: Saving session state to /var/folders/j_/403v_c_s3zzg5yrb2397fs240000gp/T/session7806841378132485821
================
basic: Launching new JRE version: JREInfo for index 0: <---- LOOK for this!
platform is: 1.7
product is: 1.7.0_09
location is: http:/ /java.sun.com/products/autodl/j2se
path is: /Library/Internet Plug-ins/JavaAppletPlugin.plugin/Contents/Home/bin/java
args is: null
native platform is: Mac OS X, x86_64 [ x86_64, 64bit ]
JavaFX runtime is: JavaFX 2.2.3 found at /Library/Internet Plug-ins/JavaAppletPlugin.plugin/Contents/Home/
enabled is: true
registered is: true
system is: true
basic: jvmParams: [JVMParameters: isSecure: false, args: -Dapple.laf.useScreenMenuBar=true -Dapple.awt.graphics.UseQuartz=true] <---- LOOK for this!
The idea to use SwingUtilities.invokeAndWait() could be quite interesting. I think Swing and AWT also want to use the first thread for the UI - so i think code started with SwingUtils.invokeAndWait() also could run on the right thread - have you tried to start your SWT app via SwingUtils.invokeAndWait()?
And for your issue with concurrently using AWT besides SWT: We don't use AWT in our app, so we didn't have issues yet - and all I say is guessed. Besides solfing your ClassNotFoundException issue, i think you also need to call the AWT and Swing event handlers from your main loop. All GUI activity on OSX has to be done from the first thread launched by an app - so all Toolkits need to be served from the same thread...
Maybe it might be worth having a look how things are managed by a offline app started with -XstartOnFirstThread - As far as i know concurrent AWT / Swing / SWT is possible here, so there has to be some kind of a 'master loop' calling SWT, AWT and Swing event handlers from first thread...
Hope this brings you further,
Bye,
Chris
|
|
|
| Re: SWT in Java WebStart App stopped working on OSX after upgrading to Java 7 [message #998868 is a reply to message #986215] |
Thu, 10 January 2013 16:25  |
Dylan McReynolds Messages: 9 Registered: June 2011 |
Junior Member |
|
|
Chris,
Thanks. I hadn't thought of starting up the app from the AWT thread...that's quite an interesting idea. Perhaps more graceful than putting it to sleep while waiing for the Dispatch Executor to get around to launching. I'll play with that when I've recovered from the next big blocker.
Just for posterity (if anyone else is reading this) it looks like SWT_AWT is still broken in Java 7 as of Update 10. The OpenJDK developers have provided a patch for Java 7 and Java 8 and SWT_AWT that depends on a new class, sun.lwat.macosx.CViewEmbeddedFrame. It would be pretty easy to patch SWT_AWT myself, I think, but I would want to wait until the new class and its dependencies have been delivered in OpenJDK.
|
|
|
Powered by
FUDForum. Page generated in 0.01956 seconds