Monday, May 25, 2009

Maven: Compile to a RAM-drive

While preparing to do a backup recently, I realized that I had over 2GB in 110.000 files which was the result of either an Ant build or Maven target. It occured to me that with Maven especially, this is nothing more than garbage to keep around, since Maven will copy the artefacts to its /.m2 folder anyway!

In a previous blog entry, I explained how to mount a RAM-drive on Ubuntu and use it as a development folder for much higher performance in the compile-test-run cycle. I have to admit, I don't use this for each and every project since it's a little complex and fragile.

But there's an interesting compromise to be had here. It turns out it is possible to instruct Maven to build artefacts to a RAM-drive. That way you not only gain some performance but also some automatic "garbage collection" in that by the next boot, you will have no traces of these build steps laying around. It would also be a very healthy thing to do if you're running from of an SSD drive, which are susceptible to wear-and-tear. The following will explain how to set this up with Maven.

You are going to need a RAM-drive for this purpose. It is extremely easy to set one up on Ubuntu. In the following I set the permissions of the mount to that of the Ubuntu user "plugdev" which is the one being used for auto-mounting USB-drives etc. That way all users should have permission to use it:

sudo mkdir /media/ramdrive
sudo chgrp plugdev /media/ramdrive
sudo chmod g+w /media/ramdrive
sudo chmod +t /media/ramdrive
sudo mount tmpfs /media/ramdrive -t tmpfs

You can have your system automatically create and mount a TMPFS partition for you, by modifying your /etc/fstab file. Simply add the following to it:

none /media/ramdrive tmpfs defaults,user,size=1G,mode=0777 0 0

An alternative approach could be to have the RAM-drive mounted at compile time. This is perfectly possible by calling out to an Ant target in Maven, and have it execute a Bash script. The problem is though, in order to mount filsystems on Linux you need to be a super user. So for this approach to work, you would need to hardwire your SUDO password in the script and that would be pretty dumb. It is entirely possible there is a way to do it, but if there is I am unaware of it.

The POM modification
Basically all we need to do is instruct Maven where out build directory is, our output directory and our test directory. This can be done by simply specifying it within the build tag:


You'll notice I place everything under the sub-folder "maven-targets", this is so that none of my targets conflicts with other stuff on my RAM-drive. Also, the actual sub-folder for each individual project will be named the same as the project.

As Maven profile
While the above certainly works, it's arguably some heavy bending of Maven's conventions and we run the risk that other people not as fortunate as us (i.e. Windows users) won't have a RAM-drive nor the possibility to create one. To remedy this, we can encapsulate this custom behaviour in a Maven profile.

Sadly in a profile, we are not allowed to specify build paths like we just saw above. We can however cheat a bit, by going through some properties. Start by defining some global properties somewhere in a properties tag under the project tag:


This complies with the standard Maven conventions. Then in the non-profile build tag, do like before but rather than hardwire the paths, use the properties we just defined. Like so:


The behaviour thus far should not differ in any way from the default Maven build cycle. The last thing we need to do now is to add a profile for emitting to the RAM-drive:


That's it. Now you just select the profile "RAM-drive" in your IDE when you build, without it having negative consequences for your less fortunate collegues. Of course a similar setup can be made with Ant and most other build environments.

Saturday, May 16, 2009

The pain of request scoped JSF

While I like the idea of a component based web framework, JSF never really felt right to me. There are too many pitfalls and the whole programming model (even with the use of Facelets) feels cumbersome and more complex than necessary. I could probably write up a detailed list of reasons for why I think JSF is the least productive and fun web frameworks of those I know, but that is not the purpose of this blog post. Suffice to say this appears to be a shared sentiment. This post addresses only JSF's focus on server state and the associated overloaded POST aspect.

The problem of state
All programs that does anything remotely interesting, needs to keep some kind of state. In web applications, there are really only two places to put state and that is either on the server or on the client. Because HTTP itself is stateless, most frameworks stores state on the server in a session that is allocated the very first time a unique user visits. This is done either through an associated cookie or a sessionId that's passed along at all times. It's a simple approach that works reasonable well, but it also has some problems.

  • Scalability - When you do state, inevitably you start to consume memory that accumulates over time only to be cleared when your session times out. While memory and swap space by itself is relatively cheap, you can only throw hardware at it while your user count remains relatively low. Another problem comes to play when you decide to add more machines to assist in carrying the workload, since then you need to propagate out to a globally shared state between all the machines.

  • Complexity - The moment you do state, you have to think about concurrency and visibilty. Everything is essentially shared so opening several windows in the browser or using asyncronious (Ajax) calls can potentially wreck havoc in the state space for your session. Only with a debugger and non-trivial testing can you gain an overview of this aspect. It does not help that in JSF, there's (to my knowledge) no way to detect a new page load in a session scoped backing bean so you can't use that to do a partial "reset".

  • Unpredictable - Have you ever been working on something online, then picked up a phone call or gone to lunch only to return and receive an error message that says your session has timed out?. In JSF you often receive the more cryptic message "Could not restore view!". This happens because of the stateless nature of HTTP, there's no way for the server to know if a user is still sitting there in the other end, so it relies on a timeout for the session. There's a reverse proportional relationship between the size of this session timeout and the amount of memory consumed by the server, which is why the timeout is often kept down around 30 min.

I'm not totally against state on the server when it's used as a application level caching mechanism or for lightweight session info like language setting etc. Unfortunately it is all too common to see a heavyweight hierarchy from another layer (JPA entities comes to mind) creep into the user session and then it's bye bye to scalability.

JSF favors statefullness
Everything about the JSF programming model is clearly made with session scoped backing beans in mind. For instance, if you try to use various components in request scope, you will find it to be a major problem how events dispatch BEFORE your bean have had its properties filled out from the POST request. So, since JSF does not provide sufficient context, what people often do is to go behind JSF's back and grab the required context from the request parameters.

Example, say that you have a JSF page that displays some info about a customer entity. You would like an easy way to test and interface with legacy apps, so you allow a request parameter called customerId to be passed along as initial context. From within this page, you may perform various CRUD operations on the customer, which means you pass along this context in various ways, typically by including something like this in your POST-back form:

<html:form id="someform">
   <html:commandButton value="Show customer" action="showCustomer"/>
   <html:inputHidden id="customerId" value="#{customerBB.customerId}" binding="#{customerBB.customerIdHidden}"/>

What people do then in the backing bean, is to use lazy detection code to first try to fetch a property directly (if they know the form name) or from bound components. The latter approach would look something like this:

private static final String CUSTOMER_ID_PARAM = "customerId";
private Long customerId;
private HtmlInputHidden customerIdHidden;

public HtmlInputHidden getCustomerIdHidden() {
return customerIdHidden;

public void setCustomerIdHidden(HtmlInputHidden customerIdHidden) {
this.customerIdHidden = customerIdHidden;

public Long getCustomerId(){
if(customerId == null){
String customerIdString = getRequestParameter(CUSTOMER_ID_PARAM, false);
if(customerIdString != null && !customerIdString.isEmpty())
customerId= Long.parseLong(customerIdString);
else if(getCustomerIdHidden() != null){
customerIdString = getRequestParameter(getCustomerIdHidden().getClientId(getFacesContext()), false);
if(customerIdString != null && !customerIdString.isEmpty())
customerId = Long.parseLong(customerIdString);
return customerId;

Very verbose and fragile. And while JSF proponents will probably claim this is not the sanctioned way to use JSF, that's the kind of hacks I've seen on numerous occasions. In the following sections I'll describe an approach which is essentially a return to an action based framework where the idea is to separate functionality out into distinct pages and backing beans, with a controlled context flowing between these.

Managed properties
It turns out, you can instruct JSF to automatically initialize a backing bean property from both POST and GET requests. You do this via the managed-property tag in faces-config.xml, like so:


That still leaves us with the problem that in JSF, input variables are identified on the form [formname]:[inputname], so a <h:inputHidden> would not be injected into the beans customerId field. There's a way around this though. In your form, simply escape back to basic HTML by using the <core:verbatim> tag. This prevents JSF from modifying the tag name and id:

   <input type="hidden" id="customerId" name="custumerId" value="#{customerBB.customerId}"></input>

Overloaded POST's with GET redirects
A strongly associated aspect of the state on the server, is how everything in JSF is done through POST's. That presents a particular problem to JSF authors who wish to write in request scope, since an URL no longer expresses any of the necessary minimum state needed for the website to "live in the know". Hitting refresh in the browser won't work. What I do is to peek over at the RESTfull architectures, and only use POST for actions that causes state to mutate (updating or creation), and GET for the remaining idempotent actions.

For instance, rather than using a <html:commandLink> and navigation rules to go to an edit page for an item in a list, I'll use <html:outputLink> that points to the JSF page itsef along with the necessary context:

<html:outputLink value="customer-edit.jsf">
   <html:outputText value="Edit"></html:outputText>
   <core:param name="customerId" value="#{customerBB.customerId}"/>

Note that this actually has nothing to do with the form, it simply expands to a hyperlink which is why in this case we won't need the <core:verbatim> tag.
The second part to this is to ensure we always emit the new context from the logic in the backingbean, that means for mutating POST operations to forward to a GET. This can be done by manually navigating to a result URL rather than returning a navigation rule. The following could be an example of what to do after a save operation was invoked on the consumer-edit.jsf page.

.redirect("customer-view.jsf?customerId=" + getCustomerId());

In conclusion
JSF makes it very hard to avoid state on the server, but I hope this entry will have proven that it is possible to compose simple CRUD pages with this objective in mind. It's arguably bending JSF beyond its intentions, but if you have had your share of problems with JSF as I have, perhaps this classic way of thinking in request parameters will let you utilize some of JSF's nice looking components in a simple way without walking down the dreaded statefull alley. As a side effect, it becomes trivial to document the state space and assert preconditions of your pages.

The approach probably does not scale beyond relatively simple pages although I could claim adherence to the Separation of concerns principle. So if you command your own toolchain, I would urge you to have a look at Wicket (for classic broad-spectred web apps) or GWT (for data-intensive intranet apps) instead.