Embedding JSF with Winstone

May 8th, 2006

Sometimes, when developing a JSF application, it would be nice not to have to wait for your favorite container to start up. That’s especially true if your container is a full JEE stack like Glassfish or JBoss. Likewise, there are times when you might need to embed a web application in another, say some server process or desktop application. While there are a number of options available, I’d like to demonstrate how to embed a simple JSF application using the Winstone Servlet Container. To help demonstrate how this is done, we’ll use a well know sample application: Duke’s guessNumber game, and, to make things even more interesting, we’ll convert the application to use Facelets (mostly because I love Facelets, but partly because I didn’t care to figure out how to make Winstone compile JSPs ;) ).

First, let’s take a look at the web app itself. To convert the application to a Facelets app, we’ll have to rename the JSPs, then make them conform to XHTML and Facelets specifications. First off, a really easy one: index.html. This page simply redirects us to guessNumber.xhtml. I could probably have done this in web.xml, but it was in the original app, so we’ll just run with it like that.

index.html:

Pretty simple and boring. Let’s now take a look at our template file (for a fuller introduction to using Facelets, please see Rick Hightower’s excellent article, as well as Jim Hazen’s Getting Started article):

layout.xhtml:

Nothing real exciting there either. Next we have greeting.xhtml and response.xhtml.

greeting.xhtml:

response.xhtml:

Having fixed up our views to work using Facelets, let’s now see exactly how we do the embedding. That magic is done in the following class.

WinstoneServer.java:

That code is taken pretty much verbatim from the Winstone documentation. I split it out into methods on the class to make it prettier, but that’s about it. It’s an extremely simple process. Of course, there are many more options available, all of which are documented on Winstone’s site. My goal here isn’t to be a Winstone tutorial, so we’ll just use the minimum configuration, which is where to find the web root.

The web root probably needs a word here. What I’ve done in my example, which you’ll see in the archive attached to this article, is to put the web root directory in the source directory. By doing it this way, when Eclipse compiles my project it moves my web root to the build directory, making it simple to load it from the classpath. There are at least two other ways to accomplish the task: hard coding a path on the filesystem, and archiving the web root to a .war and telling Winstone to use the war. Each has its pros and cons. Your choice will depend on your intended usage. Ideally, for a packaged and deployed application, it would be nice to be able to jar the web root up with the application, but I have not had any luck getting it to load the web app from inside a jar. Given the limited scope of this demonstration, though, I opted not to pursue that very far.

Now, the UserNumberBean class, the Faces-managed bean that is the actual heart of the application. I’ve included the full source code here for a couple reasons: the upgrade to JSF 1.2 necessitated some source changes, and there was apparently some sort of error in the inclusion of the code in the article linked above resulting in the case of some identifiers being mangled somewhat.

UserNumberBean.java:

The web.xml and faces-config.xml files used to wire the web application together are pretty standard, but I’ll include them here for your perusal:

web.xml:

faces-config.xml:

The archive attached to this blog does not have the dependencies included for size and (possible) legal restrictions, so here’s a list of what my workspace has:

  • commons-el.jar
  • commons-logging-1.0.4.jar
  • el-api.jar
  • el-ri.jar
  • jsf-api-1.2.jar
  • jsf-facelets-1.1.jar
  • jsf-impl-1.2.jar
  • log4j-1.2.13.jar
  • winstone-0.8.1.jar

That’s all there is to. To run the sample application, simply run embed.WinstoneServer, point your browser at http://localhost:8080/, and start guessing.

As I’ve hopefully made clear, embedding a JSF application can be quite simple, though that simplicitly is linked somewhat to the embedding environment. Please note that this sample is not meant to be a catalog of best practices for JSF, Facelets or Winstone embedding, but to be a simple introduction to the topic, and, to that end, I hope you’ll find it useful.

(You can download the source archive here).

Popularity: 4% [?]

3 Comments

  1. Rick Knowles says

    Hi,

    Glad to see Winstone is useful for this kind of thing. The quick startup time is one of the things I’ve found helpful for development too.

    The method you mentioned takes advantage of the embedding API. This is one way of doing it I hadn’t thought of. The way I usually do it is to add an Ant task (or more often Maven goal) that looks like:

    and then define the app.build and app.name variables. This allows you to just run “ant clean war winstone” for example, and ant will load and run the container as a task.

    The method you mentioned is fine, and probably better for IDEs etc than the Ant method, which suits the shell environment in practice.

    Anyway, thanks for an interesting read, and let me know if you find any other more interesting uses for Winstone.

    Regards,

    Rick Knowles

    May 11th, 2006 | #

  2. Rick Knowles says

    I just noticed my ant code snippet got removed by the HTML filter. Here it is again, escaped this time:

    May 11th, 2006 | #

  3. jason says

    Hey, Rick. Thanks for the feedback. I considered doing something like that, and probably will if I ever move this idea past a proof of concept into a “real” application. I worked up this approach while investigating embedding a web admin console in a server process, but that project was shelved so this effort was too. I do still use this particular approach some for testing web apps, though. It works really well, and is just a touch faster than waiting for Glassfish to boot. ;)

    May 11th, 2006 | #

Sorry, the comment form is closed at this time.

With many thanks to Kaushal Sheth
`