Ben Fagin

02/11/2011

0

Avoiding XML Configuration In Java View Rendering Frameworks

Ben Fagin // in Technology

A seemingly unavoidable component of web development these days is working with XML configuration files. Though useful for connecting the multitude of components that go into the average application, there are some obvious downsides. For starters, XML is a headache to look at, and when you're unsure of a specific element you get to stare at an even more unappealing schema descriptor. Most troublesome is the way that configuration files are generally loosely coupled to the application. Runtime information like enums and other constants are unavailable to the configuration files. It's a one-way street, so to speak: XML configures the application, not the other way around. Being separate from the code means that the configuration can be hard to keep up to date. Change a class's name or its package and all of those fully qualified class names in your configuration files are useless. Perhaps the most inconvenient characteristic of this setup is that, because the XML is parsed and evaluated at server startup, changes will almost always require a full restart of the application server. We hates this!! Development slows down when, every time a developer makes a change, the server has to be restarted--bad enough for one developer, terrible for multiple developers, testers, and content loaders working on the same application server.

Background

For a long time, many of the popular Java frameworks like Spring and Hibernate were only configurable through XML. In 2002, JSR-175 gave us general purpose annotations, and now the tide has turned. Both of these frameworks are now almost entirely configurable through the use of annotations directly in the code. Class names and field names once seemingly pulled out of the air are now tightly coupled to the class files themselves. In the application server, a properly configured servlet container should be able to pick up changes to class files automatically. IDE's have improved as well, and some of the better ones such as IntelliJ, which we use here at Vodori, can validate class names, resource paths, and more right in your XML files, as well as keep track of annotations currently in use.

There are limits of course. 'hotswapping' is complicated by the capabilities of the container. Changes which affect the flow of your progarm, such as dynamically mapped urls in a web application, will generally require a restart. And while reloading classes addresses functional updates to the running program, many smaller and more frequent updates in web development happen at the view layer: minor changes to html, jsp, css, and templates. These subsystems are often managed by powerful view rendering frameworks inside of the application. So how possible is it to avoid configuration files in some of the more popular frameworks? I will be investigating that question in this and two future articles, starting first with JSP.

Working With JSP

Basic JSP development requires minimal configuration, mostly upfront. Configure the server's web.xml file properly and you're ready to go. When your JSP files are changed they will be picked up and translated again next time they are accessed. Working with single files is fine, but how do the more object-oriented features respond? The <jsp:include> action and the corresponding "@ include" directive allow you you include full files inside of each other with few surprises. You can even access access dynamic content at outside urls, with or without parameters. The JSP syntax also allows for well-templated pages to be generated using an XML-style format where everything is enclosed in an element, including page text (using <jsp:text>) For a true modular development style however, tags are far superior.

Tags are like JSP snippets, and for the most part they are just as dynamically modifiable. Tag files ending in .tag can be dropped into a directory (usually /WEB-INF/tags) and can be utilized by placing <%@ taglib prefix="xyz" tagdir="/WEB-INF/tags" %> at the top of your JSP pages. A good IDE will be able to provide instant validation of any changes, as well as parameter hints ("xyz:a is missing required attribute..."). Tags can also have an associated TLD, or "Tag Library Descriptor" which codifies a tag's configuration and operation. This file is optional, but it is useful in cases where a complete library is being created separately for distribution. In my own work, I have found that in most cases the TLD is overkill when you can specify the majority of the details right in the tag file.

A Closer Look: Tag Handlers

Tags can also use custom tag handlers. Tag handlers are Java classes which determine how a tag goes about its work. Your drop-in tags use the default "Simple" tag handler, but what if you want to use a custom one? Creating the handler class is as easy as extending TagSupport. It turns out however that specifying a tag handler for a tag absolutely requires the use of the TLD file. This is because the "tag-class" attribute is not available in the tag directives which you can specify in the tag file. Fortunately, if you do have to use a TLD then changes made are usually instant, noticable then next time a JSP page using the tag is requested.

A nifty trick might be to specify something like a  "HandlerService" for your tags in the TLD, and then that class could be used to determine programmatically which handler should be called. Of course this still requires the TLD, but necessitates fewer updates and offers some interesting alternatives. Inverting the problem, it's possible to define a tag which uses a single handler to run other tag handlers. I've created an example of this which I call ReflectiveTag. Given a fully qualified class string, the handler will instantiate another handler to delegate the work to. A more in-depth discussion of this idea is available on my personal blog.

Wrapping Up

Tags give you the power to create dynamic, object oriented web sites with minimal overhead. Though they cannot explicity 'inherit' from one another, handler classes certainly can, and tags can always utilize other tags in a nested or even cooperative manor (O'Reilly has a great article on this). For most web applications, JSP can perform the required duties, and as we've seen it can usually do it in realtime with few server restarts. However it is often the case that something more advanced is required. Next time I'll be talking about Sitemesh and the much larger Tapestry frameworks, which attempt to provide a greater level of functionality by fully embracing the MVC design pattern.

 

Is JSP your thing? Vodori is currently looking for enthusiastic web developers.

READ MORE.

 

Share Article