Absolute Path of a Servlet Installation

I’m currently developing some Java Servlets and one of the tasks is to create images dynamically. But where to store them accessible for users?

If you want to show the user for example a graph of some stuff that changes frequently you need to generate the image dynamically. The rendering of the graphic is one thing, but where to store the picture so that the visitor can access it from the web?

There were many options to try, and I found that getServletContext().getRealPath (".") from ServletRequest was the result I’ve been looking for. So to spare you the tests I’ll provide the different options (download):

Let’s assume your webapps-directory is /var/lib/tomcat6/webapps/ , your servlet context is project and the user asks for the servlet test the output probably looks like:

new File (".").getAbsolutePath () => /var/lib/tomcat6/.
request.getPathInfo () => null
request.getPathTranslated () => null
request.getContextPath () => /project
request.getRealPath (request.getServletPath ()) => /var/lib/tomcat6/webapps/project/test
request.getServletPath () => /test
getServletContext ().getContextPath () => /project
getServletContext ().getRealPath (".") => /var/lib/tomcat6/webapps/project/.

That’s it for the moment ;-)

Download: Java: ServletTest.java (Please take a look at the man-page. Browse bugs and feature requests.)

MFC-9120CN Setup

I just bought a new printer, the Brother MFC-9120CN. It’s also able to scan and to copy documents and to send them by fax. Since the installation instructions are win/mac-only I’ll shortly explain how to setup the device in a Linux environment.

My new MFC-9120CN
My new MFC-9120CN

Decision for this printer

First of all I was searching for a printer that is in any case compatible to Linux systems. You might also have experiences with this driver f$ckup, or at least have heard about it. The manufactures often only provide drivers for Win or Mac, so you generally get bugged if you want to integrate those peripherals in your environment. The MFC-9120CN scores at this point. It is able to print and scan via network. Drivers for the printer are available and the the scanned documents can be sent at any FTP server. So you don’t need to have special drivers for scanning, just setup a small FTP server. This model is also a very cheap one compared to other color-laser MFP’s, and with the ADF it completely matches my criteria.


I already noticed some disadvantages. One is the speed, the printer is somewhat slow. Since I’m not printing thousands of pages it’s more or less minor to me, but you should be aware of that. Another issue is the fact, that the device always forgets the date if it is turned of for a time.. And the printer is a bit too noisy.


The printer comes with a large user manual (>200 pages). It well explains setup the fax functionality, but the installation of the network printer and scanner is only described for win/mac, so I’ll give you a small how-to for your Linux systems.

Network Setup

To use this device via network you have to connect it to a router. It should be able to request an IP via DHCP, but if you don’t provide a DHCP server you need to configure the network manually (my values are in parenthesis):

  • IP: menu->5->1->2 ( )
  • Netmask: menu->5->1->3 ( )
  • Gateway: menu->5->1->4 ( )

If this is done you should be able to ping the printer:

usr@srv % ping
PING ( 56(84) bytes of data.
64 bytes from icmp_req=1 ttl=255 time=0.306 ms

If you browse to this IP using your web browser you’ll find a web interface for the printer. We’ll need this website later on.

Printer Setup

Big thanks to the CUPS project, it’s very easy to setup the network-printer! If you haven’t installed cups yet, do it now:

aptitude install cups foomatic-db

Just browse to your CUPS server (e.g. http://localhost:631 if it is installed on your current machine) and install a new printer via Administration->add Printer (you need to be root). Recent CUPS versions will detect the new printer automatically and you’ll find it in the list of Discovered Network Printers. Just give it a name and some description, select a driver (I’m using Brother MFC-9120CN BR-Script3 (color, 2-sided printing)) and you’re done! Easy, isn’t it!? ;-) For those of you that have an older version of CUPS: The URI of my printer is dnssd://Brother%20MFC-9120CN._printer._tcp.local/ .

Scanner Setup

As explained above, the printer is able to send scanned documents to a FTP location. That is, there is no need for a scanner driver! Just install a small FTP server, I decided for ProFTPd:

aptitude install proftpd-basic

Make sure, that the /etc/proftpd/proftpd.conf contains the following lines:

DefaultRoot ~
RequireValidShell off
AuthOrder mod_auth_file.c  mod_auth_unix.c
AuthUserFile /etc/proftpd/ftpd.passwd
AuthPAM off

and create a new virtual FTP user:

ftpasswd --passwd --name YourPrinter --uid 10001 --home /PATH/TO/FILES --shell /bin/false

You will be asked for a password. The scanned documents will be stored in /PATH/TO/FILES . This command creates a file ftpd.passwd . Move this file to /etc/proftpd/ , if you didn’t execute the command in that directory. Restart ProFTPd:

/etc/init.d/proftpd restart

You should be able to connect to your FTP server:

usr@srv % ftp localhost
Connected to localhost.
220 ProFTPD 1.3.4a Server (Debian) [::ffff:]
Name (localhost:you): YourPrinter
500 AUTH not understood
500 AUTH not understood
SSL not available
331 Password required for printer
230 User printer logged in
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
200 PORT command successful
150 Opening ASCII mode data connection for file list
226 Transfer complete
ftp> quit
221 Goodbye.

If that was successful, let’s configure the scanner to use this FTP account. Use your web browser to open the interface of the printer (e.g. and go to Administrator Settings->FTP/Network Scan Profile (you have to authenticate, default login is admin and the password is access). Here you’ll find 10 different profiles that can be configured. Click for example on Profile Name 1 and modify the profile:

  • Host Address: The IP of the FTP server (e.g. )
  • Username: The username of the virtual FTP user you’ve created (e.g. YourPrinter )
  • Password and Retype Password: The password of the virtual FTP
  • Store Directory: /

If you submit these values you’ll be able to scan to your FTP server. Just give it a try! ;-)

Additional Notes

I recommend to configure your firewall to drop all packets of your printer that try to leave your own network.

Conditionally autoscroll a JScrollPane

I’m currently developing some GUI stuff and was wondering how to let a JScrollPane scroll automatically if it’s already on the bottom and the size of it’s content increases.

For example if you use a JTextArea to display some log or whatever, than it would be nice if the scroll bars move down while there are messages produced, but it shouldn’t scroll down when the user just scrolled up to read a specific line. To scroll down to the end of a JTextArea can be done with just setting the carret to the end of the text:

JTextArea log = new JTextArea (20, 20);
log.setEditable (false);
JScrollPane scroller = new JScrollPane ();
scroller.setViewportView (output);

// [...]

log.append ("your message");
log.setCaretPosition (log.getDocument ().getLength ());

But we first want to check whether the scroll bar is already at the bottom, and only if that’s the case it should automatically scroll down to the new bottom if another message is inserted. To obtain the position data of the vertical scroll bar on can use the following code:

JScrollBar vbar = scroller.getVerticalScrollBar ();

// get the current position
int currentPosition = vbar.getValue ();

// getMaximum () gives maximum + extent.
int maxPosition = vbar.getMaximum () - vbar.getVisibleAmount ();

if (currentPosition == maxPosition)
	// in this case we want to scroll after the new text is appended

Unfortunately log.append ("some msg") won’t append the text in place, so the size of the text area will not necessarily change before we ask for the new maximum position. To avoid a wrong max value one can also schedule the scroll event:

private void logText (String text)
	final JScrollBar vbar = scroller.getVerticalScrollBar ();
	// is the scroll bar at the bottom?
	boolean end = vbar.getMaximum () == vbar.getValue () + vbar.getVisibleAmount ();
	// append some new text to the text area
	// (or do something else that increases the contents of the JScrollPane)
	log.append (text + "\\n");
	// if scroll bar already was at the bottom we schedule
	// a new scroll event to again scroll to the bottom
	if (end)
		EventQueue.invokeLater (new Runnable ()
			public void run ()
				EventQueue.invokeLater (new Runnable ()
					public void run ()
						vbar.setValue (vbar.getMaximum ());

As you can see, here a new event is put in the EventQueue, and this event is told to put another event in the queue that will do the scroll event. Correct, that’s a bit strange, but the swing stuff is very lazy and it might take a while until the new maximum position of the scroll bar is calculated after the whole GUI stuff is re-validated. So let’s be sure that our event definitely happens when all dependent swing events are processed.


Some days ago I discovered galternatives, a GNOME tool to manage the alternatives system of Debian/Ubuntu. It’s really smart I think.

For example to update the default editor for your system you need to update the alternatives system via:

update-alternatives --set editor /usr/bin/vim

There is also an interactive version available:

update-alternatives --config editor

To see available browsers you need to run

update-alternatives --list x-www-browser

However, the alternatives system is a nice idea I think, but it’s a bit confusing sometimes. And installing a new group or adding another entry to an existing group is pretty complicated and requires information from multiple other commands beforehand.

With galternatives you’ll get a graphical interface to manage all these things. That really brings light into the dark! Just install it via

aptitude install galternatives

You’ll be astonished if you give it a try! ;-)

YOURLS Firefox Extension Version 1.4

I submitted a new version of the YOURLS Firefox extension.

It just contains some minor changes, but I want to inform my loyal readers! The add-on is currently in the review queue, hopefully this time I’ll get a complete review by the AMO-team ;-)

If you’re crazy you can try the new version, it’s available on SourceForge and on AMO.

UPDATE: I just received a fully review, so my add-on is finally stable!!

J-vs-T goes Java

I just ported the Jabber -vs- Twitter bridge to Java.

That was a point on my todo list for a long time, because I hate the hacked stuff from the improvised Perl solution. And in the end I finally did it ;-)

You can find the new XMPP to Twitter bridge with the name XTB in my sidebar. It’s now written in nice Java code, easy to understand and much easier to work with! So feel free to give it a try!

End of announcement! :P


Some days ago IonHunter came into the world!

IonHunter is the tool I’m actually developing to receive one of these diplomas. It’s is a software to identify biomarkers in a huge number of LC/MS runs. IonHunter is able to preprocess mass spectrometry data, to merge multiple runs of the same sample and also to correct retention time shifts to align various experiments.

The whole software is modularly designed and easy to extend with further plugins. So developers feel free to join my development!

Currently it isn’t published, but since it’s written in Java it will run on nearly all operating systems. We focused on usability and comfort for mass spec scientists, who will use the tool.

This is just a small announcement for the recently launched website, you might want to take a look at it!? (-;

Small hint for my faithful readers: Subscribe to IonHunters newsletter to stay informed and miss no release!

Presentation using two screens

Yesterday I attended a presentation of a colleague, but unfortunately during his speech the PDF viewer on his laptop crashed.

His supervisor told him to use pdf_presenter_console . Don’t know whether you’ve already heard about this tool? It’s able to display the current slide on the beamer-screen while you can see the next slide on your real screen. Generally a nice idea, but the software seemed to be a bit unstable ;-)

Anyway, I always wanted to find a solution to see some notes for a single slide while the slide is active, and today I set to work.

I searched for tools that are able to open two different PDF’s at once, I tried impressive, some vnc hacks, and so on, until I realized that there is already a smart solution on my laptop using the lightweight PDF viewer XPDF!

XPDF has a nice remote feature, if you run it like

xpdf -remote SOMEID presentation.pdf &

you can use your terminal to send some commands to the viewer. For example to go to the next slide try the following (see the COMMANDS section of XPDFs man page):

xpdf -remote SOMEID -exec nextPage

Great, isn’t it!? (if you receive the error error: "nextPage" file not found scroll down to XPDF is buggy)

I think the rest is clear, open two different XPDF-instances, one for the notes and one for the presentation itself:

usr@srv % xpdf -remote NOTES notes.pdf &
usr@srv % xpdf -remote PRESENTATION presentation.pdf &

and define some keys to scroll through the PDFs. You could use xbindkeys to bind the keys to the commands, for example I use F9 to go to the next slide and added the following to my ~/.xbindkeysrc :

"xpdf -remote PRESENTATION -exec nextPage && xpdf -remote NOTES -exec nextPage"
    m:0x10 + c:75

After running

xbindkeys -f ~/.xbindkeysrc

I’m able to go to the next slide by pressing F9 . To find the keycodes for some keys you may use xbindkeys -k or xev . Take a look at the documentation for more information (GER). Of course presentation.pdf and notes.pdf should have the same number of pages ;-)

XPDF is buggy

The -exec flag didn’t work for me, returning the following error:

usr@srv % xpdf -remote SOMEID -exec nextPage
error: "nextPage" file not found

I tried version 3.02 and also 3.03. The problem is located in the XPDF wrapper script, located in /usr/bin/xpdf . If you take a look at the contents you’ll find the following lines (in my case it’s 25ff):

while [ "$#" -gt "0" ]; do
    case "$1" in
        cmd="$cmd $1 "$2"" && shift ;;
        title="$2" && shift ;;

They simply forgot to define the -exec parameter to take an argument. So nextPage is not seen as argument for -exec and XPDF tries to find a file called nextPage that is obviously not present. To patch this you just need to add -exec like:

while [ "$#" -gt "0" ]; do
    case "$1" in
        cmd="$cmd $1 "$2"" && shift ;;
        title="$2" && shift ;;

or just use xpdf.real directly and skip the wrapper:

usr@srv % xpdf.real -remote SOMEID -exec nextPage

Since modifying files in /usr/bin isn’t a good idea I recommend to just substitute xpdf for xpdf.real in your ~/.xbindkeysrc .

That’s it for the moment, I wish you a nice presentation ;-)

Compress Google's Reader

If you are using Google’s Reader to aggregate news feeds you might have recognized that Google re-engineered its feed-reader to fit into the styles of other Google-services.

The new interface slimmed a bit and is more lightweight, but I’m arguing about the large white-spaces! Too much space is unused and to less information is presented. Such disadvantages are also discussed at other places.

First I thought I’ll get used to it, but now I decided to change it on my own. So I created a small user script for the Firefox extension Greasemonkey. Here you see the difference (click the images for larger versions):

Reader w/o modification
Reader w/o modification
Reader w/ modification
Reader w/ modification

So you see, there is less space at the top of the page and single entries got closer together. The script is available in the download section, all you need is the browser Firefox and its extension Greasemonkey. If you have both installed just click the following link to the download and Greasemonky will ask you to install my short script. That’s it for the moment ;-)

Update 22.11.2011: Updated the UserScript to support googles new layout.

Download: JavaScript: Google Reader Whitespace Remover (Please take a look at the man-page. Browse bugs and feature requests.)

Sharing a Wifi connection

Due to different circumstances I had to figure out how to share a wireless connection with some wired clients. And what should I say, that’s a very simple task ;-)

The scenario

With your notbook you are able to connect to an AP with access to the internet, but other machines within your network infrastructure don’t have access to the outside world, and you want your local machines to also use this wireless connection of your notebook. Figure 1 visualizes this use case.

The setup

First of all I have to admit I don’t know which software needs to be installed. Since I previously did some network hacks with this notebook I didn’t have to install something that wasn’t actually present, but I think you’ll need something like network-manager-gnome , dnsmasq-base and dnsmasq-utils . And of course you also need a Linux notebook (e.g. with a Debian or an Ubuntu) with wifi hardware, an AP with internet connection and a RJ45 Ethernet port on the notebook for the wired connection to other PC’s.

The first thing you should do is to connect to the AP, so your notebook will be able to access the WWW.

The next step is to connect another machine to your notebook using a network cable. This machine needs to be configured as a DHCP-client. (Since this might be any operating system of your choice I don’t describe the configuration, but most systems should already be configured correctly)

Now you have to setup a shared connection on your notebook. Right-click the network indicator icon in your systems panel (next to your clock) and choose Edit Connections…, compare to figure 2.

This will open a new window with connections you still configured. In the Wired tab click Add to install a new shared connection, see figure 3.

You’ll see another window to configure this new connection. Just give it a name like share and choose the method Shared to other computers in the IPv4 Settings tab, as shown in figure 4.

Last but not least open a terminal and add a new entry to the nat-table:

sudo iptables -t nat -A POSTROUTING -j MASQUERADE

That’s it, using this newly created connection you’re able to connect your clients behind your notebook through your wireless connection.