|
|
|
|
|
|
|
|
|
|
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 22: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 13:45 |
Christian Niessner Messages: 7 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 #1798266 is a reply to message #957764] |
Wed, 14 November 2018 17:30 |
Al Bundy Messages: 27 Registered: November 2011 |
Junior Member |
|
|
I've found a working solution - the trick seems to be to initialize awt before switching the thread.
On issue: I can not go to fullscreen. :-/
import java.awt.Toolkit;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
import java.util.concurrent.Executor;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.logging.ConsoleHandler;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class SWTTest
{
private static void log(final Object theMessage)
{
log(theMessage, null);
}
private static void log(final Object theMessage, final Throwable theError)
{
System.out.println("" + theMessage);
if (theError != null)
theError.printStackTrace(System.err);
Logger.getLogger("webstart_test").log(Level.INFO, "" + theMessage, theError);
}
public static void main(String[] args)
throws Exception
{
final Logger logger = Logger.getLogger("webstart_test");
final FileHandler logfile = new FileHandler("%h/webstart_test.log");
final ConsoleHandler console = new ConsoleHandler();
logfile.setFormatter(new SimpleFormatter());
console.setFormatter(new SimpleFormatter());
logger.addHandler(logfile);
logger.addHandler(console);
log("start");
String osName = System.getProperty("os.name");
log("OS: " + osName);
if (!osName.startsWith("Mac") && !osName.startsWith("Darwin"))
{
SWTTest.run();
}
else
{
try
{
Class<?> _c = Class.forName("com.apple.concurrent.Dispatch");
final Method _get_instance = _c.getMethod("getInstance", null);
final Object _instance = _get_instance.invoke(null, null);
final Method _get_executor = _instance.getClass().getMethod("getNonBlockingMainQueueExecutor", null);
final Executor _executor = (Executor) _get_executor.invoke(_instance, null);
Toolkit.getDefaultToolkit();
final FutureTask<Void> _f = new FutureTask<Void>(new Callable<Void>()
{
/**
* {@inheritDoc}
*/
@Override
public Void call()
throws Exception
{
log("Los gehts...");
SWTTest.run();
log("app fertig");
return null;
}
});
_executor.execute(_f);
_f.get();
TimeUnit.SECONDS.sleep(5);
log("main fertig");
}
catch (final Throwable _e)
{
log(_e.getMessage(), _e);
}
}
}
private static void run()
{
try
{
log("creating display");
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setText("Hello, world!");
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
catch (Exception _e)
{
log(_e.getMessage(), _e);
}
finally
{
log("bye....");
}
}
}
Attention: com.apple.concurrent.Dispatch was removed in Java 9 - so this seems to work only in java 8.
Or get the classes from: https://github.com/openjdk-mirror/jdk7u-jdk/tree/master/src/macosx/classes/com/apple/concurrent
Al
|
|
|
|
Powered by
FUDForum. Page generated in 0.03666 seconds