Building with Tycho – part 2 (RCP applications)

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).

New 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.

36 thoughts on “Building with Tycho – part 2 (RCP applications)

  1. Thanks for taking the time to put this and the previous blog on Tycho together. Wish I had found these a couple of days ago, it could have saved me a fair amount of grief in coming to terms with Tycho. Very clear, concise and well done. Kudos ;-)

    Cheers,
    Jioel

  2. Hey! Thanks for your work on these posts, they are really useful!

    Tycho is quite good, but poorly documented at this point, so far, your blog has the best tips :)

    Keep up the good work!

  3. HELLO! Thanks for your post, they are useful for me.
    I’ve been looking for the usage of Tycho a long time.
    Now, I can finally sleep well.
    Thanks lot!

  4. Hi I still have a problem with the :

    [ERROR] Failed to execute goal org.sonatype.tycho:maven-osgi-packaging-plugin:0.7.0:product-export (default-product-export) on project js.rcpexample: Product includes native launcher but no target environment was specified -> [Help 1]

    I have added this to the plugin section in my parent pom:

    0.8.0

    win32
    win32
    x86

    true

    I am using apache-maven-3.0-beta-1, tycho 0.8.0 and windows vista 32 bit.

    It works fine if I uncheck:

    “The product includes native launcher artifacts”

    in the .product file though.

    • Hi Js,

      My best suggestion is to try out Tycho 0.9.0 that just got released or post a question on the Tycho users mailing list with your complete configuration.

      Good Luck!
      Mattias

  5. Hi, I’ve got a product file that builds correctly and I can run it…however, the feature the the app is being built against has a ‘rootfiles’ folder which is not being deployed when the product is exported by Tycho.

    Exporting via Eclipse, using the same .product file puts the contents of ‘rootfiles’ into the exported apps directory. Do you know if there is any way of getting Tycho to exhibit the same behavior ?

    • Hi Gordon,

      I’m sorry but I don’t know how/if Tycho supports that particular feature. I saw your post on the users mailing list. Hope you’ll get some better answers from there. Good Luck! Regards, Mattias

    • Thanks for your positive feedback. I don’t read German but Chrome translation told me your feedback was positive ;)

      Regards, Mattias

  6. Eclipse RCP/OSGi/Tycho newbie here, trying to go through this example (with eclipse 3.6, tycho 0.9.0, and maven 3.0-beta-1), and failing at it. Packaging fails for me with following error:
    [INFO] Resolving target platform for project MavenProject: se.mattiasholmqvist:se.mattiasholmqvist.rcpexample.plugin:1.0.0-SNAPSHOT @ D:learningtychoeclipse_workspacese.mattiasholmqvist.rcpexample-parentse.mattiasholmqvist.rcpexample.pluginpom.xml
    [ERROR] Internal error: java.lang.RuntimeException: org.osgi.framework.BundleException: Bundle se.mattiasholmqvist.rcpexample.plugin cannot be resolved
    Resolution errors:
    Bundle se.mattiasholmqvist.rcpexample.plugin – Missing Constraint: Require-Bundle: org.eclipse.ui; bundle-version=”0.0.0″
    Bundle se.mattiasholmqvist.rcpexample.plugin – Missing Constraint: Require-Bundle: org.eclipse.core.runtime; bundle-version=”0.0.0″

    I have a sense of missing something fundamental here. Where are these two supposed to be resolved from?

    • He Stevo,

      They are to be resolved from the Eclipse target platform. Did you provide the -Dtycho.targetPlatform switch when you compiled with mvn package? Or did you try to use a target definition file?

      Regards, Mattias

  7. Hi Mattias,

    Thank you for the great tutorial. I finally got things all working yesterday, so I am now really pleased. However, I had problems initially, as my .product file was located in the same project as the rpc app. Basically, when the pom’s were generated, I changed the packaging from eclipse-plugin to eclipse-application, but received an error that it couldn’t locate the plugin. Putting the product in a separate project obviously works, as the poms are separate for eclipse-plugin and eclipse-application. So my question is, if the product is in the same project as the rpc app, how should the pom be configured?

    Regards
    Steve

  8. I have taken the example template project (checked it out) and modified it for my project — the problem is that it creates jars in the target directories, but does not create an eclipse application in the parent product target. What am I doing wrong?

  9. Thanks for writing a hands-on tutorial about Tycho. I still bump in to errors of the type:

    import org.eclipse.swt.SWT;
    ^^^^^^^^^^^^^^^^^^^
    The import org.eclipse.swt.SWT cannot be resolved

    I currently use Tycho 0.10.0 and also tried a snapshot of 0.11.0. Same issue. Developing on a Windows machine but building on a Linux host. Tried your suggestions above but still no luck. I see several issues in the Tycho bug list refering to SWT. Maybe this is still an issue but I envie you having get past the problem. Another suggestion?

  10. Hi Mattias,

    thanks for the tutorial. I’m trying to repeat your steps but I’m failing with two different issues. Firstly, I have to put numeric versions by hand (the resolution of .qualifier and .SNAPSHOT doesn’t work). Secondly, Tycho produces a plug-in JAR named name-1.0.0.jar which is fine for Maven, but Eclipse expets name_1.0.0 (remind _ instead of -). Any ideas about it? (Using MVN3, Tycho 0.10, PDE 3.6.1)

  11. Hi Matt
    I am trying to run Plugin UI test cases (written using WindowTester). I have used tycho to generate POMs for the source projects, test cases & test suite. I am able to run the test cases using m2eclipse plugin in Eclipse but not from command line. Both ways, I have maven 3.0. beta2 as maven version. I am getting the following error

    [ERROR] Failed to execute goal org.sonatype.tycho:maven-osgi-test-plugin:0.9.0:t
    est (default-test) on project com.abcd.soa.test.suite: There are test failures.

  12. Hi !
    Is anybody knows how could I realize the equivalent of the maven ‘release:prepare’ for my RCP application ? I’d like that the versions in my poms and Manifests are updated…

    Thanks before

  13. Hi I am learning the use of Tycho. I would like to know can I use annotations with Tycho and is yes How ?

    • Hi, sure you can use annotations. Tycho is only a tool to make OSGi work seamlessly with Maven and has nothing to do with actual compilation of the Java code. Annotations support is depending on the version of Java you’re compiling for. It is supported from 1.5 and up.

      Regards, Mattias

  14. I am getting the same error has Stevo,

    running Eclipse 3.6.1 with Maven 3.03 and Tycho (0.11.1 and 0.12.0)

    Here’s the error

    C:workspacestests>mvn package -Dtycho.targetPlatform=C:/eclipse/delta/
    [INFO] Scanning for projects…
    [WARNING] No explicit target runtime environment configuration. Build is platform dependent.
    [WARNING] -Dtycho.targetPlatform is deprecated and WILL be removed in the next Tycho version.
    [WARNING] No explicit target runtime environment configuration. Build is platform dependent.
    [WARNING] -Dtycho.targetPlatform is deprecated and WILL be removed in the next Tycho version.
    [WARNING] No explicit target runtime environment configuration. Build is platform dependent.
    [WARNING] -Dtycho.targetPlatform is deprecated and WILL be removed in the next Tycho version.
    [WARNING] -Dtycho.targetPlatform is deprecated and WILL be removed in the next Tycho version.
    [INFO] Resolving target platform for project MavenProject: ce:ce.rcpexample.feature:1.0.0-SNAPSHOT @ C:workspacestestsce.rcpexa
    mple.featurepom.xml
    [WARNING] -Dtycho.targetPlatform is deprecated and WILL be removed in the next Tycho version.
    [INFO] Resolving target platform for project MavenProject: ce:ce.rcpexample.plugin:1.0.0-SNAPSHOT @ C:workspacestestsce.rcpexam
    ple.pluginpom.xml
    [ERROR] Internal error: java.lang.RuntimeException: org.osgi.framework.BundleException: Bundle ce.rcpexample.plugin cannot be reso
    lved
    [ERROR] Resolution errors:
    [ERROR] Bundle ce.rcpexample.plugin – Missing Constraint: Require-Bundle: org.eclipse.ui; bundle-version=”0.0.0″
    [ERROR] Bundle ce.rcpexample.plugin – Missing Constraint: Require-Bundle: org.eclipse.core.runtime; bundle-version=”0.0.0″
    [ERROR] -> [Help 1]
    org.apache.maven.InternalErrorException: Internal error: java.lang.RuntimeException: org.osgi.framework.BundleException: Bundle ce
    .rcpexample.plugin cannot be resolved
    Resolution errors:
    Bundle ce.rcpexample.plugin – Missing Constraint: Require-Bundle: org.eclipse.ui; bundle-version=”0.0.0″
    Bundle ce.rcpexample.plugin – Missing Constraint: Require-Bundle: org.eclipse.core.runtime; bundle-version=”0.0.0″

  15. I was able to find the problem,

    -Dtycho.targetPlatform=C:/eclipse/delta/

    was pointing to the delta package only, so it cuoldnt find the non delta constraint.

    when I pointed to c:eclipse I started getting missing constraint error related to the delta files.

    So I merged both eclipse feautes/plugins and delta features/plugings together.

    Now I am able to compile.

    The remaining question I have is about the following WARNING

    [WARNING] -Dtycho.targetPlatform is deprecated and WILL be removed in the next Tycho version.

    What when I dont specify the targetPlatform I cannot successfully compile it.

  16. Hi Mattias,

    I have read your tutorials, which are great. But I’m missing the point how to handle third party libraries. I have also seen your post to the tycho mailing list, where you describe, that you want to combine a target platform with a local directory of osgi bundles [1]. I think, that’s a good approach. We are currently generating osgi bundles of our third party (maven) dependencies with the Felix bundle plugin. So this approach would be a perfect solution for us.

    Our goal is to have a configuration, which let’s us start our RCP app within eclipse and also build it with tycho. We could then have continuous integration and the developers would still have short turn around times.

    I would appreciate, if you could give me some hints, how to integrate third party libraries in such a scenario. What do you think is the best practice?

    Best regards,
    Henrik

    [1] http://software.2206966.n2.nabble.com/Combining-implicit-target-platform-and-explicit-target-platform-locations-td4553749.html

    • Hi Henrik,

      Thanks for the good feedback!

      What I ended up doing with third-party bundles was to set-up a P2 repository that could be read from the .target definition file. The target files could never handle local file system paths but it worked by setting up the P2 repository on the local machine and point to it using a .target file. Hope this points you in the right direction. I’m currently not working with Tycho so this is only what I remember from my head. :)

      You can always try and post a question on the mailing list!

      Good luck! Regards, Mattias

  17. Hi Mattias,

    actually this was one of my ideas to solve this problem. Configuring and testing all of my ideas would have taken some time. So, thank you for pushing me in the right direction.

    Regards,
    Henrik

  18. Mattias,

    one more question. Did you create the p2 repo manually or did you generate it? If the latter, which tools did you use?

    • Hi Henrik,
      I’m afraid I don’t remember exactly how I did this so I guess looking at the p2 stuff from eclipse.org and using Google is the best hint I can give you at this moment. Sorry.

      Good luck!

Leave a Reply

Your email address will not be published. Required fields are marked *

*


− one = 2

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>