Archive for April, 2008

Tomcat’s Jasper (re)compiler

April 13, 2008 4 comments

Let’s say you create a new JSP. You put some content on the page and save it at 9:00 am. The first time you access the page from a browser, Tomcat compiles the JSP for you. Great! Your page does everything you (and the product team) want it to. You check the file in to your version control system.

When the product team sees your page, they love it! It looks great and has everything they wanted when they wrote the requirements. But now they want something entirely different, so they give you the latest and greatest requirements.

You go back to your favorite JSP editor (which is undoubtedly IntelliJ if you’ve used it) and change the page to meet the new requirements. You save the file at 10:00 and access it through your browser just to make sure you got everything right. Thanks to the magic of Tomcat, you see the new version of your page without even restarting the server. Actually, it’s not magic – Tomcat just recompiles the page when you access it. It compares the time stamps of the compiled class file and the JSP file from whence it came. It recompiles since the time stamp on the file is now 10:00, and the time stamp of the compiled page was 9:00.

You show the page to the product team, which meets all of their most recent requirements. But now they don’t want that any more – they want the page exactly how it was the first time. You shrug and tell them that’s not a problem and will only take a few minutes (knowing you can revert the file with your fancy version control system).

You go back to your desk and use your state-of-the-art version control system to revert the page to your 9:00 version. You open it in your editor just to make sure it’s the right one, and it is – everything has been restored to the first version of the page. Now to check it out in a browser…

Uh oh – the browser still shows the 10:00 version of the page (which is not what you want). You go back to your editor and look at the code. It’s the 9:00 version of the page – exactly what you (and your product team) want. But the browser is showing the 10:00 version. Editor – 9:00 (correct) version; browser – 10:00 (wrong) version. What’s going on? Maybe it’s the cache – you clear your browser’s cache and hit the page again. Same problem. You restart Tomcat and again clear your browser’s cache just to be sure. Still the wrong version. What in the world is going on?

If you’ve worked with Tomcat, you may already know. Tomcat doesn’t recompile the page because the time stamp is older (earlier) than the compiled version. It sees that the time stamp is 9:00 on your file (since you did a revert with your version control system to get the version you created at 9:00). But it compiled a file with the same name (in the same location) that had a 10:00 time stamp, so it doesn’t recompile the page. It has a more recent version of the file already compiled. But that’s not the version you want. You want the old one. So what can you do to make it recompile?

  • Modify the file (add a space and delete it) and then save it. The time stamp is changed to the current time (say, 11:00) and the next time you access the page, Tomcat will recompile since 11:00 > 10:00. This is probably the easiest solution.
  • Change the settings on your version control system so a revert will give you a time stamp with the current time. Doesn’t sound like fun to me – I’m not even sure it’s possible on all version control systems.
  • Dig through the source for Tomcat (since it is open source) and make Tomcat work the way you want it to. This might be a good place to start, but I wouldn’t want to do it.

This is the way Tomcat works – it only recompiles if it sees a more recent time stamp on the JSP. The reason it does this is for performance – it doesn’t (and shouldn’t) have to recompile a page every time it’s accessed. However, since it uses a “less than” comparison, it doesn’t ever recompile older versions of a file (as explained in the example above).

Those are the facts – here’s my opinion. I think this is a problem because Tomcat’s compiler behaves unexpectedly. If the compiler recognizes that it should recompile when the time stamp is later, I also expect it to know that it should recompile if the time stamp is earlier. It’s the same file in the same location, and the time stamp has changed. It obviously needs to be recompiled. Tomcat should recompile a JSP whenever it finds that the time stamp is different.

Now to convince one of the Tomcat developers to make this simple change…

Tags: , ,