poniedziałek, 19 lipca 2010

Build SWT application with maven

There are couple of issues when trying to use SWT with application using Maven for building and deploying. The most fundamental is that you have to deliver separate application per architecture and windowing system. Another one is the fact there are no up-to-date releases of SWT in common Maven repositories. And finally when trying one platform independent binary all handles platforms must be include particular SWT implementations, but here another issue appears: how to put appropriate SWT on class path.

First lets populate our local maven repository with SWT libraries. The first step is to obtain desirable swt implementation for os/ws/arch triples. Lets assume that for needs of this example we limit supported triples to linux/gtk/x86_64, win32/win32/x86, win32/win32/x86_64.

Best can be use p2 director to grab libraries. There is not easy way for importing all swt implementations into one location therefore here you are somewhat weird workaround - each impl needs to be grabbed into separate location.

director/director -consolelog -r http://download.eclipse.org/releases/helios 
-d SWT_GTK -i org.eclipse.swt.gtk.linux.x86
director/director -consolelog -r http://download.eclipse.org/releases/helios 
-d SWT_GTK64 -i org.eclipse.swt.gtk.linux.x86_64
director/director -consolelog -r http://download.eclipse.org/releases/helios 
-d SWT_WIN -i org.eclipse.swt.win32.win32.x86 -p2.os win32 -p2.ws win32 -p2.arch x86
director/director -consolelog -r http://download.eclipse.org/releases/helios 
-d SWT_WIN64 -i org.eclipse.swt.win32.win32.x86_64 -p2.os win32 -p2.ws win32 -p2.arch x86_64

Note that specifying profile details is needed for non-native implementations.

In order to use eclipse:to-maven target we need to mimic eclipse installation with plugin folder. For Linux users:

/tmp/SWTLIBS$ find SWT* -name "org.eclipse.swt.*.jar" | xargs -I{} cp {} SWTLIBS/plugins/
/tmp/SWTLIBS$ ls SWTLIBS/plugins
org.eclipse.swt.gtk.linux.x86_3.6.0.v3650b.jar     org.eclipse.swt.win32.win32.x86_3.6.0.v3650b.jar
org.eclipse.swt.gtk.linux.x86_64_3.6.0.v3650b.jar  org.eclipse.swt.win32.win32.x86_64_3.6.0.v3650b.jar

Once done install jars to the maven repository:
mvn eclipse:to-maven -DdeployTo=eclipse.org::default::file:///home/krma/.m2/repository 
-DeclipseDir=. -DstripQualifier=true

After that we can receive following dependency entries:

 <groupid>org.eclipse.swt.gtk.linux</groupId>
 <artifactid>x86_64</artifactId>
 <version>3.6.0</version>
</dependency>
<dependency>
 <groupid>org.eclipse.swt.win32.win32</groupId>
 <artifactid>x86_64</artifactId>
 <version>3.6.0</version>
</dependency>
<dependency>
 <groupid>org.eclipse.swt.win32.win32</groupId>
 <artifactid>x86</artifactId>
 <version>3.6.0</version>
</dependency>
<dependency>
 <groupid>org.eclipse.swt.win32.win32</groupId>
 <artifactid>x86_64</artifactId>
 <version>3.6.0</version>
</dependency>

But with such configuration there will be one problem. First of all all the SWT implementation will be included to our build. But this is actually not really true as our artifact names are duplicated.

The solution is to force other naming for artifactID by manual installing each jar into local maven repository
mvn install:install-file -Dfile=org.eclipse.swt.gtk.linux.x86_3.6.0.v3650b.jar -DgroupId=org.eclipse -DartifactId=swt.gtk.linux.x86 -Dversion=3.6.0 -Dpackaging=jar -DgeneratePom=true -Dmaven.repo.local=/path/to/mvnrepo

Now the following can be used:
<dependency>
 <groupid>org.eclipse</groupId>
 <artifactid>swt.gtk.linux.x86</artifactId>
 <version>3.6.0</version>
</dependency>
<dependency>
 <groupid>org.eclipse</groupId>
 <artifactid>swt.gtk.win32.win32</artifactId>
 <version>3.6.0</version>
</dependency>