Building RCP applications (products) have always been quite smooth when working from within Eclipse IDE. To me, it is extremely important that the development team can easily build their product and have continuous integration of the product on a CI server such as Hudson.
Previously, PDE build have been the way to build RCP applications in a headless build environment (such as Hudson, for example), but all those Ant scripts and configuration options in the build.properties file are not that appealing to me.
Tycho provides support for building RCP applications from product configuration files. As we will see, this makes the headless build for RCP applications a lot less confusing.
One nice thing that I forgot to mention about Tycho in my previous post is that is has great support for Manifest-first development. This means that the development team does not need to synchronize their Manifest files with the pom.xml that Tycho uses, it is handled automatically for them. The developers can use “Imported packages” and “Required plug-ins” as usual and Tycho will use that information to resolve the compilation target for each bundle. I find this workflow easier and more appealing than pom-first development (for example BND-plugin with a separate
.bnd file for configuring exported/imported packages). I guess you have to figure out which way works for you.
This might not be as appealing for some of you who are accustomed to specifying Maven dependencies in the pom.xml but Tycho supports pom-first development as well. However, since I like to work Manifest-first I will use it for my examples here. For info on pom-first development, check out the Tycho users mailing list or the official website.
This will be a quick intro on how to get started with a small Eclipse RCP application in Tycho. The first steps involves creating the setup of one plugin/feature/product so you who are Eclipse-wise don’t need to follow these steps thoroughly.
Note: This post will assume Tycho 0.7.0 and Eclipse 3.5.2. Some of the issues in this post will probably be fixed in upcoming releases of Tycho. Hopefully the main workflow will remain somewhat steady. I will also only provide examples for the explicit target platform resolver. The implicit p2 resolver should work just as fine, check out the previous post to see how to set it up. I will also not include all configuration options that are available for Tycho, but please comment if you miss something and I might add it later!
Let’s build an application!
Creating the application plug-in
Start by creating a plug-in that defines our RCP-application. There are some templates ready for creating example RCP application in the Eclipse distributions. I used the “Hello RCP” template which contains a simple application saying “Hello RCP” in the title bar. See the screenshots below for how I created my example plugin.
Creating the application feature
Products in Eclipse can either be plugin-based or feature-based. We will build a feature-based application so we start by creating a project that will contain the main feature for our RCP application. The feature contains a feature.xml, which is used to define which plug-ins constitutes the feature. When asked for plug-ins to include in the feature, reference the plug-in that we created in the first step.
The feature will be referenced by the product definition, which tells Tycho to use it when constituting the product.
Configuring the product definition
We need to create the product definition that constitute our product. This will include the feature project that we created previously and the Eclipse RCP feature. Pay attention to the naming of the product definition file since Tycho uses the convention that the file name should match the maven module with a .product suffix.
Start by creating a new project (I prefer keeping the product file in a separate project).
Name the project so that it matches your product in whatever way you find appropriate. I named my project se.mattiasholmqvist.rcpexample. Tycho now assumes that my product definition file is name se.mattiasholmqvist.rcpexample.product
We create our product configuration file and add it to our product project.
Choose an ID and a name for the product and make sure that you set your product includes native launcher artifacts.
We need to create a new product definition. This definition refers to the application extension that our application plug-in defines (this comes from the RCP template).
You need to specify which features constitutes the product. Since we build an Eclipse RCP product you need to include the RCP feature (org.eclipse.rcp) and the feature that we created earlier which contains our application-defining plug-in. Make sure that the definition specifies that the product is build using features.
Setting up the build files
From our workspace location, we can now generate a parent pom.xml together with a pom-file for the plug-in project we just created. Fire up your command line and generate the pom-files.
mvn3 org.sonatype.tycho:maven-tycho-plugin:generate-poms -DgroupId=se.mattiasholmqvist -Dtycho.targetPlatform=/Users/mattias/dev/eclipse-3.5.2-delta/
This goal is typically run only once since you don’t want to replace any changes you’ve made to the parent pom. I use only the parent pom to add plug-ins to the build. I’m not sure if that’s the way to go but it seems like a good idea that the individual plug-in projects has minimum-sized pom files that we don’t need to change that often.
You don’t actually need to run <code>generate-poms</code>. This maven goal is only used to bootstrap the build by creating the initial pom files so you don’t need to create these files yourself initially. If you have a parent project with many plug-in projects this might be quite useful. If you want more control over what’s happening, just copy & paste the pom.xml files I created (shown below) and modify them to your need.
This renders a parent pom.xml that looks something like this:
<?xml version="1.0" encoding="UTF-8"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <groupId>se.mattiasholmqvist</groupId> <artifactId>rcpexample-parent</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>pom</packaging> <build> <plugins> <plugin> <groupId>org.sonatype.tycho</groupId> <artifactId>tycho-maven-plugin</artifactId> <version>0.7.0</version> <extensions>true</extensions> </plugin> </plugins> </build> <modules> <module>se.mattiasholmqvist.rcpexample.feature</module> <module>se.mattiasholmqvist.rcpexample.plugin</module> </modules> </project>
As we can see this does not contain a module for the product project that we created earlier. Tycho cannot understand that our product project defines a product, but that’s a minor thing. We should add the product project to the parent pom.xml so that the modules section looks like this:
<modules> <module>se.mattiasholmqvist.rcpexample.feature</module> <module>se.mattiasholmqvist.rcpexample.plugin</module> <module>se.mattiasholmqvist.rcpexample</module> </modules>
We also need to create a pom.xml in the product project that looks like this:
<?xml version="1.0" encoding="UTF-8"?> <project> <modelVersion>4.0.0</modelVersion> <parent> <groupId>se.mattiasholmqvist</groupId> <artifactId>rcpexample-parent</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <groupId>se.mattiasholmqvist</groupId> <artifactId>se.mattiasholmqvist.rcpexample</artifactId> <version>1.0.0</version> <packaging>eclipse-application</packaging> </project>
Note the eclipse-application packaging in the pom. This tells Tycho that the project is actually an RCP application and Tycho starts looking for a product definition file during the build.
Installing the delta pack in the target platform
To build applications that depend on platform-specific parts of the Eclipse SDK (such as SWT), we need to provide a target platform that contains the Eclipse Delta pack. There are multiple sources on the web that describes how to install the delta pack so look at for example this site or this one.
Building the product
We are now ready to build our product.
mvn3 package -Dtycho.targetPlatform=/Users/mattias/dev/eclipse-3.5.2-delta/
This should build your product and place an executable application under /target directory in your product project. There are however currently some issues that you might run into depending on your build environment/target platform.
The import org.eclipse.swt.graphics.Point cannot be resolved.
You might run into something like this:
[ERROR] Failed to execute goal org.sonatype.tycho:maven-osgi-compiler-plugin:0.7.0:compile (default-compile) on project se.mattiasholmqvist.rcpexample.plugin: Compilation failure: Compilation failure: /Users/mattias/dev/projects/tychoexamples/clean/se.mattiasholmqvist.rcpexample.plugin/src/se/mattiasholmqvist/rcpexample/plugin/ApplicationWorkbenchWindowAdvisor.java (at line 1):[-1,-1] package se.mattiasholmqvist.rcpexample.plugin; ^ The type org.eclipse.swt.graphics.Point cannot be resolved. It is indirectly referenced from required .class files /Users/mattias/dev/projects/tychoexamples/clean/se.mattiasholmqvist.rcpexample.plugin/src/se/mattiasholmqvist/rcpexample/plugin/ApplicationWorkbenchWindowAdvisor.java (at line 3):[-1,-1] import org.eclipse.swt.graphics.Point; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... ...
This is a problem with Tycho not knowing which native environment to build for. Tycho needs this information to find the correct SWT fragment in the target platform. The expected default behaviour would be that Tycho looks for a fragment that is supported by the system running the build but currently there are some issues with MacOS X (which I use). However, this issue will be fixed in release 0.8.0 of Tycho.
So, we need to provide this information to Tycho somehow. In my case, I want to build for MacOS X, Cocoa windowing system and the x86 architecture. We have three options (that I know). We can provide these properties on the command line, in the Maven settings.xml or in the pom.xml directly.
On the command line it looks like this:
mvn3 package -Dtycho.targetPlatform=/Users/mattias/dev/eclipse-3.5.2-delta/ -Dosgi.os=macosx -Dosgi.ws=cocoa -Dosgi.arch=x86
In the pom.xml (or the settings.xml for that matter):
<properties> <osgi.os>macosx</osgi.os> <osgi.ws>cocoa</osgi.ws> <osgi.arch>x86</osgi.arch> </properties>
Missing target environment
This might also be a problem:
[ERROR] Failed to execute goal org.sonatype.tycho:maven-osgi-packaging-plugin:0.7.0:product-export (default-product-export) on project se.mattiasholmqvist.rcpexample: Product includes native launcher but no target environment was specified -> [Help 1]
Which is due to the fact that the Tycho packaging plugin needs configuration to know which target environment to build the product for. We can solve this by adding the following to the
plugins section of the parent pom.xml:
<plugin> <groupId>org.sonatype.tycho</groupId> <artifactId>maven-osgi-packaging-plugin</artifactId> <version>0.7.0</version> <configuration> <environments> <environment> <os>macosx</os> <ws>cocoa</ws> <arch>x86</arch> </environment> </environments> </configuration> </plugin>
We’re done, let’s start the application!
Open the target directory of your product project (in my case se.mattiasholmqvist.rcpexample/target) and you should find an executable RCP application. In my case (since I’m on a Mac) I found a rcpexample.app in my target directory. Behind this file is this beautifully built, and extremely useful application:
That’s it for building a simple Eclipse RCP app with Tycho. Good luck!
As a reminder, please check out the Tycho users mailing list. Help the people at Sonatype out with feedback on their project.