Tuesday, May 29, 2012

Eclipse-based applications as standard mac application bundle

It's not every day that a 5 digits bug number get's fixed in Eclipse*, so I'm happy to report that the long standing bug 57349 is now fixed in Juno (Eclipse 3.8 / 4.2). It means that you can now deliver eclipse-based applications as mac os x bundled applications.

New layout

For an end user, the biggest change brought here is that the application is now an opaque entity and it has an icon. See screenshot below of the same application to compare.

Now in the details, the new layout pictured on the left mainly differs from the legacy one on the right by two things:
  • the top level folder is now suffixed with .app; thus making the application an opaque entity that requires a special user action to navigate into it (this is also why the left picture does not show the top level folder)
  • the actual launcher included in the Contents folder is included as a child of the top level folder where as in the past it was in a folder whose name was the name of the launcher (e.g. myRCP in the example).

How do you enable this new layout?

  1. Make sure the application you are building uses p2 included in Juno
  2. Move your build environment to use PDE Build from Juno, or Tycho 0.15.
       This will cause the additional metadata necessary to support this new layout to be generated.
  3. When you invoke the p2.director (the one from Juno) to create your application simply suffix the install folder with .app and let the magic happen. If you don't want to keep the legacy shape, don't use the .app suffix. Here is an example of command line: ./eclipse -application org.eclipse.equinox.p2.director -installIU <iufortheproduct> -destination Applications/myCool.app -profile <somename> -repository <therepotoinstalltheproductfrom>

Note to tycho users

Tycho 0.15 (still in snapshot at the time of writing this post) generates the appropriate metadata and p2 repo, but the support to create an installation and archive with the correct layout is not yet released (bug 378021). To obtain the desired shape you can either call the p2 director as mentioned above, or use the workaround provided in bug 378021.

Note to PDE build users

PDE build generates the appropriate metadata and p2 repo, but it will not create an installation and archive with the correct layout. To obtain the desired shape you will have to manually invoke the p2 director as indicated above.

And to conclude I would like to mention that this work has been sponsored by Manumitting Technologies. * Well actually, at this point I count 28 5 digits bug number fixed in Juno and one 4 digits bug number - bug 9503

Monday, May 28, 2012

Running tycho tests on multiple machines

Recently I ran into a situation where I wanted to run the tests of an RCP application on different machines. Obviously, the simplest solution consists in running the full build on each machines. This means that every bundle and test bundle will be compiled on each machine, and the tests executed on each machine.

Of course, this works. However I'm not a fan of this approach because I like to test what I ship. What I'm getting at is that when the code is compiled on different machines, there is a chance that different binaries can be produced, which means that from a purist point of view the testing done is invalid since you have not tested the binaries that are finding their way into the final distribution of the product.

What I'm describing below is a way to structure the build that allows:
  • tests to be executed on multiple machines without recompiling the tested code;
  • developers to keep on running mvn clean install and get the code to compile and the tests to run;
  • developers to have minimal understanding of the overall build setup to add a bundle and its tests.

First, let's review the relevant modules of the setup:
  • code : bundle that needs to be tested
  • test : bundle that contains the tests
  • repo : p2 repository containing the bundles being built
  • allTests : parent and aggregator that build and execute the tests
  • parent : main parent and aggregator for the build that includes code, repo and allTests.
The main idea behind this setup is that it provides two main entry points. One that allows for the complete build to run and a second one that just executes the tests. With these abilities it becomes very easy to create a setup where:
  • a main build machine would run a complete build and publish the p2 repository to a shared drive or a repository manager. This is done by executing mvn clean install in top level aggregator here called parent;
  • multiple test machines would be configured to just execute the tests and obtain the artifacts to tests from the repository created by the main build. This is done by executing mvn clean install -DtestedRepo=<pathtorepo>
  • the coordination between the main build and the tests would be done using a CI.

The repo used to obtain the artifacts needs to be setup when the test build is run. In case of a full build, we don't want this repo to be used since it could cause interference. Therefore, the repository is defined in a test specific profile, in the allTests aggregator that also becomes the parent of all the tests projects.
Rather than requesting the activation of the profile and passing the repository parameter, this profile is only activated when the testedRepo property is set.

Et voila, it is that simple. This approach also has the following additional benefits:
  • catch errors early without wasting multiple build executors since the main build will first run to completion by executing the tests;
  • potential build time reduction, if download jars from a repository is faster than building them.
The complete code for this example can be found at https://bitbucket.org/prapicault/tycho-tests-multiple-machines.