Friday, August 21, 2009

Spring and GWT Servlet Instantiation

I'm another person who wants to make a web application that uses Spring (dependency injection) and GWT (RPC and UI rendering).


GWT recommends setting up a servlet to do the RPC by declaring it in web.xml like this.

 <!-- Servlets -->
 <servlet>
    <servlet-name>stockPriceServiceImpl</servlet-name>
    <servlet-class>com.google.gwt.sample.stockwatcher.server.StockPriceServiceImpl</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>stockPriceServiceImpl</servlet-name>
    <url-pattern>/stockwatcher/stockPrices</url-pattern>
  </servlet-mapping>

That way, the web-app container (eg. Tomcat) will construct the servlet object.

Now I want my servlet object to have Spring context beans injected into it.

I could write special Spring-specific code to put in my servlet to do get the Spring application context and find all the beans it needs, but that's cumbersome, and can't take advantage of Spring's autowiring.

I happened to watch Ben Alex, of Spring Security, give a great Introduction to Spring Security talk, where he mentioned that it's hard to give up Dependency Injection just to fit in with the web-app container. So instead of letting the web-app container create the Spring Security filter that one could declare in web.xml, he declares (at around 9'10") a DelegatingFilterProxy in web.xml, and gives it a name "springSecurityFilterChain". The clever DelegatingFilterProxy, when it is started by the container, loads the spring context, finds the bean with that name (ie. the bean called springSecurityFilterChain), and uses it as the actual filter.

I want to do the same thing, but instead of filters, I want to do it for the servlet itself. Luckily, Spring provides a class to do that: org.springframework.web.context.support.HttpRequestHandlerServlet. All I have to do is replace the servlet-class line in the web.xml above with that HttpRequestHandlerServlet. Then, when the servlet is required, the HttpRequestHandlerServlet will look in the application context for a bean called "stockPriceServiceImpl". To make sure we have one of those, the applicationContext.xml needs to include something like:

<bean id="stockPriceServiceImpl" class="com.google.gwt.sample.stockwatcher.server.StockPriceServiceImpl"/>
There are two problems with this. The first one is that the HtpRequestHandlerServlet can only hand requests to HttpRequestHandler objects. Now we know that the stockPriceServiceImpl is a servlet, and it can handle these requests, but it doesn't use the right method names. Now I should really make a new version of the HttpRequestHandlerServlet that can hand off requests to a javax.servlet.HttpServlet or even to a javax.servlet.GenericServlet. The GWT RemoteServiceServlet extends these two standard java classes. But that's for another day. For today, I simply made my StockPriceServiceImpl class implement HttpRequestHandler and added the following method:

@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response) 
                         throws ServletException, IOException {
  service(request, response);
}

Now, spring is able to construct the stockPriceServiceImpl, but it still doesn't work. There's a NullPointerException that happens. I delved around in the source, and discovered that the stockPriceServiceImpl needed to locate its servletContext, so that it could load various serialization files. When the web-app constructs a servlet, it initialises it with the appropriate context. When Spring initialises it, it doesn't - by default. But, we can tell spring that we want it to do so, if the object implements ServletContextAware. So, I added that as an interface that the stockPriceServiceImpl implements, and then had to implement the setServletContext method. Unfortunately, the ServletContext object to be passed doesn't have a convenient constructor (it's an interface). So I created an anonymous class to provide the context, like this:

public void setServletContext(ServletContext servletContext) {
  final ServletContext context = servletContext;
  try {
    init(new ServletConfig() {
      @Override
      public String getInitParameter(String name) {
        return null;
      }
      @Override
      public Enumeration getInitParameterNames() {
        return null;
      }
      @Override
      public ServletContext getServletContext() {
        return context;
      }
      @Override
      public String getServletName() {
        return null;
      }
    });
  } catch (ServletException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
  }
}

And now it seems to work. (It took me long enough to get here that I thought I'd better jot down what I did!) Next step, as I said, is to see if I can adapt HttpRequestHandlerServlet so that it can just instantiate a javax.servlet.GenericServlet directly without having to add those dodgy bits.

Thursday, August 13, 2009

Mothers Milk

First Drop wines is a fairly new Barossa "virtual" winery. The comic-style label for 2007 Mother's Milk caught my eye at The Wine Emporium the other day, and I decided that it was worth a try. James Halliday gave it 4.5 stars, and I can see why. It's definitely fruit driven: soft and smooth, but with a medium body, and that all important cigar complexity. The length is quite good too. Dangerously easy to drink! I'll have to try a side-by-side tasting against the 2007 Jim's Hill...

Saturday, August 1, 2009

Shiraz Expo

You'll remember that I discovered Pol Gessner champagne was available at Dan Murphy's. Given that Hamilton is a little out of the way, you might be wondering how I found out. Well, there's a good answer: I was attending the 2009 Shiraz Expo there back in early May.

I thought it would be good to record for posterity some of the 30-odd Shirazes that I tasted there, and what I thought of some of them. First of all, let me mention the expensive ones, in no particular order:
  • Penfolds Grange (2004) ($570) - exceptionally full bodied, cigar/tobacco tastes; very long.
  • Kays Amery Block - deep fruity liquorice, no smoke/pepper.
  • Elderton Command - powerful, but limited back palate length.
  • Grant Burge Meshach - smooth, full bodied spice.
  • Penfolds St Henri (2001) - dry, low tannin, not particularly fruity. I don't get this wine.
  • Penfolds RWT - Full bodied to chewy! smooth with fruit/tannin balance, not too spicy.
  • Saltram No. 1. All spice, where's the fruit gone?
  • Wolf Blass Platinum - very long.
  • BVE E&E Black Pepper - Nice complexity, again not too spicy
  • Eileen Hardy - too light... no body.
  • Henschke Mt Edelstone Good long tobacco & spices.
  • St Hallett Old Block - Nice smoky/leathery flavours with good mouth filling body.
  • Annies Lane Coppertrail. Light bodied but smooth.
Some of the under-$40 ones that I'd like to taste again:
  • Henschke Keyneton Estate - balanced & fruity.
  • Wolf Blass Grey Label - Chocolate & vanilla hints, medium body, with good length.
  • BVE Ebenezer - Smooth, balanced, medium bodied peppery, with front palate length only.
  • Leasingham Bin 61 - Light bodied.
  • Brokenwood - Syrupy plums with good length and balance.
  • St Hallett Blackwell - Smoky and smooth, medium body.
  • Glaetzer The Bishop - Smooth with well-integrated oak, quite a good length.
Some cheaper (under $20) ones that are probably good value, but hard for me to judge effectively with the other competition.
  • Charles Cimicky The Trumps - a medium-weight peppery Barossa shiraz.
  • Richmond Grove Barossa
  • Thorn Clark Sandpiper
 I only tried a couple of cheaper WA wines (Vasse Felix and Cape Mentelle). While I like Cabernets from that side of the country, particularly Margaret River, on this occasion the Shiraz didn't rate.

I look forward to attending another Dan Murphy Shiraz Expo. The value for money was excellent (it was free!), and it was great to find a place with such a big variety of wines. I just need to get to the Wine Emporium in the valley now to compare.

Spring and Champagne, Bordeaux, Clare, Yarra

There's a couple of things to talk about. I'm getting frustrated trying to get the latest spring/hibernate/jpa libraries to work together to do the whole hbm2ddl business. It seems to delete the tables for my entities, instead of creating them. I'll try the Spring milestone libraries next instead of the MyEclipse bundled 2.5 ones.

But probably more importantly, I wanted to let you know about some Champagne. Now Joanna will tell you that I'm really not a Champagne person. In fact I'd rather have a Rockford Basket Press than the (sparkling) Black Shiraz that seems more popular. When we have méthode champenoise sparkling whites here in Australia, I struggle to find much in them. But I do remember about 10 years ago my Auntie Barbara shared a Pol Gessner with us, and it was a revelation: a yeasty, almost nutty flavour with a very creamy smooth bead. Now the memory may have aged well, and it was a pleasant dinner, so I may be raving a little too much about it. But I've always thought that I'd buy some more if I saw some. And now I've discovered where I can get it - it's exclusively imported by Dan Murphy. They're not local, but my local Vintage Cellars people advised me to try a Dumangin Vintage 2000 or a Gimonnet Brut (both premier cru grand classe) which were only slightly out of my price range. But a birthday and good loyalty-scheme-points seemed like a reasonable excuse, so I indulged.

We tried the Dumangin the other night, at our local restaurant "Plum" for a late birthday celebration. The food was pretty good - my pork belly (no, the one on the plate!) was not as succulent as I might have hoped - but the champagne did take me back. I'm not quite sure that the flavour was as strong in the nutty line. Perhaps "biscuity" as the salespeople suggested was a more accurate description. Maybe I need to look for blanc de noirs with more pinot. But the creamy yeast was there, and perhaps that made it worthwhile.

We also shared a 2005 Chateau d'Aurilhac from the Haut Médoc in Bordeaux. It was my first Bordeaux for a while, and we saw the smooth subtleties, complexities, and some length. I find it's chiefly the subtlety that distinguishes these French wines from the "blockbuster" Australian ones. The wine complemented my pork, and by all accounts the beef and duck too, so I'm quite happy with that one. There's another bottle waiting for the next occasion. (Another positive review)

A few days later, we had another family meal with a lamb stew, and so another Cabernet-based wine was called for. I decided to try a contrasting Clare Valley Kilikanoon Blocks Road Cabernet Sauvignon. While there was still smoothness, the wine was certainly very fruit-driven and had much stronger flavour than the Bordeaux. I'm not sure that the violets (as advertised on the label) were there, but I admit I'm not particularly familiar with the scent anyway. The berries were there, with a very slight hint of liquorice. The length was good, but not exceptional. With various driving commitments to think of, we spread the drinking pleasure over two nights. The vacu-vin seems to have preserved the quality nicely.

And just to make you think that my life really is centred on wine (and to save me from trying to remember details for another post), I'll also mention that we matched a roast pork with a Yarra Valley Sticks Pinot Noir. Now I'm not in the Sideways class of pinot fans, but Sticks, for about $20, seems to provide a reliable if not earth-shattering one. There's a slight tannic savour in there that distinguishes it from the cheap strawberry-cordial flavours of some others. In summer, it would definitely need cooling, but we found that on our 5°-25° Brisbane winter days a room temperature was just right.

Cheers!