Speeding up development by splitting a webapp into parts

I love tagfiles: they feature a well known syntax (EL from JSP), they allow for reusable UI components, they are well supported by my favourite IDE and, most importantly, modifications are instantly visible because the servlet container does not have to restart.
At least in theory, because reality often looks different: after a few edits tomcat will choke with class loading issues, it will claim to not find tagfiles and it won’t pick up changes to them which inevitably results in reloading the entire application. Mind you, this is not a PermGen issue. I never conclusively found out whether I am doing something wrong, whether it is an issue with the spring framework or whether tomcat is buggy.
My everyday woes tangent a larger issue: making frequent changes during development to applications with a long start time. Issues like the one at hand force the servlet container to restart often which is a huge productivity killer. I hear that jrebel is a good tool which removes the needs for restarts by hot-deploying changes into the JVM. A fundamental solution would be OSGI which would tackle the problem at the application design phase.

Splitting the application into two parts

The problem at hand manifests itself by an unstable view technology which requires the view components to be restarted frequently, so I looked into ways of “physically” relocating the view into a new application which could be restarted often and would sport a negligible start time. So we end up with a pure backend application and a thin UI application which delegates all real work to the backend webapp.
A brute force approach would have been exposing all backend functionality as webservices and consuming them in the UI, but that is 1) a lot of work and 2) the resulting UI application wouldn’t be that lightweight.

 

Server-side forwards to the rescue

It turns out that there is a delightfully simple way: we can move only the JSPs and tagfiles to the UI application and use server side forwards to communicate between two webapps. In this design the UI webapp is internally encapsulated and hidden behind (inside?) the backend webapp. A request lifecycle thus looks like this:
1. Browser sends HTTP request to servlet container
2. Servlet container creates an HttpServletRequest and routes it to the backend webapp
3. The backend webapp performs all business logic, takes care of persistence etc and produces a set of data objects (DTOs)
4. The backend webapp populates the HttpServletRequest with attributes from the DTOs
5. The backend webapp forwards the HttpServletRequest to the JSPs in the UI webapp
6. The UI webapp executes JSPs and renders the result
7. The backend webapp commits any transactions and returns control to the servlet container
8. The servlet container sends HTML (or whatever) back to browser

The imlementation

… is quite simple: whichever servlet in the backend webapp wants to render something just has to forward the HttpServletRequest and HttpServletResponse to the UI webapp. When using spring, it becomes really simple:
public class ForwardingJstlView extends JstlView{
  protected String targetContextName="/webapp-jsp";
  protected RequestDispatcher getRequestDispatcher(HttpServletRequest request, String path) {
     ServletContext context = getServletContext().getContext(targetContextName);
     return context.getRequestDispatcher(path);
  }
}
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">

  <property name="viewClass" value="ForwardingJstlView"/>

  <property name="prefix" value="/WEB-INF/jsp/" />

  <property name="suffix" value=".jsp" />

</bean>

The key part is the context lookup of the view application which is called “webapp-jsp” here.

Note that context lookup must be enabled (by default it is not) and that is best done with a context.xml file in the webapp’s META-INF directory:

<Context docBase="webapp-jsp" path="/webapp-jsp" crossContext="true" reloadable="true">
...
</Context>

And that’s really it. Since Spring uses only request attributes and not any magic to communicate with the view, this approach will really work as long as the JSPs, tags and tagfiles don’t use anything funny that must be present in the application runtime environment (i.e. static classes, beans in the ServletContext etc).

[update 2013-08-13]

Side effects

At this point it is not clear to me how exactly classloading works in this scenario. If the backend webapp passes a class which exists only in its own WEB-INF/lib to the UI webapp, should that raise a ClassNotFoundException? I practically tested it only with classes located in the server lib which allows access to the classes with an ugly side effect: an object of class A created by the backend webapp will not be assignable to the same class A in the UI webapp because they formally belong to different classloaders. This turns out to be a major setback with localisation and formatting taglibs (thing fmt:formatDate) because although the SpringLocalizationContext implements the jstl LocalizationContext it cannot be cast to it which leads to a weird ClassCastException when using jstl formatting.

Resources

Tagfiles documentation
http://docs.oracle.com/javaee/1.4/tutorial/doc/JSPTags5.html

Dealing with “java.lang.OutOfMemoryError: PermGen space” error
http://stackoverflow.com/questions/88235/dealing-with-java-lang-outofmemoryerror-permgen-space-error

Jrebel
http://zeroturnaround.com/software/jrebel/

OSGI
http://www.osgi.org

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.