Deploy SWT App as .jar on Windows and Linux

SWT Designer allows you to create the views, editors, perspectives, pref pages, composites, etc. that comprise Eclipse SWT & RCP applications and plug-ins.

Moderators: Konstantin.Scheglov, gnebling, Alexander.Mitin, jwren, Eric Clayberg

Deploy SWT App as .jar on Windows and Linux

Postby cochand » Mon Jul 18, 2005 12:57 pm

I've built a SWT Application Window app using Eclipse and SWT Designer. Now I want to wrap that up in a jar (or whatever is appropriate) and test it from the users point of view on Windows and Linux. I'd like to smply give someone a jar and tell them how to easily run it. I would've thought the process would be obvious, but apparently it isn't.

I've read some of the other older posts in this group, and I've gone to eclipse.org, without finding much help.

Please point me to the help. What are the fundamental steps for deploying a typical SWT application?

Thanks.
cochand
 
Posts: 17
Joined: Wed Jul 06, 2005 1:20 pm

Postby Slot Head » Mon Jul 18, 2005 4:05 pm

I sure hope you get a good response to this.

I've got a very similar question and perhaps what's written below will help you some. The following is a post I made on eclipse.org's SWT forum. I have gotten only one response to this, and it was "...maybe eclipse doesn't work... go use a command line utility from Sun." Not happy with that.

They say they want you to do your homework, check FAQ's use google, research old posts, etc., before posting at eclipse.org. Ironically, the better of a job you do, the less response you get, while the experts there happily answer really lazy questions like "where can I find a tutorial?" (which should take 5 seconds on google).

I have a lot more confidence in this forum and will probably post the following here after I do a little more research. I would even hope that after we iron this out, instantiations would make it one of their articles.

The one thing I can be pretty confident about is this: if you use Eclipse 3.0.1 or 3.0.2 and follow my recipe below, you will succeed.

If, however, you're determined to wrap your app and the SWT/JFace libs all into one SINGLE jar, you should know there's a utility out there that claims to do this. I think it's at http://one-jar.sourceforge.net/. I tried it briefly and didn't like how slowly it ran (i.e., how long it took to build the single jar). It is a cool idea and probably worth another look. Please report back any findings here.

==============

***BACKGROUND
In eclipse 3.0.x, we used the File, Export Jar function to make a jar file
of our app. We used a manifest file that specified the main class and had
a Class-Path stmt that specified SWT/JFace support jars. We successfully
deployed those jars in a lib folder beneath the app folder on various
Windows 2000 and XP machines. (We also installed the SWT support DLL,
JDBC drivers and various other support files that probably aren't relevant
to this problem.)

The manifest file looked like this:

Manifest-Version: 1.0
Main-Class: com.companyname.pkgname.etc.MainWindow
Class-Path: lib\swt.jar lib\jface.jar lib\runtime.jar lib\jfacetext.jar
lib\osgi.jar lib\text.jar

(The Class-Path line in the actual file was one line.)

This all worked well.

***NEW SITUATION

Now, with Eclipse 3.1, the above jars are renamed in a better, more
consistent way that includes version numbers. The new file names are
considerably longer - 170 characters total - so fitting them all on one
line may be a concern.

Obviously, we need to restructure our jar building process a bit. We've
done that in too many ways to list here, but would be happy to enumerate,
if asked.


***PROBLEM

1. After days of trying, we can't build a jar file that works. Every jar
we build causes the JVM Launcher to fail with "Could not find main class."

2. When launching on a command line with:
java -jar appname.jar
the error message is:

Exception in thread "main" java.lang.NoClassDefFoundError:
org/eclipse/jface/window/ApplicationWindow
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
at java.security.SecureClassLoader.defineClass
(SecureClassLoader.java:124)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
at java.net.URLClassLoader.access$100(URLClassLoader.java:56)
at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:268)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)

(The above is a test of a stripped down app. It's a blank JFace
ApplicationWindow and nothing else. This was to make sure 3rd party libs
weren't the issue)

***QUESTIONS

1. Any thoughts on what's wrong here?

2. Is the list of libraries to support SWT and JFace different with 3.1?

3. With Eclipse 3.1, has anyone succeeded in using File, Export Jar to
make a jar that they simply doubled click on, and it ran in Windows?


TIA, all responses appreciated!

=============

***FURTHER COMMENTS

1. In case you're interested, we used zerog.com's InstallAnywhere. It's pretty cool because it is very java friendly and will even install a JVM. This produced the easy, seamless, shrink-wrap kind of installation experience we sought: everything including Java gets installed simply running one setup.exe, and they're supposed to work for platforms other than win32 as well. The only issues we have with IA are:
* We now have to upgrade to v7.x to get java 1.5 support.
* They are pricey.


2. When you use SWT-Designer to build a JFace app, you can look in the Package Explorer and see what libs it puts into the Java Build Path for you:

org.eclipse.core.runtime_3.1.0.jar
org.eclipse.jface.text_3.1.0.jar
org.eclipse.jface_3.1.0.jar
org.eclipse.osgi_3.1.0.jar
org.eclipse.swt.win32.win32.x86_3.1.0.jar
org.eclipse.ui.forms_3.1.0.jar
org.eclipse.ui.workbench_3.1.0.jar

These files can all be found in the root of the plug-ins folder. So if that's what it takes to compile, maybe it's what is needed to run??? (though I have some doubts and other thoughts I won't go into here for now).

So, I tried copying them all to a lib folder under my app, edited the manifest file accordingly, and built a jar using File, Export Jar. So far, that hasn't worked either.

I come from the win32 world where I would have solved this problem long ago using some utility (like depends.exe provided by MS) to identify the various libraries (DLL's) I need to ship. I wonder: is there such a utility in the Java world?
Slot Head
 
Posts: 36
Joined: Sun Jul 10, 2005 9:50 am

Postby cochand » Mon Jul 18, 2005 7:43 pm

Thanks for the thoughts. I'm trying to figure out what's going on here. Eric will save us! :D

I'm not stuck on it being jar. Whatever works is fine with me, at least based on my current understanding of deploying Java apps.

My assumption is that I'm missing something very simple. Instantations and SWT Designer must know very straightforward steps to deploying and running SWT Designer built apps on Windows and Linux, otherwise I'm confused as to how people use SWT Designer to build working apps. I'm feeling pretty dumb right now.
cochand
 
Posts: 17
Joined: Wed Jul 06, 2005 1:20 pm

Postby cochand » Mon Jul 18, 2005 8:14 pm

Perhaps we need to create our own Makefile?
cochand
 
Posts: 17
Joined: Wed Jul 06, 2005 1:20 pm

Postby Kelly » Tue Jul 19, 2005 4:38 am

I only put the project into a jar file, have never tried putting the complete thing into a jar file.

Here is what I do to get a zip file that can be given to another person. They have to have Java installed.

This may not be the correct way but it works for me.

1. create a directory for your package, not in your workspace.
c:\mypackage
2. copy any jar files from the eclipse plugin directory that you are using to c:\mypackage. for example.
org.eclipse.core.boot_3.1.0.jar
org.eclipse.core.runtime_3.1.0.jar
org.eclipse.jface.text_3.1.0.jar
org.eclipse.jface_3.1.0.jar
org.eclipse.osgi_3.1.0.jar
org.eclipse.swt.win32.win32.x86_3.1.0.jar
org.eclipse.swt_3.1.0.jar
swt-gdp-win32-3138.dll
swt-win32-3138.dll

3. copy any other jars or DLL files you are using to the c:\mypackage directory

4. create a manifest.mf file in your eclipse project directory, like c:\workspace\myproject\manifest.mf

5. place into the manifest.mf file the following lines.
Manifest-Version: 1.0
Class-Path: org.eclipse.swt.win32.win32.x86_3.1.0.jar org.eclipse.swt_3.1.0.jar org.eclipse.core.runtime_3.1.0.jar org.eclipse.jface_3.1.0.jar
Main-Class: com.MyMain

The version can be any number you like I am guessing.
The Class-Path must contain all jar files you are using in your project. They must be all on one line, sadly this true :(
You can create directories in the c:\mypackage directory if you like to hold other jars, just make sure the path is in the Class-Path and be sure to use the widows directory seperator '\' relative to your c:\mypackage directory like.
myotherjars\other.jar
The Main-Class must point to the class that contains you main method.

6. In eclipse highlight and right click your project and execute the File->export menu command.
7. select 'Jar File' click 'Next'
8. uncheck any files you do not want in your jar file.
8a. select the export destination of c:\mypackage\myjar.jar
8b. use options 'Compress contents of jar file' and 'Overwrite existing file without warning'
8c. click 'Next'
9. select options about exporting classes with warnings and errors, this is up to you really.
10. click 'Next'
11. select 'Use existing manifest from workspace'
12. type into the space something like 'myproject/manifest.mf'
13. click 'Finish'

This should create a myjar.jar file in the c:\mypackage directory.
If it fails and tells you a file is out of sync then use the 'Refresh' option on that file in the eclipse program.
right-click on file and use 'Refresh' menu item or 'F5'

14. create a batch file in the c:\myprackage\mypackage.bat and place in it the following lines

java -Djava.library.path=. -jar myjar.jar

I do not mess with the CLASSPATH evironment variable because the manifest file CLASS-PATH seems to over ride it anyway.

Now you can use winzip or whatever zip program you like to create a zip file of the c:\mypackage directory.

I hope this helps and you can understand my poor instructions.
Kelly
 
Posts: 38
Joined: Wed Feb 02, 2005 8:22 am

Postby cochand » Tue Jul 19, 2005 6:08 am

Kelly is a hero! Her 14 step process works.

I did need to copy swt-win32-3138.dll from ...\eclipse\configuration\org.eclipse.osgi\bundles\64\1.cp to the c:\mypackage (as Kelly refers to it) directory.

I wonder if that means I'll have to copy a Linux dll to the "deploy" directory as well. I guess any supported platform will need to include that dll in the zip file?

Additionally, I had a few problems getting the correct manifest. I had to let the JAR Export routine Generate the manifest file and then run the export again and Use existing manifest from workspace. I'm a little fuzzy on exactly what was wrong here. If I get a better understanding, I'll post it.
cochand
 
Posts: 17
Joined: Wed Jul 06, 2005 1:20 pm

Postby Kelly » Tue Jul 19, 2005 11:38 am

I am happy that it was some help to you.

The swt???.dll files can also be found in the plugins\org.eclipse.swt.win32.win32.x86_3.1.0.jar file use winzip to extract them.

Eclipse seems to have some memory in that if eclipse did not create it in the workspace it knows nothing about it, which is a curse and a blessing at times. I use the 'Refresh' option in eclipse to get files I placed thier to show up.

Not sure about using DLL files under Linux, I use FreeBSD and have not ported my project to UNIX yet.
Kelly
 
Posts: 38
Joined: Wed Feb 02, 2005 8:22 am

Extra space causes File, Export Jar to fail

Postby Slot Head » Wed Jul 20, 2005 8:44 am

Kudos to Kelly for the excellent description.

My team discovered a subtle but deadly bug in Eclipse's File, Export, Jar function which was killing us (see my earlier post in this thread).

The bug is this: I put an extra space at the end of this line in my manifest file:
Main-Class: com.domain.test.MainWindow

That was all it took to cause utter failure. The jar file simply wouldn't run. Removing the space made everything work.

This was driving me nuts, so I did what any manager would do: make it somebody else's problem. Luckily for me that somebody is a really sharp developer (Eric H.: you da man!).

This has been reported as Bugzilla Bug 104525 at eclipse.org. It will be interesting to see what level of denial the eclipse people will come up with, but we have proven beyond a shadow of a doubt on mulitple systems that we make this fail or succeed by adding or removing that one little space character.
Slot Head
 
Posts: 36
Joined: Sun Jul 10, 2005 9:50 am

Postby Slot Head » Wed Jul 20, 2005 10:20 am

Here's an attempt at a demo and recommended procedure for non-experts. All comments and criticism will be appreciated.

You will need to have SWT-Designer installed on Eclipse 3.1. Since this is geared toward win32 types, watch out for what direction your slashes lean!

JFace App Building and Deployment Demo and Recommended Guidelines for Win32 Environment

1. From the File menu, select New, Project, Designer, SWT/JFace Java Project.

2. From the File menu, select New, Other, Designer, JFace ApplicationWindow. Name this class MainWindow.

3. Make sure the above runs.

4. Under your project's folder, create a folder named lib.

5. In the lib folder put the following files, all of which can be found in the {ECLIPSE}\plugins folder:
org.eclipse.swt.win32.win32.x86_3.1.0.jar
org.eclipse.swt_3.1.0.jar
org.eclipse.jface_3.1.0.jar
org.eclipse.core.runtime_3.1.0.jar

6. In the project folder, create a file named manifest.txt. Make it look like this:
Manifest-Version: 1.0
Main-Class: MainWindow
Class-Path: lib\org.eclipse.swt.win32.win32.x86_3.1.0.jar lib\org.eclipse.swt_3.1.0.jar lib\org.eclipse.jface_3.1.0.jar lib\org.eclipse.core.runtime_3.1.0.jar

7. Make sure the above Class-Path line is just one (long) line! Including additional Class-Path lines seems to result in all but the last one getting ignored.

8. The libs included in the lib and the Class-Path statement were empirically determined to be the minimum required for this simplistic JFace demo app. As your app grows, expect other libraries to be needed. These may include:
org.eclipse.osgi_3.1.0.jar
org.eclipse.jface.text_3.1.0.jar
org.eclipse.text_3.1.0.jar

And, you may also want to add 3rd party libs like jdom.jar, JDBC database drivers, etc. The max allowed length of the Class-Path line is unknown by this developer and is an obvious concern, especially now that eclipse.org greatly lengthened the names of these libs! If anyone determines this max length, please report it back here.

9. In the Main-Class line above, make sure there is no extra white space following the name of the class! This has been reported as an eclipse bug which will cause the JVM launcher to not find it and fail. Also, notice this demo uses the "default package" which is not a recommended practice for real apps. Better would be to organize your app into packages. For example, com.yourdomain.appname.gui.MainWindow. All of that would need to be spelled out in the Main-Class line. In general, assume the processing of the manifest file is archaicly picky and unrobust. Make sure capitalization, syntax, etc. is as shown above.

10. Locate the SWT support DLL for eclipse 3.1: swt-win32-3138.dll. This can be found in C:\eclipse\configuration\org.eclipse.osgi\bundles\63\1\.cp (they don't make these too easy to find, do they?). To do anything in eclipse, you or somebody else probably already had to install this somewhere. Here, it is recommended that you also put it in your app folder so you can test it with your app, back it up easily with your app, and so you don't forget to deploy it. You might even consider putting this only in each project's folder so you don't have the dll hell uncertainty of multiple copies of dll's all over the place.

11. In Eclipse, from the File menu, select Export, Jar file. Select Next to enter the Jar Package Specification dialog.

12. Put checkmarks only in the following:
The src folder for your project.
Export generated class files and resources
Compress the contents of the JAR file

13. Click on Browse to define a jar file name and location for your app. Appname.jar located in your project's folder is suggested.

14. Click Next to enter the JAR Packaging Options screen. Choose options you want. Don't forget to put a check mark in Export class files with warnings if you have any warnings, which are easy enough to get, especially with the 1.5 jdk and 5.0 compliance.

15. Click on Next to enter the JAR Manifest Specification screen.

16. Select Use existing manifest from workspace. Browse to select the manifext.txt file prepared above.

17. Click on Finish.

18. In Windows Explorer (not eclipse), double click on the jar file. It should run. If a "Could not find main class..." message box appears, it doesn't necessarily mean your main class (MainWindow) is missing, it just means something in general is wrong. Chances are what really happened is it did find your MainWindow class (and the obligatory public static void main(String args[]) method within it), but some dependent class thwarted proper loading.

19. Troubleshooting. All jar files are really just zip files. Examine the contents of your jar file using WinZip. The manifest.mf file in there should look like the manifest.txt you provided above. You should see your MainWindow.class in there.

20. Another way to test your jar file is to run it via java. In a command window or batch file, run this:
java -jar appname.jar
The nice thing about this is that it will give you slightly better information if it fails and you can use parameters to set the amount of memory the JVM gets, etc.
Notice also the -cp parameter as another way of specifying class path. For a quick list of parameters, simply type java and hit enter.

21. Deployment. After making sure your jar file runs, deploy as follows:
a. Put jar file and swt-win32-3138.dll in target folder. Alternatively, put the dll in system32 or somewhere else on PATH.
b. Put lib folder beneath the above.
c. Create icon to run jar file. By default, windows maps jar files to the JVM launcher, but the java command line mentioned above has its advantages.

22. Use of CLASSPATH environment variable. Since this is global to the target system and can be updated by anybody's installer/app, this developer is recommending against using or depending on this. If you used it and then another app came along and updated it, your specs within it may get pushed to back of the line and guess who gets a phone call at 3:00 am? Getting CLASSPATH stripped down to as little as possible or nothing at all is offered for consideration.
Slot Head
 
Posts: 36
Joined: Sun Jul 10, 2005 9:50 am


Return to SWT Designer

Who is online

Users browsing this forum: No registered users and 1 guest