brush clojure

Monday, June 25, 2012

Asynchronous long-running requests with Servlet 3.0 and Grizzly

Maintaing a lot of open connections on a sever can be expensive, certainly in the traditional thread-per-connection model. When the server is waiting for some event (disk IO, network etc.) before sending a response, a lot of resources are reserved for doing very little.In the traditional thread-per-request model, a thread mainly holds the state of the connection. I am building a service which will take a long to respond to each request because it waits on external process each time, so before diving into a technology I took the time to measure the performance of three possible approaches: traditional 2.5 servlet, 3.0 Asynchronous servlet and NIO (Asynchronous IO) with Grizzly.

The Setup

A request in the form http://{host}/hi?wait=100 causes the server to wait for the given amount of milliseconds before returning a response. I did some measurements on three solutions to see how they actually respond to a big concurrent load.

2.x servlet

This is pretty straightforward:
 
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
  long waitTime = parseWaitTime(request);
  slowOperation(waitTime);

  response.setContentType("text/plain");
  PrintWriter out = response.getWriter();
  out.println("waited " + waitTime + "ms");
}
The slowOperation could consist of simple sleep, but as for the asynchronous implementations use a scheduled executor, I provided a similar implementation here to make the comparison fairer.
 
private final ScheduledExecutorService ses = Executors.newScheduledThreadPool(16);
private void slowOperation(long time) {
  final Semaphore m = new Semaphore(0);

  ses.schedule(new Runnable() {
      @Override
      public void run() { m.release(); }
    }, time, TimeUnit.MILLISECONDS);

  try {
    m.acquire();
  } catch (InterruptedException e) {
    System.out.println("never happens");
  }
}

3.0 servlet

The 3.0 specification allow to exit doGet without writing a response. The saved AsyncContext can be used later to do that.
 
@WebServlet(urlPatterns = {"/hi"}, asyncSupported = true)
public class SlowAsyncServlet extends HttpServlet {
    private final ScheduledExecutorService ses = Executors.newScheduledThreadPool(16);

    public void doGet(HttpServletRequest request, HttpServletResponse response) {
        final AsyncContext ac = request.startAsync();
        final long finalTime = parseWaitTime(request);
        ses.schedule(new Runnable() {
            @Override
            public void run() {
                try {
                    ac.getResponse().getWriter().write("waited " + finalTime + "ms");
                } catch (IOException e) {
                    System.out.println("Error");
                }
                ac.complete();
            }
        }, finalTime, TimeUnit.MILLISECONDS);
    }
}

Grizzly

Grizzly is a server framework which allows to take advantage of the Java NIO without handling all details. Grizzly is not limited to a HTTP server, it is supported next to other implementations. I took the example at http://grizzly.java.net/nonav/docs/docbkx2.0/html/httpserverframework-samples.html as starting point and ended with the following HTTPHandler:
public class NonBlockingEchoHandler extends HttpHandler { 

    private final ScheduledExecutorService ses = Executors.newScheduledThreadPool(16);

    private static int count = 0;

    @Override
    public void service(final Request request,
                        final Response response) throws Exception {

        final char[] buf = new char[128];
        final NIOReader in = request.getReader(false); // put the stream in non-blocking mode
        final NIOWriter out = response.getWriter();
        final long waitTime = parseWaitTime(request);
        response.suspend();
 
        in.notifyAvailable(new ReadHandler() {

            @Override
            public void onDataAvailable() throws Exception {
                in.notifyAvailable(this);
            }

            @Override
            public void onError(Throwable t) {
                System.out.println("[error]" + t);
                response.resume();
            }

            @Override
            public void onAllDataRead() throws Exception {
                 ses.schedule(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            out.write("waited " + waitTime + "ms");
                        } catch (IOException e) {
                            System.out.println("Error");
                            return;
                        } finally {
                            try {
                                in.close();
                            } catch (IOException ignored) {
                            }
                            try {
                                out.close();
                            } catch (IOException ignored) {
                            }
                            response.resume();
                        }
                    }
                }, waitTime, TimeUnit.MILLISECONDS);
            }
        });
      }

The Measurement

Nothing too exciting, just running ab with different number of concurrent request like this:
ab -r -g servlet2.5-c100 -n 6000 -c 100 http://127.0.0.1:8080/servlet2.5/hi?wait=100
Response times are logged in a file used by gnuplot to generate the diagrams below. I deployed the servlets under Jetty 8.1.3, and started the grizzly server on a Macbook Pro with i5 and 8GB RAM. The only VM parameter was -Xss256k, to keep thread memory usage low. While running the measurements, I also observed the JVM threads an memory usage. The thread usage result are close to the expectations, by 200 concurrent request Jetty was using 54 threads initially, which went up to 261 for servlet 2.5 and to 100 for servlet 3.0. Grizzly started with 39 threads which went up to 55.

The Result

The result? The measurements were not exactly matching my expectations. I expected a clear difference in the performance which only started to appear by very high loads, while performance degradation was noticeable in all three setups. The diagrams below show how response time is distributed among 6,000 requests, fired in concurrent batches with different sizes. Ideally, all request would be processed in 100ms and the result would be three horizontal lines at 100ms. With 10 concurrent requests, as expected, all 3 servers behave just fine. The few request finished faster than 100ms indicate some flaw in the ab result, I am not sure what causes it.

With 100 concurrent request the three implementations still go close together:

By 200 concurrent requests the three servers start showing a different behavior...

more and more so with 500 and 1000 concurrent request, see below.

By high loads both servlets are responding well in most cases, with some percentage of the requests taking really long to process. Grizzly's response time deviation stays low, with very few requests taking really long.

Apart from the threads usage, the results don't show the clear advantage of asynchronous request processing until really high loads. A lot depends on how the JVM is handling threads and context switching. Asynchronous or thread-per-request, some session state has to be kept on the server until sending the response.

If one clear conclusion can be drawn from this, it is: Test your assumptions, get measurable metrics and asess your requirements before binding to a technology.



Sunday, February 12, 2012

Storing XML in a JSON database

Isn't any JSON database also an XML database? JSON and XML look almost equally expressive, so if I could convert between the two formats, preserving all the information, I could put my XMLs in a JSON database. Lately there are a few databases which accept JSON and let you query on JSON properties.

Googling for such a converter didn't bring me to an undisputedly stable convertor, and my fingers itching to do some Clojure programming, the choice was easily made: I had to try this with Clojure. Hers is the result: https://github.com/kolov/x2j.

The implementation is shockingly compact. I am new to Clojure and writing this compact code was by no means fast, and the code is by no means optimal. Still, it covers the tests. I am impressed wit the compactness of the result. I produce a jar with class Converter, exposing the following 3 methods:

public static String x2j(String xml);
public static String j2x(String jsonContainingOneElement);
public static String j2x(String jsonContainingManyElements, String elementName);

Let's try it with MongoDB. Define two XMLs:


 Joe
 
Main Street Atlanta
34234234324 books tv
John
Jarvis Street Atlanta
NC 679898 books film

In Java:

String xml1 = ""
                + "Joe"
                + ... ;
String xml2 = ...

Let's start. Connect to MongoDB:
Mongo m = new Mongo(SERVER, PORT);
DB db = m.getDB(DB);
boolean auth = db.authenticate(USER, PASSWORD);
DBCollection coll = db.getCollection(COLLECTION_NAME);

Write the two XMLs:

String json1 = Converter.x2j(xml1);
System.out.println("XML: " + xml1);
System.out.println("XML -> Json: " + json1);
coll.insert((DBObject) JSON.parse(json1));

String json2 = Converter.x2j(xml2);
System.out.println("XML: " + xml2);
System.out.println("XML -> Json: " + json2);
coll.insert((DBObject) JSON.parse(json2));

The log shows:

XML: Joe
Main StreetAtlanta
34234234324bookstv
XML -> Json: {"person":{"hobbies":{"hobby":["books","tv"]},"id":{"#text":"34234234324","@type":"passport"},"address":{"street":"Main Street","city":"Atlanta"},"name":"Joe"}} XML: John
Jarvis StreetAtlanta
NC 679898booksfilm
XML -> Json: {"person":{"hobbies":{"hobby":["books","film"]},"id":{"#text":"NC 679898","@type":"licence"},"address":{"street":"Jarvis Street","city":"Atlanta"},"name":"John"}}

That looks OK. Let's now query some data:

DBCursor cursorDoc = coll.find(new BasicDBObject("person.hobbies.hobby", "tv"))
while (cursorDoc.hasNext()) {
 DBObject value = cursorDoc.next();
 System.out.println("Read Json: " + JSON.serialize(value));
  . . 
}
Oops, the log:

Read Json: { "_id" : { "$oid" : "4f36d8c103648a32fb075bc0"} , "person" : { "hobbies" : { "hobby" : [ "books" , "tv"]} , "id" : { "#text" : "34234234324" , "@type" : "passport"} , "address" : { "street" : "Main Street" , "city" : "Atlanta"} , "name" : "Joe"}}

The returned Json has to elements: the person entity and some ID data I don't care about at the moment. That's the reason for the Convertor method:
public static String j2x(String jsonContainingManyElements, String elementName);

Let's filter out _id and get the non-id-element only:

private String convertDbToXml(DBObject value) {
  String json = JSON.serialize(value);
  for (String key : value.keySet()) {
  if (!key.equals("_id")) {
   return Converter.j2x(json, key);
  }
 }
 return null;
}

With this, I run two searches:
findMatches(coll, "person.hobbies.hobby", "tv");
findMatches(coll, "person.hobbies.hobby", "books");

Here's the result:

Searching: person.hobbies.hobby=tv
Read Json: { "_id" : { "$oid" : "4f36d8c103648a32fb075bc0"} , "person" : { "hobbies" : { "hobby" : [ "books" , "tv"]} , "id" : { "#text" : "34234234324" , "@type" : "passport"} , "address" : { "street" : "Main Street" , "city" : "Atlanta"} , "name" : "Joe"}}
Json -> XML: bookstv
Main StreetAtlanta
Joe
Searching: person.hobbies.hobby=books Read Json: { "_id" : { "$oid" : "4f36d8c103648a32fb075bc0"} , "person" : { "hobbies" : { "hobby" : [ "books" , "tv"]} , "id" : { "#text" : "34234234324" , "@type" : "passport"} , "address" : { "street" : "Main Street" , "city" : "Atlanta"} , "name" : "Joe"}} Json -> XML: bookstv
Main StreetAtlanta
Joe
Read Json: { "_id" : { "$oid" : "4f36d8c103648a32fb075bc1"} , "person" : { "hobbies" : { "hobby" : [ "books" , "film"]} , "id" : { "#text" : "NC 679898" , "@type" : "licence"} , "address" : { "street" : "Jarvis Street" , "city" : "Atlanta"} , "name" : "John"}} Json -> XML: booksfilm
Jarvis StreetAtlanta
John

That looks fine, I get back the XML I wrote earlier and the search on XML content worked.

How good is this approach? I don't know, an XML database should be a better choice for extensive XML storage. The conversion leaves several issues open:
- absolutely no namespace support
- Querying XML data in Json terms and not in the 'native' XPath.
Still, it is an easy way to add basic XML functionality to a JSON datastore.

Friday, November 18, 2011

Sample Clojure/Compojure Web Application with Maven and IntelliJ

After learning a bit of Clojure I decided to start a simple Clojure web application project to try more things out. I expected I would easily find tons of sample projects to start from, but at the end I couldn't find a single Getting Started for the type of project I wanted:
- I am too comfortable with Maven to want to change it with leiningen or anything else.
- Starting a quick Jetty server is great but I still want to have the traditional WAR.

I don't know, may be these are all things a hard-core Clojure developers laugh at, but that is what I feel comfortable with at the moment.

Googling I found this very complete and precise blog entry:
http://blog.kartikshah.com/2010/12/how-to-intellij-idea-for.html It all worked as described, using leiningen. I tweaked it a bit:
- mavenized it: removed leningen, edited the pom to add clojure compilation using the clojure-maven-plugin;
- removed the GAE stuff;
- renamed a few folders and packages.

See below the core Clojure class implementing HttpServlet and routing request using Compojure:

(ns pwc.core
  (:gen-class :extends javax.servlet.http.HttpServlet)
  (:use compojure.core
        ring.util.servlet)
  (:require [compojure.route :as route]))

(defroutes hello
  (GET "/" [] "Hello World Wide Web!")
  (GET "/user/:id" [id]
    (str "Hello user " id ))
  (route/not-found "Page not found"))

(defservice hello)

The Compojure routing is explained here

The project is available at git. Build a war from maven or import the pom.xml in IntelliJ and run the war artifact in a servlet container. I ran it in tomcat, starting conservative: in the run configuration I deployed the non-exploded war, running the package goal before launch.

**NOTE** One month later, I don't think this is the way to go if you want to dive into Clojure. I've joinde the leiningen/emacs way.




Wednesday, February 23, 2011

Staged Maven build in Hudson with shared workspace

Staged Builds

Continous Integration is all about providing feedback, the faster the better. It is all being said by Martin Fowler, I'll just quote a crucial sentence from the Staged Builds section:
Probably the most crucial step is to start working on setting up a staged build.
So true, I had the opportunity to think about it each time when I had to wait for 40 long minutes before I see the build turning red or green. These exhaustive cryptographic tests taking 8 minutes or these cool integration tests taking 6 minutes - let them run each time but not as a part of the commit build. Enough said, check the article

Hudson provides all needed parts to set up a staged maven build, but I wasn't able to find a clear guidance on how to glue a staged build together. I found some useful hints and even better comments here. There is definitely more than one way of setting up a staged build, here is how I put the puzzle pieces together:

The scenario
Let's start with an imaginary scenario to illustrate the point. Let there be 3 modules: A, B and C. Module B's tests take too long an are unlikely to fail. Module C is an assembly using A and B and on which some integration tests are run.

Let's see how to make a 3-stage build:
* stage1 compiles and tests A, only compiles B
* stage2 tests (the already compiled) B
* stage3 packages and tests C (using A and B snapshots).

The key is to let the 3 stages run in the same workspace, so that each stage picks up where the previous one stopped. Behavior can be coupled to a stage with a profile, so for this example I define 3 maven profiles - stage1, stage2 and stage3.

It is important that the profiles add, not suppress tasks. Then the profiles can be used in a additive way, i.e. -Pstage1,stage2 will execute all tasks linked to both stage1 and stage 2. to take tests as example, do no -DskipTests=true in a stage, but define empty test files set in one stage and extend it in the next stage.


The parent pom:
<modules>
  <module>A</module>
  <module>B</module> 
</modules>
<profiles>
  <profile>
   <id>stage3</id>
   <modules>
    <module>C</module>
   </modules>
  </profile>
</profiles>

Nothing special in the A's pom. The B's pom:
<build>
<plugins>
  <plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-surefire-plugin</artifactId>
   <configuration>
    <includes>
     <include>No default tests included</include>
     </includes>
    </configuration>
   </plugin>
  </plugins>
</build>

<profiles>
  <profile>
   <id>stage2</id>
   <build>
   <plugins>
    <plugin>
     <groupId>org.apache.maven.plugins</groupId>
     <artifactId>maven-surefire-plugin</artifactId>
     <configuration>
      <includes>
       <include>**/Test*.java</include>
       <include>**/*Test.java</include>
       <include>**/*TestCase.java</include>
      </includes>
     </configuration>
    </plugin>
   </plugins>
  </build>
</profile>
</profiles>
 
Needed Hudson Plug-ins

The URL SCM plug-in lets you access archives from another build as SCM URLs. The trick is to let one stage provide the workspace for the next stage. Potentially this means passing huge archives between build nodes, more on that later. The M2 Extra Steps Plugin is needed to unzip the archive from the previous stage before starting the maven build.

Stage 1 Job

Define a Maven job that checks out the workspace from SCM. In the job settings, check 'Archive artifacts' and select the whole workspace (pattern **/*.*). The goal: clean, install.

Stage 2 Job

Copy Stage1 Job to a new job Stage2. In the Source Code Management section, select URL Copy. The URL to watch is something like http://hudson-server/job/stage1/lastSuccessfulBuild/artifact/*zip*/archive.zip. Go to Configure M2 Extra Build Steps and add an Execute Shell step: unzip archive.zip The goal: -Pstage2, install. Note that there is no clean. Finally, archive the workspace for the next stage.

Stage 3 Job

The Stage3 is much like stage2. The URL to watch will be http://hudson-server/job/stage2/lastSuccessfulBuild/artifact/*zip*/archive.zip. The goal will contain -Pstage2 but no clean.

Conclusion

This setup is pretty straightforward an pretty new for me, but I already notice a few points I am not really happy with:
- Packing, transferring and unpacking the workspace could cost a lot of time.
- The separate projects are too much aware about the build they will be part of. I'd prefer to be able to tweak the build without editing each particular project. Possibly inventing some profile names more descriptive than stage1, stage2 is the way to go.



Tuesday, March 16, 2010

How to de-FRAMESET a servlet application using Apache Tiles 2

The problem


There's is a good old application from the days when struts still had to be invented and framesets weren't considered evil. The problems associated with a FRAMESET are another topic, the fact is the application owner wants to get rid of the FRAMSET and asked me to look for a solution that would be unobtrusive and easy to implement, understand and maintain.

Current Situation


The application uses no web-app framework, each Use Case is implemented in a separate servlet, all of them neatly mapped in the web.xml. The FRAMESET setup is classic: apart from the static elements, the navigation happens in a 'body' and a 'menu' frame. The normal flow is to select a command from the menu frame, e.g. Place Order results in (<a href="/placeorder" target="'body"/>), then submit a few forms in the body frame (<form action="/placeorder" method="POST">...</form>). Without frameset, when a HTTP request for /placeorder reaches the application, we want the servlet response decorated with the other fragments: menu, header and the rest. The differences are essential: there is just one request/response and all page fragments have to share the same HEAD, CSS etc.

Introducing Apache Tiles 2


The good news is that version 2.x of Apache Tiles, which has started as struts extension, is now framework-independent. It offers support for JSP, Freemarker, and can be used directly from a servlet or filter. First of all, a template is needed to replace the frameset, e.g. main.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles"%>
<html>
<head>
 <link href="/online/theme/online.css" rel="stylesheet" type="text/css">
    <script language="javascript" src="/online/js/algemeen.js"></script>
</head>
<body>
<table border="1" cellspacing="0" cellpadding="0"
 style="width: 100%; height: 100%">
 <tr>
  <td colspan="2"><tiles:insertAttribute name="top" /></td>
 </tr>
 <tr>
  <td><tiles:insertAttribute name="menu" /></td>
  <td><tiles:insertAttribute name="body" /></td>
 </tr>
 <tr>
  <td colspan="2"><tiles:insertAttribute name="bottom" /></td>
 </tr>
</table>
</body>
</html>
Based on that template a tile definition can render a decorated view of any servlet output (e.g. /placeorder). A definition per servlet is needed in tiles.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE tiles-definitions PUBLIC
       "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
       "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">

<tiles-definitions>
  
 <definition name="placeorder.tile" template="/layout/main.jsp">
  <put-attribute name="top" value="/algemeen/onlinetop.html" />
  <put-attribute name="menu" value="/besturing/menu.jsp" />
  <put-attribute name="body" value="/placeorder" />
  <put-attribute name="bottom" value="/algemeen/onlinebottom.html" />
 </definition>
</tiles-definitions>

This definition still has to be rendered, e.g. from another JSP, let's call it placeholder_tiled.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>

<tiles:insertDefinition name="placeorder.tile" />

A separate tile definition and a JSP page for each servlet would be too much code repetition. Let's see how to the output of any servlet.

A View decorating servlet


I like the idea of having separate URLs for the servlet output and for a composite view of the same output. Thanks to Tiles 2 API, one servlet could provide decorated views of the output of all servlets. In tiles.xml, I added a tile definition with all attributes except body defined:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE tiles-definitions PUBLIC
       "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
       "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">

<tiles-definitions>
 <definition name="main.tile" template="/layout/main.jsp">
  <put-attribute name="top" value="/algemeen/onlinetop.html" />
  <put-attribute name="menu" value="/besturing/menu.jsp" />
  <!-- name="body"  not defined -->
  <put-attribute name="bottom" value="/algemeen/onlinebottom.html" />
 </definition>
 
</tiles-definitions>


Let's define a servlet that will fill in the missing body attribute for each URL ending with .tiled:

<servlet>
 <display-name>TilesServlet</display-name>
 <servlet-name>TilesServlet</servlet-name>
 <servlet-class>com.assenkolov.common.web.TilesServlet</servlet-class>
 <init-param>
 <param-name>template.name</param-name><param-value>main.tile</param-value></init-param>
 <init-param>
 <param-name>attribute.name</param-name><param-value>body</param-value></init-param>
</servlet>

<servlet-mapping>
 <servlet-name>TilesServlet</servlet-name>
 <url-pattern>*.tiled</url-pattern>
</servlet-mapping>

Finally, the servlet itself:
public class TilesServlet extends HttpServlet {
 private String templateName;
 private String attributeName;

 @Override
 public void init() throws ServletException {
  super.init();
  templateName = getInitParameter("template.name");
  attributeName = getInitParameter("attribute.name");
 }

 @Override
 public void service(HttpServletRequest request, HttpServletResponse response) 
  throws  ServletException, IOException {
   ServletContext servletContext = request.getSession().getServletContext();

   TilesContainer container = ServletUtil.getContainer(servletContext);
   AttributeContext attributeContext = container.startContext(request, response);

   // Remove the ".tiled" suffix from the request path
   String requestPath = request.getServletPath().replace(".tiled", "");
   Attribute attr = new Attribute(requestPath);

   Map attrs = new HashMap();
   attrs.put(attributeName, attr);
   attributeContext.addAll(attrs);

   container.render(templateName, request, response);
   container.endContext(request, response);
  }
}

This servlet always renders the same tiles definition, providing an appropriate body. No separate tiles definition and JSP for each view.

What's next?

All the code above only provides an easy template-decorated view for each servlet output. There is sill a lot of work that has to be done manually:
- move all separate styles, scripts etc. from the separate pages to the template
- requestDispacher.forward in a servlet closes the output stream while it is still needed for the tiles template; all forwards must become includes;
- all navigation javascript referring to top.menu ot top.body has to be refatored manually.

Tuesday, June 16, 2009

Generating Business objects with CGLIB

Don't code what you can generate

At my currrent project I ended up generating run-time proxies for my Business Objects with CGLIB. As this is somewhat unusual for a straightforward enterprise application, I still wonder about the pros and cons of this approach.

The main thing the application does is product configuration - given a definition of some tree of products, it lets the user create and edit product attributes, add and remove subproducts according to that definition. It is a requirement that the definition is external and it is expected to change regularly, so as much as possible of the product logic should be defined there.

A fragment of some imaginary domain objects definition to illustrate the case:
<productdefinition id="someProduct">
<date id="startingDate" nullable="false">
<enumeration id="area">
<enum default="true" value="World">
<enum value="Europe">
</enumeration>
<boolean id="allInclusive" defaultvalue="false">
<range id="limit" min="10" max="5000" step="10" defaultvalue="1250">
<subproduct type="someSubproduct">
<multiplicity mincount="0" maxcount="1" defaultcount="1"/>
</subproduct>
<productdefinition>


<productdefinition id="someSubproduct">
<text id="reason" pattern="\a{1,30}"/>
</productdefinition>


Whatever our Java classes implementation:
  • when creating SomeProduct some values have to be set initially: setArea('World'), setLimit(1250) etc. A properly initialized instance of SomeOtherProduct should be added as a subproduct.
  • someProduct.setStartDate(null) or someProduct.setArea("Japan"), someProduct.setLimit(10000) should all cause an error because the provided value is not acceptable according to the definition.
  • Rendering a GUI for editing a product attribute and processing the user input is uniform for all product attributes
  • etc. etc.


An intuitive approach was to try something PropertyBean-like with named properties. The implementation is straightforward, but the interface is somewhat clumsy:

interface Product {
Object getPropertyValue( String propertyName);
void setPropertyValue( String propertyName, Object propertyValue);
. . .
}

class ProductImpl implementing Product { . . . }

This works, but the use cases coed using this interface code is clumsy and prone to errors:

someOtherProduct.setPropertyValue("someProduct.sumeSubproduct[0].reason", "Lousy service");

An example without nested properties is too awful to reproduce here, though not difficult to imagine. Forget auto code completion,
type checking, refactoring facilities. The natural Java way of doing this is:

someOtherProduct.getSomeProduct().get(0).setArea("Europe");

And you need to invent some trics to write the equivalent of:
<form:input path="someProduct.someSubproduct[0].reason"/>

The interface that I actually would like for the use case implementations is:



interface SomeProduct {
Date getStartingDate();
void setStartingDate( Date date) throws BadValueException; // Null not accepted
List getSomesubproduct();
SomeSubproduct addSubproduct();
void deleteSubproduct( Subproduct p);
. . .
}

interface SomeSubproduct() {
String getReason();
void setReason( String reason);
}



Given existing ProductImpl instances, coding the implementations of those interfaces is a repetitive task, all getter/setters/addXXX/deleteXXX etc. will look alike. A code generation library could generate this trivial code for us. CGLib is a code generation library (a lot of tautology here) and I know it is good enough for Hibernate, so I thought it should do the job for me too. With a productImpl instance and a desired interface, the CGLib code needed to produce the proxy is surprisingly little:


class ProductProxyFactory {

public static Object createProxy(ProductImpl productImpl, Class clazz) {
Enhancer e = new Enhancer();
e.setSuperclass(clazz);
Callback callback = new ProductProxyCallback(clazz.getSimpleName(),
productImpl, productMapping);
e.setCallback(callback);
return e.create();
}
}

public class ProductProxyCallback implements MethodInterceptor {
private ProductImpl productImpl;

public Object intercept(Object object, Method method, 
Object[] args, MethodProxy  proxy) throws Throwable {
String methodName = method.getName();
if ( methodName.startsWith("get")) {
String propertyName = findMappedPropertyName(methodName); // find mapped property from method name
Object propertyValue = productImpl.getPropertyValue(propertyName );
Class subProductClass = findSubProductClass(propertyName ); // property value might be a product too
if (subProductClass != null) {
return createSubproductProxy(result, subProductClassName, mapped);
} else {
return result;
} else {
// Process setXXX, addXXX, deleteXXX methods and methods inherited from Object
. . .


Let's see an example:

// There is some old code that still creates product using the clumsy Product interface
ProductImpl productImpl = new ProductImpl( someProductDefinition);
// and sets some data
productImpl.setProperty( "startDate", today);

// Let's create a proxy implementing SomeProduct interface:
SomeProduct someProduct = (SomeProduct)createProxy( productImpl, SomeProduct.class);
Date date = someProduct.getStartingDate()


The code above is schematic, of course, in reality the application does not have to create any proxies explicitly. Not bad, the old classes have received a new face - another interface to the same data, and the only code that has to be written for each new interface is the interface definition itself.

Pros & Cons

- This approach adds complexity. This part of the application has confused more than one project members joining the team - 'Hey, why can't I find the implementation of SomeProduct?". Is it worth maintaining this extra complixity for the needs af smaal audience - the developpers of one application?
- The code above is schematic, the real implementation has to take care of more details - external mapping file, caching proxy instances etc. The real code is already more complicated than the example and could potentially become too complicated, as business analysts add new requirements to the application.
- Object identity issues pop up if you use proxies and this case is not different - it is possible to create many proxies working on the same underlying productImpl.
- Some OOP has gone here. Try to override SomeProduct.getStartDate() or to set a breakpoint on it. I guess it happens when you mess up with AOP.

Let's not forget the pros:

- No typing, retyping and copy-pasting of trivial code or introducing errors there. Changing a product is limitied to editing tha java interface and a mapping file.
- There is one well-defined place where all products are defined. There is one well-defined class where the behaviour of all products is defined, and no lazy or evil programmer can override it somewhere.


Is that DSL?
I wonder how this approach relates to the DSL concept of trading generality for expressiveness. The starting point is undoubtedly a domain-specific XML. While the DSL examples I have seen have a code-generation phase, here code is generated at run time vs. source generation phase. An obvious difference is that one can not inspect/change/override the generated code. While this is a DSL according to scholars (see http://ftp.cwi.nl/CWIreports/SEN/SEN-E0309.pdf) is this the sort of the DSL that is hot right now? I am curious on your thoughts on this.

Sunday, November 9, 2008

Browse sources and javadoc in maven

A few times I have tried to find the name of a library containing a particular class name. It is not something one needs often, but for those rare occasions I have not found a consistent way for such a search.

That shouldn't be too much work to do, I thought, and I haven't had a hobby project for a while. Two weekends and 50 GB of data later I'm launching a maven search site:
http://jaclaz.com/jacla/search.do

As an extra, all javadocs and sources can be browsed online if present in the repository.

PS: I underestimated how complex it is t keep a PC on 24/7 at home. The site is off-line.

PPS: On-line as http://alljavaclasses.com

Thursday, October 23, 2008

Measuring user session size with HtmlUnit and remote JMX

Keeping the user session small is a very important requirement for the application I am working on. The application architecture has tried to keep the size as small as possible, but how big is it eventually? The best way to know is to measure how much memory each new session costs. This turned out pretty straightforward with standard Java and open source tools:
- HtmlUnit provides a compact Web client. With little programming you can emulate some user action. An example follows which logs a new user.
- Start the Application Server in a separate JVM. Allow for remote JMX Monitoring.
- Start thousands of new sessions en follow what happens to memory usage in the server JVM using MemoryMXBean. JConsole is the easiest way to monitor the memory usage, but if you want to do some calculations or logging you'll have to gain access to the remote MXBean programmatically.

The method is independent of any server technology. You don't even need the application sources. A pic to illustrate what is going on:



and some implementation details:

Start the server and allow for remote JMX monitoring
Add the following to the java arguments:

-Dcom.sun.management.jmxremote.port=1444
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false


Program a simple web client to perform some user action

HtmlUnit's Webclient is a beauty. Here's an example of logging in in the Pluto portlet container an clicking on a link:


public void loginAndStartUseCase() throws Exception {
final WebClient webClient = new WebClient();
HtmlPage page = (HtmlPage) webClient.getPage("http://localhost:8080/pluto/portal/MyPage");
List forms = page.getForms();
boolean loginFormSubmitted = false;
for (HtmlForm htmlForm : forms) {
if (htmlForm.getActionAttribute().equals("j_security_check")) {
htmlForm.getInputByName("j_username").setValueAttribute("pluto");
htmlForm.getInputByName("j_password").setValueAttribute("pluto");
htmlForm.submit(htmlForm.getInputByName("login"));
loginFormSubmitted = true;
break;
}
}
if (!loginFormSubmitted) {
throw new RuntimeException("Login Form expected here");
}
page = (HtmlPage) webClient.getPage("http://localhost:8080/pluto/portal/MyPage");
page = clickLink(page, "MyUseCase");

page.getAllHtmlChildElements();
}

private static HtmlPage clickLink(HtmlPage page, String linkText) throws IOException {
LOG.debug("click " + linkText);
List anchors = page.getAnchors();
for (HtmlAnchor htmlAnchor : anchors) {
if (htmlAnchor.getFirstChild().asText().equals(linkText)) {
return (HtmlPage) htmlAnchor.click();
}
}
throw new RuntimeException("No link " + linkText);
}


Obtain a remote memory monitoring MXBean proxy

private static Object getMXBean(String beanType, Class beanClass, int port) throws MalformedURLException,
IOException, MalformedObjectNameException {
JMXServiceURL u = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:" + port + "/jmxrmi");
JMXConnector jmxConnector = JMXConnectorFactory.connect(u);
MBeanServerConnection beanServerConnection = jmxConnector.getMBeanServerConnection();

Hashtable props = new Hashtable();
props.put("type", beanType);
ObjectName on = new ObjectName("java.lang", props);

Set found = beanServerConnection.queryMBeans(on, null);
if (found.size() != 1) {
throw new RuntimeException("1 bean expected");
}

ObjectInstance objectInstance = found.iterator().next();

Object mxBean = ManagementFactory.newPlatformMXBeanProxy(beanServerConnection, objectInstance.getObjectName()
.toString(), beanClass);
return mxBean;
}


Start measuring!

Now you can start a new user session (or 10, or 1000), measure the memory impact and calculate whatever you want


MemoryMXBean memoryBean = (MemoryMXBean) getMXBean("Memory", MemoryMXBean.class, 1444);
for (many times) {
for(many_times) { loginAndStartUseCase(); }
memoryBean.gc();
long used = memoryBean.getHeapMemoryUsage().getUsed();
. . .



That's what my memory usage looks like after 10000 sessions:



This is an Excel chart built from comma-separated logging output.

The blue line shows the total memory usage - it usage grows consistently, it looks like no sessions have been released. The red line shows the calculated average session size. The average is pretty unreliable in the begin but stabilizes after a while - the cost of a new user just logging in and starting the use case seems to be around 3k.

Few remarks:
- Programming the Html WebClient for a more complex use case can be time consuming. Is there a good scripting alternative? Selenium was great, but starting a real browser for each user new session is not an option
- Make sure no sessions are released during the measurement. The test goes pretty fast, a normal session timeout of 15-30 min will be more than enough to reach your users limit.

Tuesday, October 7, 2008

Annotated controllers in Spring Portlet MVC

Usually trying out something new with the Spring framework goes smoothly. Reading the reference documentation provides me with the right amount of information to start and soon things work as expected - by me.

That is not what happened when I started using the annotated controllers in Spring Portlet MVC. I took me some time to get my first portlet working at all, and even more time to figure out how our team should write our portlets.

To sort things out, I started with a simple annotated controller that would allow me to collect a first and second name from the user, with few validations. A screenshot of two portlets on one Pluto page to get the idea:


That shouldn't be very difficult, right?

For me, it was. Here is a quick link to the final version.

The documentation is very clear about the design decision that all portlet details should be exposed to the portlet developer:

Most other portlet MVC frameworks attempt to completely hide the two phases from the developer and make it look as much like traditional servlet development as possible - we think this approach removes one of the main benefits of using portlets. So, the separation of the two phases is preserved throughout the Spring Portlet MVC framework.


Right, the portlet dispatcher has 2 phases, but the portlet annotations do not. You have to annotate your portlet's two phase controllers with the servlet annotation designed for one phase processing, so now and then you'll be short of words.

A small remark before we start: in your spring configuration, add the following interceptor to the DefalutAnnotationHandlerMapping:


<bean class="org.springframework.web.portlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<bean class="org.springframework.web.portlet.handler.ParameterMappingInterceptor" />
</property>
</bean>


This will copy the action parameter from the ActionRequest to the ActionResponse, so that the same parameter is present in the subsequent RenderRequest.

Let's start with a simple controller:

@Controller
@RequestMapping("VIEW")
public class PersonController {

@RequestMapping(params = "action=editPerson")
public void action(@ModelAttribute("person")
Person person) {
. . .
}

@RequestMapping(params = "action=editPerson")
public ModelAndView render(@ModelAttribute("person")
Person person) {
return . . .
}
}
and a url to kick off the controller action:

<portlet:actionURL>
<portlet:param name="action" value="person" />
</portlet:actionURL>


Here comes the first surprise: only the action method is called in both phases, render is never called. And the first lesson learned is:

@RequestMapping - argument types determine the phase mapping

The implementation of AnnotationMethodHandlerAdapter gives the details: each annotated method can be marked as a 'render' and/or 'action' method, or none. Action methods do not compete to handle render requests and vice versa. A method is marked as an action method mapping, if one of its parameters is of type ActionRequest, ActionResponse, InputStream, Reader. The coresponding render method argument types are RenderRequest, RenderResponse, OutputStream, Writer.
So in the example above both methods are neither action nor render and the best match in both cases is the first method in the list: action.

To avoid such surprises, don't forget to *always* include one the above classes in the annotated function arguments. My personal rule is always to include a request argument. Here comes the next controller version:


@RequestMapping(params = "action=editPerson")
public void action(ActionRequest request, @ModelAttribute("person") Person person);

@RequestMapping(params = "action=editPerson")
public ModelAndView render(RenderRequest request, @ModelAttribute("person") Person person)


This is not very nice; it is not always clear why this finction argument is there and a perfectionist reviewer could even remove it. Support for portlet specifics in the annotation would be better:

@RenderMapping(params = "action=editPerson", phase="ACTION")
public void action(@ModelAttribute("person") Person person)


Let's do validations. The submitted form is handled in the action phase, all subsequent renders should show the same validation errors. The next controller version:


@Controller
@RequestMapping("VIEW")
public class PersonController {

@RequestMapping(params = "action=person")
public void action(ActionRequest request, Person person, Errors errors) {
ValidationUtils.rejectIfEmpty(errors, "firstName", "firstName.empty", "First name cannot be empty");
}

@RequestMapping(params = "action=person")
public ModelAndView render(RenderRequest request, Person person, Errors errors) {
return new ModelAndView("person");
}
}


The result is frightening: the error message is never shown from the following JSP fragment:


First Name
<form:input path="firstName"/>
<form:errors path="firstName"/>

The reason is the command object present in the arguments list of the render method; remove it an you'll see the validation warning. Here comes the next lesson:

Don't pass command objects as render parameters

Each time a command object argument is needed, it's bound again with the current request, no matter action or render request.
The next version of our controller is:


@RequestMapping(params = "action=person")
public ModelAndView render(RenderRequest request) {
. . .

With no command object as render parameter, the errors are preserved from the action phase to all subsequent render requests.

Now we have a non-empty implicit model which Spring holds for us in the session, hence the extra render parameter org.springframework.web.portlet.mvc.ImplicitModel=true in the request. Model data created in the ACTION phase is available in the RENDER phase.

Where to create your command object?

In the servlet example at http://static.springframework.org/spring/docs/2.5.x/reference/mvc.html#mvc-ann-requestmapping the bean is prepared in the GET request processing, bind and validate at following POSTs, in two separate methods. I like the idea of having two different methods for the first call when the bean is created, and for subsequent calls when it is filled and validated:

@RequestMapping(params = "action=startPerson")
public ModelAndView renderFormFirst(RenderRequest request) {
ModelAndView modelAndView = new ModelAndView("/WEB-INF/jsp/person.jsp");
Person person = new Person();
// initialize from model...
person.setFirstName("John");
modelAndView.addObject("person", person);
return modelAndView;
}

@RequestMapping(params = "action=person")
public ModelAndView renderForm(RenderRequest request, ModelMap modelMap) {
return new ModelAndView("/WEB-INF/jsp/person.jsp");
}


Having only a render handler for starting the process is fine: normally an action handler will set render parameters for the next render, like in:

@RequestMapping(params = "action=person")
public void action(ActionRequest request, ActionResponse response, Person person, Errors errors, SessionStatus sessionStatus) {
ValidationUtils.rejectIfEmpty(errors, "firstName", "firstName.empty", "Please, fill in your first name");
ValidationUtils.rejectIfEmpty(errors, "lastName", "lastName.empty", "Please, fill in your last name");
if (!errors.hasErrors()) {
response.setRenderParameter("action", "hello");
}
}


The next inconsstiency in the annotated portlet controllers:
@ModelAttribute methods called for both action and render phase

The @ModelAttribute annotated methods, as can be expected, is handled the same in both phases. Chances are you won't need most of them in the action phase, like the following example:

@ModelAttribute("countries")
public List getCountries() {
. . .
}


Once again, a better annotation would be:


@ModelAttribute("countries", phase="RENDER")
public List getCountries() {
. . .
}


As this is not available, my rule is: don't use Model attribute. Call it explicitly in the needed (probably render) method.

Wednesday, June 11, 2008

Generating IBM RSA Websphere projects with Maven

Rational Software Architect (RSA) may not be the best development environment, but when it comes to WAS-integrated IDEs, there are not that many choices. RSA is the familiar Eclipse packaged together with some plugins, which provide integration with Websphere. Starting with a Websphere Web application with RSA is easy - just choose the right project type and you can immediately run the application in Websphere from the IDE.

If you are working with Maven, however, there are very good reasons why you will not want to create any projects drom RSA. All of them boil down to the DRY principle - Don't Repeat Yourself. The Maven POM files already describe your projects and dependencies, why would you want to do this second time in RSA? You are going to make your release builds (and continuous integration) with Maven anyway, and any RSA project changes you make have no impact on the build. You may end up bulding something different than what you develop. Maintaining dependencies at two places - in maven poms and in your RSA project is not good, and Maven is much better in the dependency stuff.

Besides, why lock to RSA? If you can generate the IDE files for RSA/Websphere, so you can for Eclipse/Tomcat, for example.

The Maven Eclipse plugin generates the needed IDE files. The point is you want to be able to use them directly in RSA. It took me some time to get the POMs right, so I thought it is worth sharing.

Typically in a Websphere app, you have an EAR project, a Web project and several JAR projects. In this example, I start with 3 projects: ERA, WAR, JAR. Define them in the parent POM:



<modules>
<module>app-jar</module>
<module>app-web</module>
<module>app-ear</module>
<modules>


Further in the parent POM, declare you are using java 5.0:


<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>


N.B. Define 1.5 and not 5.0, this was fatal for my RSA installation!

There's nothing special about the JAR project, the generated eclipse project is fine. For the Web project, few more settings are essential. Assuming you have a maven webapp archetype project, include the following under build/plugins in the project's pom:


<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<configuration>
<wtpversion>1.5</wtpversion>
<wtpContextName>myapp</wtpContextName>
<additionalProjectFacets>
<jst.java>5.0</jst.java>
<com.ibm.websphere.extended.web>6.1</com.ibm.websphere.extended.web>
<com.ibm.websphere.coexistence.web>6.1</com.ibm.websphere.coexistence.web>
</additionalProjectFacets>
</configuration>
</plugin>


The generated project will be a Dynamic Java project, and RSA wil recognise src/main/webapp as the web root folder. The web context name is also define in the plugin settings.

Similar setting are needed for the EAR POM:



<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<configuration>
<wtpversion>1.5</wtpversion>
<additionalProjectFacets>
<jst.ear>1.4</jst.ear>
<com.ibm.websphere.extended.web>
6.1
</com.ibm.websphere.extended.web>
<com.ibm.websphere.coexistence.web>
6.1
</com.ibm.websphere.coexistence.web>
</additionalProjectFacets>
</configuration>
</plugin>


The generated project is recognized by RSA as an EAR project. Of course, you need a correct application.xml in src/main/application/META-INF. This project doesn't contain any code, but is still usefull for maven, as it will build the release EAR.

Once that all is done, go the the project root and run mvn eclipse:eclipse with any extra options you may need. Import the generated projects in RSA (File/Import/Existing projects int workspace). The resulting file structure is the well known maven webapp structure:



To run the application from RSA, drag the EAR project to 'Web Sphere Application Sever' in the Servers view and start te server.

There is one issue that has not been addressed here - how do you get all those WAS-specific IBM files. Update follows.

Profiles

It's a good idea to set all those settings in maven under a profile. For the next environment, add a new profile.

Hiccups

Yes, they are very present:
- Go to the app-web project, Properties, J2EE dependencies, Web libraries - all library dependencies are there but not the project dependency on app-dom, while it obviously should be. Add it. I couldn't find a solution for this, tips about it will be very appreciated.
- Make sure that the web module element in application.xml has no id attribute. The id runs out of sync each time project files are generated.
- Sadly enough, after fiddling with application and server deployment configuration, now and then I just have to restart RSA to make the web application running.

Sunday, April 27, 2008

Portlet development with Eclipse and Pluto

I had to set up a portlet development environment with Eclipse. The portlet is being built with Spring Portlet MVC 2.5.2 and will eventually run under Websphere, but Eclipse WTP and Websphere don't go together well. So I thought I'll try to run my portlet from Eclipse/WTP in a portlet container running under Tomcat. Pluto is such a container and does the job. It has its own peculiarities, it needs to generate its own web.xml using your web.xml and portlet.xml as input. Pluto provides an ant task to do this.

A good integration with eclipse and Maven should take care of the following issues:
- dependency management: download the needed Pluto ant task jar with all its dependencies.
- automatically generate web.xml for Pluto each time when needed - in Eclipse and during a Maven build.

The steps I took to get all nicely running:
1. Install Tomcat/Pluto bundle and configre it as a server in eclipse.
2. Tell Maven to save together all dependencies needed for the Pluto Ant Task.
3. Define an Ant build file with the Pluto task.
4. Add the execution of the Ant task in the Maven build.
5. Generate eclipse project, add the portlet application to the pluto server, run the server end configure a page with the portlet. It is fun to have more portlet instances on the same page.
6. Fix issues that prevent the portlet from running.
7. Define an Eclipse Custom Builder to update the web.xml automatically.

Once this is done, start Tomcat/Pluto from eclipse, log in as admin and add your portlet to a Pluto portal page. After that, just start the server and go to your portal page.

The details of how to perform the above steps:

Install Tomcat/Pluto bundle and configre it as a server in eclipse

I installed pluto 1.1.6 based on tomcat 5.5 - pluto-current-bundle.zip from http://archive.apache.org/dist/portals/pluto/

In the Eclipse Servers tab, define a new Apache Tomcat 5.5 server. IMPORTANT: In the server configuration page, select 'Use Tomcat installation (takes control of tomcat installation)' under Server locations. I don't understande why, but otherwise pluto doesn't see the portlet.


Tell Maven to save together all dependencies needed for the Pluto Ant Task.


First of all, the org.apache.pluto:pluto-ant-tasks dependency must be present in your (root) pom.xml. Then, add the following, preferably under a new profile pluto:


<profile>
<id>pluto</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>generate-resources</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>target/libs-for-pluto</outputDirectory>
<includeArtifactIds>
pluto-ant-tasks,pluto-util,pluto-descriptor-api,pluto-descriptor-impl,commons-logging,castor,xercesImpl
</includeArtifactIds>
</configuration>
</execution>
. . .


This way, all dependencies needed for the Pluto ant task will be copied in target/libs-for-pluto folder where they can be used by the ant task.

Define an Ant build file with the Pluto task

In a new file, e.g. generate-pluto-web-xml.xml, define the task which generates the web.xml file needed by pluto in the web-inf folder. A place is needed for the original web.xml that will be procerssd by the task, I've placed it in src/main/config.

The contents of update-web-xml.xml:

<project name="pluto-update-web-xml" basedir="." default="generate-web-xml">
<path id="pluto.task.classes" >
<fileset dir="target/libs-for-pluto" includes="**/*" />
</path>

<typedef name="passemble"
classname="org.apache.pluto.ant.AssembleTask" classpathref="pluto.task.classes" />

<target name="generate-web-xml">
<echo>Generating Pluto web.xml</echo>
<passemble webxml="src/main/config/web.xml"
portletxml="src/main/webapp/web-inf/portlet.xml"
destfile="src/main/webapp/web-inf/web.xml" />
</target>

</project>

At this point, you should be able to run this ant task from the command line. It is better to do this from maven, see next step.

Add the execution of the Ant task in the Maven build.
In pom.xml, add the following under the profile pluto:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>generate-resources</phase>
<configuration>
<tasks>
<ant antfile="${basedir}/generate-pluto-web-xml.xml">
<target name="generate-web-xml" />
</ant>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>


At this point, running manually
mvn eclipse:eclipse -P pluto
will produce a web.xml as needed for pluto. The original web.xml stays in src/main/config. Needless to say, you must have a good portlet.xml in src/main/webapp/WEB-INF. Don't forget to make it a Web project.

Configure your portlet in Pluto
That is pretty straightforward - go to the Admin tab in pulto, and add your portlet to a new or existing page. The portlets in the application you deployed on pluto should be visible in the Portlet Application list box on the admin page.
Fix issues

When I first started the page with the portlet, I got the following stack trace:

java.lang.ClassCastException: org.springframework.web.servlet.support.JstlUtils$SpringLocalizationContext cannot be cast to java.lang.String
org.apache.taglibs.standard.tag.common.fmt.BundleSupport.getLocalizationContext(BundleSupport.java:134)
org.apache.taglibs.standard.tag.common.fmt.SetLocaleSupport.getFormattingLocale(SetLocaleSupport.java:251)
org.apache.taglibs.standard.tag.common.fmt.FormatDateSupport.doEndTag(FormatDateSupport.java:116)
org.apache.jsp.WEB_002dINF.themes.pluto_002ddefault_002dtheme_jsp._jspx_meth_fmt_formatDate_0(pluto_002ddefault_002dtheme_jsp.java:602)


Whatever the reason, I just removed the tag causing the error: a tag in pluto-default-theme.jsp and voila, it worked.

Define an Eclipse Custom Builder to update the web.xml automatically

You can define a custom bulder to update your web.xml in src/main/webapp/WEB-INF automatically each time you build the project or change web.xml in src/main/config. That's not really necessary, unless you are going to change web.xml often.

Alternatively, run mvn generate-resources manually each time you change web.xml.

To define a custom builder:

- In Eclipse, go to Project properties, Builders. New, Ant Builder.
In the Main tab, select the ant file and the working folder.


In the Refresh tab, select Specific Resources an click on Specify Resources. Select src/main/webapp/WEB-INF/web.xml. After each build, eclipse will refresh this resource.

In the Build Options tab, check 'Specify working set of relevant resources'. Click on Specify resources and select main/webapp/config/web.xml.

Now each time you change this file you see the ant task output in the console and the file is updated.

Tuesday, April 15, 2008

Open Session In View with JSF and Spring

I expected that a quick google session would immediately deliver the standard solution for this situation, but it didn't go this way.

The problem: I want Open Session in View for an JSF/Spring application. Ok, I know there is something fishy about open session in view, but believe me, for this application this is just fine. There is a chance that the application will become a portlet eventually, so I didn't want to have to handle portlet and servlet filters issues too. Instead, I want to use the convenient hooks provided by JSF to open and close the hibernate session - phase listeners. Happily, the Spring-provided OpenSessionInViewFilter reveals the technicalities of how Spring deals with the hibernate session factory.

Here is the result:

public class HibernateRestoreViewPhaseListener implements PhaseListener {

public void afterPhase(PhaseEvent event) {
}

protected SessionFactory lookupSessionFactory() {

FacesContext context = FacesContext.getCurrentInstance();
ServletContext servletContext = (ServletContext) context
.getExternalContext().getContext();
WebApplicationContext wac = WebApplicationContextUtils
.getWebApplicationContext(servletContext);
return (SessionFactory) wac.getBean("hibernate-session-factory",
SessionFactory.class);
}

public void beforePhase(PhaseEvent event) {
SessionFactory sessionFactory = lookupSessionFactory();
if (!TransactionSynchronizationManager.hasResource(sessionFactory)) {
Session session = getSession(sessionFactory);
TransactionSynchronizationManager.bindResource(sessionFactory,
new SessionHolder(session));
}
}

public PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW;
}

protected Session getSession(SessionFactory sessionFactory)
throws DataAccessResourceFailureException {
Session session = SessionFactoryUtils.getSession(sessionFactory, true);
session.setFlushMode(FlushMode.MANUAL);
return session;
}
}

The session gets closed when Render Response phase is finished:


public class HibernateRenderResponsePhaseListener implements PhaseListener {

public void afterPhase(PhaseEvent event) {
SessionFactory sessionFactory = lookupSessionFactory();

SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager
.unbindResource(sessionFactory);
closeSession(sessionHolder.getSession(), sessionFactory);
}
. . .



Don't forget to register the listeners in faces-config.xml

<lifecycle>
<phase-listener>
...HibernateRestoreViewPhaseListener
</phase-listener>
<phase-listener>
...HibernateRenderResponsePhaseListener
</phase-listener>
</lifecycle>



I have the feeling this is not the final solution and this post will be edited soon.