Much ado about scripting, Linux & Eclipse: card subject to change


Using Git like CVS

Tonight I moved the sources from phpeclipse and CVS to PDT and Git.

Below are some gotchas and tips for initial repo creation, how to keep the central remote copy up to date, and how to work around complaints about updating master directly from remote. I'm sure there's a better way to do this w/o the need for the workaround, but this is what I found worked.

Initial setup

To crawl a directory and create a git project for each subfolder:

for d in $(find . -maxdepth 1 -type d -not -name "." | \
  egrep -v ".ssh|logs|OLD|download|upload"); do cd $d; \
    git init; git add .; git commit -m "initial commit" .; \
  cd ..; \

See also Setting up a shared repository.

Create local clone via commandline

git clone ssh://servername/path/to/.git folderToCreateLocally

Create local clone w/ eGit

Once your repo is created, you can clone a copy from the remote server onto your local box, and import it into Eclipse (with eGit installed) using File > Import > Git > Projects from Git > Clone... .

Commit local changes via commandline

As outlined before, you can git pull, git checkout, git commit, and finally git push your changes.

If you encounter an error trying to commit changes back to the repo, see the section below, "Allow a ref update to the currently checked out branch of a non-bare repository".

Commit local changes w/ eGit

With eGit, you can pull, push, checkout, commit, merge, etc. using the context menu on a Git project or with the Synchronize view. I don't recommend using any of the change sets / models except the Git Change Set, since the others will tend to show more than is actually needed (like local changes which Git doesn't track).

Allow a ref update to the currently checked out branch of a non-bare repository

Update the ~/.gitconfig file on the remote server to look something like this:
    name = Your Name
    email = your@email.address
    branch = auto
    diff = auto
    interactive = auto
    status = auto
    editor = vim
    tool = vimdiff
    denyCurrentBranch = warn

Retrieve changes into remote repo

Because I'm using the remote server to both host http-accessible files AND host the git repo, it's important that changes checked into the git repo be then checked out into the local filesystem so that the local workspace is in synch with the repo's metadata.

To pull changes, I use git status (to review changes), git reset HEAD <filename> (to reset specified file, or omit filename to reset all changes) and finally git checkout to retrieve the changed file from the repo into the working directory.

Access the server w/o a password prompt

To skip being prompted for a password when you connect over ssh, scp, or fish, add your public SSH key to the ~/.ssh/authorized_keys file on the remote server.

Access the server via an alias

Instead of having to reference the server as username@server when connecting, you can add an entry to your ~/.ssh/config file that looks like this:

Host shortName
User yourUsername
Port 22


HOWTO: Contributing to JBoss Tools using Git

If you'd like to use Git instead of SVN as your SCM tool of choice, here's how you can connect to the JBoss Tools SVN repo, pull down all the sources, work on them locally, then either commit changes back into the SVN repo (or submit a patch, if you're not already a committer).

The instructions below assume you have either Linux, Mac OSX, or Windows w/ cygwin. If you have none of those, YMMV.

Fetch sources from SVN

First, fetch sources from SVN using git-svn. If you don't want to check out all the components, use a subset of the components listed below. The complete list is here.

# create a directory into which to check out the JBoss Tools projects
mkdir ~/trunk; cd ~/trunk;

# fetch projects - this will take quite some time
# Committers, use
# Contributors, use
for d in \
  archives as birt bpel bpmn build cdi common \
  deltacloud documentation drools \
  esb examples flow freemarker gwt hibernatetools \
  jbpm jmx jsf jst maven modeshape portlet profiler \
  requirements runtime seam site smooks struts \
  tests tptp usage vpe ws xulrunner; do \
    git svn clone${d};

Configure Eclipse

Next, fire up Eclipse Helios 3.6 for Java EE Developers.

Install the latest eGit from

Install the latest m2eclipse from and optionally,

Restart when prompted.

Import Git projects into Eclipse

Now, import Git projects into Eclipse using:

File > Import 
    Git > Projects from Git
        Click 'Add' then browse for ~/trunk/ 
        Enable [x] Look for nested repositories 
        Click 'Search', then click 'OK' when done

        Select a local repo from the list, click 'Next'
        (*) Import Existing Projects
        (*) Try to share automatically
        Click 'Next'
        Click 'Select All', then click 'Finish'

Repeat for other components you want to import. You can add each component to a working set to keep your workspace sorted by component.

Resolve missing dependencies

While the Eclipse Helios 3.6 for Java EE Developers contains most of the dependencies against which JBoss Tools must be compiled, it does not contain everything. For that, you need to install extra dependencies. There are two places to go:

  1. JBoss Tools Target Platform p2 Repo (also available as an archived update site zip for offline use) - contains all the,, and features needed to compile / install all of JBoss Tools. You can install everything, or just the pieces you need.
  2. JBoss Tools Nightly Repo (Update Site) - if you don't have all the source projects in your workspace, you can resolve dependencies against this site and install them from here. Once again, you can install everything, or just the pieces you need.

Build & run tests

With m2eclipse installed, you can simply right-click a project and select 'Run As > Maven Build (ALT-SHIFT-X, M)', which will prompt you complete a run configuration dialog. Here are the simplest options you need to set:

   Goals: clean install
   [x] Resolve Workspace artifacts

You can also run Maven to build your projects outside Eclipse, if you prefer.

If running outside Eclipse, you can run tests which are still tied to the Eclipse debugger.

Commit changes to master repo

Because there's no support yet for 'git svn rebase' or 'git svn dcommmit' you're stuck pushing changes to the master repo using the commandline. However, you can shorten the amount of typing needed using an .alias file. See below.

Use an .alias file

To avoid having to type the same git commands over and over, I use these shortcuts in my ~/.alias file:

# update local git-svn repo from master SVN repo
alias   gitup='for d in $(find . -maxdepth 1 -type d); do cd $d; echo $d; if [[ -d .git ]]; then git svn rebase; fi; cd -; done'

# Push local changes to master SVN repo
alias   gp='git svn rebase; git svn dcommit'

# commit local changes to local git-svn repo
alias   ci='git commit -m'

# check status of local git-svn repo
alias   stat='git status'

So, after committing changes (with eGit or via commandline) I can push those to the master SVN repo w/ a simple 'gp'. If your shell doesn't read the .alias file, make sure your .bashrc loads the file using one of these commands:

source /home/yourUserName/.alias
. /home/yourUserName/.alias
Or, put them directly in your .bashrc file.


Git vs. SVN - Basic Commandline Syntax Reference

Learning the git workflow takes a bit of brain retraining, but since I've been using SVN almost entirely via commandline (because Subversive sucks and locks up my Eclipse when I try to use it for anything beyond synching/updating/committing a handful of files), adopting git's commandline syntax is reasonably similar. Consider these simple operations:

Initial checkout from existing repo for a given branch git clone; cd sonatype-tycho; git checkout origin/tycho-0.10.x svn checkout
Update locally checked out files from central repo git pull svn update
List locally changes files/folders git status svn stat
Diff locally changed file git diff somefile.txt svn diff somefile.txt
Revert locally changed file* git checkout somefile.txt svn revert somefile.txt
Revert ALL local changes (except untracked files)* git reset --hard HEAD svn revert . -R
Add new file git add file.txt svn add file.txt
Add new folder recursively git add folder svn add folder
Delete file git rm file.txt svn rm file.txt
Delete folder git rm -r folder (non-recursive by default; use -r to recurse) svn rm folder (recursive by default; use -N to not recurse)
Commit changed file to central repo git commit -m "message" file.txt; git push svn ci -m "message" file.txt
Ignore files/folders (in the current folder) echo "target
bin" > .gitignore; \
git ci -m "gitignore" .gitignore
svn propset svn:ignore "target
bin" .; \
svn ci -N -m "svn:ignore" .

Obviously you can do a lot more w/ Git than with SVN (like stashing local changes temporarily), but for the sake of simply moving from a VCS to a DVCS and being able to continue to work the same way you already do, the above table should provide a good introduction.

My First Maven Plugin

Having been working with Maven and Tycho for about the last 8 months, it was high time I got around to writing my first Maven plugin, because I need to break myself from my tendency to revert to ant and bash whenever I need to do something outside the normal Maven flow.

So, first I imported the git sources for Tycho 0.11.0-SNAPSHOT from so I'd have something from which to learn. Sure, Hello World samples are nice, but a working example is always more fruitful.

git clone

Next, I imported a few Tycho projects (tycho-p2-facade, tycho-p2-plugin, tycho-p2-publisher-plugin) from the git clone folder into Eclipse using m2eclipse 0.10.2. Because these are Maven projects and don't need Eclipse project clutter, there are no .project files and therefore they couldn't be imported as pre-existing projects.

So, I had to wobble through the New > Maven Project wizard a little until I figured out that I could check the 'Create a simple project (skip archetype selection)' box to create a new .project file in an existing project folder. Only wrinkle here is that if there's an existing pom.xml in a project, the New Maven Project wizard complains. The obvious workaround is to rename the existing pom.xml to pom.xml_, create the new Maven Project in w/ m2eclipse in the existing folder (as above), then replace the pom.xml that m2eclipse creates with the actual (renamed) one, pom.xml_ and refresh the project in Eclipse. Voila! I also updated the project settings to use JDK5 instead of the default JDK1.4. You need only do File > Import > Maven > Existing Maven Projects and browse for the pom files. So much easier than what I did above. Thanks to everyone for setting me straight!

So, with sample code to clone from it was time to create my own plugin project, then a second project on which that plugin depended in order to test the dependency chain thru Maven.

The first uses the "maven-archetype-plugin" archetype v1.1; the second, the "maven-archetype-quickstart" archetype v1.1. Here are the two projects:

  1. sample-plugin
  2. sample-project

The glue between these projects is in the sample-project's pom.xml:

And that's seemingly it. Next... adding actual useful functionality to a plugin, then using that functionality in our JBoss Tools build's parent pom.xml.


In Which I Explain Once Again That Linux Is A Viable Alternative to Windows

I was recently asked this question:

Can linux be used for a normal computer, operating email programs, word processing, etc? I am quite frustrated with all the "improvements" that Windows keeps getting; each improvement making it slower and more prone to erratic behavior. I use a computer only for the above tasks, and would really like to get away from the problems.

As I've been telling friends, colleagues, family, and everyone who'll listen for about the past 5 years... YES.

  • Mail: Instead of Outlook, you can use Thunderbird.

  • Calendar: use Sunbird or go online w/ Google Calendar

  • Web: Instead of Internet Explorer, Firefox, Opera, Chrome, or Konqueror. None will "accidentally" install spyware for you.

  • Office: Instead of the bloated and dinosauric (20 years old!) MS Office's Word, Excel & Powerpoint, use Open Office's Writer, Calc & Impress. (Open Office is now 10 years old - old enough to be feature rich, young enough to be standards-compliant.)

  • Chat: instead of MSN, use pidgin (supports all IM protocols, including MSN, Yahoo, gtalk, IRC, Twitter, Facebook) and/or Skype (for audio/video chat)

  • Audio/Video playback & streaming: instead of Windows Media Player, VLC player.

  • Solitaire: PySol includes 200 solitaire games; Firefox "Cards" plugin contains dozens more.

More advanced users:

I personally use linux flavours designed for older machines so they're lightweight, faster, and less bloated. Then, if I need a more "bloated" app (like something from the KDE school instead of the XFCE or GDE school), I simply install that into the operating system as an add-on. Of course if you *want* eye candy (like 3D desktops and transitions when you open/close applications) you can get that too. It's pure eye candy, but it's available if you need Vista or Win7-like "bling".

If you want to try Linux before jumping in fully, I advise two options:

  • Xubuntu, designed for old machines and to stay more-or-less the same over time. Download and install it into Windows without having to reformat your hard drive. Good for your grandmother's desktop machine.

  • Fedora, designed for newer machines and to stay up to date with recent improvements in the Linux world. Can be installed onto a USB key so you can boot your system from that without having to touch your existing Windows install. Good for your parents or your machine, or for an office.

  • There are of course lots of other Linux distros out there...


HOWTO: Find the feature that contains a plugin

Tycho is awesome.

However, like all build systems, it has its limitations.

One such limitation is that when you're building against a target platform, and something's missing, you get errors such as these:

[INFO] Cannot complete the request.  Generating details.
{org.osgi.framework.executionenvironment=OSGi/Minimum-1.0,OSGi/Minimum-1.1,, osgi.arch=x86, osgi.os=macosx, org.eclipse.update.install.features=true, org.osgi.framework.system.packages=}
[Software being installed: 1.2.0.qualifier, Missing requirement: org.eclipse.tptp.platform.instrumentation.ui 4.4.1.v201009092123 requires 'bundle org.eclipse.hyades.probekit [4.2.0,5.0.0)' but it could not be found, Cannot satisfy dependency: 4.3.1.v201009092123-797908s73533D4H6D56 depends on: org.eclipse.tptp.platform.instrumentation.ui [4.4.1.v201009092123], Cannot satisfy dependency: 1.2.0.qualifier depends on: 4.3.0]
[ERROR] Internal error: java.lang.RuntimeException: org.eclipse.equinox.p2.core.ProvisionException: No solution found because the problem is unsatisfiable. -> [Help 1]
org.apache.maven.InternalErrorException: Internal error: java.lang.RuntimeException: org.eclipse.equinox.p2.core.ProvisionException: No solution found because the problem is unsatisfiable.

The important part of that error message is as follows: 1.2.0.qualifier
   requirement: org.eclipse.tptp.platform.instrumentation.ui 4.4.1.v201009092123 
      requires 'bundle org.eclipse.hyades.probekit [4.2.0,5.0.0)' 
         but it could not be found 4.3.1.v201009092123-797908s73533D4H6D56 
   depends on: org.eclipse.tptp.platform.instrumentation.ui [4.4.1.v201009092123]
     dependency: 1.2.0.qualifier 
        depends on: 4.3.0]

So, how do you find which feature contains that plugin, so that you can add it to your target platform?

First, you need access to the repository. If you have direct server access to the repository from which the plugin comes (eg., the TPTP Helios update site), you can run this script in the root of that repository.

If you don't have server access (eg., you can't ssh to and look in ~/downloads/tptp/updates/helios), then you can pull down a zip of the site (or use a p2.mirror script to fetch a copy of the site to your local machine)... and then run this script in the root of that repository.

Essentially the script finds matching feature jar files, unpacks them to extract the feature.xml files therein, and then greps those files for lines which suggest an included plugin matching the pattern for which you're searching:

$ findInFeature platform.probekit

From there, it's a trivial exercise to add another line item into your target platform file. First, paste in the feature jar:

Then use vim to pattern-replace that string:


And you'll end up with a new added to the target:

<unit version="4.5.1.v201009092123-7H7BF8PAkF7B77ZARCNEK" id=""/>


JBoss Tools: making it easier to build against a complex target platform

So you want to be a JBoss Tools developer? Awesome. Welcome to the family. SVN sources are here, JIRA's over here and there's cold beer in the fridge*.

But you say it's a pain in the tuchus to download over 25 zips or add a whole bunch of update sites and hope you get everything you need? Yeah, no argument there. If only there was an easier way to resolve all the dependencies you need to get building, much less to even RUN this stuff.

To make this process simpler, I've created a p2 repo (update site) from our target platform file, which has been recently updated to include Helios SR1 dependencies. You can track subsequent work in progress here: JIRA JBIDE-6982. You can also report any issues there too.

So, now, just add this single site** into your vanilla Eclipse 3.6.1 Classic (or a Helios SR1 bundle), uncheck the box for 'Group Items by Category' and you can install everything listed. For great justice.

Some handy links:

Some handy HOWTOs:

* - Due to beer2peer limitations, YMMV.

** - I'm aware that the update site throws a 403 if you open it in a browser. I can't be arsed to generate an index.html just yet, nor are there categorized features. Because really, you don't need either - this site is only meant to be used by p2.


Linux modem tethering with berry4all, Rogers 3G network, and Blackberry Bold 9000

Because I'll be out of town for the next couple days, part of my packing list included setting up tethering via my Blackberry.

First I tried barry but was unsuccessful in trying to make a successful connection.

Then I found berry4all.

I had two problems, but thanks to the extensive FAQ, I managed to solve them:

  1. Ensure your device (in my case, Blackberry Bold 9000) has its APN correctly set in Setup > Options > Advanced > TCP
  2. Ensure other network connections are disabled using route -n; ifconfig -a before attempting to connect via tethered 3G modem. See also If your PPPD does not support replacedefaultroute
  3. Ensure /etc/resolv.conf is being correctly updated with the appropriate DNS entries (I have to do this by hand at the moment, but tweaked the default /opt/bbtether/ script to add this line so that I can automatically update the file immediately before connecting:
    cp -f /etc/resolv.conf.bbtether /etc/resolv.conf
    python &
    where /etc/resolv.conf.bbtether contains:
  4. Load up a bandwidth speed test such as and see what network speed you can get.

Admittedly, tethered speeds are nothing close to wifi speeds.

  • With Rogers 3G network and Blackberry Bold 9000 attached via USB, I managed to get about 500-2800kbps down and 100-200 kpbs up.
  • With Rogers "Exterme" cable internet access (wifi @ home) I get 9800kbps down, 960kbps up.

But at least I can surf on my laptop using the 3G network while I'm away from the office.

To disconnect wired & wifi, then tether automatically and stay connected until CTRL-C is pressed, try this script:

if [[ $UID != 0 ]]; then
 echo "Must be run as root!"
 /etc/init.d/network stop
 cp /etc/resolv.conf.bbtether /etc/resolv.conf
 route -n; ifconfig

 cd /opt/bbtether; python rogers -P **YOUR_DEVICE_PASSWORD_HERE**

 /etc/init.d/network start
 route -n; ifconfig


p2 Repository Association And The Fine Art Of Forceably Enabling Disabled Sites 2: Tycho Edition

Back in February, I blogged about how to add associate sites to an update site generated w/ the Buckminster or B3 aggregator.

Since we've moved our build infrastructure to use Tycho + Maven, I had to port the script over to work there for our update site aggregation.

Here are the moving pieces:

  • pom.xml that builds the site, listing input sites as <repository> entries, and a shout-out to build.xml, below, to do extra stuff during the install phase
  • build.xml ant script called by pom.xml, above, to do additional work after the creation of the update site zip
  • properties file listing the aggregate sites to add


Troubleshooting Mirrors / Using Profiles & Target Platform Definition Files With Tycho

If you look in the mirror and you say his name 5 times, he'll appear behind you breathing down your neck. - Candyman

If only troubleshooting mirrors was so simple. Have you ever been running a build or an install which stalls at the provisioning step, with a message like:

[INFO] Fetching org.eclipse.birt.integration.wtp.ui_2.6.0.v20100617-1315.jar.pack.gz (4.3MB of 46.13MB at 171.56kB/s) from

The solution here is often simply to force p2 to pick a specific mirror rather than letting it choose any mirror it wants.

How, you ask?

Well, assuming you were polling this site looking for artifacts to install or update...

... you would then change that URL to this, and look at the list of available mirrors:

Now it's a trivial matter to select a mirror that's close to you and try that instead of the mirror, such as:

If you're running a Tycho build, this URL should be changed in your parent-pom.xml ...


... or your .target platform file, depending on which way you're building.

<repository location=""/>

If you rely on a parent-pom.xml, make sure you're activating the profile with the revised URL...

mvn3 clean install -U -B -fae -Phelios

... or, if you're building against a .target platform file, make sure you update the URL in that file, and that your build points to the profile which will load the .target file.

mvn3 clean install -U -B -fae -P!helios,helios-no-target

UPDATE, 2010/08/11: Forgot to mention that there are a number of p2 update site zips available here to help with your offsite mirroring:


Blog comments or spam? No idea.

I don't speak Chinese. Or Korean. Or Japanese. I mention this because lately I've been getting a couple comments per post in a foreign character set, and I can't tell if it's spam or a legit comment.

Please, if you have something to say, stick to English, French, German, or Spanish. Hell, even Latin, lolcode, or twitterspeak. Anything other than that I'll just delete as spam.




Update Site Aggregation: B3 vs. Tycho

Last year, I used to aggregate update sites with the Buckminster Aggregator, but since that won't install into Eclipse 3.6 (Helios), I had to migrate to the B3 Aggregator. This new version of the Aggregator is greatly expanded and worked fine until recently, when it has begun to suffer from a rather nasty p2 problem: instead of the Director just installing the aggregator into an Eclipse instance prior to then running the aggregation, I get "The copies of profile SDKProfile are not in sync," and the whole process dies.

So, in order to find a workaround, I went back to Tycho, and discovered you can merge update sites with little more than two simple files:

  • a site.xml, which lists the features to aggregate and how to categorize them, and
  • a pom.xml to list the source sites and drive the aggregation.

Unfortunately the Tycho solution doesn't include the ability to add associate sites to the metadata after generation, but that can simply be done as a downstream step (Tycho can call Ant using the maven-antrun-plugin).


pogoplug network attached storage (NAS) for linux, mac, windows

A couple months ago I bought a PogoPlug. Because it's an ungodly pink colour and because I've been hella busy with other stuff, I finally unboxed it today, and discovered that while:

... setting it up for Linux was not entirely trivial.

While the above article helped, a couple points were not immediately obvious:

  • If you mount the drive as root, it's not accessible as anyone else; if you mount as the user, not even root can read it.
  • Use of a /etc/pogoplugfs.conf file is highly recommended, so that you can log in w/o having to key in your username and password every time. Create this file as root, and set it chmod 644 if not already:
  • To automount the drive on startup (eg., on my old xubuntu 6 system), as root, try creating a new file, /etc/init.d/pogoplug:
    #! /bin/sh
    # Provides:          
    # Required-Start:    $remote_fs $syslog
    # Required-Stop:     $remote_fs $syslog
    # Should-Start:      $named
    # Default-Start:     2 3 4 5
    # Default-Stop:      1
    # Short-Description: pogoplug fs mount as myusername
    # Description:       pogoplug fs mount as myusername
    sudo -u myusername /usr/bin/pogoplugfs --mountpoint /media/pogoplug
    exit 0
  • Then, to activate this file, as root:
    chmod +x /etc/init.d/pogoplug; \
    for x in 2 3 4 5; do \
      cd /etc/rc${x}.d; ln -s /etc/init.d/pogoplug S99pogoplug; \

With Fedora 12, I could simply create a startup task using System < Preferences < Startup Applications from the gnome menu.


#FailWhale v2.0

#Fail Bot?
-- Someone's been watching too much made-for-tv sci-fi, I think


My love-hate with SVN, Part 8: Installation Ease Of Use (UPDATED)

Back in July 2009, I blogged about My love-hate with SVN, Part 6: Installation Ease Of Use. With Helios just around the corner, I wanted to produce an updated repo for use with the latest & greatest Eclipse 3.6.

Now the <p2.mirror/> script will fetch and use Ant-Contrib automatically.

Here's the updated 15M update site zip, which includes the following:

Subversive 0.7.9
SVN Connector 2.2.2
SVNKit 1.3.3
JNA 3.2.3
ECF 3.1.0
Any problems, please report them in bug 284077.


So long and thanks for all the faece

I'm done with Faecebook. Here's why. And here's how to quit. I encourage you to do the same.

Instead, find me on Twitter and LinkedIn.


HOWTO: Build a XulRunner Update Site with Tycho 0.8 + Maven 3

0. Install Maven 3 by downloading then unpacking the tar.gz:

cd /tmp; \
wget; \
tar xvzf apache-maven-3.0-alpha-7-bin.tar.gz; \
chmod 755 apache-maven-3.0-alpha-7/bin/mvn; \
alias mvn3='/tmp/apache-maven-3.0-alpha-7/bin/mvn'

1. Check out sources:

cd /tmp; \
svn co; \

2. Run build:

cd xulrunner; mvn3 -fae clean install

3. You will get a p2 repo / update site in the target folder of the site project, from which you can install XulRunner or XPCOM into your Eclipse.

cd site/

Note that the parent-pom.xml used above can in fact be much simpler. You only need the following:
<?xml version="1.0" encoding="UTF-8"?>
  <name>JBoss Tools Parent</name>



Better Bootstrapping For Athena Projects

Inspired by Tycho and Maven, I've simplified the self-bootstrapping process for Athena builds.

Previously, you needed a script to fetch org.eclipse.releng.basebuilder and org.eclipse.dash.common.releng before you could run a build; if on this is done for you automatically. Or, if building locally (or on Windows), you had to fetch these yourself.

Now, you can simply tell your build.xml to bootstrap itself, and it will fetch those projects for you. You can also tell it which version of basebuilder or common.releng to use, rather than being tied to the defaults.

For details, see Getting Started - Bootstrapping.


Cleaner Ant Build Logs: Get Rid of "Trying to override old definition of task"

If you use macros in Ant, you have probably seen clutter in your log such as

Trying to override old definition of task ...

Here's how to purge this garbage from your log and keep your build output cleaner.

  1. move your macros into a target such as <target name="init">
  2. have your main target(s) depend on the target that defines the macros
  3. call your macros

You can make your log even quieter with -q when running ant, eg., ant -f build.xml -q

Here's a complete example that will first self-bootstrap itself by downloading Ant-Contrib, define two ant macros, and produce very quiet output (unless debug=true):

<project default="run">
 <property name="COMMON_TOOLS" value="${}" />
 <property name="debug" value="false"/>

 <target name="get.ant-contrib" unless="ant-contrib.jar.exists">
  <property name="ANTCONTRIB_MIRROR" value="" />
  <get usetimestamp="true"
  <touch file="${COMMON_TOOLS}/" />
  <mkdir dir="${}/ant-contrib-1.0b2-bin.zip_" />
  <unzip src="${COMMON_TOOLS}/"
  <copy file="${}/ant-contrib-1.0b2-bin.zip_/ant-contrib/lib/ant-contrib.jar"
  <delete dir="${}/ant-contrib-1.0b2-bin.zip_" includeemptydirs="true" quiet="true" />

 <target name="init">
  <available file="${COMMON_TOOLS}/ant-contrib.jar" type="file" property="ant-contrib.jar.exists" />
  <antcall target="get.ant-contrib" />

  <taskdef resource="net/sf/antcontrib/antlib.xml">
    <pathelement location="${COMMON_TOOLS}/ant-contrib.jar" />
  <macrodef name="debug">
   <text name="echo" />
      <isset property="debug" />
      <istrue value="${debug}" />
      <echo message="@{echo}" />

  <macrodef name="list.count">
   <attribute name="list" default="" />
    <var name="count" value="" />
    <for param="listitem" list="@{list}" delimiter=", ">
      <var name="count" value="${count}0" />
    <length property="list.count.return" string="${count}" />

 <target name="run" depends="init">
  <property name="list" value="foo bar baz"/>
  <list.count list="${list}" />
  <debug>For list [${list}], size = </debug>



HOWTO: Build Plugin & Feature Projects, Then Run Their Unit Tests w/ Tycho :: GEF Example

Note that the instructions below are for Linux (or MacOSX). On Windows, your YMMV, but the process is the same.

1. Check out the entire source tree of your project from CVS, SVN, or Git into ~/build.

2. If needed, move plugins, features & test plugins into:


(Test features should go into features/ folder too.)

3. Install scala from

4. Fetch genpom.scala and parent-pom.xml; save in ~/build or equivalent.

5. Tweak parent-pom.xml to suit your needs or use as-is.

6. Run this to generate pom.xml files for plugins, features, and tests:

cd ~/build/plugins/; scala ../genpom.scala
cd ~/build/features/; scala ../genpom.scala
cd ~/build/tests/; scala ../genpom.scala

7. Download Maven 3 from

8. Install Maven 3

sudo su; cd /opt; tar xvzf apache-maven-3.0-alpha-7-bin.tar.gz
ln -s apache-maven-3.0-alpha-7 maven3

9. For convenience, alias mvn3 to the new maven:

alias mvn3='/opt/maven3/bin/mvn 2>&1 clean install | tee buildlog.latest.txt'

10. Build the plugins, features, and finally tests:

cd ~/build/plugins/; mvn3
cd ~/build/features/; mvn3
cd ~/build/tests/; mvn3
Look in ~/build/plugins/org.eclipse.*/target/ for generated jars.
Look in ~/.m2/repository/org/eclipse/* for published jars.
To automate steps 6 and 10, you can run this script in the ~/build/ folder:
for f in plugins/ features/ tests/; do \
  cd $f; scala ../genpom.scala; \
  /opt/maven3/bin/mvn 2>&1 clean install | tee buildlog.latest.txt; \
  cd ..; \

(The above blog is also posted here.)


Dash Athena: Post-EclipseCon Wrap-Up

Updates to Athena since Feb 2010

Ease of use

  • You can now run buildExtra.xml#extraPackaging via build.steps=buildExtra rather than requiring build.steps=buildZips.
  • Publishing support will improve thanks to bug 306854... anyone want to contribute to writing a Hudson job, please feel free!

Packaging Support

  • bug 306300 Athena removes .jar files and only contains pack 200 files in update site - new default setting (keep both artifact types) is removeUnpackedJars=false, but can revert to old behaviour (and smaller update site) with removeUnpackedJars=true
  • bug 307016 SDK and Runtime zips produced with buildZips target are missing {notice,epl-v10}.html files; if root files exist they will now be copied into the SDK, Runtime, Examples zips; ${allZip} will also include this so it can be copied from there too (custom packaging in buildExtra.xml#extraPackaging task)

Testing Support

  • bug 296352 Can't connect to vnc server - fixed using Xnvc option in Hudson job and improvements to testLocal task

Publishing Support

  • bug 302170 Work around Hudson's missing lastS*Build folders - promote.xml will now recurse into Hudson job tree looking for correct build to publish
  • Publishing support will improve thanks to bug 306854... anyone want to contribute to writing a Hudson job, please feel free!

Bug Fixes

  • bug 304800 Temporary regression caused by adopting new build.xml script with too-aggressive cleanup default
  • bug 307016 SDK and Runtime zips produced with buildZips target are missing {notice,epl-v10}.html files; if root files exist they will now be copied into the SDK, Runtime, Examples zips; ${allZip} will also include this so it can be copied from there too (custom packaging in buildExtra.xml#extraPackaging task)

Documentation & Branding

  • bug 272723 Logo design contest for Athena under way: vote early, vote often!


I'm in love with Tycho 0.8 and Maven 3


Signed up for GitHub, downloaded apache-maven-3.0-alpha-7-bin.tar.gz, and built Tycho from source. Took a bit of path wrangling (namely figuring out that maven runs based on current directory), but it built and most of the tests passed. Not bad for my first day ever using Maven.

# First download Maven3 and unpack into /opt/
export MAVEN_OPTS="-Xmx512m"
export TYCHO_TARGET_PLATFORM=/home/nboldt/eclipse/35clean/eclipse
$mvn clean install -e -V -Pbootstrap-1
$mvn clean install -e -V -Pbootstrap-2 -Dtycho.targetPlatform=$TYCHO_TARGET_PLATFORM
$mvn clean test -e -V -Pits -Dtycho.targetPlatform=$TYCHO_TARGET_PLATFORM

The really confusing part was "what now? what did I just build? And how do I use it?" Answer: You can now run maven3 from .../sonatype-tycho/tycho-its/target/apache-maven-3.0-alpha-7/bin/mvn


Attended the Sonatype-sponsored Tycho Build Workshop, and amazed Pascal by saying good things about Tycho and Maven3. Apparently I'm known to complain about all things p2, despite my numerous blogs and wiki contributions touting its success and usefulness. Also installed m2eclipse to see how effective the pom editor is.

During the workshop, I got the following JBoss Tools projects to build: jmx, archives, as, flow, jbpm3/4, drools, bpel, smooks, common. That's nearly half our projects! Thanks to Jason and Igor for their invaluable assistance.

The reason it was so easy was that Max had already created a scala script to generate all the pom.xml files we need to build JBoss Tools, and a parent-pom.xml on which those tiny pom.xml files depend. (For me as a Maven noob, not having to think at all about creating poms made this transition a no-brainer. Speaking of no-brainers, my slides from Monday's talk about Dash Athena and Zombies are here (PDF).

As an added bonus, Tycho, being more strict than PDE, exposes missing information in MANIFEST.MF files such as dependencies on plugins. PDE-based builds are apparently more forgiving because they generally include more crap than is actually needed in the target platform against which the build runs; Tycho builds against what you tell it you need. So, the mavenification of JBoss Tools will actually cause us to have better described plugins, and therefore make them easier to build anywhere. I'm very impressed so far.

Unlike Dash Athena which needs to be told all the IUs (features/plugins) against which your project needs to build, Tycho determines this information from your manifests, so the information need not be duplicated.

I still need to look at how to build update sites from the output of a Tycho build, and how to hook in SWTBot/JUnit4 tests. I have a suspicion this may be handled using Buckminster tools such as their Aggregator, or my own custom Ant hackery using the SWTBot wiki docs. Time will tell.


This morning on a whim I decided to see if I could port Max's scala script (aside: I've never seen scala before yesterday) to generate pom.xml files for EMF or GEF. Success! With some minor tweaks, I've managed to build GEF 3.6 into my local maven repo (~/.m2). Obviously there's more to be done here... but damn, this is easy.


Beyond CVS 0.8.9 Released!

It's true that the shoemaker's children often go shoeless; so to my little Sourceforge project, Beyond CVS/SVN - maintained tirelessly over the years by Chris Callendar - has had to wait *years* to finally get its own update site.

Sad, I know. But thanks to a recent breakthough in being able to insert associate sites into p2 repo metadata, you can now install Beyond CVS/SVN without having to hunt down Subclipse or Subversive's update sites.

Here's the new site: If you point Eclipse at it, you can install the features therein. If you point a browser at it, you can see instructions for how to do the install. And if you want an offline install, here's the zip: (README).


Athena: p2 repos w/ associate sites

Want to insert associate update sites into your user's Eclipse when they go to install your features from an update site/zip? With an Athena build this is now a trivial exercise. For example... say you're building a plugin which supports integration with Subclipse or Subversive. In a traditional install from an SDK or runtime zip, you'd unpack into eclipse/, and wonder why the new plugins didn't work. In the new p2 install world, you point Eclipse at the update site or zip, and are told that you cannot install the SVN integration because missing requirements cannot be found. So you hunt down the required sites, add them to Eclipse, and try again; this time you are allowed to install the new features. To improve the ease of use for the end user, Athena now allows you to define associate.sites in your If this property is set, URLs will be added into your p2 repo's metadata and Eclipse will automatically add those sites when it scans your zip or site. No more manual copy+paste from documentation needed!

And, of course, you can reuse these sites when resolving dependencies against which to build or test:


p2 Repository Association And The Fine Art Of Forceably Enabling Disabled Sites

This week I've spent some time exploring how to associate p2 repo sites with other sites. The reason for this is that we publish features which depend on other publishers' features, and so would like to be able to have our update site automatically enable sites on which we depend in the end user's Eclipse.

The first attempt to do this was by using p2.inf files. Based on examples on blogs and in newsgroups, I added this p2.inf file into our BIRT Integration feature:

instructions.configure=addRepository(location:http${#58}//,type:0,name:Eclipse Galileo,enabled:true); \
   addRepository(location:http${#58}//,type:1,name:Eclipse Galileo,enabled:true); \
   addRepository(location:http${#58}//,type:0,name:Eclipse 3.5,enabled:true); \
   addRepository(location:http${#58}//,type:1,name:Eclipse 3.5,enabled:true); \
   addRepository(location:http${#58}//,type:0,name:BIRT 2.5,enabled:true); \
   addRepository(location:http${#58}//,type:1,name:BIRT 2.5,enabled:true);
Unfortunately, this didn't work - I got this error while building:

 java.lang.IllegalArgumentException: No action found for: addRepository.

So, hoping that using a fully-qualified name for the action would help, I tried this:

instructions.configure=org.eclipse.equinox.p2.touchpoint.eclipse.addRepository(location:http${#58}//,type:0,name:Eclipse Galileo,enabled:true); \
   org.eclipse.equinox.p2.touchpoint.eclipse.addRepository(location:http${#58}//,type:1,name:Eclipse Galileo,enabled:true); \
   org.eclipse.equinox.p2.touchpoint.eclipse.addRepository(location:http${#58}//,type:0,name:Eclipse 3.5,enabled:true); \
   org.eclipse.equinox.p2.touchpoint.eclipse.addRepository(location:http${#58}//,type:1,name:Eclipse 3.5,enabled:true); \
   org.eclipse.equinox.p2.touchpoint.eclipse.addRepository(location:http${#58}//,type:0,name:BIRT 2.5,enabled:true); \
   org.eclipse.equinox.p2.touchpoint.eclipse.addRepository(location:http${#58}//,type:1,name:BIRT 2.5,enabled:true);

Success! The build no longer complained. Of course I wasn't getting any associate sites enabled when I added the new repo into Eclipse. Why, I wondered?

Thankfully, I was told that the now-deprecated Metadata Generator (org.eclipse.equinox.p2.metadata.generator.EclipseGenerator) doesn't support p2.inf files, so it was finally time to switch to Eclipse 3.5's Update Site Publisher (org.eclipse.equinox.p2.publisher.UpdateSitePublisher), which can be run like this as a drop-in replacement for the above application:

<echo>Run p2.publisher.UpdateSitePublisher using launcherjar = @{launcherjar}</echo>
<java jar="@{launcherjar}"
      fork="true" timeout="10800000"
      failonerror="false" maxmemory="256m" taskname="p2">
  <fileset dir="${}/plugins"
           includes="org.eclipse.equinox.launcher_*.jar, org.eclipse.equinox.p2.publisher_*.jar, org.eclipse.equinox.p2.updatesite_*.jar"
  <fileset dir="${clean.eclipse.home}/plugins"
           includes="org.eclipse.equinox.launcher_*.jar, org.eclipse.equinox.p2.publisher_*.jar, org.eclipse.equinox.p2.updatesite_*.jar"
  <pathelement location="${}/plugins" />
  <pathelement location="${clean.eclipse.home}/plugins" />
 <arg line=" org.eclipse.equinox.launcher.Main -application org.eclipse.equinox.p2.publisher.UpdateSitePublisher" />
 <arg line=" -metadataRepository file:${updateSiteJarDir}/ -metadataRepositoryName "${} ${} Update Site"" />
 <arg line=" -artifactRepository file:${updateSiteJarDir}/ -artifactRepositoryName "${} ${} Artifacts"" />
 <arg line=" -source ${updateSiteJarDir}/" />
 <arg line=" -compress -publishArtifacts -reusePack200Files -configs *,*,*" />

Having switched out the deprecated app for its successor, I then discovered that using the instructions.configure touchpoint was way too late in the process to be of any use; this information is only used when you install the feature, not when you poll the repo for metadata. So to add the BIRT 2.5 update site I'd have to install the BIRT integration feature... which depends on the BIRT 2.5 site. I needed to inject this requirement in at an earlier point in the process.

So, the next step was to hit up #equinox-dev and ask for help, which I got from Pascal "LeNettoyeur" Rapicault, fellow IBM alumnus. He suggested that I append into the content.xml file in my repo the following information. Note that type 0 and 1 represent metadata repo and artifact repo, and options=1 or 0 is used to mark the site enabled or disabled.

  <references size='2'>
    <repository uri=''
url='' type='0' options='1'/>
    <repository uri=''
url='' type='1' options='1'/>

Success, I again thought, since the associated sites were finally being added and enabled into Eclipse when the repo was scanned for metadata. I even scripted this process so that it could be integrated into our build process, or simply reused, eg., to merge two update sites and add some associate site for optional feature installs.

But alas, every step forward brings another step backward, as I discovered that available but disabled sites are NOT enabled despite the instructions in the repo. In other words, I cannot force an existing, yet disabled site to become enabled because my repo requires it. I can only document the requirement and hope that users will RTFM without getting too annoyed.

So, what's the solution? Well, there currently isn't one. But if this scenario seems like something you'd like to see improved, please cast your votes & comments in one of these bugs:


Ontario's capital now in the U.S.A.

Air Canada does not permit flight searches which have both an origin and destination in the United States.
-- When did Toronto (YYZ) move to the US? I suspect this is why Air Canada keeps needing federal bail out money: geography lessons.


Monitor fail

Well, that's a week of my life I'll never have again. Spent most of last week playing with WinXP, LinuxMint 8, and Fedora 11 & 12 (both 32- and 64-bit) trying to find a solution to my external display issues.

Turns out that it's a software issue: the latest xorg intel driver has a bug.

Humorous Pictures


Beyond Compare 3 for 64-bit ubuntu linux

Last week, I switched my xubuntu 8.04 (Hardy Heron) box to Linux Mint 8 (Helena), to see how things had evolved in the past 18 months. Unfortunately, I also decided to switch from 32- to 64-bit, and of course not everything works the way it used to.

Luckily, the good folks at Scooter Software pointed me to this hack to allow their 32-bit Linux flavour of Beyond Compare 3 to find the 32-bit libraries it needs to run.

So, here's an updated version of that hack for ubuntu 9.10 Karmic Koala or Linux Mint 8 Helena:

  1. Download the i386 libqt3-mt .deb package into /tmp
  2. Download the latest Beyond Compare 3 .deb package into /tmp
  3. $ sudo su
  4. apt-get install ia32-libs
    cd /tmp; dpkg-deb --extract /tmp/libqt3-mt*.deb libqt3-mt
    cp -R libqt3-mt/usr/lib/* /usr/lib32; rm -fr /tmp/libqt3-mt
    dpkg -i --force-architecture /tmp/BCompareLinux*.deb


PDE Best Practices : A Noob's Guide To Plugin & Build Health

I've drafted a collection of tips for keeping your plugins healthy and your builds green.

Feel free to add to, change, or comment on the list here:

Switching monitors with xrandr

Sure, there are applets and other GUI tools to do this, but nothing beats the purity of going commando, er, commandline. :) Thanks to this article for the inspiration.

# reset 
xrandr --auto

# turn off laptop screen
xrandr --output LVDS --off

# 24" 16x12 on
xrandr --output VGA --mode 1600x1200

# reset 
xrandr --auto

# turn off external screen
xrandr --output VGA --off

# laptop screen on
xrandr --output LVDS --mode 1280x800

UPDATE, 2010/01/05:

To enable both screens and force the larger one to include the taskbar:

# reset 
xrandr --auto

# laptop screen on
xrandr --output LVDS1 --mode 1280x800 --noprimary --pos 1600x0

# 24" 16x12 on
xrandr --output VGA1 --mode 1600x1200 --primary --pos 0x0

# echo current status
xrandr --current