Bug 40003 - Productize java_swt
Summary: Productize java_swt
Status: RESOLVED FIXED
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.0   Edit
Hardware: Macintosh Mac OS X - Carbon (unsup.)
: P3 normal with 1 vote (vote)
Target Milestone: 3.0 M9   Edit
Assignee: Andre Weinand CLA
QA Contact:
URL:
Whiteboard:
Keywords: readme
Depends on:
Blocks: 40178
  Show dependency tree
 
Reported: 2003-07-14 04:20 EDT by Andre Weinand CLA
Modified: 2009-04-17 01:52 EDT (History)
6 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andre Weinand CLA 2003-07-14 04:20:24 EDT
- write Readme entry
- get arguments from Info.plist (in addition to command line)
- get it more in line with /usr/bin/java
Comment 1 Andre Weinand CLA 2003-07-16 04:48:56 EDT
- add call to SetFrontProcess immediately after CPSEnableForegroundOperation
Comment 2 Andre Weinand CLA 2003-07-16 08:26:06 EDT
- file Radar bug against Apple
Comment 3 Andre Weinand CLA 2003-07-17 09:48:05 EDT
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.
Comment 4 Andre Weinand CLA 2003-08-05 09:00:13 EDT
[from McQ]
consider making java_swt part of the standalone Mac SWT drop.
Comment 5 Andre Weinand CLA 2003-09-16 12:56:40 EDT
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>
Comment 6 Andre Weinand CLA 2003-09-25 05:20:54 EDT
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.
Comment 7 Andre Weinand CLA 2003-09-25 05:22:45 EDT
BTW: the source for java_swt lives in project "platform-launcher", sub directory "library/carbon/
swt_launcher"
Comment 8 Andre Weinand CLA 2004-06-11 19:24:08 EDT
.