Matt RaibleMatt Raible is a Web Developer and Java Champion. Connect with him on LinkedIn.

The Angular Mini-Book The Angular Mini-Book is a guide to getting started with Angular. You'll learn how to develop a bare-bones application, test it, and deploy it. Then you'll move on to adding Bootstrap, Angular Material, continuous integration, and authentication.

Spring Boot is a popular framework for building REST APIs. You'll learn how to integrate Angular with Spring Boot and use security best practices like HTTPS and a content security policy.

For book updates, follow @angular_book on Twitter.

The JHipster Mini-Book The JHipster Mini-Book is a guide to getting started with hip technologies today: Angular, Bootstrap, and Spring Boot. All of these frameworks are wrapped up in an easy-to-use project called JHipster.

This book shows you how to build an app with JHipster, and guides you through the plethora of tools, techniques and options you can use. Furthermore, it explains the UI and API building blocks so you understand the underpinnings of your great application.

For book updates, follow @jhipster-book on Twitter.


Over 10 years ago, I wrote my first blog post. Since then, I've authored books, had kids, traveled the world, found Trish and blogged about it all.

SiteMesh passed the 10 minute test

I decided to go out on a limb this evening and give SiteMesh a run for its money. The first warning sign was that the documentation refers to version 2.0.2, while the downloads section refers to version 2.0.1. So I proceeded to download 2.0.1. I promptly noticed that the install guide indicated I needed to download SiteMesh's two TLDs and configure them in my web.xml. Blech - this is so year 2000 - most modern containers support loading taglibs from JAR files with a URI.

So I did a good ol' cvs co of sitemesh from First of all, I'd like to say kudos to and their CVS repositories - they've been rock solid for the few weeks I've used them. After checking out sitemesh, the first thing on my agenda was to give it the tried n' true ant test. This means I navigate to the sitemesh folder and simply type "ant". At this point, I should get one of two things - a BUILD SUCCESSFUL with a JAR or a help message telling me what I should type. I got the former, which I prefer.

After this, I integrated it into my app using the decorators documentation and deployed it. At first, I received the lovely ol' "getOutputStream() has already been called for this response" error, so I hacked to use PrintWriter writer = response.getWriter(); instead of PrintWriter writer = new PrintWriter(response.getOutputStream());. Build, copy, package, deploy and voila - it all worked!! Wow that was easy. ;-)

Here's the weird part. I decided to reverse my hack on to prove that I'd actually fixed the bug. Now I'm back to the original code I got from CVS and I can't get the getOuputStream() error to rear its ugly head. Doh!! This experience begs the following question.

Is SiteMesh stable enough on Tomcat 5 that I can should use it in my Spring Live sample app?

SiteMesh definitely passed my 10 minute test, we'll see if it holds up for the long haul. So far, I'm quite impressed with its easy configuration and quick implementation. I especially like that you can literally guess at it's syntax and you'll get it right. Maybe I was just lucky... heh

P.S. You should probably know I'm a big fan of Tiles. I wonder if SiteMesh will let me switch a decorator on the fly like Tiles does?

Posted in Java at Mar 24 2004, 12:07:56 AM MST 16 Comments

Matt, the site does indeed reference 2.0.2, sorry for that, will fix. "loading taglibs from JAR files with a URI" should work IIRC, I'll check it out and update the docs. About the getOutputStream bug, we are fully aware of this (only an issue on Tomcat engines) and working on it, and I can say that SM is more than stable enough for all my production apps (running on WLS). About the switching decorators, check out the DecoratorMappers documentation. On the fly switching is much easier and powerful than with Tiles. Cheers!

Posted by Mathias Bogaert on March 24, 2004 at 04:46 AM MST #

Matt, loading TLDs from a jar file works when you have *one* TLD to work with. Which would you prefer? Secondly, the getOutputStream() thing is documented (and being worked on). It's non-trivial, depending on the circumstances it's encountered in. And as Mathias said, switching decorators on the fly is trivial.

Posted by Joseph Ottinger on March 24, 2004 at 05:56 AM MST #

Joseph - I did some research and it looks like you are correct if you're using JSP 1.1. However, with JSP 1.2, you can include multiple TLDs in the META-INF directory and they'll all be recognized. For instance, Apache's standard taglib (v 1.0.5) has 10 TLDs in it's META-INF directory, and you can easily use 3 or 4 of them in a JSP just by referencing the URI. If you're using SiteMesh, you have to be using JSP 1.2 (b/c of Filters in Servlet 2.3). From the JSP 1.2 Spec:

<p class="smokey"> <strong>JSP.7.2.1 Packaged Tag Libraries</strong>

JSP page authoring tools and JSP containers are required to accept a tag library that is packaged as a JAR file. When deployed in a JSP container, the standard JAR conventions described in the Servlet 2.3 specification apply, including the conventions for dependencies on extensions.

Packaged tag libraries must have at least one tag library descriptor file. The JSP 1.1 specification allowed only a single TLD, in META-INF/taglib.tld, but in JSP 1.2 multiple tag libraries are allowed. See Section JSP.7.3.1 for how TLDs are identified.

Posted by Matt Raible on March 24, 2004 at 08:56 AM MST #

Ah, VERY cool! I'll have to check up on that - JSP 1.2 isn't my experience area, obviously. :)

Posted by Joseph Ottinger on March 24, 2004 at 11:58 AM MST #

!A little off topic here: Here's something you might find interesting - a look inside the tomcat 5 server.xml file has this: {{{ <Connector port="8080"..... <!-- Note : To use gzip compression you could set the following properties : compression="on" compressionMinSize="2048" noCompressionUserAgents="gozilla, traviata" compressableMimeType="text/html,text/xml" --> }}} It appears that Tomcat might finally natively support gzip compression, and it correlates to the mime type, rather than the file extension. Neat, huh?

Posted by Will Gayther on March 24, 2004 at 02:02 PM MST #

Will - which version of Tomcat? I'm losing track...

If SiteMesh can pass Matt's 10-minute test, I guess it's worth checking out. Mathias/Joe: when does it look like 2.1 will be done?

Posted by gerryg on March 24, 2004 at 02:26 PM MST #

Despite the misleading documentation, the TLDs are in the JAR and don't need to be downloaded separately. The URIs are /sitemesh-decorator and /sitemesh-page.

Posted by Jon Pierce on March 24, 2004 at 06:24 PM MST #

Matt, In less than 4 hours, I moved an existing site off of Tiles and on to Sitemesh. The ONLY problems I had were with regard to an incompatibility with Sitemesh 1.3 and Tomcat 4.0. Something to do with the way Tomcat incorrectly (as I recall) used JSPWritters.... Anyhow, upgrading to 2.x fixed it. Dynamic decorating on the fly... yes!!! You can write your own Mappers, or use the existing ones to do specific decorating in real time.

Posted by Mike on March 25, 2004 at 09:07 AM MST #

Mmmm... Tomcat and incompatibility. Where have I heard those two words together before? I'm starting to wonder whether Tomcat should be ousted as the J2EE reference servlet container or whether more people should be making their stuff work with Tomcat *first*, and force the other containers to match. Does anyone else think this sticky problem needs more investigation?

Posted by gerryg on March 25, 2004 at 11:53 AM MST #

Jon - you are correct - the "no TLDs in JARs" is fixed in SiteMesh's CVS.

Gerry - it should be noted that Tomcat is *not* the reference implementation for Servlets and JSPs. See this post (at the bottom). As for its incompatibilities, I've had *way* more compatibility issues with other containers than Tomcat. Especially with the J2EE 1.4 bleeding-edge type stuff.

Posted by Matt Raible on March 25, 2004 at 12:17 PM MST #

Matt - ya got me there. So now the question is how many people *do* think that Tomcat is the RI servlet container? I certainly did. One thing people at my company have been trying to do is get our entire development staff lined up behind one appserver from desktop to production (WL8). But we also have a stated objective of being able to run on multiple appservers. I figure it's best to catch the incompatibilities nickel & dime fashion than in one big lump. One of the things I need to do is set up automated web-testing, but I've heard that existing stuff doesn't handle dynamics very well, and we have a lot of dynamic navigation and even dynamic form elements (not just appear/disappear, but for example additional options in a radio group or select tag!). Any suggestions? Automated testing against multiple containers would be useful. BTW, glad to hear you have it easy with Tomcat. Mileage may vary, I suppose.

Posted by gerryg on March 25, 2004 at 02:06 PM MST #

Ok, I've fixed the TLD issue. The documentation is updated and the sitemesh-blank and sitemesh-example now use it. Get it from CVS or wait for SiteMesh 2.0.2. Cheers!

Posted by Mathias Bogaert on March 25, 2004 at 04:24 PM MST #

Has anyone managed to integrate Sitemesh 2.1 with Spring?

Posted by Ian Gower on August 04, 2004 at 08:35 AM MDT #

Yep - I'm using it with the Spring Live sample app. It works for me with Struts as well as Spring MVC and all its supported views: JSP, Velocity and FreeMarker.

Posted by Matt Raible on August 04, 2004 at 09:19 AM MDT #

Hi - I am having a problem with the Equinox SiteMesh setup, and since I know you check your blog entry comments (and your email is not immediately obvious), I figured I would drop the message here. Whenever I try to navigate to a page through a Struts forward, I hit something like:

<code> 2004-10-10 09:31:23 StandardWrapperValve[default]: Servlet.service() for servlet default threw exception java.lang.NullPointerException at com.opensymphony.module.sitemesh.filter.PageResponseWrapper.getPage( at com.opensymphony.module.sitemesh.filter.PageFilter.parsePage( at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter( </code>

Have you seen this before?

Posted by Scott McClure on October 10, 2004 at 07:51 AM MDT #

Scott - it's probably best to ask this question on the Equinox mailing list, but I'll try to help here. My guess is that you're using a servlet container other than Tomcat that might have issues with SiteMesh. Joe has a SiteMesh Acceptance Test Results page that might help. If you are using Tomcat and you're seeing issues, you might try upgrading to the latest release.

Posted by Matt Raible on October 10, 2004 at 08:29 AM MDT #

Post a Comment:
Comments are closed for this entry.