March 3, 2017

Drawing Phylograms with Java

I know we don't often post technical tips on this blog, but this particular problem took so long to dig up a solution to that I thought it might be worth sharing with the wider community to save anyone else from getting a headache.

A recent project required me to construct phylogenetic trees and illustrate them as phylograms with selected nodes highlighted in a different colour. In Java, programatically, and entirely server-side (the end results being downloadable as PNG files via standard HTTP URLs). Turns out that this is actually quite a big ask - there are lots of Java tools for drawing phylo trees, but none of them are able to include the node-highlighting feature without interacting with them via a GUI - not so great for doing things from inside a script.

Christian Zmasek saved the day with his Forester library. Not only does his software support script-based generation of tree diagrams, but it also has a very cool and succinct method for highlighting selected nodes in different colours (and Christian very kindly created a new HowTo entry for me to demonstrate how this feature works - see here).

This worked great on my Mac laptop that I use for coding work. Then, I uploaded it to an Amazon instance for remote testing and started getting horrible HeadlessExceptions. Turns out that the Forester library works its magic by firing up the Archaeopteryx application window in the background, invisibly, and 'faking' interactions with it to make it render the tree as required. The application is built around a JFrame - and JFrames are one of the very few parts of Java Swing that do not work at all in headless environments, even with the java.awt.headless flag set to true. 

What to do? Nothing really - if JFrames don't work then that's a Java issue that is largely unsolveable. But... you can trick it!

Using the Xvfb tool (in this case on Ubuntu Linux) you can set up a 'fake' windowing environment on your server that tricks Java into thinking it is opening up real windows, even though no such thing is actually happening. Simply by adding Xvfb into the list of things to start at boot, before Tomcat, and including a command in Tomcat's setenv.sh to set the DISPLAY variable, you can trick Java into making JFrames work even in this technically headless environment (of course you also have to make sure you do _not_ set the java.awt.headless flag).

Problem solved, and now my project-in-progress is generating very nice phylogram PNG images. Thanks Christian!

Topics: Bioinformatics, java