When you want to work effectively with Maven/Tycho on a larger project, you quickly find yourself wanting more features than the simple build presented in my previous posts. In this post i will cover some important features of Tycho that you might need to work more effectively with Tycho.
I suspect this post will be quite massive so I’ll skip the screenshots in this one. Instead I decided to create a sample project structure and put it up on my github account. See the readme for information on how to set up the example projects.
Overall structure and idea
The parent project (with .parent suffix) is the mother of the build. Practically all configuration of the build is handled by its pom.xml file. We strive to keep the sub-projects as small as possible to minimize the duplication of information in the development environment (Eclipse in this case) and the headless build system (Tycho/Maven).
The information that we’re required to provide in the sub-projects’ pom.xml files are the version of the project (which is verified against the version provided in the Manifest.MF) and the type of project (feature/bundle/test bundle/update site).
I will describe the things that I reckon is most important in the example projects so that you (hopefully) can follow what’s happening when building the projects.
Features and update sites
The sample project contains a feature project and an update site project. These two projects are intended to give some extra help from within the Eclipse IDE. When the plugins are built by the CI server (I assume you have one!?), the server can also push the update site (containing the feature) to an HTTP server (or similar) that is available for developers that want to use the plugins as target platform in their development. This makes the build quite modular and nice to work with.
Tycho makes the automation for building for your features and update sites quite a simple task. You need to create a pom.xml for your feature looking somewhat like this:
<project> <modelVersion>4.0.0</modelVersion> <parent> <groupId>se.mattiasholmqvist</groupId> <artifactId>examples</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <groupId>se.mattiasholmqvist</groupId> <artifactId>examples.feature</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>eclipse-feature</packaging> </project>
Note: See the sub-project with .feature-suffix for the provided example.
This pom file is very similar to the bundle pom file. The only difference is the <packaging> tag that tells Tycho to build the project as a feature. The nice thing about these tiny poms is that the dependency management becomes quite easy. You can more or less work without caring about the Maven configuration since Tycho uses the Manifest and feature.xml to setup the correct build dependencies.
Of course, you would also need to specify a proper target platform. In my previous posts, I’ve shown how to do this with the -Dtycho.targetPlatform switch, which works but there is a cooler and more flexible way that also works great with Tycho.
Target platform definitions
Ok, we have our build set up nicely and all seems to be working fine. However, the great success of your project has made it grow significantly and it seems that not all developers that join the project are able (or willing) to setup their target platforms (in Eclipse) in accordance with the Tycho build since it requires quite a lot of understanding about Tycho/OSGi and perhaps Eclipse P2 as well. This causes disturbance to your project and you do your best to help your teammates out, but you reckon there must be a better/simpler way of tackling this issue than to manually manage the target platform installation for each developer.
A short tale about the target definition file
The target definition file is quite a newcomer to the Eclipse development environment. It is a nice feature that lets you specify the target platform in a structured fashion (although the previously supported directory-based platforms are still supported in Eclipse) which I highly recommend. Another even nicer thing is that Tycho also supports resolving the target platform from the Eclipse target definition file. This means that setting up the development environment for a new developer in simply a matter of locating the target definition file and click on “Set as target platform”, and the target platform is now consistent with the platform that Tycho uses. This is probably not a perfect description but you can find some more info from the Eclipse help and some more info on using them in practice can be found here.
The first step – creating the .target file
I like to keep my target platform in a separate project, just for structure and separation. My guess is that you can make it work by putting it anywhere you want, but in my example I’ve put it in the project called
I’ve created a target definition file in Eclipse (it’s found in the New-> menu) and I’ve called this file example_target.target and placed it directly in the target platform project directory. I selected a few Eclipse dependencies that I needed for my bundle and saved the file.
We also need to provide some configuration to this project. I’m not sure if this is the only way to do this at the time of writing but I’m sure that it works for me. This is a snippet from the pom.xml that I use for the target-platform project:
<build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>build-helper-maven-plugin</artifactId> <version>1.3</version> <executions> <execution> <id>attach-artifacts</id> <phase>package</phase> <goals> <goal>attach-artifact</goal> </goals> <configuration> <artifacts> <artifact> <file>example_target.target</file> <type>target</type> <classifier>example_target</classifier> </artifact> </artifacts> </configuration> </execution> </executions> </plugin> </plugins> </build>
Tycho supports unit-testing (JUnit) of code within bundles by default. This has long been a hazzle (for me atleast), when working with Ant + PDE build so this support is extremely welcome. Tycho tests bundles via the integration-test Maven goal, which is different from the regular test goal. It also makes life easier if you know a bit about the conventions Tycho uses for finding tests (this might however be subject to change in the future).
Start by creating a simple bundle that will contain the classes of your application. Second, we will create a separate bundle that will contain our tests. The convention here is to use the same same as the bundle with your application classes and add the prefix .tests to the test bundle name. I provide a (really stupid) test in the project with .tests-suffix in the github repo.
Note: The Test suffix is important if you want to use the default configuration of Tycho, or it won’t find your test class. Below is a snippet from the configuration of the test plugin for my example projects which enables unit testing for the project:
I also made the .tests project a fragment to the bundle it belongs to. This makes it easier to locate classes to depend on. I think this setup works well within Eclipse/OSGi development.
Code coverage using EclEmma
Using code coverage in an OSGi environment is special. There are however some Eclipse plugins that support code coverage and it is possible to integrate these with Tycho. I want to give credit to the guys at Sonatype for helping me out with this. They recently posted some information on their website related to code coverage, so my example project might serve as a good complement to this article. I thought it might be a good idea to wrap our discussions up in an example that is perhaps a bit more accessible than the posts on the mailing list. My example is however a bit more simplistic than the example in the article above. I do not copy resources from multiple test bundles, but instead generate a report for each bundle. Check out the article if you need that feature.
In large, the code coverage is handled by a Maven profile so you need to pass a
-Pcoverage flag to enable it.
To run the test suite (1 test in the example project) with code coverage and reporting:
mvn integration-test verify -Pcoverage
In my examples project I’ve put together a small bundle project that contains Eclemma Equinox runtime. It would probably be possible just to deploy it to a locally accessible Maven repository but for ease of use of the examples I’ve made it a part of the build instead. When you run
mvn integration-test with the
coverage profile in the parent project directory, this bundle will do code coverage of all bundles/packages that matches the configuration in the parent pom.xml. See the
<profiles> configuration in the parent- and test project pom.xml files for exactly how this is done.
Hope this post can help someone out there with use Tycho which is a great tool for your OSGi development.
Checkout Sonatype’s Tycho website to keep up-to-date with the development of Tycho.