Monday, July 30, 2007

Maven2 SWT builds




Building a SWT application with maven can be tricky. The public maven repositories don't have current versions of SWT. You must download the recent version for each platform that you need to support and place them in your own repository. Since SWT needs the native libraries for your platform, you will need to package those in individual jar (or zip) files and deploy those to your local repository. I recommend giving them the same artifactId as your Java SWT libraries with a suffix like '-native'. So for three platforms you should have six artifacts like the following.

swt/swt-win32/3.2.2/swt-win32-3.2.2.jar
swt/swt-win32-native/3.2.2/swt-win32-native-3.2.2.jar
swt/swt-linux-gtk/3.2.2/swt-linux-gtk-3.2.2.jar
swt/swt-linux-gtk-native/3.2.2/swt-linux-gtk-native-3.2.2.jar
swt/swt-macosx/3.2.2/swt-macosx-3.2.2.jar
swt/swt-macosx-native/3.2.2/swt-macosx-native-3.2.2.jar

Now you can use profiles to determine the proper dependency and the maven-dependency-plugin to unpack the proper native libraries. First create a profile for each platform that you need to support in your pom.xml file and set properties defining the proper dependencies for each platform:

<profiles>
<profile>
<id>unix</id>
<activation>
<os>
<family>unix</family>
</os>
</activation>
<properties>
<swt.os-specific-dep>swt-linux-gtk</swt.os-specific-dep>
<swt.version>3.2.2</swt.version>
</properties>
</profile>
<profile>
<id>windows</id>
<activation>
<os>
<family>windows</family>
</os>
</activation>
<properties>
<swt.os-specific-dep>swt-win32</swt.os-specific-dep>
<swt.version>3.2.2</swt.version>
</properties>
</profile>
<profile>
<id>mac</id>
<activation>
<os>
<family>macosx</family>
</os>
</activation>
<properties>
<swt.os-specific-dep>swt-macosx</swt.os-specific-dep>
<swt.version>3.2.2</swt.version>
</properties>
</profile>
</profiles>

You can reference these properties in your pom for dependencies and for the unpack goal of the maven-dependency-plugin. The example below uses the appassembler-maven-plugin output directory to unpack the native libraries. You can use the appassembler plugin to create scripts for launching your application and add extra JVM arguments which you will need to do.

<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<executions>
<execution>
<id>assemble</id>
<phase>package</phase>
<goals>
<goal>assemble</goal>
</goals>
<configuration>
<programs>
<program>
<mainClass>esrl.gsd.fsl.enroute.client.Client</mainClass>
<name>enroute-client</name>
</program>
</programs>
<extraJvmArguments>-Djava.library.path=lib</extraJvmArguments>
</configuration>
</execution>
</executions>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>swt</groupId>
<artifactId>${swt.os-specific-dep}-native</artifactId>
<version>${swt.version}</version>
<type>jar</type>
<overWrite>true</overWrite>
<outputDirectory>
${project.build.directory}/appassembler/lib
</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

Notice the extra JVM argument given to the appassembler plugin and the output directory for the unpack configuration.

%> mvn package

This will unpack the proper native libraries in the lib directory of the assembled application, and create shell scripts for launching the application as well as copy all the other necessary dependencies to the assembled application. See the dependency and appassembler plugins for more configuration options.

6 comments:

Anonymous said...

Hello,

I'm trying to figure out how to use the appassembler-maven-plugin to generate daemon scripts. Have you ever looked into this?

A.

Brice Lambi said...

I have, but I don't think that goal is working yet. I haven't had any luck with it either.

Unknown said...

Hi, Do you know maybe how to change default script generated by appassembler-maven-plugin.
I'd like to create my own, but I do not know how to do that. I've serched the internet, but without any success :(

Greg

Unknown said...

Thanks for the nice article.

The only trouble is the first step ... What if you give your program to someone other, this guy must also repeat these steps ...

I discovered just now http://repo1.maven.org/maven2/org/eclipse/swt/

Here is the 3.3.0-v3346 version online ...
This version includes the most important changes like DateTime.class ...

Therefore you can skip the first steps and let maven get you the version ...

have a nice day

tom said...

The 3.3.0-v3346 version doesn't work with jface, because it is not resolved as a version between 3.3.0 and 3.4.0.

Miguel Rodríguez said...

Perfect!!. Thanks for your help