Alex headshot

AlBlue’s Blog

Macs, Modularity and More

Writing and running SWT applications

2006, eclipse, swt

Eclipse can be used to develop and run SWT applciations, and once you've written an SWT application, you can launch it with a quick keystroke (Alt+Shift+X S). The nice thing about this is that the launch configuration will automatically add the appropriate native SWT libraries to the path when run with this method, but not the Java libraries.

This makes sense; when compiling a Java program, you need to have the SWT libraries defined on the classpath in order to compile the code, so they're there anyway when the code is run. Most developers will have at some point dug into the Eclipse plugins directory (either using an absolute path or an extension of the ECLIPSE_HOME variable) to link to both the generic and platform-specific org.eclipse.swt Jar.

The problem with linking to Eclipse's internal SWT plugin is that it's pretty fragile. Obviously, you're defining the project in terms of a specific operating system (so a project with a _win32 in the classpath won't work when you edit it on the Mac) but also you're locked to a specific version, which is likely to become dated. My Mac application for 3.1 has 3.1.0 for the generic SWT Jar, and 3.1.1 for the PPC bindings. Obviously, the 3.2 install has 3.2.0, but now it uses a build ID v320.

The net effect is that referring to any specific version of a Jar is probably going to lead to fragile SWT application development. There is a solution though that can solve the problem: user libraries. This allows you to define a classpath container (like the JRE_LIB) with a preset list of Jars, but only refer to it by name. As long as this library is defined on any system, your project should be able to refer to just a dependency on SWT and that's it.

To define a user library, go to the Window - Preferences, and then navigate to Java/Build Path/User Libraries. You can then click New, and call it SWT. Now select the SWT library, and do Add JARs, and then select the appropriate Jars from the Eclipse plugin install. Having done that once, you can now add this to any project that requires the SWT libraries. Simply edit the project's build path (in 3.2, you can right-click on the project and do Build Path - Add Libraries) and choose User Libraries from the list. You can then select the newly created SWT library, and the necessary Jars are automatically part of the build path. The nice thing about this approach is you have exactly one, portable entry (both OS and Eclipse version) in the .classpath, which makes it nice and sharable in a team repository: <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/SWT"/>. (By the way, the difference between a user library and a variable is that a user library can contain many individual JARs, whereas a classpath variable can only refer to one JAR or a directory; they both have their uses. A user library is implemented with something called a classpath container, so you might hear that term too.)

You'll still need to run the application as an SWT app (to get the native libraries on the path) but at least now you'll have a portable way of representing the Java libraries.

Personally, I think it would be great if 3.2 had a pre-defined library called SWT, but even though the Run As SWT Application is part of the JDT, it doesn't look like providing the user library SWT will be. Vote for bug 138792 if you think this would be a good idea.

By the way, there are a lot of new 'execution environments' in 3.2 that you can define on your Java projects now, instead of JRE_LIB. You can define a new Java project, and replace the JRE with an execution environment like OSGi/Minimum 1.0 or CDC-1.1/Foundation-1.1. The idea is that you can build an OSGi portable application and run it in an Equinox setup. I predict this will be the start of a lot of OSGi server-side applciations in the upcoming future; I'll blog more about that later.