Community
Participate
Working Groups
- write Readme entry - get arguments from Info.plist (in addition to command line) - get it more in line with /usr/bin/java
- add call to SetFrontProcess immediately after CPSEnableForegroundOperation
- file Radar bug against Apple
Here is the story why SWT application needs a special launcher on MacOS X. [I posted this on the SWT mailing list]: The problem is neither SWT nor Eclipse, it's /usr/bin/java (and its bundle cousin "JavaApplicationStub"; the JavaApplicationStub extracts the arguments from the Info.plist file instead of from the command line). /usr/bin/java (and JavaApplicationStub) starts the Java VM in the second thread because it runs an event loop in the first thread (the "Main" thread), and assumes that the Java code (in any thread) behind the scene communicates with the event loop in the Main thread. But this assumption breaks with SWT because it uses code (Carbon and Cocoa natives) that normally runs in the main thread and knows nothing about the fact that another event loop is already running. [BTW, I will file a Radar bug against this behavior of /usr/bin/java since it prevents running Java code in the "main" thread] So the only fix for this is a replacement for /usr/bin/java (and the "JavaApplicationStub") that runs no additional event loop in the main thread but starts the Java VM there. This is java_swt. OK, this was the theory. Some caveats: - for Java 1.3.1 "JavaApplicationStub" contained some workarounds to avoid the deadlocks, so with it Eclipse would run without problems as long as started from the bundle (via JavaApplicationStub ) and not from /usr/bin/java. (that's the reason why the launcher always creates a bundle on the fly instead of using /usr/bin/java) - after installing any version of 1.4.1, the "JavaApplicationStub" was replaced with a version without the workaround (for all VM versions including 1.3.1 !). As a consequence, I had to adapt Eclipse's MacOS X launcher (org.eclipse.jdt.launching.macosx) to continue using the old version of the "JavaApplicationStub" (by shipping a copy of it). - this copy no longer seems to work under Panther. That's the reason why launching Eclipse under 1.3.1 on Panther fails. I haven't tried to find the cause of this, because Panther is scheduled for the end of this year, with 1.4.1 as default VM, and Eclipse will switch to 1.4.1 in September. So there is probably not a great need for running Eclipse on 1.3.1 on Panther. - my new Java VM launcher "java_swt" is only activated if a 1.4.1 VM is selected in the Info.plist file. Otherwise, the old 1.3.1 code is used. This is done because I didn't want to fix something (1.3.1) that wasn't broken in Jaguar. (However, in Panther it is broken...) - I understand that it would make sense to run SWT applications (which don't require 1.4.1) on Panther and a 1.3.1 VM. I believe that my fix (the java_swt launcher) will work under 1.3.1 too. I just have to find the time to verify it.
[from McQ] consider making java_swt part of the standalone Mac SWT drop.
for M3 java_swt supports to live within a (double clickable) application bundle. In this case java_swt extracts its arguments from the bundle's info.plist file. It uses the syntax described here: http://developer.apple.com/documentation/Java/Reference/ Java141JavaDict/index.html Since Eclipse doesn't (yet) support to create application bundles automatically, here are the necessary steps to produce a double-clickable SWT application: - create this directory structure (it uses '/' and '*' to show the type of files like "ls -F") MyApp.app/ Contents/ Info.plist MacOS/ java_swt* PkgInfo Resources/ MyApp.icns Java/ dll/ libswt-carbon-XXXX.jnilib MyApp.jar swt.jar - file PkgInfo contains just the 8 characters 'APPL????' - MyApp.icns is a 128x128 icon - swt.jar contains the Java part of SWT; you can copy it from the org.eclipse.swt.carbon project - libswt-carbon-XXXX.jnilib is the corresponding dll; copy it from org.eclipse.swt.carbon too - MyApp.class is the jar archive containing your app's code (including its main class) - Info.plist is the following: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/ PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>CFBundleExecutable</key> <string>java_swt</string> <key>CFBundleGetInfoString</key> <string>MyApp, Copyright MyApp Corp. 2003. All rights reserved.</string> <key>CFBundleIconFile</key> <string>MyApp.icns</string> <key>CFBundleIdentifier</key> <string>org.myapp.myapp</string> <key>CFBundleInfoDictionaryVersion</key> <string>6.0</string> <key>CFBundleName</key> <string>MyApp</string> <key>CFBundlePackageType</key> <string>APPL</string> <key>CFBundleShortVersionString</key> <string>3.0</string> <key>CFBundleSignature</key> <string>????</string> <key>CFBundleVersion</key> <string>3.0</string> <key>Java</key> <dict> <key>ClassPath</key> <string>$JAVAROOT/swt.jar:$JAVAROOT/MyApp.jar</string> <key>MainClass</key> <string>org.myapp.Main</string> <key>VMOptions</key> <string>-Djava.library.path=$JAVAROOT/dll</string> </dict> </dict> </plist>
Another tidbit for using SWT and AWT in the same application (I've posted this on 9/18 on the news group eclipse.platform.swt): The problem with using AWT in a SWT application is, that whenever you use any AWT class the Mac OS X implementation of AWT goes through an initialization sequence that sets up the menu bar and adds an icon to the Dock. The assumption here is that whenever you use AWT your application automatically becomes an UI application. On the Mac a consequence of this is that your application starts an event loop. However, if you are an SWT application, another event loop is already running. This results in a deadlock. The good news: I found a workaround: In Java 1.4.1 AWT supports a so called "headless" mode, in which it does not initialize the UI (and does not create the event loop). In this mode you'll get java.awt.HeadlessExceptions if you try to create UI elements like Buttons etc. However, working with BufferedImages does not require a UI and works fine. You'll just have to pass a "-Djava.awt.headless=true" command line argument to your application or call the following just before loading AWT: System.setProperty("java.awt.headless", "true"); and your code no longer deadlocks.
BTW: the source for java_swt lives in project "platform-launcher", sub directory "library/carbon/ swt_launcher"
.