<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;Dk8BQH0yfip7ImA9WhRUGEs.&quot;"><id>tag:blogger.com,1999:blog-4667121987470696359</id><updated>2012-01-29T12:20:51.396-07:00</updated><category term="Spring Restlet" /><category term="Spring MVC 3.1" /><category term="Job Interviews" /><category term="Apache ZooKeeper Leader Election" /><category term="EasyMock" /><category term="Apache Hive Example" /><category term="Java Memory Leaks" /><category term="Java Agent" /><category term="jvmti" /><category term="Restlet Spring 2.0" /><category term="jersey jax-rs example maven" /><category term="Jersey JAXB Schema" /><category term="Interviewing" /><category term="Spring Framework" /><category term="Code review plugin for eclipse" /><category term="Spring JmsTemplate" /><category term="Ubuntu Karmic" /><category term="ZooKeeper ZKClient example" /><category term="Http POST" /><category term="Apache ZooKeeper Example" /><category term="JAXWS Spring Example" /><category term="Java Instrumentation" /><category term="Jersey Client" /><category term="Hadoop Pig" /><category term="REST Caching" /><category term="AspectJ Maven Plugin" /><category term="BatchMessageListenerContainer Spring" /><category term="10th anniversary" /><category term="jersey jax-rs" /><category term="spring jersey jax-rs" /><category term="Spring Web Service example" /><category term="RESTful URIs" /><category term="MongoDB" /><category term="Software Bugs" /><category term="Spring with Annotations" /><category term="REST Client Frameworks" /><category term="Spring MVC Tutorial" /><category term="Spring 2.5" /><category term="Spring JmsTemplate WebLogic" /><category term="Sales interview." /><category term="hashCode() and equals()" /><category term="Spring JMS" /><category term="Jamon" /><category term="RESTful Web Services O'Rielly" /><category term="javassist" /><category term="SOAP UI REST" /><category term="Aspect J" /><category term="Google Chrome for Linux" /><category term="Java Erasure" /><category term="Database Shards" /><category term="Career Oppurtunities" /><category term="JAXRS" /><category term="Spring 2.5 example" /><category term="Weblogic Shared Subscription" /><category term="Service Locator" /><category term="Spring MVC Jamon Templating" /><category term="Spring MVC Jamon" /><category term="Hadoop Pig Example" /><category term="java" /><category term="JAX-RS Sub-resources" /><category term="Jersey JAX-RS Schema Validation" /><category term="MAT Eclipse" /><category term="jms security weblogic" /><category term="jax-rs" /><category term="Session tracking Tomcat" /><category term="Spring Restlet Web Service" /><category term="JMS Weblogic" /><category term="Java EE versus Jave SE developers" /><category term="Java 6 instrumentation" /><category term="Restlet 2.0" /><category term="REST Conflating Models" /><category term="Pig JSON Example" /><category term="HTTP Query Variables" /><category term="Apache Hadoop" /><category term="MAVEN" /><category term="SOAP UI" /><category term="JMS Patterns" /><category term="Restlet" /><category term="Jamon Templating Engine" /><category term="jaxs-caching response" /><category term="Debugging Memory" /><category term="Message Proxy" /><category term="Eclipse" /><category term="Mophia MongoDB example" /><category term="External Entity Injection" /><category term="Coherence and JMS" /><category term="Documenting Software" /><category term="Morphia for MongoDB" /><category term="Defensive Programming" /><category term="Weblogic JMS Distributed Queue" /><category term="Spring 2.5 Auto Wiring" /><category term="JBoss Resteasy" /><category term="XML Injection" /><category term="Forcing GC Java" /><category term="Weblogic JMS QueueBrowser" /><category term="WebLogic Partitioned Distributed Topic" /><category term="Immutability" /><category term="Hive Web Interface" /><category term="Maven Hibernate Shards" /><category term="Easy Mock Class mock" /><category term="JMS Message Ordering" /><category term="HTTP GET" /><category term="Restlet ConverterService" /><category term="Spring RestTemplate" /><category term="redefine Java Classes" /><category term="Hadoop Pig Maven Example" /><category term="JSR 311" /><category term="JAX-WS Enunciate" /><category term="Visual VM" /><category term="Tomcat Administration" /><category term="Strongly Typed Service Locator" /><category term="Builds" /><category term="Java Generics" /><category term="Overstock.com" /><category term="Restlet JAXB" /><category term="Web Service documentation" /><category term="JMS Batch" /><category term="Spring BatchMessageListenerContainer" /><category term="Chris Angel" /><category term="Being a worker bee" /><category term="Runtime Profiling" /><category term="Enunciate jax-rs" /><category term="Weblogic JMS Spring" /><category term="Jersey enunciate" /><category term="Jersey google protocol buffers" /><category term="Software" /><category term="Sherlock Holmes" /><category term="JAXWS Maven" /><category term="Distributed Queues" /><category term="JMS Shared subscriptions" /><category term="Restlet 2.0 Maven example" /><category term="Spring Framework Weblogic JMS Security" /><category term="Apache Cassandra" /><category term="jersey jaxrs maven" /><category term="SOA. Service" /><category term="Religion" /><category term="XML Security" /><category term="Google Protocol Buffers" /><category term="Hadoop Map Reduce Maven" /><category term="Windows 7" /><category term="RESTEasy Client" /><category term="Apache Cassandra Hadoop" /><category term="JAXWS" /><category term="hack" /><category term="Apache ZooKeeper Barrier" /><category term="hibernate" /><category term="JNI" /><category term="Exceptions with REST" /><category term="AspectJ Logging" /><category term="Hive JSON" /><category term="REST" /><category term="HWI" /><category term="Hibernate Optimistic locking" /><category term="REST Clients in Java" /><category term="Spring MVC 3.1 Example" /><category term="Lamba Probe for Tomcat" /><category term="Hibernate Shards" /><category term="REST protocol buffers" /><category term="Java Memory Leaks Usual Suspects" /><category term="Spring Java Config" /><category term="Jupiter Eclipse Plugin" /><category term="Caching" /><category term="Spring 3.1" /><category term="Cassandra Hector" /><category term="Restlet Client" /><category term="Apache Wink Client" /><category term="asm" /><category term="Apache Cassandra Map Reduce" /><category term="Hector Example" /><category term="Documentation in IT" /><category term="Plugin Dependency" /><category term="javaassist" /><category term="Batch message consumption" /><category term="JMS Topic Scaling" /><category term="Apache Wicket" /><category term="Custom Collection Type Hibernate" /><category term="Spring WebLogic JmsTemplate" /><category term="Profiling java" /><category term="YOXOS" /><category term="Weblogic JMX example" /><category term="HTTP Methods" /><category term="Worker Bee" /><category term="Tolerence" /><category term="EasyMock Final classes" /><category term="REST Web service" /><category term="Jersey Guice" /><category term="XXE" /><category term="Spring MVC REST" /><title>Sleepless in Salt Lake City</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://sleeplessinslc.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://sleeplessinslc.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Sanjay Acharya</name><uri>http://www.blogger.com/profile/01933976956977901677</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="28" src="http://3.bp.blogspot.com/-QuUnYIQQ4Ck/Txo3-4hza9I/AAAAAAAABBQ/QMZO-wT7v6A/s220/profile.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>70</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/blogspot/OidcY" /><feedburner:info uri="blogspot/oidcy" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;DUYBSHc4eip7ImA9WhRUGEw.&quot;"><id>tag:blogger.com,1999:blog-4667121987470696359.post-7566104247607940396</id><published>2012-01-28T23:05:00.000-07:00</published><updated>2012-01-28T23:05:59.932-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-28T23:05:59.932-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Jamon" /><category scheme="http://www.blogger.com/atom/ns#" term="Spring MVC Jamon" /><category scheme="http://www.blogger.com/atom/ns#" term="Spring MVC Jamon Templating" /><category scheme="http://www.blogger.com/atom/ns#" term="Jamon Templating Engine" /><category scheme="http://www.blogger.com/atom/ns#" term="Spring MVC 3.1" /><title>Spring MVC 3.1 with Jamon Templating</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/9HQODUuA6muputuPy8YDyzqaicI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9HQODUuA6muputuPy8YDyzqaicI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/9HQODUuA6muputuPy8YDyzqaicI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9HQODUuA6muputuPy8YDyzqaicI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
Quite clearly as my BLOGs show, I have been working with my favorite technology stack recently, i.e., Spring. In particular, I have been working on &lt;a href="http://static.springsource.org/spring/docs/current/spring-framework-reference/html/mvc.html"&gt;Spring MVC&lt;/a&gt; and am looking at finding the right view technology to use with Spring. I am biased toward &lt;a href="http://freemarker.sourceforge.net/"&gt;FreeMarker &lt;/a&gt;as it appears to be a super set of &lt;a href="http://velocity.apache.org/"&gt;Velocity &lt;/a&gt; and can work with JSPs if required. That said, I have noticed on some Spring Forum postings queries on using &lt;a href="http://www.jamon.org/"&gt;Jamon &lt;/a&gt;with Spring.&amp;nbsp; There does not appear to be a concrete example of the same on the web. There are many that talk about performance monitoring of Spring with its namesake &lt;a href="http://jamonapi.sourceforge.net/"&gt;JAMon&lt;/a&gt; however. So here goes my attempt at integrating Spring with Jamon.
&lt;br /&gt;
&lt;br /&gt;
So what is &lt;a href="http://www.jamon.org/"&gt;Jamon&lt;/a&gt;? Quoting the words of the creators of Jamon, "&lt;i&gt;Jamon is a text template engine for Java, useful for generating dynamic HTML,XML, or any text-based content. In a
typical Model-View-Controller architecture, Jamon clearly is aimed at the View (or presentation)
layer&lt;/i&gt;".&lt;br /&gt;
&lt;br /&gt;
One of the constructs that is central to Jamon is&lt;a href="http://en.wikipedia.org/wiki/Type_system"&gt; type safety&lt;/a&gt;. Jamon on the view tier provides compile time type safety that is quite lost when using for example, &lt;a href="http://en.wikipedia.org/wiki/JavaServer_Pages"&gt;JSPs&lt;/a&gt;, and the expression language libraries that are associated with it.&lt;br /&gt;
&lt;br /&gt;
With technologies like JSP, errors are detected by a developer at runtime and they fix the same as they develop the application. Detecting an error at compile time however is really beneficial if the cost of starting an application and testing a request path is significant.Jamon templating with the compile time type safety it provides the presentation tier, mitigates the turn around time for development and refactoring. I will not delve into the details of Jamon as the same can be &lt;a href="http://www.jamon.org/tutorial/TutorialPath.html"&gt;read on the Jamon website&lt;/a&gt;.
&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.artima.com/lejava/articles/jamon.html"&gt;An interview on the web with one of the creators of Jamon&lt;/a&gt; describes how templating languages like FreeMarker and Velocity only partially fill the void of type safety when working with a framework like Spring MVC and infact have a hole that can lead to non type safe behavior.&lt;br /&gt;
&lt;br /&gt;
Consider the following snippet using Spring MVC with FreeMarker for rendering the view:&lt;br /&gt;
&lt;pre class="java" name="code"&gt;@Controller
public class LoginController {
  public ModelAndView login(User user, BindingResult result) {
     ModelAndView mav = new ModelAndView("user");
     ......
     if (result.hasErrors()) {
       mav.addObject("user", user); 
       ....
       return mav;
     }
     ...
  }
}
&lt;/pre&gt;
The corresponding FreeMarker template, &lt;i&gt;login.ftl&lt;/i&gt;, might look like:
&lt;br /&gt;
&lt;pre class="xml" name="code"&gt; &amp;lt;@spring.bind "user.*"/&amp;gt;
 &amp;lt;@spring.formInput "user.username", id="username"/&amp;gt;
&lt;/pre&gt;
With the above, all is well and the runtime binding works just fine. However, if a developer accidentally forgot to:&lt;br /&gt;
&lt;ul style="text-align: left;"&gt;
&lt;li&gt; Add the user object to the model&lt;/li&gt;
&lt;li&gt;Or misspelled the "key" to the user object as "&lt;i&gt;user&lt;/i&gt;" but as "&lt;i&gt;users&lt;/i&gt;"&lt;/li&gt;
&lt;li&gt;Or misspelled "&lt;i&gt;user.username&lt;/i&gt;" on the FreeMarker template as "&lt;i&gt;user.usrname&lt;/i&gt;"&lt;/li&gt;
&lt;li&gt;Or placed a wrong type in the value for the &lt;a href="http://static.springsource.org/spring/docs/current/api/org/springframework/web/servlet/ModelAndView.html"&gt;ModelAndView &lt;/a&gt;instead of the User object &lt;/li&gt;
&lt;/ul&gt;
They would experience failures at runtime and even a strong templating language like FreeMarker would be powerless to detect the issues mentioned due to the loose coupling between the Spring MVC controller and the Template. Objects added to the ModelAndView object are of signature &lt;i&gt;addObject(String, Object)&lt;/i&gt;, ie., quite a few rooms for accidents. This decoupling nature of Spring MVC would hurt even a presentation tier written using Jamon right? Well would it really ? What if&amp;nbsp; type safety could be maintained all the way from the Spring Controller tier to the view tier with Jamon?

Lets say for the sake of discussion, we desire to render a login page using Jamon with Spring MVC.&amp;nbsp;
A&lt;a href="http://www.jamon.org/UserGuide.html"&gt; Jamon Template&lt;/a&gt; for the user login titled &lt;i&gt;LoginView.jamon&lt;/i&gt; is shown below in which the User object is explicitly passed in to the Jamon template. There are no iffs or &lt;a href="http://teslkoreanews.com/wp-content/uploads/2010/09/ephelump-butt.jpg"&gt;butts &lt;/a&gt;regarding what is available to the Template here, it is the User object and only the User object that is made available to the template. It is possible to pass in &lt;i&gt;null &lt;/i&gt;due to a programming mistake or runtime time error in which case all bets are off and this concern transcends compile time safety. At compile time a LoginView.class is made available:
&lt;br /&gt;
&lt;pre class="xml" name="code"&gt; &amp;lt;%import&amp;gt;
com.welflex.model.User;
&amp;lt;/%import&amp;gt;
&amp;lt;%args&amp;gt;
User user;
&amp;lt;/%args&amp;gt;

&amp;lt;form....
    ...
    &amp;lt;input type="text" id="userName" name="userName" value="&amp;lt;% user.getUserName() %&amp;gt;"&amp;gt;
    ....
    &amp;lt;input type="submit" name="Login" value="Login"/&amp;gt;
 &amp;lt;/form&amp;gt;
&lt;/pre&gt;
The Login Controller is designed to return a Jamon Renderer rather than a ModelAndView as shown below:
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;@Controller
public class LoginController {
  /**
   * @return Return a Jamon Renderer
   */
  @RequestMapping(value = "/login.html", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
  @ResponseBody
  public Renderer login() {
    User user = new User("Enter user name", "Enter password");
    return new LoginView().makeRenderer(user);
  }
}
&lt;/pre&gt;
Nice and dandy, so how does one tell Spring MVC to handle the Jamon Renderer? Look no further than below where a custom &lt;a href="http://static.springsource.org/spring/docs/current/api/org/springframework/http/converter/HttpMessageConverter.html"&gt;HttpMessageConverter &lt;/a&gt;is created for the same:
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;public class JamonTemplateHttpConverter extends AbstractHttpMessageConverter&amp;lt;Renderer&amp;gt; {

  @Override
  protected boolean supports(Class&amp;lt;?&amp;gt; clazz) {
   // Only Renderer classes are supported by this HttpMessageConverter
   return Renderer.class.isAssignableFrom(clazz);
  }
  
  @Override
  public boolean canWrite(Class&amp;lt;?&amp;gt; clazz, MediaType mediaType) {
    return supports(clazz) &amp;amp;&amp;amp; MediaType.TEXT_HTML.equals(mediaType);
  }
  ...

  @Override
  protected void writeInternal(Renderer t, HttpOutputMessage outputMessage) throws IOException,
    HttpMessageNotWritableException {
    Charset charset = getContentTypeCharset(outputMessage.getHeaders().getContentType());
    t.renderTo(new OutputStreamWriter(outputMessage.getBody(), charset));
  }
  ...
}
&lt;/pre&gt;
Of particular note in the above class is the fact that it knows how to handle Jamon Renderers and also writes the renderer's content to the HttpServlet output stream. The next step involves letting Spring know of the renderer. This operation is accomplished in the Web Configuration class as shown below:
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;
@EnableWebMvc
@Configuration
@Import({ControllerConfig.class})
public class WebConfig extends WebMvcConfigurerAdapter {
  ...  
  @Override
  public void configureMessageConverters(List&amp;lt;HttpMessageConverter&amp;lt;?&amp;gt;&amp;gt; converters) {
    converters.add(new JamonTemplateHttpConverter());
  }
  ...
}
&lt;/pre&gt;
The above is one way where type safety is preserved using Jamon and Spring MVC. What about if one wishes to use the ModelAndView paradigm from Spring as is standard practice ? Well I could not do the same ! At least not without some customizations. Spring Dispatcher Servlet is strongly tied to the ModelAndView class for its functioning and sadly ModelAndView is not an interface. However, the good thing is that that ModelAndView is not "final" and neither are its methods. In addition, the &lt;a href="http://static.springsource.org/spring/docs/current/api/org/springframework/web/servlet/View.html"&gt;View &lt;/a&gt;part of ModelAndView is an interface so we start by creating a custom implementation of the View whose primary purpose is to render the contents:
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;public class JamonView implements View {
  private final Renderer renderer;
  
  public JamonView(Renderer renderer) { this.renderer = renderer; }
  
  @Override
  public String getContentType() { return MediaType.TEXT_HTML_VALUE; }

  @Override
  public void render(Map&amp;lt;String, ?&amp;gt; model, HttpServletRequest request, HttpServletResponse response) throws Exception {  
    // Note that the Model is never used at all here.
    StringWriter writer = new StringWriter();
    renderer.renderTo(writer);
    response.getOutputStream().write(writer.toString().getBytes());
  }
}
&lt;/pre&gt;
The ModelAndView object is what is central to Spring's &lt;a href="http://static.springsource.org/spring/docs/current/api/org/springframework/web/servlet/DispatcherServlet.html"&gt;DispatcherServlet &lt;/a&gt;and as one would probably guess, the only option I had at my disposal (no cglib enhancements please) was to extend ModelAndView as shown below:
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;public class JamonModelAndView extends ModelAndView {  
  
  public JamonModelAndView(Renderer renderer) { super(new JamonView(renderer)); }
  
  public JamonModelAndView(JamonView view) { super(view); }
  
  // Probably want to ensure that other methods are not invokable by throwing UnsupportedOperationException
  // Sadness that ModelAndView is not an interface or one could use dynamic proxies! Also there is no 
  // higher level abstraction one can use
}
&lt;/pre&gt;
On could also have the &lt;i&gt;JamonModelAndView &lt;/i&gt;be a static static class that provided methods to create a ModelAndView with signatures that accept a Renderer or JamonView. With the custom extension to ModelAndView, a resulting Controller class for the &lt;i&gt;Login &lt;/i&gt;operation would look like the following where two separate execution paths are demonstrated, one for a successful login and a second where validation errors were detected. God bless &lt;a href="http://en.wikipedia.org/wiki/Liskov_substitution_principle"&gt;Liskov and his substitution principle&lt;/a&gt; Also note that the User object is automatically bound and its properties validated with values passed in from the form:
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;@Controller
public class LoginController {
  ....
  @RequestMapping(value="/login.html", method = RequestMethod.POST)
  public ModelAndView login(@Valid User user,  BindingResult result,  Map&amp;lt;String, Object&amp;gt; model) {
   return result.hasErrors() ?  new JamonModelAndView(new LoginView().makeRenderer(user, result))
      : new ModelAndView("redirect:/welcome.html");    
  }
  
  @RequestMapping(value="/welcome.html")
  public ModelAndView welcome() {
    return new JamonModelAndView(new WelcomeView().makeRenderer());
  }
}
&lt;/pre&gt;
With the above, we are all but done with a type safe rendering approach using Spring MVC and Jamon. What remains is the part where form submission and the input variable mapping has to be defined in the Jamon Template. If one does the following where the &lt;i&gt;userName &lt;/i&gt;property is quoted as a non type safe string, we are left with a hole all over again regarding our type safe mantra:
&lt;br /&gt;
&lt;pre class="xml" name="code"&gt;&amp;lt;form....
    ...
    &amp;lt;input type="text" id="userName" name="userName" value="&amp;lt;% user.getUserName() %&amp;gt;"&amp;gt;
    ....
    &amp;lt;input type="submit" name="Login" value="Login"/&amp;gt;
 &amp;lt;/form&amp;gt;
&lt;/pre&gt;
I have broken my head trying to figure out a type safe way to describe how to specify the input form mappings in a type safe way and ended up with a cheap solution that requires the definition of a constant somewhere that describes the same. Please note that the constant itself is not safe from any refactoring done on the User bean as it not strongly typed to the actual method signature of &lt;i&gt;setUserName(User)&lt;/i&gt;:
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;&amp;lt;form....
    ...
    &amp;lt;input type="text" id="userName" name="&amp;lt;% User.USER_NAME_PROPERTY %&amp;gt;" value="&amp;lt;% user.getUserName() %&amp;gt;"&amp;gt;
    ....
    &amp;lt;input type="submit" name="Login" value="Login"/&amp;gt;
 &amp;lt;/form&amp;gt;
&lt;/pre&gt;
&lt;b&gt;Running the Example:&lt;/b&gt;
&lt;br /&gt;
&lt;br /&gt;
A simplistic application &lt;a href="http://home.comcast.net/~acharya.s/java/springJamon.zip"&gt;demonstrating a Login Form with validation is available for download here&lt;/a&gt;. Extract the same and execute a "&lt;i&gt;mvn jetty:run&lt;/i&gt;" to launch the application. Access the application at &lt;a href="http://localhost:9090/"&gt;http://localhost:9090&lt;/a&gt; and login using any username/pass combo to a simple welcome page. If you are an eclipse user, install the eclipse plugin for Jamon for syntax highlighting and IDE support. I would recommend that any user trying this example attempt to change code and witness for themselves the benefits of compile time type safety that Jamon provides. Please note that if you use the J2EE perspective on your project, you will not be able to see the Jamon configuration options sadly. On the Java perspective however, all is visible when you goto &lt;i&gt;Project-&amp;gt;Properties-&amp;gt;Jamon&lt;/i&gt;.
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Conclusion:&lt;/b&gt;
&lt;br /&gt;
&lt;br /&gt;
The question remains whether Jamon is a suitable candidate for the presentation tier when using something like Spring MVC? My answer as any smart architect would say is, it depends! If the web application is primarily a read-only, i.e, whose focus is to render data for display, then yes, you cannot go wrong with the benefits of Jamon. Where Jamon for the view tier suffers is when an application has a lot of forms requiring user input and the fact that there is no way to guarantee type safety of the input variables without the use of constants as shown above. The mantra of type safety is only partial in such cases and if this is something you are willing to tolerate, more power to you. Jamon cannot be faulted for this deficiency as the Java language itself has no way of describing the property names in a type safe manner. In addition, Jamon does not provide an expression language or tag based support from what I know of. Jamon has a lot going for it and I have personally developed a couple of applications using it for my view tier. Features like macros provided by FreeMarker make development easier and if one is careful and thorough with good unit/automation/manual coverage of ones application, the fear of runtime errors due to lack of type safety can be mitigated in favor of the powerful EL and Macro support provided by the other view technologies for Spring MVC. In addition, there is strong integration support from the Spring Framework for FreeMarker and Velocity with provided macros etc. If any person who stumbles on this BLOG has used FreeMarker or Velocity with Spring, I would like to hear of their experience of same please.In addition, if anyone has integrated their Spring MVC application with Jamon in different way, I'd love to hear the approach.
&lt;br/&gt;
&lt;br/&gt;
Lets get the bottom line straight though, Jamon, FreeMarker, Velocity, whatever, in the end remember the following:
&lt;br /&gt;
&lt;br/&gt;
&lt;i&gt;Developing with Spring my friends is a fine thing....&lt;/i&gt;
&lt;br/&gt;
&lt;i&gt;
Your code will sing, and your projects will fly to successful wins as if they had wings....&lt;/i&gt;
&lt;br/&gt;
&lt;i&gt;There just ain't no going wrong with this thing....&lt;/i&gt;
&lt;br/&gt;
&lt;i&gt;It's not just some temporary fling....&lt;/i&gt;
&lt;br/&gt;
&lt;i&gt;Embrace it, and it will treat you like a king!&lt;/i&gt;
&lt;br/&gt;
&lt;br/&gt;
Peace!
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4667121987470696359-7566104247607940396?l=sleeplessinslc.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OidcY/~4/mcusVo2iQNo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sleeplessinslc.blogspot.com/feeds/7566104247607940396/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4667121987470696359&amp;postID=7566104247607940396" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/7566104247607940396?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/7566104247607940396?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OidcY/~3/mcusVo2iQNo/spring-mvc-31-with-jamon-templating.html" title="Spring MVC 3.1 with Jamon Templating" /><author><name>Sanjay Acharya</name><uri>http://www.blogger.com/profile/01933976956977901677</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="28" src="http://3.bp.blogspot.com/-QuUnYIQQ4Ck/Txo3-4hza9I/AAAAAAAABBQ/QMZO-wT7v6A/s220/profile.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://sleeplessinslc.blogspot.com/2012/01/spring-mvc-31-with-jamon-templating.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU8NQXs_eSp7ImA9WhRVEEU.&quot;"><id>tag:blogger.com,1999:blog-4667121987470696359.post-3799126188617853927</id><published>2012-01-08T22:44:00.001-07:00</published><updated>2012-01-08T22:44:50.541-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-08T22:44:50.541-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Spring 3.1" /><category scheme="http://www.blogger.com/atom/ns#" term="Spring MVC 3.1 Example" /><category scheme="http://www.blogger.com/atom/ns#" term="Spring Web Service example" /><category scheme="http://www.blogger.com/atom/ns#" term="Spring RestTemplate" /><category scheme="http://www.blogger.com/atom/ns#" term="Spring Java Config" /><category scheme="http://www.blogger.com/atom/ns#" term="Spring MVC Tutorial" /><category scheme="http://www.blogger.com/atom/ns#" term="Spring MVC REST" /><title>Spring  3.1  MVC Example</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/kg7_BxiWPPDxlubsU7FBB_XDb7U/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kg7_BxiWPPDxlubsU7FBB_XDb7U/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/kg7_BxiWPPDxlubsU7FBB_XDb7U/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kg7_BxiWPPDxlubsU7FBB_XDb7U/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
I started Sleepless in Salt Lake City with an &lt;a href="http://sleeplessinslc.blogspot.com/2008/02/introduction-software-development-and.html"&gt;example of Spring MVC that used auto-wiring&lt;/a&gt; with &lt;a href="http://www.springsource.org/node/561"&gt;Spring 2.5&lt;/a&gt;. Sadly, I have lost that code. On the bright side however, Spring has made some advances that I am hoping to catch up with a re-vamp of the original BLOG. This BLOG primarily hopes to demonstrate the use of Spring Java Config spanning different tiers of an application with a simple &lt;a href="http://blog.springsource.org/2011/06/13/spring-3-1-m2-spring-mvc-enhancements-2/"&gt;Spring MVC 3.1&lt;/a&gt; example that one can use for learning as well.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/beans.html#beans-java"&gt;Spring JavaConfig&lt;/a&gt; is a means of configuring the Spring Container using pure-java, i.e., without XML if one so desired. It relies on the features of Java 5.X+ such as Generics and Annotations to express what was previously done via XML. Java Config has the following advantages:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;1.&lt;/b&gt; Injections, as it should be done using features like inheritance, polymorphism, etc. &lt;br /&gt;
&lt;b&gt;2.&lt;/b&gt; Full control on creation and initialization of beans.&lt;br /&gt;
&lt;b&gt;3. &lt;/b&gt;Makes refactoring easy without the need for something like Spring IDE&lt;br /&gt;
&lt;b&gt;4.&lt;/b&gt; Ability to refrain from Classpath scanning as that can be expensive for container initialization&lt;br /&gt;
&lt;b&gt;5.&lt;/b&gt; Use XML or property support in conjunction if desired &lt;br /&gt;
&lt;br /&gt;
Most of this BLOG is&amp;nbsp;in the form of code&amp;nbsp;with a functional examples provided as well for download and execution. The code shown below assumes that a person is familiar with Spring MVC and does not delve into the basics of the same. The examples used in this BLOG are written with the following objectives:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;1.&lt;/b&gt; Demonstrate Spring Java Config across the different tiers with no spring XML usage&lt;br /&gt;
&lt;b&gt;2.&lt;/b&gt; Demonstrate transaction management&lt;br /&gt;
&lt;b&gt;3.&lt;/b&gt; Demonstate a validator for the beans using JSR-303&lt;br /&gt;
&lt;b&gt;4.&lt;/b&gt; Demonstate the REST features of Spring XML by having the application double as a RESTful Web Service.&lt;br /&gt;
&lt;b&gt;5.&lt;/b&gt; Demonstate how Unit testing can be achieved across the tiers when using Java Config&lt;br /&gt;
&lt;b&gt;6.&lt;/b&gt; Demonstates use of RestTemplate in an integration-test of the Web Service&lt;br /&gt;
&lt;br /&gt;
In short, the making of a really long POST ;-)&lt;br /&gt;
&lt;br /&gt;
The app references in this BLOG is a simple Flight reservation system where flights can be searched and booked. The web application itself is separated into 3 tiers, Web, Service and Data Access. Each of the tiers has its own Java Configuration as shown below with the &lt;i&gt;WebConfig &lt;/i&gt;being the aggregator or top level Config:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-J8d58r3EfW8/Twe--sFJtiI/AAAAAAAABBA/nV8AxpWN3QU/s1600/dependencies.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="140" src="http://1.bp.blogspot.com/-J8d58r3EfW8/Twe--sFJtiI/AAAAAAAABBA/nV8AxpWN3QU/s640/dependencies.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
With the interest of making unit testing easier, the Config classes are separated via interface/impl.&lt;br /&gt;
&lt;br /&gt;
The data access tier defines a Java Config module as shown below:
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;@Configuration
@EnableTransactionManagement
public class DefaultDaoConfig implements DaoConfig, TransactionManagementConfigurer {
  
  // Dao Initialization
  @Bean
  public FlightDao getFlightDao() {
     return new FlightDaoImpl(getSessionFactory());
  }
   ...other DAOs

  // Session Factory configuration for Hibernate
  @Bean
  public SessionFactory getSessionFactory() {
    return new AnnotationConfiguration().addAnnotatedClass(Ticket.class)
      .addAnnotatedClass(Flight.class).addAnnotatedClass(Airport.class)
      .configure().buildSessionFactory();
  }

  // Transaction manager being used
  @Override
  public PlatformTransactionManager annotationDrivenTransactionManager() {
    return new HibernateTransactionManager(getSessionFactory());
  }
}
&lt;/pre&gt;
&lt;br /&gt;
Of interest in the above is the &lt;a href="http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/transaction/annotation/EnableTransactionManagement.html"&gt;@EnableTransactionManagement&lt;/a&gt; annotation which enables Spring's annotation driven transaction management capabilities for services annotated with @Transactional. The&lt;a href="http://static.springsource.org/spring/docs/3.1.x/javadoc-api/"&gt; @Transactional&lt;/a&gt; annotation instructs the Spring container to provide transactional semantics for the method.&amp;nbsp; A service class annotated with @Transactional is shown below. Also note that the &lt;i&gt;FlightDao &lt;/i&gt;and &lt;i&gt;TicketDao &lt;/i&gt;beans are defined to be set explicitly via the constructor without the use of the &lt;a href="http://static.springsource.org/spring/docs/3.1.x/javadoc-api/index.html?index-filesindex-1.html"&gt;@Autowired&lt;/a&gt; annotation. @Autowired could be used as well if desired for having a no-args constructor with the Spring Framework reflectively initializing the DAOs.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;@Transactional(readOnly = true)
public class ReservationServiceImpl implements ReservationService {
  private final FlightDao flightDao;
  private final TicketDao ticketDao;

  public ReservationServiceImpl(FlightDao flightDao, TicketDao ticketDao) {...}

  @Override
  @Transactional(rollbackFor = { NoSeatAvailableException.class }, readOnly=false)
  public Ticket bookFlight(Reservation booking) throws  NoSeatAvailableException {
   ...
  }

  @Override
  public List&amp;lt;Ticket&amp;gt; getReservations() {...}
}
&lt;/pre&gt;
&lt;br /&gt;
The Services tier also has a corresponding Config where the Services of the application are defined:
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;@Configuration
public class DefaultServiceConfig implements ServiceConfig {
  @Autowired
  private DaoConfig daoConfig;

  @Bean
  @Override
  public AirlineService getAirlineService() {
    return new AirlineServiceImpl(daoConfig.getFlightDao(), daoConfig.getAirportDao());
  }
  .........other services ...
}
&lt;/pre&gt;
&lt;br /&gt;
One might ask the question as to how can one mock out the &lt;i&gt;DaoConfig &lt;/i&gt;for testing purposes as it is set to be auto-wired, surely not reflection? Well, on the Configs one cannot use constructor based initialization as Spring's container expects a no-arg constructor. One can however define a setter for the Config and be able to mock the same out. The following sample of the &lt;i&gt;ControllerConfig&lt;/i&gt; demonstrates the same:
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;@Configuration
public class ControllerConfig {
  private ServiceConfig serviceConfig;
  
  @Autowired 
  public void setServiceConfig(ServiceConfig serviceConfig) {
    this.serviceConfig = serviceConfig;
  }
 
  @Bean
  public FlightsController getFlightController() {
    return new FlightsController(serviceConfig.getAirlineService(), serviceConfig.getAirportService());
  }
  ... other controllers...
}
&lt;/pre&gt;
The FlightController is shown below:
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;@Controller
public class FlightsController {
  private final AirlineService airlineService;
  private final AirportService airportService;

  public FlightsController(AirlineService airlineService, AirportService airportService) {...}

  // Flight search page initialization
  @RequestMapping(value = "/searchFlights.html", method = RequestMethod.GET)
  public ModelAndView searchFlights() throws Exception {
    List&amp;lt;Airport&amp;gt; airports = airportService.getAirports();

    ModelAndView mav = new ModelAndView("searchFlights");

    mav.addObject("airports", airports);

    return mav;
  }

  // Searching for a flight. Note that the Critiera object is automatically bound with 
  // the corresponding form post parameters
  @RequestMapping(value = "/searchFlights.html", method = RequestMethod.POST)
  public ModelAndView searchFlights(FlightSearchCriteria criteria) throws Exception {

    ModelAndView mav = new ModelAndView("searchFlights");
     ....
    FlightSearchResults searchResult = airlineService.getFlights(criteria);

    mav.addObject("flightSearchResult", searchResult);

    return mav;
  }
}
&lt;/pre&gt;
&lt;br /&gt;
Annotating a bean with&lt;a href="http://static.springsource.org/spring/docs/3.1.x/javadoc-api/index.html?index-filesindex-1.html"&gt; @Controller&lt;/a&gt; indicates to Spring that the same is part of the MVC family and to use the same for mapping request urls and servicing web requests. A few other things to note about the controller:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;1.&lt;/b&gt; Does not need to extend any particular base class&lt;br /&gt;
&lt;b&gt;2.&lt;/b&gt; The &lt;a href="http://static.springsource.org/spring/docs/3.1.x/javadoc-api/index.html?index-filesindex-1.html"&gt;@RequestMapping&lt;/a&gt; annotation defines the HTTP Method and resource serviced. In the example shown, "&lt;i&gt;/searchFlights&lt;/i&gt;" responds differently to GET and POST requests&lt;br /&gt;
 &lt;br /&gt;
All these tier configurations are wired together via &lt;i&gt;WebConfig &lt;/i&gt;which also defines the different components required to setup the Spring MVC Servlet. The &lt;a href="http://static.springsource.org/spring/docs/3.1.x/javadoc-api/org/springframework/context/annotation/Import.html"&gt;@Import &lt;/a&gt;annotation indicates to the Spring Container which Config's need to be included. Note the same can also be done in the web.xml as part of the Servlet definition if so desired.
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;@EnableWebMvc
@Configuration
@Import({ ControllerConfig.class, DefaultServiceConfig.class, DefaultDaoConfig.class })
public class WebConfig extends WebMvcConfigurerAdapter 
// Validator for JSR 303 used across the application
  @Override
  public Validator getValidator() {...}

 // View Resolver..JSP, Freemarker etc
  @Bean
  public ViewResolver getViewResolver() {...}

 // Mapping handler for OXM
  @Bean
  public RequestMappingHandlerAdapter getHandlerAdapter() {.. }
 
 @Override
  public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
    configurer.enable();
  }
}
&lt;/pre&gt;
The annotation&lt;a href="http://static.springsource.org/spring/docs/3.1.x/javadoc-api/"&gt; @EnableWebMvc &lt;/a&gt; is required to tell Spring that this is a MVC application. Implementing the &lt;a href="http://static.springsource.org/spring/docs/3.1.x/javadoc-api/"&gt;WebMvcConfigurerAdapter&lt;/a&gt; allows for customization the Spring Servlet and path handling. Alternatively, one could also extend &lt;a href="http://static.springsource.org/spring/docs/3.1.x/javadoc-api/index.html?index-filesindex-1.html"&gt;WebMvcConfigurationSupport &lt;/a&gt;directly and provide the necessary customization&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Validation of Requests using JSR-303 Bean Validation API:
&lt;/b&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://jcp.org/en/jsr/detail?id=303"&gt;JSR-303&lt;/a&gt; standardizes the validation for the Java Platform. Use it if you wish for validation. The annotations from the API are used to specify validation constraints and the runtime enforces the same. As this example utilizes Hibernate, adding Hibernate-Validator which is an implementation of the API is a natural choice.
In the example provided the Reservation class is annotated with the annotations from the JSR to provide runtime validation and messages. The messages could be obtained from a resource bundle if desired:
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;public class Reservation {
  @XmlElement
  @NotBlank(message = "must not be blank")
  private String reservationName;

  @Min(1)
  @XmlElement
  private int quantity = 1;

  @XmlElement
  @NotNull(message = "Flight Id must be provided")
  private Long flightId;
  ....
}
&lt;/pre&gt;
The web deployment descriptor is where the application converges and&amp;nbsp; the &lt;a href="http://static.springsource.org/spring/docs/3.1.x/javadoc-api/index.html?index-filesindex-1.html"&gt;DispatcherServlet &lt;/a&gt;is notified of the Context class to use and the location of the &lt;i&gt;WebConfig&lt;/i&gt;. As previously mentioned, it is possible to provide a comma separated list of Configs in the web.xml if desired versus importing them in the &lt;i&gt;WebConfig&lt;/i&gt;:
&lt;br /&gt;
&lt;pre class="xml" name="code"&gt;&amp;lt;web-app&amp;gt;
        &amp;lt;servlet&amp;gt;
                &amp;lt;servlet-name&amp;gt;springExample&amp;lt;/servlet-name&amp;gt;
                &amp;lt;servlet-class&amp;gt;org.springframework.web.servlet.DispatcherServlet
                &amp;lt;/servlet-class&amp;gt;
                &amp;lt;init-param&amp;gt;
                        &amp;lt;param-name&amp;gt;contextClass&amp;lt;/param-name&amp;gt;
                        &amp;lt;param-value&amp;gt;org.springframework.web.context.support.AnnotationConfigWebApplicationContext
                        &amp;lt;/param-value&amp;gt;
                &amp;lt;/init-param&amp;gt;
                &amp;lt;!-- Tell Spring where to find the Config Class
                     This is the hook in to the application. --&amp;gt;
                &amp;lt;init-param&amp;gt;
                        &amp;lt;param-name&amp;gt;contextConfigLocation&amp;lt;/param-name&amp;gt;
                        &amp;lt;param-value&amp;gt;com.welflex.web.WebConfig&amp;lt;/param-value&amp;gt;
                &amp;lt;/init-param&amp;gt;
                &amp;lt;load-on-startup&amp;gt;1&amp;lt;/load-on-startup&amp;gt;
        &amp;lt;/servlet&amp;gt;
        ....
&amp;lt;/web-app&amp;gt;
&lt;/pre&gt;
&lt;br /&gt;
&lt;b&gt;Unit Testing:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Unit testing the tiers is very easily supported by the&lt;a href="http://static.springsource.org/spring/docs/current/spring-framework-reference/html/testing.html"&gt; Spring Testing framework&lt;/a&gt;. When testing the service layer for example, one does not really need to integrate with the database and the corresponding interactions can be mocked out. For this reason, the objects in the DAO config are provided&amp;nbsp;as mocks as shown below:
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;@Configuration
@EnableTransactionManagement
public class MockDaoConfig implements DaoConfig {
 
  @Bean
  public FlightDao getFlightDao() {
    return Mockito.mock(FlightDao.class);
  }
  ..// Other mocks
}

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {MockDaoConfig.class,
    DefaultServiceConfig.class }, loader = AnnotationConfigContextLoader.class)
public class AirportServiceTest {
  @Autowired
  private AirportDao airportDaoMock;

  @Autowired
  private ApplicationContext ctx;

  @Test
  public void getAirportCode() {
    // Obtain Airport service from the context
    AirportService a = ctx.getBean(AirportService.class);

    // Alternatively, instatiate an Airport Service by providing a mock
    AirportService a2 = new AirportServiceImpl(airportDaoMock);
  }
  ...
}
&lt;/pre&gt;
In the above test, the Config's being used are the concrete implementation of &lt;i&gt;ServiceConfig &lt;/i&gt;and a mock of &lt;i&gt;DaoConfig&lt;/i&gt;. This enables the testing of the Service tier by mocking the Data access tier. Some people prefer to test each class in isolation&amp;nbsp; by wiring the same up with the required dependencies explicitly while others prefer to obtain the class from the container with all dependencies wired up. The choice of style of testing is a topic for another BLOG but it is sufficient to accept that either style is supported. It is to be noted that one does not need to mock all the beans for testing and can define specific Config objects as required. As with the Service tier mocking out the Data Access tier, the&amp;nbsp; Controller tier can also be tested by mocking out the Service tier objects.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Spring MVC Restful Services:&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&amp;nbsp;&lt;/b&gt; &lt;br /&gt;
One of the goals of this example was to demonstrate how the web application doubles as a service as well. Consider the following controller which provides representations for the web application and a service consumer:
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;@Controller
public class ReservationsController {
  private final AirlineService airlineService;
  private final ReservationService reservationService;

  public ReservationsController(ReservationService reservationService, AirlineService airlineService) {...}

  @RequestMapping("/reservations.html")
  public ModelAndView getReservationsHtml() {...}

  @RequestMapping(value = "/reservations/{reservationId}.html", method = RequestMethod.GET)
  public ModelAndView getReservationHtml(@PathVariable Long reservationId) {...}

  // Web Service Support to provide XML or JSON based of the Accept Header attribute
  @RequestMapping(value = "/reservations", method = RequestMethod.GET, produces = {
      MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE })
  @ResponseBody
  public Reservations getReservations() {...}

  @RequestMapping(value = "/reservations/{reservationId}", method = RequestMethod.GET, produces = {
      MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE })
  @ResponseBody
  public Ticket getReservation(@PathVariable Long reservationId) {...}
  ....
}
&lt;/pre&gt;
In the above shown controller, the &lt;i&gt;getReservationsHtml()&lt;/i&gt; returns a HTML representation of the reservations while the call to&lt;i&gt; getReservations() &lt;/i&gt;returns an XML or JSON representation of the reservations. The type of representation returned depends on the Accept header provided to the service. The @ResponseBody annotation indicates that a view is not targetted but that the resulting object should be translated directly. The example itself uses &lt;a href="http://static.springsource.org/spring-ws/site/reference/html/oxm.html"&gt;Spring OXM&lt;/a&gt; for marshalling and unmarshalling XML via JAXB.

An integration test for the above controller using &lt;a href="http://static.springsource.org/spring/docs/3.1.x/javadoc-api/index.html?index-filesindex-1.html"&gt;RestTemplate &lt;/a&gt;is shown below:
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;public class WebServiceIntegrationTest {
  private RestTemplate template;
  private static final String BASE_URL = "http://localhost:9091";

  @Before
  public void setUp() {
    // Create Rest Template with the different converters
    template = new RestTemplate();
    List&amp;lt;HttpMessageConverter&amp;lt;?&amp;gt;&amp;gt; converters = ...;
    template.setMessageConverters(converters);
  }

  private static final String FLIGHT_NUMBER = "LH 235";

  @Test
  public void reservations() {
    Flight singleFlight = template.getForObject(BASE_URL + "/flights/" + FLIGHT_NUMBER,
      Flight.class);

    Reservation res = new Reservation();
    res.setFlightId(singleFlight.getId());
    res.setQuantity(10);
    res.setReservationName("Sanjay Acharya")

   // Post to create a ticket
    Ticket ticket = template.postForObject(BASE_URL + "/bookFlight", res, Ticket.class);
    assertNotNull(ticket);
    System.out.println("Ticket reserved:" + ticket);

    // All Reservations
    Reservations reservations = template.getForObject(BASE_URL  + "/reservations", Reservations.class);
    assertTrue(reservations.getTickets().size() == 1);

    // Single reservation
    assertNotNull(template.getForObject(BASE_URL + "/reservations/" + ticket.getId(), Ticket.class));
  }
}
&lt;/pre&gt;
&lt;br /&gt;
For more information on the RestTemplate, check out my other BLOG on&lt;a href="http://sleeplessinslc.blogspot.com/2010/02/rest-client-frameworks-your-options.html"&gt; Rest Client Frameworks&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Side Note:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
In this example, I have used a framework called &lt;a href="http://pojomatic.sourceforge.net/"&gt;Pojomatic&lt;/a&gt; for the convenience it provides in implementing &lt;a href="http://pojomatic.sourceforge.net/pojomatic/index.html"&gt;equals(), hashCode() and toString()&lt;/a&gt; for my POJOs. I prefer its brevity over using the the tools provided by the Apache commons project which I have used in my previous BLOGs. Check the same out.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Running the Example:&lt;/b&gt;
&lt;br /&gt;
&lt;br /&gt;
The example provided herewith demonstrates the Flight Spring MVC example. It uses an in memory database which is primed with data on start up. The model package in the example is overloaded as far as its responsibilities go. The POJO's there in serve as database model objects and data transfer objects. The example, unit tests or integration tests are by no means designed to
 be comprehensive and are only present only for demonstration purposes.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;1.&lt;/b&gt;&lt;a href="http://home.comcast.net/%7Eacharya.s/java/springMvcExample.zip"&gt; Download the example from HERE&lt;/a&gt;&lt;br /&gt;
&lt;b&gt;2.&lt;/b&gt; Execute a&lt;b&gt; mvn jetty:run&lt;/b&gt; to start the application.&lt;br /&gt;
&lt;b&gt;3.&lt;/b&gt; Execute a &lt;b&gt;mvn integration:test&lt;/b&gt; to see the Web Service calls being exercised &lt;br /&gt;
&lt;b&gt;4.&lt;/b&gt; The Flight Web Application is available at &lt;a href="http://localhost:8080/"&gt;http://localhost:8080&lt;/a&gt;

&lt;br /&gt;
&lt;b&gt;5.&lt;/b&gt; Web service url's can be accessed directly via:
&amp;nbsp; &lt;a href="http://localhost:8080/reservations"&gt;http://localhost:8080/reservations&lt;/a&gt;

, &lt;a href="http://localhost:8080/reservations/%7Bid"&gt;http://localhost:8080/reservations/{id&lt;/a&gt;}, &lt;a href="http://locahost:8080/flights"&gt;http://locahost:8080/flights&lt;/a&gt;, &lt;a href="http://localhost:8080/airports"&gt;http://localhost:8080/airports&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Conclusion:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
I find the clarity and control of object initialization and wiring really convenient with Spring Java Config. Walking the dependency tree is also very intuitive. In addition, due to the strong typing, refactoring is made easy even without a tool like&lt;a href="http://www.springsource.org/springide/release-20"&gt; Spring IDE&lt;/a&gt;. What I like about Spring MVC versus other web frameworks is its simplicity with the Front Controller/Dispatcher pattern. One can use whatever Ajaxian technology they like to enhance the user experience. The framework itself is very non-invasive, i.e., it does not require the use of Spring across all the tiers. The Restful support facilitates easy interaction with Ajax based technologies and makes the web app a true resource based system. I do not use Spring MVC on any production application sadly. If anyone who does have experience with the same stumbles upon this BLOG, I would love to hear of the same.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4667121987470696359-3799126188617853927?l=sleeplessinslc.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OidcY/~4/Rf8uP51bjFg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sleeplessinslc.blogspot.com/feeds/3799126188617853927/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4667121987470696359&amp;postID=3799126188617853927" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/3799126188617853927?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/3799126188617853927?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OidcY/~3/Rf8uP51bjFg/spring-31-mvc-example.html" title="Spring  3.1  MVC Example" /><author><name>Sanjay Acharya</name><uri>http://www.blogger.com/profile/01933976956977901677</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="28" src="http://3.bp.blogspot.com/-QuUnYIQQ4Ck/Txo3-4hza9I/AAAAAAAABBQ/QMZO-wT7v6A/s220/profile.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-J8d58r3EfW8/Twe--sFJtiI/AAAAAAAABBA/nV8AxpWN3QU/s72-c/dependencies.png" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://sleeplessinslc.blogspot.com/2012/01/spring-31-mvc-example.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEcBRnY4fSp7ImA9WhRWFkg.&quot;"><id>tag:blogger.com,1999:blog-4667121987470696359.post-4598482991230569239</id><published>2012-01-03T22:47:00.001-07:00</published><updated>2012-01-03T22:47:37.835-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-03T22:47:37.835-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Apache ZooKeeper Leader Election" /><category scheme="http://www.blogger.com/atom/ns#" term="Apache ZooKeeper Example" /><category scheme="http://www.blogger.com/atom/ns#" term="ZooKeeper ZKClient example" /><category scheme="http://www.blogger.com/atom/ns#" term="Apache ZooKeeper Barrier" /><title>Apache ZooKeeper - A maven example</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/BWmRuRhh3p5vPFmSIkAmh507Prk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/BWmRuRhh3p5vPFmSIkAmh507Prk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/BWmRuRhh3p5vPFmSIkAmh507Prk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/BWmRuRhh3p5vPFmSIkAmh507Prk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
Let me begin with - &lt;b&gt;Happy New Year&lt;/b&gt;! I am starting this years BLOG entry with some playing I did over the holidays with &lt;a href="http://zookeeper.apache.org/"&gt;Apache ZooKeeper&lt;/a&gt;. So what is Apache ZooKeeper?&amp;nbsp; Broadly put, ZooKeeper provides a service for maintaining distributed naming, configuration and group membership. Zookeeper provides a centralized coordination service which is distributed, consistent and highly available. In particular, it specializes in coordination tasks such as leader election, status propagation and rendezvous. Quoting the ZooKeeper documentation, " &lt;i&gt;The
    motivation behind ZooKeeper is to relieve distributed applications the
    responsibility of implementing coordination services from scratch.&lt;/i&gt;"&lt;br /&gt;
&lt;br /&gt;
Zookeeper facilitates the coordination of distributed systems via a hierarchical name space called &lt;a href="http://zookeeper.apache.org/doc/current/zookeeperOver.html#sc_dataModelNameSpace"&gt;ZNodes&lt;/a&gt;. A ZNode can have children Znodes as well as have data associated with it (figure linked from official ZooKeeper documentation): &lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://zookeeper.apache.org/doc/current/images/zknamespace.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="183" src="http://zookeeper.apache.org/doc/current/images/zknamespace.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
ZooKeeper also has the concept of &lt;i&gt;Nodes &lt;/i&gt;and&lt;i&gt; Ephermeral Nodes&lt;/i&gt;. The former survives the death of the client that created it while the latter does not. Nodes can also be SEQUENTIAL where a SEQUENCE number is associated with Node. Sequences clearly lend themselves for queue type or ordered behavior when required. ZNodes cannot be deleted as long as they have children under it. &lt;br /&gt;
&lt;br /&gt;
The &lt;a href="http://zookeeper.apache.org/doc/current/zookeeperOver.html#Simple+API"&gt;Zookeeper API &lt;/a&gt;itself it a very simple programming interface that contains methods for CRUD of a ZNode and data along with a way to listen for changes to the node and/or its data.&lt;br /&gt;
&lt;br /&gt;
One can read quite a bit about Zookeeper from their documentation and I will not delve into details. My goal in this BLOG is to provide some simple examples of how Zookeeper can be used for:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;1.&lt;/b&gt; Leader Election&lt;br /&gt;
&lt;b&gt;2.&lt;/b&gt; Rendezvous or Barrier&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;1. Leader Election Example:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
As mentioned previously, Zoo Keeper specializes in&amp;nbsp; &lt;a href="http://en.wikipedia.org/wiki/Leader_election"&gt;Leader Election&lt;/a&gt;, where a particular server of a type is elected the leader and upon its demise, another stands up to take its place. The concept of Ephemeral nodes is pretty useful in such a scenario where a service upon start up registers itself as a candidate in the pool of resources to be used. For the sake of discussion, consider an Echo Service with the fictional constraint that there can be only one Echo Service at any given time servicing requests but should that robust service die, another one is ready to resume the responsibility of servicing clients. The EchoService on start up registers an ephemeral node at "&lt;i&gt;&lt;b&gt;/echo/n_000000000X&lt;/b&gt;&lt;/i&gt;". It further registers a watcher on its predecessor Echo Service, denoted by the ZNode,&amp;nbsp;  "&lt;i&gt;&lt;b&gt;/echo/n_000000000X&lt;/b&gt;&lt;/i&gt;-1", with the intent that should the predecessor die, then the node in question can assume leadership if it is the logical successor as shown in the picture below:&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-_nXQXLv8kPg/TwO60Y-bdzI/AAAAAAAABA4/PVu6KHRBggc/s1600/leader.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="302" src="http://2.bp.blogspot.com/-_nXQXLv8kPg/TwO60Y-bdzI/AAAAAAAABA4/PVu6KHRBggc/s640/leader.png" width="640" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Leader Election of Echo Server&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The reason for registering a watch on the predecessor versus the root of "&lt;b&gt;/&lt;i&gt;echo&lt;/i&gt;&lt;/b&gt;" is to prevent &lt;a href="http://zookeeper.apache.org/doc/current/recipes.html"&gt;herding as described in the Zookeeper recipes&lt;/a&gt;. In other words in the event of&amp;nbsp; a leader being decommisioned, we wouldn't want all the Echo Server leadership contenders to stress the system by requesting ZooKepper for the children of the "&lt;i&gt;/echo&lt;/i&gt;" node to determine the next leader. With the chosen strategy, if the predecessor dies, then only its follower is the one that executes the call to get the children of "&lt;i&gt;/echo&lt;/i&gt;". The example provided herewith spawns two Echo Servers and has a client that calls the server. One of the two servers is considered the leader and assumes the responsibility of servicing the requests of the client. If the leader dies, then the successor Echo Server assumes leadership and starts servicing client requests. The client will connect to the next leader automatically upon the death of the current leader. The Echo Server code is shown below: 
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;public class EchoServer extends Thread implements IZkDataListener, IZkStateListener {
  private ZkClient zkClient;
  // My ZNode
  private SequentialZkNode zkNode;

  // My leader ZNode
  private SequentialZkNode zkLeaderNode;
  private ServerSocket serverSocket;
  
  // Port to start server on
  private final Integer port;
  private final List&amp;lt;SlaveJob&amp;gt; slaves;
  private final Object mutex = new Object();
  private final AtomicBoolean start = new AtomicBoolean(false);
  private final Random random = new Random();

  public EchoServer(int port, int zkPort) {
    this.port = port;
    this.zkClient = new ZkClient("localhost:" + zkPort);
    this.slaves = new ArrayList&amp;lt;SlaveJob&amp;gt;();
  }

  @Override
  public void run() {
    try {
      // Sleep for some randomness leader selection
      Thread.sleep(random.nextInt(1000));

      // Create Ephermal node
      zkNode = ZkUtils.createEphermalNode("/echo", port, zkClient);

      // Find all children
      NavigableSet&amp;lt;SequentialZkNode&amp;gt; nodes = ZkUtils.getNodes("/echo", zkClient);

      // Find my leader
      zkLeaderNode = ZkUtils.findLeaderOfNode(nodes, zkNode);

      // If I am leader, enable me to start
      if (zkLeaderNode.getPath().equals(zkNode.getPath())) {
        start.set(true);
      } else {
        // Set a watch on next leader path
        zkClient.subscribeDataChanges(zkLeaderNode.getPath(), this);
        zkClient.subscribeStateChanges(this);
      }

      synchronized (mutex) {
        while (!start.get()) {
          LOG.info("Server on Port:" + port + " waiting to spawn socket....");
          mutex.wait();
        }
      }
      // Start accepting connections and servicing requests 
      this.serverSocket = new ServerSocket(port);

      Socket clientSocket = null;
      
      while (!Thread.currentThread().isInterrupted() &amp;amp;&amp;amp; !shutdown) {
        clientSocket = serverSocket.accept();
        // ... start slave job
      }
    }
    catch (Exception e) {
     ....
    }
  }

  private void electNewLeader() {
    final NavigableSet&amp;lt;SequentialZkNode&amp;gt; nodes = ZkUtils.getNodes("/echo", zkClient);

    if (!zkClient.exists(zkLeaderNode.getPath())) {
      // My Leader does not exist, find the next leader above
      zkLeaderNode = ZkUtils.findLeaderOfNode(nodes, zkNode);
      zkClient.subscribeDataChanges(zkLeaderNode.getPath(), this);
      zkClient.subscribeStateChanges(this);
    }

    // If I am the leader then start
    if (zkNode.getSequence().equals(nodes.first().getSequence())) {
      LOG.info("Server on port:" + port + "  will now be notified to assume leadership");
      synchronized (mutex) {
        start.set(true);
        mutex.notify();
      }
    }
  }
  .....

  @Override
  public void handleDataDeleted(String dataPath) throws Exception {
    if (dataPath.equals(zkLeaderNode.getPath())) {
      // Leader gone away
      LOG.info("Recieved a notification that Leader on path:" + dataPath
        + " has gone away..electing new leader");
      electNewLeader();
    }
  }
}
&lt;/pre&gt;
&lt;br /&gt;
The Echo Client is shown below which connects to the leader of the Echo Server ensemble:
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;public class EchoClient implements IZkDataListener, IZkStateListener, IZkChildListener {
  private Connection connection;
  private Object mutex = new Object();
  private final ZkClient zkClient;
  private SequentialZkNode connectedToNode;

  public EchoClient(int zkPort) {
    this.zkClient = new ZkClient("localhost:" + zkPort);
  }

  private Connection getConnection() throws UnknownHostException, IOException, InterruptedException {
    synchronized (mutex) {
      if (connection != null) {
        return connection;
      }

      NavigableSet&amp;lt;SequentialZkNode&amp;gt; nodes = null;
      
      // Check to see if there an Echo server exists, if not listen on /echo for 
      // a Server to become available 
      while ((nodes = ZkUtils.getNodes("/echo", zkClient)).size() == 0) {
        LOG.info("No echo service nodes ...waiting...");
        zkClient.subscribeChildChanges("/echo", this);
        mutex.wait();
      }

      // Get the leader and connect
      connectedToNode = nodes.first();
      Integer port = zkClient.readData(connectedToNode.getPath());
      connection = new Connection(new Socket("localhost", port));
      
      // Subscribe to Server changes
      zkClient.subscribeDataChanges(connectedToNode.getPath(), this);
      zkClient.subscribeStateChanges(this);
    }

    return connection;
  }

  public String echo(String command) throws InterruptedException {
    while (true) {
      try {
        return getConnection().send(command);
      }
      catch (InterruptedException e) {
        throw e;
      }
      catch (Exception e) {
        synchronized (mutex) {
          if (connection != null) {
            connection.close();
            connection = null;
          }
        }
      }
    }
  }

  private static class Connection { 
    // Code that connects and sends data to Echo Server
    public String send(String message) {
      ....
    }
  }

  @Override
  public void handleDataDeleted(String dataPath) throws Exception {
    synchronized (mutex) {
      if (dataPath.equals(connectedToNode.getPath())) {
        LOG.info("Client Received notification that Server has died..notifying to re-connect");
        if (connection != null) {
          connection.close();
        }
        if (connectedToNode != null) {
          connectedToNode = null;
        }
      }
      mutex.notify();
    }
  }

  @Override
  public void handleChildChange(String parentPath, List&amp;lt;String&amp;gt; currentChilds) throws Exception {
    synchronized (mutex) {
      LOG.info("Got a notification about a Service coming up...notifying client");
      mutex.notify();
    }
  }
}
&lt;/pre&gt;
&lt;br /&gt;
A simple test of the example starts an EchoClient and two servers. One of the servers assumes leadership and starts servicing request while the other server sits waiting to assume leadership. The client in turn sends messages which is serviced by the leader. When the leader terminates, messages are then serviced by the successor that assumes leadership.
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;  @Test
  public void simpleLeadership() throws InterruptedException {

    EchoClient client = new EchoClient(ZK_PORT);
    EchoServer serverA = new EchoServer(5555, ZK_PORT);
    EchoServer serverB = new EchoServer(5556, ZK_PORT);

    serverA.start();
    serverB.start();
 
    // Send messages
    for (int i = 0; i &amp;lt; 10; i++) {
      System.out.println("Client Sending:Hello-" + i);
      System.out.println(client.echo("Hello-" + i));
    }
    
    if (serverA.isLeader()) {
      serverA.shutdown();
    } else {
      serverB.shutdown();
    }
 
    for (int i = 0; i &amp;lt; 10; i++) {
      System.out.println("Client Sending:Hello-" + i);
      System.out.println(client.echo("Hello-" + i));
    }

    serverA.shutdown();
    serverB.shutdown();
  }
&lt;/pre&gt;
On running the test, you can see output similar to:
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;20:18:49 INFO - com.welflex.zookeeper.EchoClient.getConnection(44) | No echo service nodes ...waiting...
20:18:49 INFO - com.welflex.zookeeper.EchoClient.handleChildChange(171) | Got a notification about a Service coming up...notifying client
20:18:49 INFO - com.welflex.zookeeper.EchoServer.run(85) | Server on Port:5556 is now the Leader. Starting to accept connections...
Client Sending:Hello-0
Echo:Hello-0
Client Sending:Hello-1
Echo:Hello-1
.....
20:18:49 INFO - com.welflex.zookeeper.EchoServer.run(122) | Server on Port:5556 has been shutdown
20:18:49 INFO - com.welflex.zookeeper.EchoClient.getConnection(44) | No echo service nodes ...waiting...
Server has died..notifying to re-connect
20:18:49 INFO - com.welflex.zookeeper.EchoClient.getConnection(44) | No echo service nodes ...waiting...
20:18:49 INFO - com.welflex.zookeeper.EchoClient.handleChildChange(171) | Got a notification about a Service coming up...notifying client
20:18:49 INFO - com.welflex.zookeeper.EchoServer.run(85) | Server on Port:5555 is now the Leader. Starting to accept connections...
20:18:49 INFO - com.welflex.zookeeper.EchoClient.handleChildChange(171) | Got a notification about a Service coming up...notifying client
....
Echo:Hello-7
Client Sending:Hello-8
Echo:Hello-8
Client Sending:Hello-9
Echo:Hello-9
....
&lt;/pre&gt;
&lt;br /&gt;
&lt;b&gt;2. Rendezvous/Barrier Example:&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Distributed systems can use the concept of a&lt;a href="http://zookeeper.apache.org/doc/current/zookeeperTutorial.html#sc_barriers"&gt; barrier &lt;/a&gt;to block the processing of a certain task until other members of the system ensemble are available after which all the systems participating can proceed with their tasks. Having a little fun here :-) with a fictional case where &lt;a href="http://en.wikipedia.org/wiki/00_Agent"&gt;Double O agents&lt;/a&gt; of &lt;a href="http://en.wikipedia.org/wiki/Secret_Intelligence_Service"&gt;MI-6&lt;/a&gt; meet to present their reports, and reports are not edited here if you know what I mean ;-). Agents join the meeting but cannot start presenting until all the expected agents join the meeting after which they are free to present in parallel (agents are designed to grasp from multiple presenters; after all the 007 variety are trained at such things). Agents can present but cannot leave the briefing until all presenters have completed their presentation. The agent upon start up creates a ZNode under the meeting identifier, say, "&lt;i&gt;&lt;b&gt;/M-debrief&lt;/b&gt;&lt;/i&gt;", and then waits for all other agents to join before beginning their presentation, i.e.,&lt;i&gt;&lt;b&gt; barrier entry&lt;/b&gt;&lt;/i&gt;. After each presentation, the agent removes themselves from the list of ZNodes and then waits for other agents to do the same before leaving the briefing, i.e., &lt;i&gt;&lt;b&gt;barrier exit&lt;/b&gt;&lt;/i&gt;. With that said, the Agent code looks like:
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;public class Agent extends Thread implements IZkChildListener {
  // Number of agents total
  private final int agentCount;

  private final String agentNumber;

  private final Object mutex = new Object();

  private final Random random = new Random();

  private SequentialZkNode agentRegistration;
  
  private final String meetingId;

  public Agent(String agentNumber, String meetingId, int agentCount, int zkPort) {
    this.agentNumber = agentNumber;
    this.meetingId = meetingId;
    this.agentCount = agentCount;
    this.zkClient = new ZkClient("localhost:" + zkPort);
    zkClient.subscribeChildChanges(meetingId, this);
  }

  private void joinBriefing() throws InterruptedException {
    Thread.sleep(random.nextInt(1000));
    agentRegistration = ZkUtils.createEpheremalNode(meetingId, agentNumber, zkClient);
    LOG.info("Agent:" + agentNumber + " joined Briefing:" + meetingId);
    
    // Wait for all other agents to join the meeting
    while (true) {
      synchronized (mutex) {
        List&amp;lt;String&amp;gt; list = zkClient.getChildren(meetingId);

        if (list.size() &amp;lt; agentCount) {
          LOG.info("Agent:" + agentNumber + " waiting for other agents to join before presenting report...");
          mutex.wait();
        }
        else {
          break;
        }
      }
    }
  }

  private void presentReport() throws InterruptedException {
    LOG.info("Agent:" + agentNumber + " presenting report...");
    Thread.sleep(random.nextInt(1000));
    LOG.info("Agent:" + agentNumber + " completed report...");

    // Completion of a report is identified by deleting their ZNode
    zkClient.delete(agentRegistration.getPath());
  }

  private void leaveBriefing() throws InterruptedException {

    // Wait for all agents to complete
    while (true) {
      synchronized (mutex) {
        List&amp;lt;String&amp;gt; list = zkClient.getChildren(meetingId);
        if (list.size() &amp;gt; 0) {
          LOG.info("Agent:" + agentNumber
            + " waiting for other agents to complete their briefings...");
          mutex.wait();
        }
        else {
          break;
        }
      }
    }
    LOG.info("Agent:" + agentNumber + " left briefing");
  }

  @Override
  public void run() {
    joinBriefing();
    presentReport();
    leaveBriefing();
  }

  @Override
  public void handleChildChange(String parentPath, List&amp;lt;String&amp;gt; currentChilds) throws Exception {
    synchronized (mutex) {
      mutex.notifyAll();
    }
  }
}
&lt;/pre&gt;
Running the test, one would see something like the following where agents join the meeting, wait for the others before presenting, present at the meeting and then leave after everyone completes. Note that output is edited in the interest of real estate:
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;21:02:17 INFO - com.welflex.zookeeper.Agent.joinBriefing(38) | Agent:003 joined Briefing:/M-debrief
21:02:17 INFO - com.welflex.zookeeper.Agent.joinBriefing(45) | Agent:003 waiting for other agents to join before presenting report...
21:02:17 INFO - com.welflex.zookeeper.Agent.joinBriefing(38) | Agent:005 joined Briefing:/M-debrief
21:02:17 INFO - com.welflex.zookeeper.Agent.joinBriefing(45) | Agent:005 waiting for other agents to join before 
.....
:17 INFO - com.welflex.zookeeper.Agent.joinBriefing(45) | Agent:005 waiting for other agents to join before presenting report...
......
21:02:17 INFO - com.welflex.zookeeper.Agent.joinBriefing(45) | Agent:006 waiting for other agents to join before presenting report...
21:02:18 INFO - com.welflex.zookeeper.Agent.joinBriefing(38) | Agent:007 joined Briefing:/M-debrief
21:02:18 INFO - com.welflex.zookeeper.Agent.joinBriefing(45) | Agent:007 waiting for other agents to join before presenting report...
21:02:18 INFO - com.welflex.zookeeper.Agent.presentReport(57) | Agent:002 presenting report...
21:02:18 INFO - com.welflex.zookeeper.Agent.presentReport(57) | Agent:005 presenting report...
21:02:18 INFO - com.welflex.zookeeper.Agent.presentReport(57) | Agent:007 presenting report...
21:02:18 INFO - com.welflex.zookeeper.Agent.presentReport(57) | Agent:003 presenting report...
21:02:18 INFO - com.welflex.zookeeper.Agent.presentReport(57) | Agent:001 presenting report...
....
21:02:18 INFO - com.welflex.zookeeper.Agent.leaveBriefing(69) | Agent:002 waiting for other agents to complete their briefings...
21:02:18 INFO - com.welflex.zookeeper.Agent.leaveBriefing(69) | Agent:002 waiting for other agents to complete their briefings...
21:02:18 INFO - com.welflex.zookeeper.Agent.presentReport(59) | Agent:000 completed report...
21:02:18 INFO - com.welflex.zookeeper.Agent.leaveBriefing(69) | Agent:000 waiting for other agents to complete their briefings...
21:02:18 INFO - com.welflex.zookeeper.Agent.leaveBriefing(69) | Agent:002 waiting for other agents to complete their briefings...
21:02:18 INFO - com.welflex.zookeeper.Agent.leaveBriefing(69) | Agent:000 waiting for other agents to complete their briefings...
21:02:18 INFO - com.welflex.zookeeper.Agent.presentReport(59) | Agent:007 completed report...
21:02:18 INFO - com.welflex.zookeeper.Agent.leaveBriefing(69) | Agent:007 waiting for other agents to complete their briefings...
....
21:02:19 INFO - com.welflex.zookeeper.Agent.leaveBriefing(78) | Agent:007 left briefing
21:02:19 INFO - com.welflex.zookeeper.Agent.leaveBriefing(78) | Agent:003 left briefing
21:02:19 INFO - com.welflex.zookeeper.Agent.leaveBriefing(78) | Agent:002 left briefing
...
21:02:19 INFO - com.welflex.zookeeper.Agent.leaveBriefing(78) | Agent:000 left briefing
&lt;/pre&gt;
&lt;br /&gt;
&lt;b&gt;Running the code:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://home.comcast.net/%7Eacharya.s/java/zkexample.zip"&gt;Download a maven example of the above code from HERE&lt;/a&gt;. Execute a "&lt;b&gt;mvn test&lt;/b&gt;" to see the example in action or import into eclipse to dissect the code. The example itself runs its tests on a single ZooKeeper server. There is no reason why the same cannot be expanded to try on a larger ZooKeeper ensemble.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Conclusion and Credits:
&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The examples shown are highly influenced by the &lt;a href="http://zookeeper.apache.org/doc/current/zookeeperTutorial.html"&gt;examples provided at the ZooKeeper&lt;/a&gt; site. The code does not use the ZooKeeper code directly but instead uses a wrapper around the same, i.e., &lt;a href="https://github.com/sgroschupf/zkclient"&gt;ZkClient&lt;/a&gt;, which provides a much easier experience to using ZooKeeper than the default ZooKeeper API. The examples also rely heavily on the &lt;a href="http://techblog.outbrain.com/2011/07/leader-election-with-zookeeper/"&gt;excellent article and supporting code by Erez Mazor&lt;/a&gt; who utilizes Spring Framework very nicely to demonstrate Leader Election and control of the same. I simply loved his code and images and have used parts of the same in the above demonstration. I am sure I have only touched the surface of&amp;nbsp; ZooKeeper and am hoping I can learn more about the same. If my understanding about any of the concepts mentioned above is flawed, I would love to hear about the same. Again, a very Happy 2012! Keep the faith, the world won't end on December 21'st.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4667121987470696359-4598482991230569239?l=sleeplessinslc.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OidcY/~4/PRUMnX6qZno" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sleeplessinslc.blogspot.com/feeds/4598482991230569239/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4667121987470696359&amp;postID=4598482991230569239" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/4598482991230569239?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/4598482991230569239?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OidcY/~3/PRUMnX6qZno/apache-zookeeper-maven-example.html" title="Apache ZooKeeper - A maven example" /><author><name>Sanjay Acharya</name><uri>http://www.blogger.com/profile/01933976956977901677</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="28" src="http://3.bp.blogspot.com/-QuUnYIQQ4Ck/Txo3-4hza9I/AAAAAAAABBQ/QMZO-wT7v6A/s220/profile.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-_nXQXLv8kPg/TwO60Y-bdzI/AAAAAAAABA4/PVu6KHRBggc/s72-c/leader.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://sleeplessinslc.blogspot.com/2012/01/apache-zookeeper-maven-example.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkACQH8yeip7ImA9WhRWEU4.&quot;"><id>tag:blogger.com,1999:blog-4667121987470696359.post-4279448869194961557</id><published>2011-12-28T20:52:00.000-07:00</published><updated>2011-12-28T20:52:41.192-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-28T20:52:41.192-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JMS Topic Scaling" /><category scheme="http://www.blogger.com/atom/ns#" term="JMS Patterns" /><category scheme="http://www.blogger.com/atom/ns#" term="Weblogic Shared Subscription" /><category scheme="http://www.blogger.com/atom/ns#" term="Spring JMS" /><category scheme="http://www.blogger.com/atom/ns#" term="WebLogic Partitioned Distributed Topic" /><category scheme="http://www.blogger.com/atom/ns#" term="JMS Shared subscriptions" /><title>WebLogic JMS Partitioned Distributed Topics and Shared Subscriptions</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/uykLRyLD80vZ3GVO9w3aR5cCmOE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/uykLRyLD80vZ3GVO9w3aR5cCmOE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/uykLRyLD80vZ3GVO9w3aR5cCmOE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/uykLRyLD80vZ3GVO9w3aR5cCmOE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
I had previously blogged about the challenges of &lt;a href="http://sleeplessinslc.blogspot.com/2009/06/scaling-in-jms-worldin-particular.html"&gt;scaling topics with durable subscribers&lt;/a&gt;. In JMS, with topics, one can typically have a single topic subscriber for a particular [&lt;b&gt;Client ID, Subscription Name&lt;/b&gt;] tuple.&lt;br /&gt;
&lt;br /&gt;
In the example shown below the Order Topic has two durable subscribers, the &lt;b&gt;Order Processor&lt;/b&gt; and the &lt;b&gt;Auditor&lt;/b&gt;. Both of these get the message sent to the topic but at any give time, there can be exactly one of each consuming the message. There cannot be completing durable subscriptions as in the case of queues. The same translates to a scalability and availability challenge:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-PI8d4nMfLhA/TuugCepEb6I/AAAAAAAABAY/Vq8osvmLayo/s1600/simpleTopic.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="299" src="http://1.bp.blogspot.com/-PI8d4nMfLhA/TuugCepEb6I/AAAAAAAABAY/Vq8osvmLayo/s640/simpleTopic.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;a href="http://www.oracle.com/us/products/middleware/application-server/index.html"&gt;Oracle WebLogic&lt;/a&gt; has introduced the concept of a&lt;a href="http://docs.oracle.com/cd/E21764_01/web.1111/e13727/dds.htm"&gt; Partitioned distributed topic&lt;/a&gt; and shared connection subscriptions that will allow for more than one durable to subscription to be made available for a particular subscriber. In the figure shown below, with a shared subscription, one can have consumers of an "&lt;b&gt;application&lt;/b&gt;" compete for messages of a Topic and this feature promotes scalability and availability. In the figure shown below there are two Order Processors which are competing for messages and so are the two Auditors. At no given time will a message be delivered to both the consumers of the same "application":&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-YTuCeA7_sFY/TuuglmOvPFI/AAAAAAAABAg/Drz2Hx42Tkw/s1600/pdistTopicSimple.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="307" src="http://3.bp.blogspot.com/-YTuCeA7_sFY/TuuglmOvPFI/AAAAAAAABAg/Drz2Hx42Tkw/s640/pdistTopicSimple.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
WebLogic introduces the concept of a &lt;b&gt;UNRESTRICTED &lt;/b&gt;Client ID policy. With this setting on a topic, more than one connection in a cluster can share the same Client ID. The standard option of &lt;b&gt;RESTRICTED &lt;/b&gt;enforces that only a single connection with a particular Client ID can exist in a cluster.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Sharing Subscriptions:&lt;/b&gt;&lt;br /&gt;
There are two policies for Subscription sharing:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;1. Exclusive&lt;/b&gt; - This is the default and all subscribers created using the connection factory cannot share subscriptions with any other subscribers.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;2. Sharable&lt;/b&gt; - Subscribers created using this connection factory can share their subscriptions with other subscribers. Consumers can share a durable subscription if they have the same [&lt;b&gt;Client ID, Client ID policy and subscription name&lt;/b&gt;].&lt;br /&gt;
&lt;br /&gt;
To promote HA, set the Subscription on the Topic as Shareable.&lt;br /&gt;
&lt;br /&gt;
When creating a Topic in Weblogic set the Forwarding Policy to be Partitioned. This causes a message sent to a partitioned distributed topic to be sent to a single physical member. In addition, the message will not be forwarded to other members of the cluster if there are no consumers in the current physical member.&lt;br /&gt;
&lt;br /&gt;
If we want a HA solution, then the listeners will need to connect to 
each and every physical member across the cluster. Consider the 
following figure, on Consumer Machine 1, there are two consumers of Type A
 and two Consumers of Type B, the same applies to the Consumer Machine 
2. It is important to note that consumers of a type or application&amp;nbsp;connect to both the 
physical members of the cluster. Doing so ensures that in the event a consumer machine 
dies unexpectedly, the other consumer machine can still continue to 
function ensuring availability:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-31-Qt_SnilY/TuuhuEUV1wI/AAAAAAAABAo/kYGl95V0RZI/s1600/pdisttopic.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="336" src="http://2.bp.blogspot.com/-31-Qt_SnilY/TuuhuEUV1wI/AAAAAAAABAo/kYGl95V0RZI/s400/pdisttopic.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
The above can be achieved using &lt;a href="http://static.springsource.org/spring/docs/2.5.x/reference/jms.html"&gt;Spring Framework's Message Listener Container&lt;/a&gt; with some wrapper code as shown below where the PartitionedTopicContainer is a container of containers connecting to each physical member of the topic with the same client ID and subscription name:&lt;br /&gt;
&lt;pre class="java" name="code"&gt;public class PartitionedTopicContainer {
  private final List&amp;lt;DefaultMessageListenerContainer&amp;gt; containers;

  public PartitionedTopicContainer(String clientID, String subscriptionName, ConnectionFactory connectionFactory, Destination ...physicalTopicMembers) {
    this.containers = Lists.newArrayList();

    for (Destination physicalMember : physicalTopicMembers) {
      DefaultMessageListenerContainer container = new DefaultMessageListenerContainer();

      container.setConnectionFactory(connectionFactory);
      container.setDestination(physicalMember);
      container.setClientId(clientID);
      container.setDurableSubscriptionName(subscriptionName);
    }
  }

  public void setMessageListener(Object listener) {
    for (DefaultMessageListenerContainer container : containers) {
      container.setMessageListener(listener);
    }
  }

  public void start() {
    for (DefaultMessageListenerContainer container : containers) {
      container.start();
    }
  }

  public void shutdown() {
    for (DefaultMessageListenerContainer container : containers) {
      container.shutdown();
    }
  }
}
&lt;/pre&gt;
The above container could then be used as follows:

&lt;br /&gt;
&lt;pre class="java" name="code"&gt;
// Obtain each physical member of the partitioned distributed topic
Destination physicalMember1 = (Destination) context.lookup("Server1@orderTopic");
Destination physicalMember2 = (Destination) context.lookup("Server2@orderTopic");

// Container for the Order Processor
PartitionedTopicContainer subscriber1 = new PartitionedTopicContainer("orderConnectionId", "orderProcSubscription", connectionFactory, physicalMember1, physicalMember2);
subscriber1.setMessageListener(new SessionAwareMessageListener&amp;lt;TextMessage&amp;gt;() {
  public void onMessage(...) {
    System.out.println(Thread.currentThread().getId() + " of subscriber order processor got a message...");
    ...
  }
});
// Container for the Auditor
PartitionedTopicContainer subscriber2 = new PartitionedTopicContainer("auditorConnectionId", "auditorSubscription", connectionFactory, physicalMember1, physicalMember2);
subscriber2.setMessageListener(new SessionAwareMessageListener&amp;lt;TextMessage&amp;gt;() {
  public void onMessage(...) {
    System.out.println(Thread.currentThread().getId() + " of subscriber auditor got a message...");
    ...
  }
});

subscriber1.start();
subscriber2.start();
&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
The parts of the code above where a consumer of the API has to look up each and every physical member and provide the same to &amp;nbsp;the container is a lot of boiler plate and does not account well for cases when a physical member becomes available/unavailable. Luckily, WebLogic provides the &lt;a href="http://docs.oracle.com/cd/E17904_01/web.1111/e13727/dahelper.htm#CHDJFAEJ"&gt;JmsDestinationAvailabilityHelper &lt;/a&gt;API which is a way to listen to events relating to physical &amp;nbsp;member availability and unavailability. The &lt;i&gt;PartitionedTopicContainer &lt;/i&gt;shown above could easily be augmented with the availability helper API&amp;nbsp;and get notified of physical destination availability and unavailability to correspondingly start and stop the internal container to the physical destination. Psuedo-code of how this can be achieved with the above container is shown below:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;public class PartitionedTopicContainer implements DestinationAvailabilityListener {
  private final String partDistTopicJndi;

  private final ConnectionFactory connectionFactory;
   
  @GuardedBy("containerLock")
  private final Map&amp;lt;String, DefaultMessageListenerContainer&amp;gt; containerMap;

  private final Object containerLock = new Object();

  // WebLogic Handle
  private RegistrationHandle registrationHandle;

  private final CountdownLatch startLatch = new CountdownLatch(1);

  public PartitionedTopicContainer(String clientID, String subscriptionName, String clusterUrl,
    ConnectionFactory connectionFactory, String partDistTopicJndi) {
    this.clusterUrl = clusterUrl;
    this.clientID = clientID;
    this.subscriptionName = subscriptionName;
    this.partDistTopicJndi = partDistTopicJndi;
    this.containerMap = Maps.newHashMap();
    this.connectionFactory = connectionFactory;
  }

  public void start() throws InterruptedException {
    Hashtable&amp;lt;String, String&amp;gt; jndiProperties = ...;
    jndiProperties.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
    jndiProperties.put(Context.PROVIDER_URL, clusterUrl);
    
    JMSDestinationAvailabilityHelper dah = JMSDestinationAvailabilityHelper.getInstance();
   
    // Register this container as a listener for destination events
    registrationHandle = dah.register(jndiProperties, partDistTopicJndi, this);
   
    // Wait for listener notification to start container
    startLatch.await();
  }

  @Override
  public void onDestinationsAvailable(String destJNDIName, List&amp;lt;DestinationDetail&amp;gt; physicalAvailableMembers) {
    synchronized (containerLock) {
      // For all Physical destinations, start a container
      for (DestinationDetail detail : physicalAvailableMembers) {
        Destination physicalMember = lookupPhysicalTopic(detail.getJNDIName());
        DefaultMessageListener container = new DefaultMessageListenerContainer();
        
        container.setConnectionFactory(connectionFactory);
        container.setDestination(physicalMember);
        container.setClientId(clientID);
        container.setDurableSubscriptionName(subscriptionName);
        System.out.println("Starting Container for physical Destination:" + detail);
        container.start();
        containerMap.put(detail.getJNDIName(), container);
      }
    }
    startLatch.countdown();       
  }
  
  @Override
  public void onDestinationsUnavailable(String destJNDIName, List&amp;lt;DestinationDetail&amp;gt; physicalUnavailableMembers) {
    synchronized (containerLock) {
      // Shutdown all containers whose physical members are no longer available
      for (DestinationDetail detail : physicalUnavailableMembers) {
        DefaultMessageListenerContainer container = containerMap.remove(detail.getJNDIName());
        container.shutdown();
      }
    }
  }

  @Override
  public void onFailure(String destJndiName, Exception exception) {
    // Looks like a cluster wide failure
    shutdown();
  }

  public void shutdown() {
    // Unregister for events about destination availability
    registrationHandler.unregister();

    // Shut down containers
    synchronized (containerLock) {
       for (Iterator&amp;lt;Map.Entry&amp;lt;String, DefaultMessageListenerContainer&amp;gt;&amp;gt; i = containerMap.entrySet().iterator(); i
          .hasNext();) {
        Map.Entry&amp;lt;String, DefaultMessageListenerContainer&amp;gt; entry = i.next();
        System.out.println("Shutting down container for:" + entry.getKey());
        entry.getValue().shutdown();
        i.remove();
      }
    }  
  }
}   
&lt;/pre&gt;
&lt;br /&gt;
Some of the things to remember when creating a partitioned distributed topic and shared subscription:
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;1.&lt;/b&gt; Connection Factory being used should have "Subscription Sharing Policy" set as "Shareable"
&lt;br /&gt;
&lt;b&gt;2.&lt;/b&gt; Forwarding policy on the Partitioned Distributed Topic should be set as "Partitioned"
&lt;br /&gt;
&lt;b&gt;3.&lt;/b&gt; Message forwarding will not occur, so subscribers must ensure connections exist to every physical member else messages can pile up for the subscription on that topic&lt;br /&gt;
&lt;b&gt;4.&lt;/b&gt; If a server hosting a physical member is unavailable then messages from that physical topic will be unavailable until server is made available.&lt;br /&gt;
&lt;br /&gt;
Partitioned Distributed Topics and Shared Subscriptions looks promising. One thing I need to sort out is how does one handle error destinations on a per subscription level with WebLogic. Any passer by with thoughts, please do shoot it my way.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4667121987470696359-4279448869194961557?l=sleeplessinslc.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OidcY/~4/GV3NFCoYuGs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sleeplessinslc.blogspot.com/feeds/4279448869194961557/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4667121987470696359&amp;postID=4279448869194961557" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/4279448869194961557?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/4279448869194961557?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OidcY/~3/GV3NFCoYuGs/weblogic-jms-partitioned-distributed.html" title="WebLogic JMS Partitioned Distributed Topics and Shared Subscriptions" /><author><name>Sanjay Acharya</name><uri>http://www.blogger.com/profile/01933976956977901677</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="28" src="http://3.bp.blogspot.com/-QuUnYIQQ4Ck/Txo3-4hza9I/AAAAAAAABBQ/QMZO-wT7v6A/s220/profile.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-PI8d4nMfLhA/TuugCepEb6I/AAAAAAAABAY/Vq8osvmLayo/s72-c/simpleTopic.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://sleeplessinslc.blogspot.com/2011/12/weblogic-jms-partitioned-distributed.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUcERXk9fyp7ImA9WhdbGU0.&quot;"><id>tag:blogger.com,1999:blog-4667121987470696359.post-1364116051636090516</id><published>2011-10-17T21:03:00.000-06:00</published><updated>2011-10-17T21:03:24.767-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-17T21:03:24.767-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Apache Wicket" /><category scheme="http://www.blogger.com/atom/ns#" term="Hive JSON" /><category scheme="http://www.blogger.com/atom/ns#" term="HWI" /><category scheme="http://www.blogger.com/atom/ns#" term="Hive Web Interface" /><category scheme="http://www.blogger.com/atom/ns#" term="Apache Hive Example" /><title>Apache Hive Example - Hive JSON, Hive Web Interface</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/DfAvRfAFM0ORu_xX46B6SoT2zWQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/DfAvRfAFM0ORu_xX46B6SoT2zWQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/DfAvRfAFM0ORu_xX46B6SoT2zWQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/DfAvRfAFM0ORu_xX46B6SoT2zWQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
In a previous post, I had talked a bit about using&lt;a href="http://sleeplessinslc.blogspot.com/2011/02/hadoop-pig-and-java-map-reduce-maven.html"&gt; Pig with Hadoop&lt;/a&gt;. Of recent I have been playing with&lt;a href="http://hive.apache.org/"&gt; Apache Hive&lt;/a&gt; and as always thought I'd share :-). In particular this BLOG demonstrates using JSON data with Hive and also the Hive Web Interface. I wanted to have some fun playing with some technologies like &lt;a href="http://wicket.apache.org/"&gt;Apache Wicket&lt;/a&gt; and&lt;a href="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-java"&gt; Spring Java Config&lt;/a&gt; so I created my own version of Hive Web Interface which I am sharing as well.
&lt;br /&gt;
&lt;br /&gt;
Hive is a data warehouse that allows one to issue ad hoc queries to access data in HDFS via a language that is very similar to SQL. Hive's version of SQL is called HiveQL and does not support the full SQL-92 specification. Apparently Hive was created by Facebook to allow business analysts with strong SQL skills and 'little' java skills to analyze the large volumes of data collected. Hive is not a OLTP processing system by any means and querying of data can take some time to complete, depending on the size of data and complexity of the query. Hive takes the SQL queries submitted and converts the same into a series of MapReduce jobs to run on a Hadoop Cluster.
&lt;br /&gt;
&lt;br /&gt;
My steps for getting Hive going on a single node -
&lt;br /&gt;
&lt;br/&gt;
&lt;b&gt;&amp;nbsp;1. Install Hadoop:
&lt;/b&gt;&lt;br /&gt;
Instructions for installation of Hadoop is quite well detailed on&lt;a href="http://famousphil.com/blog/2011/05/installing-hadoop-0-20-2-in-ubuntu-11-04-x86-with-eclipse/"&gt; FamousPhil's blog&lt;/a&gt;. Note that you want to substitute the version of the Hadoop Tarball with the &lt;a href="https://ccp.cloudera.com/display/SUPPORT/Downloads"&gt;one from Cloudera&lt;/a&gt;. I prefer to use Cloudera's distribution as the different Hadoop artifacts are readily made available via their maven repositories and I needed them for my example. I installed Hadoop at /opt/hadoop/hadoop-0.20.2-cdh3u1
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;2. Install Hive:
&lt;/b&gt;&lt;br /&gt;
Obtain Cloudera's &lt;a href="http://archive.cloudera.com/cdh/3/hive-0.7.1-cdh3u1.tar.gz"&gt;version of Hive&lt;/a&gt; and install the same. Instructions on the same is available on the &lt;a href="https://ccp.cloudera.com/display/CDHDOC/Hive+Installation"&gt;Cloudera Installation Page&lt;/a&gt;. I installed Hive at /opt/hive/hive-0.7.1-cdh3u1
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;3. Install MySQL and Configure metastore
&lt;/b&gt;&lt;br /&gt;
Hive stores metadata in a standard relational database. Hive out of the box runs on Derby. This is fine for a single user setup but in a multi-user environment one would like to share metadata and for this reason, a centralized database like MySQL is recommended. Detailed instructions on configuring MySQL as the metastore are available on the&lt;a href="https://ccp.cloudera.com/display/CDHDOC/Hive+Installation"&gt; Cloudera MySQL installation page&lt;/a&gt;. Make sure that you copy the mysql driver to $HIVE_HOME/lib folder.

At this point, you should be able to connect to hive. The following shows a command to list all tables:
&lt;br /&gt;
&lt;pre class="sql" name="code"&gt;
&amp;gt;SHOW TABLES;
OK
Time taken:1.2 seconds
&lt;/pre&gt;

&lt;b&gt;4. Creating and Loading a Table:&lt;/b&gt;
&lt;br/&gt;
Leaning on my previous simple example with Pig, a "&lt;i&gt;comments&lt;/i&gt;" file is available in the attached example (at the bottom). Load the file provided into HDFS via:
&lt;br /&gt;
&lt;pre class="sql" name="code"&gt;  
&amp;gt;hadoop fs -put /tmp/comments /user/hadoop/comments
&lt;/pre&gt;

Note that we are assuming that the comments file is available at /tmp.
&lt;br/&gt;
&lt;br/&gt;
In Hive one finds the concept of a &lt;i&gt;Managed Table&lt;/i&gt; and an&lt;i&gt; External Table&lt;/i&gt;. When one creates a Managed table, Hive will manage the data moving forward. In other words, Hive will move the data from a source location in HDFS into Hive's warehouse. In the case of an External table, one tells Hive to refer to data in a particular HDFS location and Hive will not copy the data into its warehouse.

For the comment data,we will use a managed table and create the same using:
&lt;br /&gt;
&lt;pre class="sql" name="code"&gt;
hive&amp;gt;CREATE TABLE comment_data(comment_val STRING);
hive&amp;gt; SHOW TABLES;
OK
comment_data
Time taken: 2.42 seconds
hive&amp;gt; DESCRIBE comment_data;
OK
comment_val string 
&lt;/pre&gt;
The JSON data from the file is loaded into a single COLUMN of the comment_data table.
&lt;br/&gt;
&lt;pre class="sql" name="code"&gt;
hive&amp;gt;LOAD DATA INPATH '/user/hadoop/comments' OVERWRITE INTO TABLE comment_data;
hive&amp;gt;SELECT * from comment_data LIMIT 5; 
OK
{"commenterId":"nemesis","commentData":"Java is dead, long live Java","country":"TANZANIA"}
{"commenterId":"rambo","commentData":"Felix Lighter and James Bond work well together as they are cave men","country":"SPAIN"}
{"commenterId":"donaldduck","commentData":"Fred Flintstone is in his cave","country":"INDIA"}
{"commenterId":"donaldduck","commentData":"The world is a cave. James bond lives in a Cave.","country":"TANZANIA"}
{"commenterId":"jamesbond","commentData":"The world is a cave. James bond lives in a Cave.","country":"BHUTAN"}
Time taken: 0.117 seconds
&lt;/pre&gt;

&lt;b&gt;5. Querying Hive&lt;/b&gt;
&lt;br/&gt;
Once data is loaded into the table, one can query the same using HiveQL. Hive's &lt;i&gt;get_json_object&lt;/i&gt; function is to extract JSON data as shown below:
&lt;br /&gt;
&lt;pre class="sql" name="code"&gt;
// Select commenter Identifier and comment
hive&amp;gt;select get_json_object(comment_data.comment_val, '$.commenterId'), get_json_object(comment_data.comment_val, '$.commentData') from comment_data;
Total MapReduce jobs = 1
...
Ended Job = job_201110171315_0001
OK
nemesis Java is dead, long live Java
rambo Felix Lighter and James Bond work well together as they are cave men
donaldduck Fred Flintstone is in his cave
donaldduck The world is a cave. James bond lives in a Cave.
jamesbond The world is a cave. James bond lives in a Cave.
....

// Select all comments which contain the string '%cave%' and group them
hive&amp;gt; SELECT  b.commentData,COUNT(b.commentData) 
            FROM comment_data a LATERAL VIEW json_tuple(a.comment_val, 'commentData') b 
           AS commentData where b.commentData LIKE '%cave%' GROUP BY b.commentData;               
Total MapReduce jobs = 1
Launching Job 1 out of 1
....
Starting Job = job_201110171733_0015, Tracking URL = http://localhost:50030/jobdetails.jsp?jobid=job_201110171733_0015
Kill Command = /opt/hadoop/hadoop-0.20.2-cdh3u1/bin/hadoop job  -Dmapred.job.tracker=localhost:9001 -kill job_201110171733_0015
2011-10-17 19:57:59,797 Stage-1 map = 0%,  reduce = 0%
2011-10-17 19:58:01,807 Stage-1 map = 100%,  reduce = 0%
2011-10-17 19:58:09,855 Stage-1 map = 100%,  reduce = 100%
Ended Job = job_201110171733_0015
OK
Felix Lighter and James Bond work well together as they are cave men 927
Fred Flintstone is in his cave 935
Only a cave man could do this 907
The world is a cave. James bond lives in a Cave. 881
Time taken: 13.715 seconds
&lt;/pre&gt;

Another option when working with JSON Data is to use the&lt;a href="http://code.google.com/p/hive-json-serde/"&gt; hive-json-serde&lt;/a&gt;. With hive-json-serde one can load the JSON data into individual columns. In order to use the UDF's in hive-json-serde, the jar needs to be registered with Hive. A comment table can then be created using the following. Note that the following is an example of an EXTERNAL Table and while creating the same, we are specifying the directory that contains the comments file:
&lt;pre name="code" class="sql"&gt;
hive&amp;gt;ADD JAR /opt/hive-0.7.1-cdh3u1/lib/hive-json-serde-0.2.jar;
hive&amp;gt;CREATE EXTERNAL TABLE comment_data_split(commenterId STRING, commentData STRING, country STRING) ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.JsonSerde' LOCATION '/user/hadoop/';    
&lt;/pre&gt;

An example query of the data:
&lt;pre name="code" class="sql"&gt;
hive&amp;gt; select a.commenterId, a.commentData, count(a.commentData) from comment_data_split a where a.commentData like '%cave%' group by a.commenterId, a.commentData;
....
Ended Job = job_201110171315_0011
OK
donaldduck Felix Lighter and James Bond work well together as they are cave men 69
donaldduck Fred Flintstone is in his cave 83
donaldduck Only a cave man could do this 65
donaldduck The world is a cave. James bond lives in a Cave. 68
factorypilot Felix Lighter and James Bond work well together as they are cave men 67
factorypilot Fred Flintstone is in his cave 77
factorypilot Only a cave man could do this 81
...
&lt;/pre&gt;

Clearly the above examples are trivial queries.
&lt;/div&gt;
&lt;b&gt;6. Hive Web Interface (HWI):&lt;/b&gt;
&lt;br/&gt;
Hive comes with a web interface for those unable to get to a command line or do not wish to install Hive on their work stations. HWI allows a user to work with Hive just as they would using the console client. One can create Hive Sessions and execute HiveSQL with them. The Hive web interface is started using:

&lt;pre name="code" class="java"&gt;
&amp;gt;hive --service hwi
&lt;/pre&gt;
Executing the same starts a jetty container and one can access the hive web application at &lt;a href="http://localhost:9999/hwi"&gt;http://localhost:9999/hwi&lt;/a&gt;. 
&lt;br/&gt;

&lt;b&gt;7. HWI Amped&lt;/b&gt;
&lt;br/&gt;
One of the things I wanted to play with is to create a little more friendly web user interface to Hive than what HWI provides. So I proceeded to have some fun and do the same :-). In addition, I wanted to play with Wicket  and Spring as well to get a feel for the framework. Killing quite a few birds with one stone here. The web application itself is largely based on the hwi source code with a few tweaks. HWI Amped uses the &lt;b&gt;Thrift&lt;/b&gt; client to establish a connection to the Hive thrift service and allows a user to:
&lt;ul&gt;
   &lt;li&gt;Browse Schemas and Tables&lt;/li&gt;
   &lt;li&gt;Create Sessions and Manage Sessions&lt;/li&gt;
   &lt;li&gt;Execute HiveQL queries either in streaming where results are displayed in the browser or background mode where results are piped to a file.&lt;/li&gt;
&lt;/ul&gt;
One feature it does not support is canceling a query that is running. Maybe it should be called HWI Amped -1.
&lt;br/&gt;
&lt;br/&gt;
Running the web application:
&lt;br/&gt;

The Hwi Amped web application expects a Hive Server running at port 10001. It communicates with the Hive Server using Thrift. Start the server using:
&lt;pre name="code" class="java"&gt;
&amp;gt;hive --service hiveserver 10001
&lt;/pre&gt;

The Hwi Amped web application itself is a maven project, so from the command line execute the following to start it:
&lt;pre name="code" class="java"&gt;
&amp;gt;mvn jetty:run
&lt;/pre&gt;
The Web application can be accessed from &lt;a href="http://localhost:9090"&gt;http://localhost:9090&lt;/a&gt;. You will be required to sign in. Currently there is no authentication hook-in built but one can provide the user "hadoop" and any dummy password to access the application. 
&lt;br/&gt;
Some screen shots are shown below:
&lt;table border="1"&gt;
&lt;tr&gt;
 &lt;td&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-q_Drmn9vTiw/TpzRw4Gp6HI/AAAAAAAAA-8/CDtBIsWre4w/s1600/queryPage.png" imageanchor="1" style=""&gt;&lt;img border="0" height="135" width="320" src="http://3.bp.blogspot.com/-q_Drmn9vTiw/TpzRw4Gp6HI/AAAAAAAAA-8/CDtBIsWre4w/s320/queryPage.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/td&gt;
  &lt;td&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-ezEvmOIN3XU/TpzQEChSMrI/AAAAAAAAA-o/WbwjCTuyBPY/s1600/queryResult.png" imageanchor="1" style=""&gt;&lt;img border="0" height="138" width="320" src="http://1.bp.blogspot.com/-ezEvmOIN3XU/TpzQEChSMrI/AAAAAAAAA-o/WbwjCTuyBPY/s320/queryResult.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
 &lt;td&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-15xw4GwcbZU/TpzR5rE5B6I/AAAAAAAAA_I/4GGkL6lTkes/s1600/schemabrowse.png" imageanchor="1" style=""&gt;&lt;img border="0" height="61" width="320" src="http://2.bp.blogspot.com/-15xw4GwcbZU/TpzR5rE5B6I/AAAAAAAAA_I/4GGkL6lTkes/s320/schemabrowse.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/td&gt;
  &lt;td&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-uCmYFvAyQIg/TpzR-nHX6tI/AAAAAAAAA_U/773iI0gf8dI/s1600/tableDetail.png" imageanchor="1" style=""&gt;&lt;img border="0" height="181" width="320" src="http://4.bp.blogspot.com/-uCmYFvAyQIg/TpzR-nHX6tI/AAAAAAAAA_U/773iI0gf8dI/s320/tableDetail.png" /&gt;&lt;/a&gt;&lt;/div&gt;
 &lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
 &lt;td&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://1.bp.blogspot.com/-0BZY2qV0OFY/TpzSFE_63KI/AAAAAAAAA_c/yK7PSe2Fqy8/s1600/SessionList.png" imageanchor="1" style=""&gt;&lt;img border="0" height="54" width="320" src="http://1.bp.blogspot.com/-0BZY2qV0OFY/TpzSFE_63KI/AAAAAAAAA_c/yK7PSe2Fqy8/s320/SessionList.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/td&gt;
  &lt;td&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-0kEP2qPHhqA/TpzSKM_R-uI/AAAAAAAAA_o/2Vqy604i1DU/s1600/sessionManage.png" imageanchor="1" style=""&gt;&lt;img border="0" height="63" width="320" src="http://4.bp.blogspot.com/-0kEP2qPHhqA/TpzSKM_R-uI/AAAAAAAAA_o/2Vqy604i1DU/s320/sessionManage.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;br/&gt;
The application is a learning experience and is devoid of unit-tests. The URL for the Hive server and metastore are also hard coded and not externalized.
&lt;br/&gt;
&lt;br/&gt;
Wicket? I found programming Wicket very much like programming Swing and would definitely consider it for other applications. A book in hand would have helped me move faster through my code. I did not struggle too much in creating the application, but then the struggle is usually not for the creator but the user of the application heh? One thing I fear is I have not understood the Wicket life cycle yet and worry if Page objects created might linger for longer than expected. Wicket integration with Spring was a breeze and I used Spring Java Config to inject a Session Service into the different Wicket Pages. My hope with Java Config was to be able to get rid of applicationContext.xml totally but found that I needed it to bootstrap Wicket. Spring Java Config is definitely the way forward IMHO. 

&lt;br/&gt;
&lt;br/&gt;
On Hive, well my initial perspective (far from an expert by any means) was it feels very familiar due to it being SQLish and that the learning curve to using Hive is lesser that Pig for a person who is familiar with SQL. In addition, I think that for ad hoc querying, Hive is definitely the way to go with Pig being reserved for programmers and for periodic jobs.  That said, Phase 2 of Hwi Amped might be to add Pig support, wot?

&lt;br/&gt;
&lt;br/&gt;
Overall, quite some fun for a weekend hackathon..
&lt;br/&gt;
&lt;br/&gt;
&lt;a href="http://home.comcast.net/~acharya.s/java/hwiamped.zip"&gt;&lt;b&gt;Download HWI Amped from HERE&lt;/b&gt;&lt;/a&gt;. In the top level directory the&lt;i&gt; comments&lt;/i&gt; file is available. Any feedback on the UI is welcomed and if I have got some Hive concept wrong, please do let me know. Good luck and happy Hives..I mean Hive ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4667121987470696359-1364116051636090516?l=sleeplessinslc.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OidcY/~4/XXSN9eK0ztU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sleeplessinslc.blogspot.com/feeds/1364116051636090516/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4667121987470696359&amp;postID=1364116051636090516" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/1364116051636090516?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/1364116051636090516?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OidcY/~3/XXSN9eK0ztU/apache-hive-example-hive-json-hive-web.html" title="Apache Hive Example - Hive JSON, Hive Web Interface" /><author><name>Sanjay Acharya</name><uri>http://www.blogger.com/profile/01933976956977901677</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="28" src="http://3.bp.blogspot.com/-QuUnYIQQ4Ck/Txo3-4hza9I/AAAAAAAABBQ/QMZO-wT7v6A/s220/profile.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-q_Drmn9vTiw/TpzRw4Gp6HI/AAAAAAAAA-8/CDtBIsWre4w/s72-c/queryPage.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://sleeplessinslc.blogspot.com/2011/10/apache-hive-example-hive-json-hive-web.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0QCSX44fCp7ImA9WhdUF0U.&quot;"><id>tag:blogger.com,1999:blog-4667121987470696359.post-157697269870402109</id><published>2011-10-04T20:02:00.000-06:00</published><updated>2011-10-04T20:22:48.034-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-04T20:22:48.034-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Jersey JAXB Schema" /><category scheme="http://www.blogger.com/atom/ns#" term="jersey jax-rs" /><category scheme="http://www.blogger.com/atom/ns#" term="Jersey Guice" /><category scheme="http://www.blogger.com/atom/ns#" term="Jersey JAX-RS Schema Validation" /><category scheme="http://www.blogger.com/atom/ns#" term="JAX-RS Sub-resources" /><title>Jersey JAX-RS and JAXB Schema Validation</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/m5gegf2dCs1w8n_8K0nbI6ReXAk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/m5gegf2dCs1w8n_8K0nbI6ReXAk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/m5gegf2dCs1w8n_8K0nbI6ReXAk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/m5gegf2dCs1w8n_8K0nbI6ReXAk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
This BLOG is about &lt;a href="http://jersey.java.net/nonav/documentation/latest/user-guide.html"&gt;Jersey&lt;/a&gt; web services and Schema based validation with the same.  I have also been playing with &lt;a href="http://code.google.com/p/google-guice/"&gt;Google Guice&lt;/a&gt; (I hear it, Spring Traitor, err not quite) :-) and figured I'd use Guice instead of Spring for once. 
&lt;br /&gt;
&lt;br /&gt;
When un-marshalling XML using JAXB, schema based validation facilitates stricter validation. The&lt;a href="http://jersey.java.net/nonav/documentation/latest/user-guide.html#d4e873"&gt; Jersey recommended approach&lt;/a&gt; to enable Schema based validation is to create a &lt;i&gt; javax.ws.rs.ext.ContextResolver&lt;/i&gt;. I have seen examples of using a &lt;i&gt;javax.ws.rs.ext.MessageBodyReader&lt;/i&gt; as well. The code demonstrated is largely based and influenced by the &lt;a href="http://jersey.java.net/nonav/documentation/latest/user-guide.html#d4e873"&gt;discussion on XSD validation between Andrew Cole and Paul Sandoz&lt;/a&gt;.

The goals of the resolver are:
&lt;br /&gt;
&lt;ol style="text-align: left;"&gt;
&lt;li&gt;Enable schema based validation if desired&lt;/li&gt;
&lt;li&gt;Provide the ability to enable a custom validation event handler&lt;/li&gt;
&lt;li&gt;Enable formatted JAXB and the ability to set the character encoding&lt;/li&gt;
&lt;/ol&gt;
It is said that JAXB contexts are better of cached as they are expensive to create. I am only going by what I have read in different posts and/or discussions and do not have any metrics to claim the same.

A generic JAXB Context resolver is shown here that accomplishes the above:
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;public class JaxbContextResolver implements ContextResolver&amp;amp;&amp;lt;JAXBContext&amp;gt; {
  static final ConcurrentMap&amp;lt;String, JAXBContext&amp;gt; CONTEXT_MAP = new MapMaker()
      .makeComputingMap(new Function&amp;lt;String, JAXBContext&amp;gt;() {

        @Override
        public JAXBContext apply(String fromPackage) {
          try {
            return JAXBContext.newInstance(fromPackage);
          }
          catch (JAXBException e) {
            throw new RuntimeException("Unable to create JAXBContext for Package:" + fromPackage, e);
          }
        }
      });
  
  private Schema schema;
  private ValidationEventHandler validationEventHandler;
  
  public JaxbContextResolver withSchema(Schema schema) {
    this.schema = schema;
    return this;
  }
  ...
  public JaxbContextResolver withValidationEventHandler(ValidationEventHandler validationEventHandler) {
    this.validationEventHandler = validationEventHandler;
    return this;
  }
  
  @Override
  public JAXBContext getContext(Class&amp;lt;?&amp;gt; type) {
    return new ValidatingJAXBContext(CONTEXT_MAP.get(type.getPackage().getName()),
      schema, formattedOutput, encoding, validationEventHandler);
  }
   ...
  public static class ValidatingJAXBContext extends JAXBContext {
    private final JAXBContext contextDelegate;
     ....
    private final ValidationEventHandler validationEventHandler;

    @Override
    public javax.xml.bind.Unmarshaller createUnmarshaller() throws JAXBException {
      javax.xml.bind.Unmarshaller unmarshaller = contextDelegate.createUnmarshaller();
      
      // Set the Validation Handler
      if (validationEventHandler != null) {
        unmarshaller.setEventHandler(validationEventHandler);
      }
      
      // Set the Schema
      if (validatingSchema != null) {
        unmarshaller.setSchema(validatingSchema);
      }

      return unmarshaller;
    }

    @Override
    public javax.xml.bind.Marshaller createMarshaller() throws JAXBException {
      javax.xml.bind.Marshaller m = contextDelegate.createMarshaller();
      m.setProperty("jaxb.formatted.output", formattedOutput);

      if (encoding != null) {
        m.setProperty("jaxb.encoding", encoding);
      }

      return m;
    }

    @Override
    public Validator createValidator() throws JAXBException {
      return contextDelegate.createValidator();
    }
   }
 }
&lt;/pre&gt;
The Context resolver itself is registered as a Singleton with Jersey in an Application class. For example:

&lt;br /&gt;
&lt;pre class="java" name="code"&gt;public class NotesApplication extends Application {
  private Set&amp;lt;Object&amp;gt; singletons;
  
  public NotesApplication() {
   ....
    Schema schema = null;
   
    try {
      schema = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI).newSchema(
        getClass().getResource("/notes.xsd"));
    }
    catch (SAXException e) {
      throw new RuntimeException("Error obtaining Schema", e);
    }

    JaxbContextResolver resolver = new JaxbContextResolver().withSchema(schema)
      .formatOutput(true);
  
    Set&amp;lt;Object&amp;gt; single = Sets.newHashSet();
    single.add(resolver);
    singletons = Collections.unmodifiableSet(single);
  }
  
  public Set&amp;amp;lt;Object&amp;gt; getSingletons() {
    return singletons;
  }
}
&lt;/pre&gt;
With the above, Unmarshaller's are provided that utilize the provided schema when unmarshalling received payload. When an error occurs during Unmarshalling, Jersey catches the &lt;i&gt;javax.xml.bind.UnmarshallException&lt;/i&gt;, wraps it in a &lt;i&gt;javax.ws.rs.WebApplicationException&lt;/i&gt; and throws the same.  If one desires to customize the response sent back to the consumer the only option is to create an &lt;i&gt;javax.ws.rs.ext.ExceptionMapper&lt;/i&gt; for &lt;i&gt;javax.ws.rs.WebApplicationException&lt;/i&gt; and interrogate the cause to determine if it were a &lt;i&gt;javax.xml.bind.UnmarshallException&lt;/i&gt;. I could not find a way to map the &lt;i&gt;Unmarshall&lt;/i&gt; exception thrown by JAXB directly to an &lt;i&gt;ExceptionMapper&lt;/i&gt;. If anyone has done so, I would love to hear about their solution.

&lt;br /&gt;
&lt;pre class="java" name="code"&gt;
class WebApplicationExceptionMapper imlements ExceptionMapper&amp;lt;WebApplicationException&amp;gt; {
   public Response toResponse(WebApplicationException e) {
      if (e.getCause() instanceof UnmarshallException) {
         return Response.status(404).entity("Tsk Tsk, XML is horrid and you provide the worst possible one?").build();
      }
      else {
         return Response.....
      }
  }
}
&lt;/pre&gt;
Sometimes, one does not need the full fledged validation benefits of a schema and can make do with a &lt;i&gt;ValidationEventHandler&lt;/i&gt;. In such a case, one can provide the JaxbContextResolver with an instance of a &lt;i&gt;javax.xml.bind.ValidationEventHandler&lt;/i&gt;. The handler could then be configured to throw a custom exception which can be mapped to a custom response using an &lt;i&gt;ExceptionMapper&lt;/i&gt; as shown below. This approach is what appears on the &lt;a href="http://jersey.java.net/nonav/documentation/latest/user-guide.html#d4e873"&gt;Jersey mailing list entry&lt;/a&gt;:

&lt;br /&gt;
&lt;pre class="java" name="code"&gt;
JaxbContextResolver resolver = new JaxbContextResolver().withValidationEventHandler(new ValidationEventHandler() {
     public boolean handleEvent(ValidationEvent event) {
       if (event.getSeverity() == ValidationEvent.WARNING) {
          // Log and return
          return true;
      }
      throw new CustomRuntimeException(event);
   });

@Provider
class CustomRuntimeExceptionMapper implements ExceptionMapper&amp;lt;CustomRuntimeException&amp;gt; {
   public Response toResponse(CustomRuntimeException e) {
      return Response.status(400).entity("Oooops:" + e).build();
   }
}
&lt;/pre&gt;
Note that throwing a custom Exception and catching the same via an &lt;i&gt;ExceptionMapper&lt;/i&gt; will work only if one does NOT provide a Schema. Once a schema is in place, the exception will be caught by JAXB and swallowed and one has to catch &lt;i&gt;WebApplicationException&lt;/i&gt; and provide a custom response as described earlier.
&lt;br /&gt;
&lt;br /&gt;
An example provided herewith demonstrates a simple Notes service that manages the life cycle of a Note. It employs Guice to inject dependencies into Resource and Sub-Resource classes. The application also demonstrates the JaxbContextResolver and the registration of a schema for validating a received Note payload. Quite sweet actually. The details of integrating Guice and Jersey is not being detailed in this BLOG as there is already a pretty thorough &lt;a href="http://blog.iparissa.com/google%E2%80%99s-app-engine-java/jersey-guice-on-google-app-engine-java/"&gt;BLOG by Iqbal Yusuf &lt;/a&gt; that describes the same. 
&lt;br /&gt;
&lt;br /&gt;&lt;a href="http://home.comcast.net/~acharya.s/java/Notes.zip"&gt;
Download the maven example by clicking HERE&lt;/a&gt;, extract the archive and simply execute &lt;i&gt;"mvn install"&lt;/i&gt; at the root level to see it a client-server interaction. If any passer by is a JAXB Guru or has any tips on the Resolver, I would love to hear. Enjoy!&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4667121987470696359-157697269870402109?l=sleeplessinslc.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OidcY/~4/RcC5-2D4Lig" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sleeplessinslc.blogspot.com/feeds/157697269870402109/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4667121987470696359&amp;postID=157697269870402109" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/157697269870402109?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/157697269870402109?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OidcY/~3/RcC5-2D4Lig/jersey-jax-rs-and-jaxb-schema.html" title="Jersey JAX-RS and JAXB Schema Validation" /><author><name>Sanjay Acharya</name><uri>http://www.blogger.com/profile/01933976956977901677</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="28" src="http://3.bp.blogspot.com/-QuUnYIQQ4Ck/Txo3-4hza9I/AAAAAAAABBQ/QMZO-wT7v6A/s220/profile.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://sleeplessinslc.blogspot.com/2011/10/jersey-jax-rs-and-jaxb-schema.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcGR3c_eyp7ImA9WhdWFko.&quot;"><id>tag:blogger.com,1999:blog-4667121987470696359.post-7727034598635166532</id><published>2011-09-09T19:19:00.001-06:00</published><updated>2011-09-10T10:43:46.943-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-10T10:43:46.943-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JAX-WS Enunciate" /><category scheme="http://www.blogger.com/atom/ns#" term="Web Service documentation" /><category scheme="http://www.blogger.com/atom/ns#" term="Jersey enunciate" /><category scheme="http://www.blogger.com/atom/ns#" term="Enunciate jax-rs" /><title>Documenting Web Services with Enunciate</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/A6qD-vFpMN5QvVkzzGa9CsJNlnA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/A6qD-vFpMN5QvVkzzGa9CsJNlnA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/A6qD-vFpMN5QvVkzzGa9CsJNlnA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/A6qD-vFpMN5QvVkzzGa9CsJNlnA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;br /&gt;
Understanding the workings of a Web Service from the perspective of a consumer, be it REST or SOAP based is not the easiest. Wading through a &lt;a href="http://en.wikipedia.org/wiki/Web_Application_Description_Language"&gt;WADL&lt;/a&gt; or a &lt;a href="http://en.wikipedia.org/wiki/WSDL"&gt;WSDL&lt;/a&gt; is not a fun task, at least not for me. &amp;nbsp;Been looking into an open source project that has been around for some time called &lt;a href="http://enunciate.codehaus.org/"&gt;Enunciate&lt;/a&gt; and am pretty impressed by its capabilities.&lt;br /&gt;
&lt;br /&gt;
Enunciate provides automated documentation of your resources and end points. It also has the ability to generate client artifacts for consuming the JAX-RS services in many different programming languages.&lt;br /&gt;
&lt;br /&gt;
The process is itself quite simple. After creating your web service you have enunciate run as part of your build process and it generates nice HTML based documentation of your service along with client code (Yeah!) in different languages to consume the service. Using annotation based web services facilitates this nice magic I guess.&lt;br /&gt;
&lt;br /&gt;
To experience enunciate for myself, I created a simple web service that exposes SOAP and REST based calls of the same underlying API.&lt;br /&gt;
&lt;br /&gt;
A few simple criteria that I had for my sample application:&lt;br /&gt;
&lt;div style="text-align: left;"&gt;
&lt;/div&gt;
&lt;ul style="text-align: left;"&gt;
&lt;li&gt;Documentation should be available at the Root context&lt;/li&gt;
&lt;li&gt;Resources and Services must also be available at the Root context&lt;/li&gt;
&lt;/ul&gt;
To my pom, I added the necessary enunciate dependencies as shown below:&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/div&gt;
&lt;pre class="xml" name="code"&gt;&amp;lt;dependencies&amp;gt;
  .... 
   &amp;lt;dependency&amp;gt;
        &amp;lt;groupId&amp;gt;org.codehaus.enunciate&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;enunciate-rt&amp;lt;/artifactId&amp;gt;
	&amp;lt;version&amp;gt;1.24&amp;lt;/version&amp;gt;
   &amp;lt;/dependency&amp;gt;
 &amp;lt;/dependencies&amp;gt;

&amp;lt;build&amp;gt;
  &amp;lt;plugins&amp;gt;
    ...
    &amp;lt;plugin&amp;gt;
          &amp;lt;groupId&amp;gt;org.codehaus.enunciate&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;maven-enunciate-plugin&amp;lt;/artifactId&amp;gt;
        &amp;lt;version&amp;gt;1.24&amp;lt;/version&amp;gt;
        &amp;lt;configuration&amp;gt;
          &amp;lt;configFile&amp;gt;enunciate.xml&amp;lt;/configFile&amp;gt;
        &amp;lt;/configuration&amp;gt;
        &amp;lt;executions&amp;gt;
           &amp;lt;execution&amp;gt;
              &amp;lt;goals&amp;gt;
                 &amp;lt;goal&amp;gt;assemble&amp;lt;/goal&amp;gt;
              &amp;lt;/goals&amp;gt;
          &amp;lt;/execution&amp;gt;
        &amp;lt;/execution&amp;gt;
    &amp;lt;/plugin&amp;gt;
 &amp;lt;/plugins&amp;gt;
&lt;/pre&gt;
To customize where my service's resources will be available, i.e., at the ROOT context I created an enunciate.xml file:
&lt;br /&gt;
&lt;pre class="xml" name="code"&gt;&amp;lt;enunciate xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:noNamespaceSchemaLocation="http://enunciate.codehaus.org/schemas/enunciate-1.21.xsd"&amp;gt;
  
	&amp;lt;services&amp;gt;
		&amp;lt;&amp;lt;est defaultRestSubcontext="/"/&amp;gt;
		&amp;lt;soap defaultSoapSubcontext="/"/&amp;gt;
	&amp;lt;/services&amp;gt;

	&amp;lt;modules&amp;gt;
		&amp;lt;spring-app disabled="true" /&amp;gt;
		&amp;lt;docs docsDir="/" splashPackage="com.welflex.rest" title="Greetings Web Service API"
			copyright="Welflex"/&amp;gt;
	&amp;lt;/modules&amp;gt;
&amp;lt;/enunciate&amp;gt;
&lt;/pre&gt;
After building and running the web service, a nicely generated introduction page that looks like:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-DkkrVOOL_Tc/Tml3pemaw9I/AAAAAAAAA-E/-elgqRBXH_k/s1600/welcomepage.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/-DkkrVOOL_Tc/Tml3pemaw9I/AAAAAAAAA-E/-elgqRBXH_k/s320/welcomepage.png" style="cursor: move;" width="304" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Navigating the application, one can view the Greeting Resource and Greeting Web Service end point documentation:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://2.bp.blogspot.com/-j_N9IfPr_KY/Tml4B31Cv1I/AAAAAAAAA-M/n2p_OtB0CV0/s1600/greetingResource.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-j_N9IfPr_KY/Tml4B31Cv1I/AAAAAAAAA-M/n2p_OtB0CV0/s320/greetingResource.png" width="313" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;a href="http://1.bp.blogspot.com/-EoSkw3M7jFc/Tml4MxwXVdI/AAAAAAAAA-U/pa3NMlX-maU/s1600/greetingsoap.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/-EoSkw3M7jFc/Tml4MxwXVdI/AAAAAAAAA-U/pa3NMlX-maU/s320/greetingsoap.png" width="302" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Generated libraries for consuming the service are available for download as well along with documentation on how to use them, pretty sweet huh?
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/--AvDLlHHsnA/TmmALOsuUSI/AAAAAAAAA-Y/kFNTvfERsvU/s1600/generatedlibraries.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/--AvDLlHHsnA/TmmALOsuUSI/AAAAAAAAA-Y/kFNTvfERsvU/s320/generatedlibraries.png" width="318" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;a href="http://home.comcast.net/%7Eacharya.s/java/GreetingWebService.zip"&gt;A maven example demonstrating the above is available for DOWNLOAD HERE&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Once you download the example, execute:&lt;br /&gt;
&lt;pre name="code"&gt;&amp;gt;mvn install
&amp;gt;mvn jetty:run-exploded
&lt;/pre&gt;
&lt;br /&gt;
Access the service at&lt;a href="http://localhost:8080/"&gt; http://localhost:8080&lt;/a&gt;
&lt;br /&gt;
&lt;br /&gt;
Note that executing &lt;i&gt;mvn jetty:run&lt;/i&gt; would give me a 404's. My only option was the &amp;nbsp;run-exploded. Enuciate creates an altered &lt;i&gt;web.xml&lt;/i&gt; with its own custom classes. I am also curious to know whether using enunciate impacts the performance of the web service, and if so, by how much. Enunciate also facilitates skinning the documentation, I have not done the same but from their documentation it looks pretty straight forward.&lt;br /&gt;
&lt;br /&gt;
I found that if one has a custom Servlet Filter and/or Listener defined in the project's web.xml then to get the same included into the final web.xml generated by enunciate, one would need to set the following in enunciate.xml.&lt;br /&gt;
&lt;pre class="xml" name="code"&gt;&amp;lt;webapp mergeWebXML="src/main/webapp/WEB-INF/web.xml" /&amp;gt;
&lt;/pre&gt;
Upon merging the same, my application started throwing 404's when attempting to access the documentation. In other words, using a custom servlet filter or listener with my use case of resources mounted at root context does not seem to work with my application and needs further investigation.Without being able to set Custom Filters and Listeners is a major blocker.&lt;br /&gt;
&lt;br /&gt;
Another tool that I have included in the pom is&lt;a href="http://www.lunatech-labs.com/open-source/jax-doclets"&gt; JAX-Doclets&lt;/a&gt; which generate nice javadoc for the JAX-RS portion of the service. To view the same execute &lt;i&gt;mvn site&lt;/i&gt; and navigate to the generated documentation.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4667121987470696359-7727034598635166532?l=sleeplessinslc.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OidcY/~4/dODKl-4E-p8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sleeplessinslc.blogspot.com/feeds/7727034598635166532/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4667121987470696359&amp;postID=7727034598635166532" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/7727034598635166532?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/7727034598635166532?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OidcY/~3/dODKl-4E-p8/documenting-web-services-with-enunciate.html" title="Documenting Web Services with Enunciate" /><author><name>Sanjay Acharya</name><uri>http://www.blogger.com/profile/01933976956977901677</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="28" src="http://3.bp.blogspot.com/-QuUnYIQQ4Ck/Txo3-4hza9I/AAAAAAAABBQ/QMZO-wT7v6A/s220/profile.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-DkkrVOOL_Tc/Tml3pemaw9I/AAAAAAAAA-E/-elgqRBXH_k/s72-c/welcomepage.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://sleeplessinslc.blogspot.com/2011/09/documenting-web-services-with-enunciate.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE8ER3YzeCp7ImA9WhZSEEw.&quot;"><id>tag:blogger.com,1999:blog-4667121987470696359.post-5348369394616540319</id><published>2011-02-25T22:38:00.003-07:00</published><updated>2011-03-24T18:26:46.880-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-24T18:26:46.880-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Pig JSON Example" /><category scheme="http://www.blogger.com/atom/ns#" term="Hadoop Map Reduce Maven" /><category scheme="http://www.blogger.com/atom/ns#" term="Hadoop Pig Maven Example" /><category scheme="http://www.blogger.com/atom/ns#" term="Hadoop Pig" /><category scheme="http://www.blogger.com/atom/ns#" term="Hadoop Pig Example" /><category scheme="http://www.blogger.com/atom/ns#" term="Apache Hadoop" /><title>Hadoop Pig and Java Map Reduce - A maven example</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/O1e3mRhA9GZbMekfoblxrmOHwP4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/O1e3mRhA9GZbMekfoblxrmOHwP4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/O1e3mRhA9GZbMekfoblxrmOHwP4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/O1e3mRhA9GZbMekfoblxrmOHwP4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Recently I have been involved with the &lt;a href="http://hadoop.apache.org/"&gt;Hadoop&lt;/a&gt; family and as always would like to share :-) I am hoping to provide an individual interested in evaluating Map-Reduce and Apache Pig a starter project for the same.&lt;br /&gt;
&lt;br /&gt;
At the core of Hadoop lies &lt;a href="http://hadoop.apache.org/hdfs/"&gt;HDFS&lt;/a&gt; and the ability to perform &lt;a href="http://hadoop.apache.org/mapreduce/"&gt;Map-Reduce&lt;/a&gt; operations on data. Leaning on my previous example of &lt;a href="http://sleeplessinslc.blogspot.com/2011/01/apache-cassandra-map-reduce-example.html"&gt;Cassandra Map Reduce&lt;/a&gt;, this BLOG will help demonstrate how Map-Reduce using Hadoop can be achieved using simple plain ole Java or its exotic cousin &lt;a href="http://pig.apache.org/"&gt;Apache Pig&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Before getting started with the example, you will need to get Hadoop running in a pseudo distributed mode at the very least. &amp;nbsp;As a user of &lt;a href="http://www.ubuntu.com/"&gt;Ubuntu&lt;/a&gt;, I found the&lt;a href="http://cloudera-tutorial.blogspot.com/2010/11/running-cloudera-in-pseudo-distributed.html"&gt; BLOG by Rahul Patodi&lt;/a&gt; to be a great start to installing &lt;a href="http://www.cloudera.com/"&gt;Cloudera's&lt;/a&gt; Hadoop version. Alternatively, you can do the same by following the instructions on the &lt;a href="https://wiki.cloudera.com/display/DOC/CDH3+Deployment+in+Pseudo-Distributed+Mode"&gt;Cloudera WIKI&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
The example used in this BLOG uses a file that contains "comments" that are written to a file in HDFS in JSON format and subsequently demonstrates how Map Reduce jobs can be executed either in Java or in Pig. The jobs themselves check for certain "Key words" of interest within the comments posted, think &lt;a href="http://en.wikipedia.org/wiki/Web_Bot"&gt;Web Bot&lt;/a&gt; here :-). An example comments file could look like:&lt;br /&gt;
&lt;pre name="code"&gt;{"commenterId":"donaldduck","comment":"The world is a cave. James bond lives in a Cave.","country":"TANZANIA"}
{"commenterId":"factorypilot","comment":"Only a cave man could do this","country":"JAPAN"}
{"commenterId":"nemesis","comment":"Felix Lighter and James Bond work well together as they are cave men","country":"BRAZIL"}
{"commenterId":"jamesbond","comment":"James Bond would be dead without Q to help him.","country":"GERMANY"}
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;Java Map-Reduce&lt;/b&gt;&lt;br /&gt;
For the Java version, one would write a Mapper that would extract the comment key, check the same for occurences of the word of interest and increment the same while a Reducer in turn totals the results as show below:&lt;br /&gt;
&lt;br /&gt;
&lt;pre name="code" class="java"&gt;public class CommentWordMapReduce {
  /**
   * Mapper
   */
  public static class WordMap extends Mapper&amp;lt;LongWritable, Text, Text, IntWritable&amp;gt; {
    private final static IntWritable ONE = new IntWritable(1);

    private Text word = new Text();

    private static final String COMMENT_KEY = "comment";
    private static final Set&lt;&amp;lt;String&amp;gt; WORDS_TO_GET_COUNT_OF = new HashSet&amp;lt;String&amp;gt;(Arrays
        .asList(new String[] { "james", "2012", "cave", "walther", "bond" }));

    private final JSONParser parser = new JSONParser();
    
    
    @Override
    public void map(LongWritable key, Text value, Context context) throws IOException,
      InterruptedException {
      JSONObject jsonObj;
      try {
        jsonObj = (JSONObject) parser.parse(value.toString());
      }
      catch (ParseException e) {
        // Hmm unable to Parse the JSON, off to next record, better log though :-)
        e.printStackTrace();
        return;
      }
      String comment = jsonObj.get(COMMENT_KEY).toString();
      StringTokenizer tokenizer = new StringTokenizer(comment);

      while (tokenizer.hasMoreTokens()) {
        String token = tokenizer.nextToken().toLowerCase();
        if (WORDS_TO_GET_COUNT_OF.contains(token)) {
          word.set(token);
          context.write(word, ONE);
        }
      }
    }
  }

  /**
   * Reducer
   */
  public static class WordReducer extends Reducer&amp;lt;Text, IntWritable, Text, IntWritable&amp;gt; {
    @Override
    protected void reduce(Text key, Iterable&amp;lt;IntWritable&amp;gt; values, Context context) throws IOException,
      InterruptedException {
      int sum = 0;
      for (IntWritable val : values) {
        sum += val.get();
      }
      context.write(key, new IntWritable(sum));
    }
  }

  /**
   * @param inputPath The input file location from HDFS
   * @param outputPath Where to store results of the Map-Reduce
   */
  public boolean mapred(String inputPath, String outputPath) throws IOException,
    InterruptedException,
    ClassNotFoundException {
    Configuration conf = new Configuration();

    Job job = new Job(conf, "process word count");
    
    job.setOutputKeyClass(Text.class);
    job.setOutputValueClass(IntWritable.class);
    job.setMapperClass(WordMap.class);
    job.setReducerClass(WordReducer.class);
    job.setInputFormatClass(TextInputFormat.class);
    job.setOutputFormatClass(TextOutputFormat.class);
    
    job.setNumReduceTasks(1);
    
    FileInputFormat.setInputPaths(job, new Path(inputPath));
    FileOutputFormat.setOutputPath(job, new Path(outputPath));
    
    job.waitForCompletion(true);

    return job.isSuccessful();
  }
}
&lt;/pre&gt;
A unit test provided will simply ensure that the expected count for each interested word infact match up with the actual as shown below:
&lt;pre name="code" class="java"&gt;public void javaMapReduce() throws Exception {
   assertTrue(new CommentWordMapReduce().mapred(INPUT_HDFS_FILE, OUTPUT_HDFS_DIR));
   validateResult();
}
&lt;/pre&gt;If you wish to see the contents of the map-reduce job then execute:
&lt;pre name="code"&gt;&gt;hadoop fs -cat /users/junittest/wcresults/part-r-00000
2012 1828
bond 4490
cave 2769
james 3631
walther 921
&lt;/pre&gt;&lt;b&gt;Pig Map-Reduce:&lt;/b&gt;
&lt;p&gt;For the Pig Map Reduce equivalent of the example, there are two helper classes that I define, a custom &lt;a href="http://pig.apache.org/docs/r0.8.0/api/LoadFunc.html/"&gt;LoadFunc&lt;/a&gt; (Loader Function) for the JSON file and a &lt;a href="http://pig.apache.org/docs/r0.8.0/api/org/apache/pig/FilterFunc.html"&gt;FilterFunc&lt;/a&gt; (filter) to only include the words of interest.

The custom JSON loader is the courtesy of &lt;a href="https://gist.github.com/601331"&gt;Kim Vogt from Git Hub&lt;/a&gt; and the &lt;b&gt;Like&lt;/b&gt; Filter is a non-comprehensive version that I defined as follows:

&lt;pre name="code" class="java"&gt;public class LikeFilter extends FilterFunc {

  public Boolean exec(Tuple input) throws IOException {
    if (input == null || input.size() &lt; 2) {
      // If no filter and input element are provided, filter provides false.
      return Boolean.FALSE;
    }
   
    List&amp;lt;Object&amp;gt; elems = input.getAll();
    
    // First element is the word presented, "for example foo or bar or bond"
    Object expected = input.getAll().get(0);
    
    // Subsequent elements are the filter conditions
    List&amp;lt;Object&amp;gt; comparators = elems.subList(1, elems.size());
    
    return comparators.contains(expected);
  }
}
&lt;/pre&gt;
Using the two classes, the Pig Script for the same map-reduce task looks like:
&lt;pre name="code"&gt;comments = LOAD '/users/junittest/comments' USING com.welflex.hadoop.pig.load.PigJsonLoader() AS (commentMap:map[]);
words = FOREACH comments GENERATE FLATTEN(TOKENIZE(LOWER(commentMap#'comment')));
filter_words = FILTER words BY com.welflex.hadoop.pig.func.LikeFilter($0, '2012', 'bond', 'cave', 'james', 'walther');
grouped = GROUP filter_words BY $0;
counts = FOREACH grouped GENERATE group,COUNT(filter_words);
store counts INTO '/users/junittest/wcresults';
&lt;/pre&gt;The unit test for Pig simply registers related jars and executes the script as follows:
&lt;pre name="code" class="java"&gt;public void pigMapReduce() {
    // Get the jars required for the map reduce including custom functions
    Set&amp;lt;String&amp;gt; jars = getJarsForPig();

    // Set ExecType.MAPREDUCE if you want to run in a distributed mode
    PigServer pigServer = new PigServer(ExecType.MAPREDUCE);

    for (String jar : jars) {
      // Register the jars for Pig      
      pigServer.registerJar(jar);
    }
     //Execute the pig script       
     pigServer.registerScript(WordCountMapReduceTest.class
            .getResource("/wordcount.pig").toURI().toURL().getFile());
    // Post validation to make sure the results of the map-red are correct.
    validateResult();
}
&lt;/pre&gt;The goal of above demonstration is to be able to write the pig script in a single location in your maven project and be able to run a unit-test of the same without having to re-write the script or handle registering custom jars.

From the above example, one can witness that the Pig Script is far lesser complicated and lesser verbose when compared to the java version of the same and from an execution perspective quite performant as well.

The example is organized as follows:
&lt;pre name="code"&gt;hadoop-example
|-- hadoop &lt;-- Demonstrate the map - reduce of both Java and Pig versions
|   |-- pom.xml
|   `-- src
|       |-- main
|       |   |-- java
|       |   |   `-- com
|       |   |       `-- welflex
|       |   |           `-- hadoop
|       |   |               `-- hdfs
|       |   |                   |-- HdfsServiceImpl.java
|       |   |                   `-- HdfsService.java
|       |   |-- pig
|       |   |   `-- wordcount.pig
|       |   `-- resources
|       |       |-- core-site.xml
|       |       `-- log4j.properties
|       `-- test
|           |-- java
|           |   `-- com
|           |       `-- welflex
|           |           `-- hadoop
|           |               `-- mapred
|           |                   |-- CommentWordMapReduce.java
|           |                   `-- WordCountMapReduceTest.java
|           `-- resources
|               `-- comments
|-- pig-funcs &lt;----- Contains the custom Pig artifacts
|   |-- pom.xml
|   `-- src
|       `-- main
|           `-- java
|               `-- com
|                   `-- welflex
|                       `-- hadoop
|                           `-- pig
|                               |-- func
|                               |   `-- LikeFilter.java
|                               `-- load
|                                   |-- JsonLineParser.java
|                                   `-- PigJsonLoader.java
`-- pom.xml
&lt;/pre&gt;
&lt;/div&gt;Simply execute:
&lt;pre name="code"&gt;&gt;mvn test
&lt;/pre&gt;to witness both the Java and Pig Map Reduce versions in actions or import into your favorite IDE and do the same. You can easily change the example to search for country count or augment the size of the file and try a non-local mode of map-reduce.

I must state that when working with Hadoop and family, one needs to be careful with the versions they are working with. The above mentioned example works with Cloudera's Hadoop Version &lt;b&gt;Hadoop 0.20.2-CDH3B4&lt;/b&gt;
&lt;p/&gt;&lt;a href="http://home.comcast.net/~acharya.s/java/hadoop-example.zip"&gt;&lt;b&gt;Download the example here&lt;/b&gt;&lt;/a&gt; and happy Pigging. Oink out, or should I say Grunt out ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4667121987470696359-5348369394616540319?l=sleeplessinslc.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OidcY/~4/jGkt4Kk3T64" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sleeplessinslc.blogspot.com/feeds/5348369394616540319/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4667121987470696359&amp;postID=5348369394616540319" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/5348369394616540319?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/5348369394616540319?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OidcY/~3/jGkt4Kk3T64/hadoop-pig-and-java-map-reduce-maven.html" title="Hadoop Pig and Java Map Reduce - A maven example" /><author><name>Sanjay Acharya</name><uri>http://www.blogger.com/profile/01933976956977901677</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="28" src="http://3.bp.blogspot.com/-QuUnYIQQ4Ck/Txo3-4hza9I/AAAAAAAABBQ/QMZO-wT7v6A/s220/profile.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://sleeplessinslc.blogspot.com/2011/02/hadoop-pig-and-java-map-reduce-maven.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkENQ3c8eSp7ImA9Wx9XEUQ.&quot;"><id>tag:blogger.com,1999:blog-4667121987470696359.post-4456234468597863373</id><published>2011-01-04T19:31:00.000-07:00</published><updated>2011-01-04T19:31:32.971-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-01-04T19:31:32.971-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Apache Cassandra Map Reduce" /><category scheme="http://www.blogger.com/atom/ns#" term="Apache Cassandra" /><category scheme="http://www.blogger.com/atom/ns#" term="Apache Cassandra Hadoop" /><title>Apache Cassandra Map Reduce - An Example</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/hx2BOXD5xx2p6GGbUvC2Yb1y-F4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hx2BOXD5xx2p6GGbUvC2Yb1y-F4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/hx2BOXD5xx2p6GGbUvC2Yb1y-F4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/hx2BOXD5xx2p6GGbUvC2Yb1y-F4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Happy New Year :-)! Starting this year with a small BLOG on using &lt;a href="http://wiki.apache.org/cassandra/HadoopSupport"&gt;Map Reduce with Cassandra&lt;/a&gt;. Map Reduce on Cassandra is supported via Hadoop since version 0.6. Hadoop Map Reduce jobs can retrieve data from Cassandra and reduce the same. There is a word count example that is available via the Cassandra distribution. In this BLOG I will be using the Word Count example agains't the super column I had defined in my &lt;a href="http://sleeplessinslc.blogspot.com/2010/11/apache-cassandra-with-hector-example.html"&gt;previous BLOG on Cassandra&lt;/a&gt;. With 0.7 of Cassandra there is support to reduce the output to Cassandra itself.&lt;br /&gt;
&lt;br /&gt;
For the scope of the example, I have used the Comments Column Family from my previous BLOG and my goal is to find counts of certain words that I am interested in a time slice range. The example provided creates multiple comments on a single blog entry and then runs a Hadoop map reduce job that will output the results of words interested in into a column family that contains only the count of each word.&lt;br /&gt;
The Map Reduce job is provided a Slice Predicate providing a time range of data to search on.&lt;br /&gt;
&lt;pre name="code" class="java"&gt;ByteBuffer startKey = ...;
ByteBuffer endKey = ....;

SliceRange range = new SliceRange();
range.setStart(startKey);
range.setFinish(endKey);
range.setCount(Integer.MAX_VALUE);
SlicePredicate predicate = new SlicePredicate().setSlice_range(range);
ConfigHelper.setInputSlicePredicate(job.getConfiguration(), predicate);
job.waitForCompletion(true);
&lt;/pre&gt;&lt;br /&gt;
In the same vein, one could start different jobs across different time ranges to run simultaneously.&lt;br /&gt;
&lt;br /&gt;
The Mapper is provided with the words we are interested and only increments the counts on the word during the map process.&lt;br /&gt;
&lt;pre name="code" class="java"&gt;    public void map(ByteBuffer key, SortedMap&amp;lt;ByteBuffer, IColumn&amp;gt; columns, Context context) throws IOException,
      InterruptedException {
      
      for (Map.Entry&amp;lt;ByteBuffer, IColumn&amp;gt; entry : columns.entrySet()) {
        IColumn column = entry.getValue();
        if (column == null) {
          continue;
        }
        
        IColumn textCol = column.getSubColumn(COMMENT_COL_NAME);
        String value = ByteBufferUtil.string(textCol.value());
     
        StringTokenizer itr = new StringTokenizer(value);
        while (itr.hasMoreTokens()) {
          String nextWord = itr.nextToken().toLowerCase();
          // Only trap expected words
          if (expectedWords.contains(nextWord)) {
            word.set(nextWord);
            context.write(word, one);
          }
        }
      }
    }
  }
&lt;/pre&gt;&lt;br /&gt;
The Reducer in turn reduces the same into a Cassandra family called Word Count similar to the Word count example provided by Cassandra.&lt;br /&gt;
&lt;br /&gt;
If you run the MapReduceTest, as an output you can observe the following counts of the words I am interested in:&lt;br /&gt;
&lt;pre name="code"&gt;The word [james] has occured [1810] times
The word [2012] has occured [902] times
The word [cave] has occured [1368] times
The word [walther] has occured [481] times
The word [bond] has occured [2265] times
&lt;/pre&gt;Note that I have made every word lower case in the example. &lt;br /&gt;
To run the example, &lt;a href="http://home.comcast.net/~acharya.s/java/cassandra-map-reduce.zip"&gt;download the same from HERE&lt;/a&gt; and run "mvn test". If I have not understood something correctly, please do let me know as although Map-Reduce is Old, my experience is minimal :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4667121987470696359-4456234468597863373?l=sleeplessinslc.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OidcY/~4/kn6tiQsgz50" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sleeplessinslc.blogspot.com/feeds/4456234468597863373/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4667121987470696359&amp;postID=4456234468597863373" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/4456234468597863373?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/4456234468597863373?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OidcY/~3/kn6tiQsgz50/apache-cassandra-map-reduce-example.html" title="Apache Cassandra Map Reduce - An Example" /><author><name>Sanjay Acharya</name><uri>http://www.blogger.com/profile/01933976956977901677</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="28" src="http://3.bp.blogspot.com/-QuUnYIQQ4Ck/Txo3-4hza9I/AAAAAAAABBQ/QMZO-wT7v6A/s220/profile.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://sleeplessinslc.blogspot.com/2011/01/apache-cassandra-map-reduce-example.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0INRHo-eCp7ImA9Wx5aEko.&quot;"><id>tag:blogger.com,1999:blog-4667121987470696359.post-1015058986460151149</id><published>2010-11-08T19:59:00.000-07:00</published><updated>2010-11-08T19:59:55.450-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-11-08T19:59:55.450-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Apache Cassandra" /><category scheme="http://www.blogger.com/atom/ns#" term="Cassandra Hector" /><category scheme="http://www.blogger.com/atom/ns#" term="Hector Example" /><title>Apache Cassandra with Hector - An Example</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/cFIXqdM9hezZ9CjkNdbpL3qgCzc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/cFIXqdM9hezZ9CjkNdbpL3qgCzc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/cFIXqdM9hezZ9CjkNdbpL3qgCzc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/cFIXqdM9hezZ9CjkNdbpL3qgCzc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Recently I had been to the Strange Loop Conference in Saint Louis. While there I indulged in two things primarily, booze with old buddies and No SQL in the conference.&lt;br /&gt;
&lt;br /&gt;
In particular, I found a lot of mention of &lt;a href="http://cassandra.apache.org"&gt;Apache Cassandra&lt;/a&gt;. Why would one care about Cassandra, how about a 150 TB cluster spanning over 150 machines at Facebook ? Cassandra is used by organizations such as Digg, Twitter etc who deal with a large amount of data. I could attempt to write more on Cassandra but there is a great presentation by Eric Evans on the same&amp;nbsp;&lt;a href="http://www.parleys.com/#id=1866&amp;amp;sl=40&amp;amp;st=5"&gt;http://www.parleys.com/#id=1866&amp;amp;sl=40&amp;amp;st=5&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
If not talking about Cassandra, what am I talking about? Well, I wanted to use Cassandra to get a grasp of how Columns and Super Columns work in Cassandra. Yeah, I hear it, WTF are Super Columns? I found myself asking the same question at the Conference, but luckily for me I found this nice blog by Arin Sarkissian titled aptly "&lt;a href="http://arin.me/blog/wtf-is-a-supercolumn-cassandra-data-model"&gt;WTF is a SuperColumn?&lt;/a&gt;" explaining the same. I wanted to translate his example Schema of a Blog Application into a working example that uses Cassandra and provide a playing ground for someone like me wanting to try cassandra.&lt;br /&gt;
&lt;br /&gt;
So I am only going to use Java, sorry no Ruby or Scala for me right now. There is a Thrift Java Client for Cassandra but is limited in functionality so I proceeded to use &lt;a href="http://prettyprint.me/2010/02/23/hector-a-java-cassandra-client/"&gt;Hector&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
The model created was based Arin's schema with a few enhancements. I have updated the Author Schema to contain a user name and password with the user name being the "row key" for the Column Family Authors.&lt;br /&gt;
&lt;pre name="code" class="xml"&gt;&amp;lt;!--
    ColumnFamily: Authors
    We'll store all the author data here.

    Row Key = Author user name
    Column Name: an attribute for the entry (title, body, etc)
    Column Value: value of the associated attribute

    Access: get author by userName (aka grab all columns from a specific Row)

    Authors : { // CF
        sacharya : { // row key
            // and the columns as "profile" attributes
            password:#$%#%#$%#%
            name:Sanjay Acharya
            twitterId: sterling23,
            email: sacharya@example.com,
            biography: "bla bla bla"
        },
        // and the other authors
        dduck {
            ...
        }
    }
--&amp;gt;
&amp;lt;ColumnFamily CompareWith="BytesType" Name="Authors"/&amp;gt;
&lt;/pre&gt;The above Column Family translated to a simple Author POJO as shown below:&lt;br /&gt;
&lt;pre name="code" class="java"&gt;public class Author {
  private String userName;
  private String password;
  private String name;
  private String twitterId;
  private String biography;
  ..// Getters and Setters
}
&lt;/pre&gt;Using Hector directly, a DAO to create an author might look like:&lt;br /&gt;
&lt;pre name="code" class="java"&gt;public void create(Author author) {
    Mutator&amp;lt;String&amp;gt; mutator = HFactory.createMutator(keySpace, StringSerializer.get());
    
    String userName = author.getUserName();
    
    mutator.addInsertion(userName,COLUMN_FAMILY_NAME,
        HFactory.createColumn("password", author.getPassword(), StringSerializer.get(),
          StringSerializer.get()))
          .addInsertion(userName, COLUMN_FAMILY_NAME, 
            HFactory.createColumn("name", author.getName(), StringSerializer.get(), 
              StringSerializer.get()))
          .addInsertion(userName, COLUMN_FAMILY_NAME, 
            HFactory.createColumn("biography", author.getBiography(), StringSerializer.get(),
              StringSerializer.get()))
          .addInsertion(userName, COLUMN_FAMILY_NAME, 
            HFactory.createColumn("twitterId", author.getTwitterId(), StringSerializer.get(),
              StringSerializer.get()))
}
&lt;/pre&gt;The above code felt rather verbose so with a small compromise, column names are the same name as attribute names of the POJO and default constructor must exist for the POJO, I present an AbstractColumnFamilyDao that an AuthorDao for example would implement:&lt;br /&gt;
&lt;pre name="code" class="java"&gt;public abstract class AbstractColumnFamilyDao&amp;lt;KeyType, T&amp;gt; {
  private final Class&amp;lt;T&amp;gt; persistentClass;
  private final Class&amp;lt;KeyType&amp;gt; keyTypeClass;
  protected final Keyspace keySpace;
  private final String columnFamilyName;
  private final String[] allColumnNames;

  public AbstractColumnFamilyDao(Keyspace keyspace, Class&amp;lt;KeyType&amp;gt; keyTypeClass, Class&amp;lt;T&amp;gt; persistentClass,
      String columnFamilyName) {
    this.keySpace = keyspace;
    this.keyTypeClass = keyTypeClass;
    this.persistentClass = persistentClass;
    this.columnFamilyName = columnFamilyName;
    this.allColumnNames = DaoHelper.getAllColumnNames(persistentClass);
  }

  public void save(KeyType key, T model) {
  
    Mutator&amp;lt;Object&amp;gt; mutator = HFactory.createMutator(keySpace, SerializerTypeInferer.getSerializer(keyTypeClass));
    for (HColumn&amp;lt;?, ?&amp;gt; column : DaoHelper.getColumns(model)) {
      mutator.addInsertion(key, columnFamilyName, column);
    }

    mutator.execute();
  }

  public T find(KeyType key) {
    SliceQuery&amp;lt;Object, String, byte[]&amp;gt; query = HFactory.createSliceQuery(keySpace,
      SerializerTypeInferer.getSerializer(keyTypeClass), StringSerializer.get(), BytesSerializer.get());

    QueryResult&amp;lt;ColumnSlice&amp;lt;String, byte[]&amp;gt;&amp;gt; result = query.setColumnFamily(columnFamilyName)
        .setKey(key).setColumnNames(allColumnNames).execute();

    if (result.get().getColumns().size() == 0) {
      return null;
    }

    try {
      T t = persistentClass.newInstance();
      DaoHelper.populateEntity(t, result);
      return t;
    }
    catch (Exception e) {
      throw new RuntimeException("Error creating persistent class", e);
    }
  }

  public void delete(KeyType key) {
    Mutator&amp;lt;Object&amp;gt; mutator = HFactory.createMutator(keySpace, SerializerTypeInferer.getSerializer(keyTypeClass));
    mutator.delete(key, columnFamilyName, null, SerializerTypeInferer.getSerializer(keyTypeClass));
  }
}
&lt;/pre&gt;One might ask, why not just annotate the POJO with JPA annotations and thus handle the persistence? I did head down that route but found a project that was already doing the same, i.e., &lt;a href="http://code.google.com/p/kundera/"&gt;Kundera&lt;/a&gt;. For this reason, I kept the &lt;br /&gt;
example more focussed on Hector. Also I am a bit wary regarding whether the JPA specs will be a good fit for a Sparse column store like Cassandra. &lt;br /&gt;
&lt;br /&gt;
With the above mentioned DAO, I modeled the rest of my code to Arin's example schema. The sample code provided contains a Blog Simulation which is a Multi-threaded test that simulates the working of the BLOG application, i.e., authors being created, BLOG Entries being created and authors commenting on BLOG Entries, Finding all Blog Entries created, Getting Blog Entries by a tag, Getting comments for a Blog Entry etc etc. &lt;br /&gt;
&lt;br /&gt;
The example can be &lt;a href="http://home.comcast.net/~acharya.s/java/cassandra.zip"&gt;DOWNLOADED HERE&lt;strike&gt;&lt;/strike&gt;&lt;/a&gt;. You will not need to install a Cassandra server as the example uses an embedded Server. The code however does not demonstrate any fail over or consistency strategies. Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4667121987470696359-1015058986460151149?l=sleeplessinslc.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OidcY/~4/EVZ6OeeF48g" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sleeplessinslc.blogspot.com/feeds/1015058986460151149/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4667121987470696359&amp;postID=1015058986460151149" title="8 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/1015058986460151149?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/1015058986460151149?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OidcY/~3/EVZ6OeeF48g/apache-cassandra-with-hector-example.html" title="Apache Cassandra with Hector - An Example" /><author><name>Sanjay Acharya</name><uri>http://www.blogger.com/profile/01933976956977901677</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="28" src="http://3.bp.blogspot.com/-QuUnYIQQ4Ck/Txo3-4hza9I/AAAAAAAABBQ/QMZO-wT7v6A/s220/profile.jpg" /></author><thr:total>8</thr:total><feedburner:origLink>http://sleeplessinslc.blogspot.com/2010/11/apache-cassandra-with-hector-example.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0IBQ3k7fip7ImA9Wx5WGUU.&quot;"><id>tag:blogger.com,1999:blog-4667121987470696359.post-4004406132067715585</id><published>2010-10-01T19:20:00.001-06:00</published><updated>2010-10-01T19:05:52.706-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-01T19:05:52.706-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="MongoDB" /><category scheme="http://www.blogger.com/atom/ns#" term="Mophia MongoDB example" /><category scheme="http://www.blogger.com/atom/ns#" term="Morphia for MongoDB" /><title>MongoDB with Morphia - An example</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/4BqZGfTTdcst4ve7Z79L00R9ZUk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4BqZGfTTdcst4ve7Z79L00R9ZUk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/4BqZGfTTdcst4ve7Z79L00R9ZUk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4BqZGfTTdcst4ve7Z79L00R9ZUk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;a href="http://www.mongodb.org/"&gt;MongoDB&lt;/a&gt; is an open source highly scalable, performant document oriented database and I wanted to play with the same. The database itself is feature rich offering features such as sharding, in place updates and map reduce.&lt;br /&gt;
&lt;br /&gt;
The database is written in C++ and uses JSON style documents for mapping objects. Mongo's java API provides the concept of an object that takes name-value pair's depicting the data and then stores the same. There is a lack of type safety with this approach and also the effort of converting regular java pojo's into the downstream mongo object. &lt;br /&gt;
&lt;br /&gt;
The type safety issue is addressed by the &lt;a href="http://code.google.com/p/morphia/"&gt;Morphia&lt;/a&gt; project that allows for easy mapping of objects from-to MongoDB while also providing a querying interface. The API itself makes use of annotations thus not requiring the use of any configuration files. Think of this like Hibernate/JPA  with annotations for Mongo.&lt;br /&gt;
&lt;br /&gt;
The API itself provides for access to Mongo directly if required. In this BLOG, I am trying out a simple example of using Morphia. I developed the project in the following steps:&lt;br /&gt;
&lt;br /&gt;
1. Connection to mongo&lt;br /&gt;
2. POJO or Model&lt;br /&gt;
3. DAO&lt;br /&gt;
&lt;br /&gt;
I have used a simple data model of an Order and its ancillary objects.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;1. Connection to Mongo:&lt;/b&gt;&lt;br /&gt;
The Mongo object itself is a connection pool so one does not need to create an additional one. Take a look at the &lt;a href="http://www.mongodb.org/display/DOCS/Java+Driver+Concurrency"&gt;documentation&lt;/a&gt; on the same.&lt;br /&gt;
&lt;br /&gt;
I define a simple Connection manager that is a singleton that handles the initialization of a Morphia DataStore instance as shown below:&lt;br /&gt;
&lt;pre name="code" class="java"&gt;public final class MongoConnectionManager {
  private static final MongoConnectionManager INSTANCE = new MongoConnectionManager();

  private final Datastore db;
  public static final String DB_NAME = "mydb";
  
  private MongoConnectionManager() {
    try {
      Mongo m = new Mongo("localhost", 27017);
      db = new Morphia().map(Order.class).map(LineItem.class).map(Customer.class).createDatastore(
        m, DB_NAME);
      db.ensureIndexes();
    }
    catch (Exception e) {
      throw new RuntimeException("Error initializing mongo db", e);
    }
  }

  public static MongoConnectionManager instance() {
    return INSTANCE;
  }
  ...
}
&lt;/pre&gt;&lt;br /&gt;
Also note that in the above code, there is a call to db.ensureIndexes(). This method will synchronously create indices if not present and if present continues on seamlessly.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;2. Model:&lt;/b&gt;&lt;br /&gt;
I then defined my Order Model as shown below:&lt;br /&gt;
&lt;pre name="code" class="java"&gt;@Entity(value="orders", noClassNameStored = true)
public class Order {
  @Id
  private ObjectId id;
  @Reference
  private Customer customer;
  @Embedded
  private List&amp;lt;LineItem&amp;gt; lines;
    
  private Date creationDate;
  private Date lastUpdateDate;
  ...
  // Getters and setters
  ..
  
  @PrePersist
  public void prePersist() {
    this.creationDate = (creationDate == null) ? new Date() : creationDate;
    this.lastUpdateDate = (lastUpdateDate == null) ? creationDate : new Date();
  }
}
&lt;/pre&gt;The morphia annotations are not JPA but very similar. As shown above we are mapping the Order class to the mongo collection of "orders", we define an Id annotation indicating the order identifier. As the type of the Id has been defined as ObjectId, Mongo will generate the Id automatically. If one uses any other type, the Id must be explicitly set. Also note the explicit setting of noClassNameStored as the class name will be otherwise be stored by default. The storing of the class name becomes useful when working with multiple-inheritance structures where the correct class would need to be instantiated.&lt;br /&gt;
&lt;br /&gt;
Note that the Customer object has been defined with an @&lt;a href="http://code.google.com/p/morphia/wiki/ReferenceAnnotation"&gt;Reference&lt;/a&gt; annotation indicating that the Customer object can exist independent of the Order object and an existing one must be provided before an order can be persisted. &lt;br /&gt;
&lt;br /&gt;
The @&lt;a href="http://code.google.com/p/morphia/wiki/EmbeddedAnnotation"&gt;Embedded&lt;/a&gt; tag on the Line item indicates that the line items lie in the scope of an order and will not exist independently without an order.&lt;br /&gt;
&lt;br /&gt;
The create and update dates have not been annotated but will be included in the MongoDB collection automatically. One could alternatively add the @Property tag to the same and provide a specific name under which the property would reside.&lt;br /&gt;
&lt;br /&gt;
If there is a field that one would not want persisted, then marking the same with @Transient will prevent the same.&lt;br /&gt;
&lt;br /&gt;
Also note the segment where the prePersist methog tagged with the @PrePersist annotation is used to set the dates on the order prior to it being saved. Equivalent annotations exist for @PostPersist, @PreLoad and @PostLoad. The framework also supports the concept of EntityListeners for life cycle phases. So one can create an external class that responds to different &lt;br /&gt;
life cycle events as so:&lt;br /&gt;
&lt;pre name="code" class="java"&gt;@EntityListeners(OrderListener.class)
public class Order {
}

public class OrderListener {
  @PrePersist
  public void preCreate(Order order) {
    ...
  }
}
&lt;/pre&gt;&lt;br /&gt;
Viewing the order using the MongoDB console would display an order as such:&lt;br /&gt;
&lt;pre name="code" class="java"&gt;db.orders.find().forEach(printjson);
{
 "_id" : ObjectId("4ca4e5dbb95a4d64192cf119"),
 "customer" : {
  "$ref" : "customers",
  "$id" : ObjectId("4ca4e5dbb95a4d64172cf119")
 },
 "lines" : [
  {
   "lineNumber" : 1,
   "quantity" : 10,
   "product" : {
    "$ref" : "products",
    "$id" : "xbox"
   }
  }
 ],
 "creationDate" : "Thu Sep 30 2010 19:32:43",
 "lastUpdateDate" : "Thu Sep 30 2010 19:32:43"
}

&lt;/pre&gt;&lt;b&gt;3. DAO:&lt;/b&gt;&lt;br /&gt;
The Morphia framework provides a DAO class. Nice. The DAO class provides type safe DAO behavior. So if one has a customer object as an example:&lt;br /&gt;
&lt;br /&gt;
&lt;pre name="code" class="java"&gt;DAO&amp;lt;Customer, String&amp;gt; customerDao = new DAO&amp;lt;Customer, String&amp;gt;(Customer.class, dataSource);

// save
customerDao.save(new Customer());
// Read
Customer sanjay = customerDao.createQuery().field("lastName").equal("acharya").get();
&lt;/pre&gt;&lt;br /&gt;
The DAO class however provides many operations that might not be desired such as dropCollection(). Decorating the same or extending the same is an easy enough procedure to limit the access of some of these methods while providing additional ones.&lt;br /&gt;
&lt;br /&gt;
&lt;pre name="code" class="java"&gt;public class OrderDaoImpl extends DAO&amp;lt;Order, ObjectId&amp;gt; implements OrderDao {
  public OrderDaoImpl() {
    super(Order.class, MongoConnectionManager.instance().getDb());
  }
  ....

  @Override
  public List&amp;lt;Order&amp;gt; findOrdersByCustomer(Customer customer) {
   return createQuery().field("customer").equal(customer).asList();
  }

  @Override
  public List&amp;lt;Order&amp;gt; findOrdersWithProduct(Product product) {
    return createQuery().field("lines.product").equal(product).asList();
  }
}
&lt;/pre&gt;&lt;br /&gt;
From the above code, you see that the query API from Morphia provides an abstraction over the raw json query of mongo. Type safety is present but as in all cases for no fault of theirs, field naming will not be type safe. The "." notation is used to access nested fields,&lt;br /&gt;
&lt;br /&gt;
Another example of a query involving multiple fields is shown below:&lt;br /&gt;
&lt;pre name="code" class="java"&gt;public List&amp;lt;Product&amp;gt; getProductsWithCategory(CategoryType type, double maxPrice) {
    return createQuery().field("price").lessThanOrEq(maxPrice).field("categoryType").equal(type).asList();
  }
&lt;/pre&gt;&lt;br /&gt;
Indexes can be applied to fields via the @Indexed annotation. For example,in the code shown below, the lastName property of a Customer is to be indexed in decending order.&lt;br /&gt;
&lt;pre name="code" class="java"&gt;@Indexed(value=IndexDirection.DESC, name="lastNameIndex", dropDups=false) 
  private String lastName;
&lt;/pre&gt;&lt;br /&gt;
I found morphia pretty easy to use with mongo. It will be nice if they support the JPA annotations. There are still things I want to try such as sharding and maybe &lt;a href="http://lucene.apache.org/java/docs/index.html"&gt;Lucene&lt;/a&gt; integration for full text based search.&lt;br /&gt;
&lt;br /&gt;
The example provided demonstrates Morphia in action with tests that use the model objects and DAOs. To get the tests running, &lt;a href="http://www.mongodb.org/downloads"&gt;download MongoDB &lt;/a&gt;, install the same and have it &lt;a href="http://www.mongodb.org/display/DOCS/Quickstart"&gt;running on the default port&lt;/a&gt;. Run "maven test" in the project provided to see the tests or import the project for a code review :-)&lt;br /&gt;
&lt;br /&gt;
The example can be &lt;a href="http://home.comcast.net/~acharya.s/java/mongodb.zip"&gt;downloaded HERE&lt;/a&gt;....&lt;br /&gt;
&lt;br /&gt;
Some links:&lt;br /&gt;
1. &lt;a href="http://www.scribd.com/doc/31748637/Java-Development-with-MongoDB-Mongo-NYC-2010"&gt;A presentation on Mongo and Java&lt;/a&gt; &lt;br /&gt;
2. &lt;a href="http://www.databasejournal.com/features/article.php/3905531/10-things-you-Need-to-Know-About-NoSQL-Databases.htm"&gt;10 things about No-sql databases&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4667121987470696359-4004406132067715585?l=sleeplessinslc.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OidcY/~4/O04pBa5WUU0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sleeplessinslc.blogspot.com/feeds/4004406132067715585/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4667121987470696359&amp;postID=4004406132067715585" title="12 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/4004406132067715585?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/4004406132067715585?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OidcY/~3/O04pBa5WUU0/mongodb-with-morphia-example.html" title="MongoDB with Morphia - An example" /><author><name>Sanjay Acharya</name><uri>http://www.blogger.com/profile/01933976956977901677</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="28" src="http://3.bp.blogspot.com/-QuUnYIQQ4Ck/Txo3-4hza9I/AAAAAAAABBQ/QMZO-wT7v6A/s220/profile.jpg" /></author><thr:total>12</thr:total><feedburner:origLink>http://sleeplessinslc.blogspot.com/2010/10/mongodb-with-morphia-example.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkAHQXYzeyp7ImA9Wx5XFkU.&quot;"><id>tag:blogger.com,1999:blog-4667121987470696359.post-1460093034224560267</id><published>2010-09-16T17:45:00.000-06:00</published><updated>2010-09-16T17:45:30.883-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-16T17:45:30.883-06:00</app:edited><title>Code Pro Tools</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Kcx2YQk4u1AUXuupNVhYSZqbMzA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Kcx2YQk4u1AUXuupNVhYSZqbMzA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Kcx2YQk4u1AUXuupNVhYSZqbMzA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Kcx2YQk4u1AUXuupNVhYSZqbMzA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;I use Find Bugs and Emma. Apparently Google has now has provide Instantiations as a free tool. Particularly interested in the Code Pro &lt;a href="http://code.google.com/webtoolkit/tools/download-codepro.html"&gt;AnalytiX&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
Initial impressions of Audit, Metrics, Dependencies looks positive. avadoc repair did not do a whole lot for me. Find Dead Code on a maven project reported all my classes as dead code :-( Surely I am not using it correctly. Pretty neat generation of base boundary test cases.&lt;br /&gt;
&lt;br /&gt;
I am curious.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4667121987470696359-1460093034224560267?l=sleeplessinslc.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OidcY/~4/9qWUV6YMArE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sleeplessinslc.blogspot.com/feeds/1460093034224560267/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4667121987470696359&amp;postID=1460093034224560267" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/1460093034224560267?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/1460093034224560267?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OidcY/~3/9qWUV6YMArE/code-pro-tools.html" title="Code Pro Tools" /><author><name>Sanjay Acharya</name><uri>http://www.blogger.com/profile/01933976956977901677</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="28" src="http://3.bp.blogspot.com/-QuUnYIQQ4Ck/Txo3-4hza9I/AAAAAAAABBQ/QMZO-wT7v6A/s220/profile.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://sleeplessinslc.blogspot.com/2010/09/code-pro-tools.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUUNSXs-eip7ImA9Wx5XFUo.&quot;"><id>tag:blogger.com,1999:blog-4667121987470696359.post-752712395713923974</id><published>2010-09-14T20:12:00.004-06:00</published><updated>2010-09-15T13:01:38.552-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-15T13:01:38.552-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="XXE" /><category scheme="http://www.blogger.com/atom/ns#" term="XML Injection" /><category scheme="http://www.blogger.com/atom/ns#" term="External Entity Injection" /><category scheme="http://www.blogger.com/atom/ns#" term="XML Security" /><title>XML Injection</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/pREGAZ-eEzzG2RoeRlREHU3zvQs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/pREGAZ-eEzzG2RoeRlREHU3zvQs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/pREGAZ-eEzzG2RoeRlREHU3zvQs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/pREGAZ-eEzzG2RoeRlREHU3zvQs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Been quite sometime since I posted something. Been looking into XML vulnerabilities and figured I'd share. The contents of this BLOG are in no means referencing any employer that I have been involved with and are soley my interests in XML injection.&lt;br /&gt;
&lt;br /&gt;
When developing Web services, one would typically like to keep them secure by preventing agaisnt either Denial of Service or Security Attacks. &lt;br /&gt;
&lt;br /&gt;
So what is XML Injection? If a malicious user alters the contents of an XML document by injecting XML tags, then when an XML parser tries to parse the document, security exploits can be achieved. For the scope of this BLOG, I am not creating a Web Service but explaining in plain vanilla XML and SAX as to how the exploits can occur. The same concepts of course apply to Web Services dealing with XML.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Tag Injection:&lt;/b&gt;&lt;br /&gt;
Consider the following XML Document that represents an item that is submitted&lt;br /&gt;
for purchase. &lt;br /&gt;
&lt;pre name="code" class="xml"&gt;&amp;lt;item&amp;gt; 
    &amp;lt;description&amp;gt;Widget&amp;lt;/description&amp;gt;
    &amp;lt;price&amp;gt;500.0&amp;lt;/price&amp;gt;
    &amp;lt;quantity&amp;gt;1&amp;lt;/quantity&amp;gt;
&amp;lt;/item&amp;gt;
&lt;/pre&gt;The above XML is represented as a JAXB Object to which it would be un-marshalled as shown below:&lt;br /&gt;
&lt;pre name="code" class="java"&gt;@XmlRootElement
public class Item {
  private String description;
  private Double price;
  private int quantity;
 
 // Setters and getters
  ....
}
&lt;/pre&gt;When the above XML is parsed by a SAX Parser, the resulting Item object is correctly matched up with the corresponding attributes.&lt;br /&gt;
&lt;br /&gt;
Consider the XML fragment altered by a malicious user who was aware of the structure:&lt;br /&gt;
&lt;pre name="code" class="xml"&gt;&amp;lt;item&amp;gt; 
    &amp;lt;description&amp;gt;Widget&amp;lt;/description&amp;gt;
    &amp;lt;price&amp;gt;500.0&amp;lt;/price&amp;gt;
    &amp;lt;quantity&amp;gt;1&amp;lt;/quantity&amp;gt;
    &amp;lt;!-- Additional Rows below for price and quantity --&amp;gt;
    &amp;lt;price&amp;gt;1.0&amp;lt;/price&amp;gt;
    &amp;lt;quantity&amp;gt;1&amp;lt;/price&amp;gt;
&amp;lt;/item&amp;gt;
&lt;/pre&gt;When the above document is parsed by the SAX Parser, it interprets the second element as overriding the first and thus the price reflects as 1.00 instead of 500.00. One only needs to think of the ramifications of this successful injection. Always a fan of the dollar store :-).&lt;br /&gt;
&lt;br /&gt;
So how can one prevent the same from happening? Validating the received XML agaisnt an XSD will catch the fallacy in the structure. The following represents a simple XSD for the document:&lt;br /&gt;
&lt;pre name="code" class="xml"&gt;&amp;lt;xs:schema
 xmlns:xs=&amp;quot;http://www.w3.org/2001/XMLSchema&amp;quot;
 xmlns=&amp;quot;http://www.welflex.com/item&amp;quot;
 elementFormDefault=&amp;quot;qualified&amp;quot;&amp;gt;
 &amp;lt;xs:element name=&amp;quot;item&amp;quot;&amp;gt;
  &amp;lt;xs:complexType&amp;gt;
   &amp;lt;xs:sequence&amp;gt;
    &amp;lt;xs:element name=&amp;quot;description&amp;quot; type=&amp;quot;xs:string&amp;quot;&amp;gt;&amp;lt;/xs:element&amp;gt;
    &amp;lt;xs:element name=&amp;quot;price&amp;quot; type=&amp;quot;xs:decimal&amp;quot;&amp;gt;&amp;lt;/xs:element&amp;gt;
    &amp;lt;xs:element name=&amp;quot;quantity&amp;quot; type=&amp;quot;xs:integer&amp;quot;&amp;gt;&amp;lt;/xs:element&amp;gt;
   &amp;lt;/xs:sequence&amp;gt;
  &amp;lt;/xs:complexType&amp;gt;
 &amp;lt;/xs:element&amp;gt;
&amp;lt;/xs:schema&amp;gt;
&lt;/pre&gt;Now when the SAX Parser validates agaisnt the schema provided with the malicious XML, an exception would be risen to the effect of:&lt;br /&gt;
&lt;pre name="code" class="java"&gt;javax.xml.bind.UnmarshalException
 - with linked exception:
[org.xml.sax.SAXParseException: cvc-complex-type.2.4.d: Invalid content was found starting with element 'price'. No child element is expected at this point.]
 at javax.xml.bind.helpers.AbstractUnmarshallerImpl.createUnmarshalException(AbstractUnmarshallerImpl.java:315)
 at com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.createUnmarshalException(UnmarshallerImpl.java:503)
....
&lt;/pre&gt;&lt;br /&gt;
As to why an attacker would not simply submit a whole new document with malicious data rather than injecting the same, well I do not have a concrete answer for that and can only suppose it might have to do with source system validation by the target system?&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;XXE or Xml EXternal Entity Attack:&lt;/b&gt;&lt;br /&gt;
External entity references in XML allow data from outside the main document to be embedded into the XML document. This "feature" allows for a malicious user to either gain access to sensitive information and/or create a denial of service attack.&lt;br /&gt;
&lt;br /&gt;
Consider the following malevolent XML fragment:&lt;br /&gt;
&lt;pre name="code" class="xml"&gt;&amp;lt;Person&amp;gt;
  &amp;lt;FirstName&amp;gt;Sanjay&amp;lt;/FirstName&amp;gt;
  &amp;lt;LastName&amp;gt;Acharya&amp;lt;/LastName&amp;gt;
&amp;lt;/Person&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
Now, consider the same XML shown above with small modifications made by our friendly neighborhood attacker:&lt;br /&gt;
&lt;pre name="code" class="xml"&gt;&amp;lt;!DOCTYPE foo [&amp;lt;!ENTITY xxe SYSTEM &amp;quot;file:///etc/passwd&amp;quot;&amp;gt;]&amp;gt;
&amp;lt;Person&amp;gt;
  &amp;lt;FirstName&amp;gt;Sanjay&amp;lt;/FirstName&amp;gt;
  &amp;lt;LastName&amp;gt;Acharya&amp;amp;xxe;&amp;lt;/LastName&amp;gt;
&amp;lt;/Person&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
When an XML parser such as a SAX Parser reads the XML in, if running for example on a *NIX system will result in the loading of the contents of the /etc/passwd file into the contents of the resulting parsed document. If the same is returned to the person invoking the attack, well you can imagine their glee at accessing this sensitive data. &lt;br /&gt;
&lt;br /&gt;
The above XML read into a Person object would look like:&lt;br /&gt;
&lt;pre name="code" class="java"&gt;Person:Person [firstName=Donald, lastName=Duckroot:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
.........
couchdb:x:106:113:CouchDB Administrator,,,:/var/lib/couchdb:/bin/bash
haldaemon:x:107:114:Hardware abstraction layer,,,:/var/run/hald:/bin/false
speech-dispatcher:x:108:29:Speech Dispatcher,,,:/var/run/speech-dispatcher:/bin/sh
kernoops:x:109:65534:Kernel Oops Tracking Daemon,,,:/:/bin/false
saned:x:110:116::/home/saned:/bin/false
pulse:x:111:117:PulseAudio daemon,,,:/var/run/pulse:/bin/false
gdm:x:112:119:Gnome Display Manager:/var/lib/gdm:/bin/false
johndoe:x:1000:1000: John Doe,,,:/home/johndoe:/bin/bash
&lt;/pre&gt;&lt;br /&gt;
If the server program parsing the XML was running as root, then the attacker could also access the /etc/shadow file. Using External entity injection, the possibilities of retrieving sensitive information or creating a re-cursive failure and thus denial of service is definitely enticing for an attacker.&lt;br /&gt;
&lt;br /&gt;
Clearly the way to restrict this from happening is either to scan requests at the network level or follow a direction to strictly enforce which entities can be resolved. A strategy to combat the same is explained at &lt;a href="https://www.securecoding.cert.org/confluence/display/java/IDS10-J.+Prevent+XML+external+entity+attacks"&gt;Secure Coding&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Another option to consider is to provide a custom SAXParserFactory that will employ the EntityResolver mentioned in the SecureCoding site but is made available either for the entire VM or a particular module. One can employ a custom SAXParserFactory class by registering in a jaxp.properties file in the jre/lib directory or via META-INF/services of an individual module.&lt;br /&gt;
&lt;br /&gt;
An example of a Filtering SAX Parser Factory that could be employed using one of the above mentioned strategies is shown below. The factory delegates to the default factory to create a parser but then adds an EntityResolver to the parser before providing it back to the caller.&lt;br /&gt;
&lt;pre name="code" class="java"&gt;public class FilteringSaxParserFactory extends SAXParserFactory {
  // Delegate to this parser
  private SAXParserFactory delegate;
  
  // Delegate class
  private static final String DELEGATE_CLASS = "com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl";
  
  // Allowed Entity Paths
  private Set&amp;lt;String&amp;gt; allowedEntityPaths;
  
  public FilteringSaxParserFactory() {
    delegate = SAXParserFactory.newInstance(DELEGATE_CLASS, Thread.currentThread().getContextClassLoader());
    delegate.setNamespaceAware(true);
    delegate.setValidating(true);
    allowedEntityPaths = new HashSet&amp;lt;String&amp;gt;();
    allowedEntityPaths.add("/usr/local/entity/somefile");
  }
  
  @Override
  public boolean getFeature(String name) throws ParserConfigurationException,
    SAXNotRecognizedException,
    SAXNotSupportedException {
    return delegate.getFeature(name);
  }

  @Override
  public SAXParser newSAXParser() throws ParserConfigurationException, SAXException {
    SAXParser parser = delegate.newSAXParser();
    XMLReader xmlReader = parser.getXMLReader();
    xmlReader.setEntityResolver(new EntityResolver() {
      
      @Override
      public InputSource resolveEntity(String publicId, String systemId) throws SAXException,
        IOException {
        if (allowedEntityPaths.contains(systemId)) {
          return new InputSource(systemId);
        }
        
        // Return blank path to prevent untrusted entities
        return new InputSource();
      }
    });
    
    return parser;
  }
  ....
}
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;XML Bomb Attack:&lt;/b&gt;&lt;br /&gt;
Another form of an XML attack is whats known as an XML Bomb. The bomb is small XML fragment that makes the data provided grow exponentially during the parsing of the document thus leading to extensive memory consumption and thus room for a denial of service attack.&lt;br /&gt;
&lt;br /&gt;
Consider the following XML Bomb:&lt;br /&gt;
&lt;pre name="code" class="xml"&gt;&amp;lt;!DOCTYPE item[&amp;quot;
       &amp;lt;!ENTITY item &amp;quot;item&amp;quot;&amp;gt;
       &amp;lt;!ENTITY item1 &amp;quot;&amp;amp;item;&amp;amp;item;&amp;amp;item;&amp;amp;item;&amp;amp;item;&amp;amp;item;&amp;quot;&amp;gt;
       &amp;lt;!ENTITY item2 &amp;quot;&amp;amp;item1;&amp;amp;item1;&amp;amp;item1;&amp;amp;item1;&amp;amp;item1;&amp;amp;item1;&amp;amp;item1;&amp;amp;item1;&amp;amp;item1;&amp;quot;&amp;gt;
       &amp;lt;!ENTITY item3 &amp;quot;&amp;amp;item2;&amp;amp;item2;&amp;amp;item2;&amp;amp;item2;&amp;amp;item2;&amp;amp;item2;&amp;amp;item2;&amp;amp;item2;&amp;amp;item2;&amp;quot;&amp;gt;
       &amp;lt;!ENTITY item4 &amp;quot;&amp;amp;item3;&amp;amp;item3;&amp;amp;item3;&amp;amp;item3;&amp;amp;item3;&amp;amp;item3;&amp;amp;item3;&amp;amp;item3;&amp;amp;item3;&amp;quot;&amp;gt;
       &amp;lt;!ENTITY item5 &amp;quot;&amp;amp;item4;&amp;amp;item4;&amp;amp;item4;&amp;amp;item4;&amp;amp;item4;&amp;amp;item4;&amp;amp;item4;&amp;amp;item4;&amp;amp;item4;&amp;quot;&amp;gt;
       &amp;lt;!ENTITY item6 &amp;quot;&amp;amp;item5;&amp;amp;item5;&amp;amp;item5;&amp;amp;item5;&amp;amp;item5;&amp;amp;item5;&amp;amp;item5;&amp;amp;item5;&amp;amp;item5;&amp;quot;&amp;gt;
       &amp;lt;!ENTITY item7 &amp;quot;&amp;amp;item6;&amp;amp;item6;&amp;amp;item6;&amp;amp;item6;&amp;amp;item6;&amp;amp;item6;&amp;amp;item6;&amp;amp;item6;&amp;amp;item6;&amp;quot;&amp;gt;
       &amp;lt;!ENTITY item8 &amp;quot;&amp;amp;item7;&amp;amp;item7;&amp;amp;item7;&amp;amp;item7;&amp;amp;item7;&amp;amp;item7;&amp;amp;item7;&amp;amp;item7;&amp;amp;item7;&amp;quot;&amp;gt;
      ]&amp;gt;
      &amp;lt;item&amp;gt;
        &amp;lt;description&amp;gt;&amp;amp;item8;&amp;lt;/description&amp;gt;
        &amp;lt;price&amp;gt;500.0&amp;lt;/price&amp;gt;
        &amp;lt;quantity&amp;gt;1&amp;lt;/quantity&amp;gt;
       &amp;lt;/item&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
When attempting to Parse the above fragment, the SAX parser will stop (a feature introduced in &lt;a href="http://java.sun.com/j2se/1.4.2/relnotes.html"&gt;JDK 1.4.2&lt;/a&gt;)&lt;br /&gt;
with the following error:&lt;br /&gt;
&lt;pre name="code" class="java"&gt;javax.xml.bind.UnmarshalException
 - with linked exception:
[org.xml.sax.SAXParseException: The parser has encountered more than "64,000" entity expansions in this document; this is the limit imposed by the application.]
 at javax.xml.bind.helpers.AbstractUnmarshallerImpl.createUnmarshalException(AbstractUnmarshallerImpl.java:315)
 ... 26 more
&lt;/pre&gt;Note the fact that the parser complains about finding more than 64,000 entity expansions. The number of entity expansions is a property that can be controlled via "-DentityExpansionLimit".&lt;br /&gt;
&lt;br /&gt;
A lot of the above mentioned scenarios could be reduced by ensuring XSD validation and not using DTD's. DTD's can be totally prevented as well by setting the property "http://apache.org/xml/features/disallow-doc-type-decl" to true. If set, then any XML being parsed that has a DOC Type declaration will cause a fatal parsing error.&lt;br /&gt;
&lt;br /&gt;
An example demonstrating the XML exploits can be &lt;a href="http://home.comcast.net/~acharya.s/java/xmlinject.zip"&gt;downloaded HER&lt;/a&gt;E. Note that to witness the XXE injection, one would need to run the same on a *NIX system. The example provided does not upload private information and is only for demonstration purposes.&lt;br /&gt;
&lt;br /&gt;
Oh well, keeping this BLOG limited in content. Have not even looked into XPath XML injection. Quite interesting, I only wonder how many Web Services are out there where Tag injection exploits can be used on them. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Links I found of value:&lt;/b&gt;&lt;br /&gt;
&lt;a href="https://www.securecoding.cert.org/confluence/display/java/IDS10-J.+Prevent+XML+external+entity+attacks"&gt;1. Preventing External Entity Attacks&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.owasp.org/index.php/Testing_for_XML_Injection_(OWASP-DV-008)"&gt;2. Testing for XML Injection&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4667121987470696359-752712395713923974?l=sleeplessinslc.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OidcY/~4/HnbUnUUfHNI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sleeplessinslc.blogspot.com/feeds/752712395713923974/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4667121987470696359&amp;postID=752712395713923974" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/752712395713923974?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/752712395713923974?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OidcY/~3/HnbUnUUfHNI/xml-injection.html" title="XML Injection" /><author><name>Sanjay Acharya</name><uri>http://www.blogger.com/profile/01933976956977901677</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="28" src="http://3.bp.blogspot.com/-QuUnYIQQ4Ck/Txo3-4hza9I/AAAAAAAABBQ/QMZO-wT7v6A/s220/profile.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://sleeplessinslc.blogspot.com/2010/09/xml-injection.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkENQng9fip7ImA9WxFTFk0.&quot;"><id>tag:blogger.com,1999:blog-4667121987470696359.post-6289389161328090724</id><published>2010-04-06T20:33:00.005-06:00</published><updated>2010-04-06T20:51:33.666-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-06T20:51:33.666-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Spring BatchMessageListenerContainer" /><category scheme="http://www.blogger.com/atom/ns#" term="Message Proxy" /><category scheme="http://www.blogger.com/atom/ns#" term="Batch message consumption" /><category scheme="http://www.blogger.com/atom/ns#" term="JMS Batch" /><category scheme="http://www.blogger.com/atom/ns#" term="BatchMessageListenerContainer Spring" /><title>BatchMessageListenerContainer using Spring and MessageProxies</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/zAVSsMn41v-nABxUQy34b32xo50/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zAVSsMn41v-nABxUQy34b32xo50/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/zAVSsMn41v-nABxUQy34b32xo50/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zAVSsMn41v-nABxUQy34b32xo50/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;A few things I wanted to share on this BLOG. First is a way to Batch&amp;nbsp;consume messages using Spring's Listener Containers and the second&amp;nbsp;is an experiment on using Dynamic proxies to send messages and an application of the same.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span"&gt;1. Batch Message Listener:&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
When using the Spring Listener container, one typically consumes a&amp;nbsp;single message at a time. This works in most scenarios. There however&amp;nbsp;might be scenarios where consuming multiple messages and doing a task&amp;nbsp;in a batch might be more effecient. Clearly one way to ensure batching is&amp;nbsp;to have the message itself be an aggregation of multiple payloads that&amp;nbsp;one would need to process in batch. From a consumer perspective one can&amp;nbsp;process this single message as an atomic unit and either consume or reject&amp;nbsp;the same. Clearly this works if the producer of the messages can/will group&amp;nbsp;the messages together. Further this also means that the producer needs to&amp;nbsp;have understanding of the consumer needs regarding batch effeciency.&lt;br /&gt;
&lt;br /&gt;
What about another way of handling this scenario, where a Batch message listener is used. In this&amp;nbsp;proposal, one would receive X number of messages together as a unit and&amp;nbsp;process them all or roll back all. A Consumer can now choose to capitalize&amp;nbsp;on performance gains by batching the message. There is of course a cost as&amp;nbsp;far as the messaging system is concerned as it would need to hold onto&amp;nbsp;the messages in the batch as unprocessed as long as the JMS Transaction is active.&lt;br /&gt;
&lt;br /&gt;
I found that the &lt;a href="http://static.springsource.org/spring-batch/"&gt;spring-batch&lt;/a&gt; project had at one time a &lt;a href="http://static.springsource.org/spring-batch/apidocs/org/springframework/batch/container/jms/BatchMessageListenerContainer.html"&gt;BatchMessageListenerContainer&lt;/a&gt; that did some batching. I could not find the same in later versions&amp;nbsp;of the framework.&amp;nbsp;So I created one that does the same. It is based of the &lt;a href="http://static.springsource.org/spring/docs/2.0.8/api/org/springframework/jms/listener/DefaultMessageListenerContainer.html"&gt;DefaultMessageListenerContainer&lt;/a&gt; and has the following requirements of it:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;Receive at most X messages and process the same as a unit of work.&lt;/li&gt;
&lt;li&gt;If X messages cannot be received before a JMS Session time out, and only &lt;i&gt;X-dX&lt;/i&gt; messages have been received when the timeout occurs, then, &amp;nbsp;process&amp;nbsp;the&lt;i&gt; dX&lt;/i&gt; received messages even if it did not meet the batch size.&lt;/li&gt;
&lt;li&gt;Commit or rollback applies to the entire set of messages. What this means is if there is a bad message, in the bunch, then all messages part of the batch are rolled back.&lt;/li&gt;
&lt;li&gt;Only support JMS Transacted Sessions, not supporting User Transactions at this point. Should be easy though.&lt;/li&gt;
&lt;/ol&gt;&lt;br /&gt;
As the &lt;a href="http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/jms/listener/SessionAwareMessageListener.html"&gt;SessionAwareMessageListener&lt;/a&gt; from Spring does not have an signature&amp;nbsp;that supports multiple messages, I created one called&amp;nbsp;SessionAwareBatchMessageListener:&lt;br /&gt;
&lt;pre class="java" name="code"&gt;public interface SessionAwareBatchMessageListener&amp;lt;M extends Message&amp;gt;{
  /**
   * Perform a batch action with the provided list of {@code messages}.
   * 
   * @param session JMS {@code Session} that received the messages
   * @param messages List of messages to be processed as a unit of work
   * @throws JMSException JMSException thrown if there is an error performing the operation.
   */
  public void onMessages(Session session, List&amp;lt;M&amp;gt; messages) throws JMSException;
}
&lt;/pre&gt;&lt;br /&gt;
The &lt;i&gt;BatchMessageListenerContainer&lt;/i&gt; that I am demonstrating is an extension of the&amp;nbsp;&lt;i&gt;DefaultMessageListenerContainer&lt;/i&gt; and allows for the newly created listener.&amp;nbsp;Note that all this is possible due to beauty of the design of the Spring&amp;nbsp;code that allows for extensions.&lt;br /&gt;
&lt;br /&gt;
The container will receive messages until either the batch size is hit or&amp;nbsp;a JMS Session timeout occurs and dispatches the same to the listener to complete the&amp;nbsp;operation. The code for the same is bit verbose but shown in totality below:&lt;br /&gt;
&lt;pre class="java" name="code"&gt;public class BatchMessageListenerContainer extends DefaultMessageListenerContainer {
  public static final int DEFAULT_BATCH_SIZE = 100;
  private int batchSize = DEFAULT_BATCH_SIZE;

  public void setBatchSize(int batchSize) { this.batchSize = batchSize; }
  
  /**
   * The doReceiveAndExecute() method has to be overriden to support multiple-message receives.
   */
  @Override
  protected boolean doReceiveAndExecute(Object invoker, Session session, MessageConsumer consumer,
    TransactionStatus status) throws JMSException {
    Connection conToClose = null;
    MessageConsumer consumerToClose = null;
    Session sessionToClose = null;

    try {
      Session sessionToUse = session;
      MessageConsumer consumerToUse = consumer;
  
      if (sessionToUse == null) {
        Connection conToUse = null;
        if (sharedConnectionEnabled()) {
          conToUse = getSharedConnection();
        }
        else {
          conToUse = createConnection();
          conToClose = conToUse;
          conToUse.start();
        }
        sessionToUse = createSession(conToUse);
        sessionToClose = sessionToUse;
      }
      
      if (consumerToUse == null) {
        consumerToUse = createListenerConsumer(sessionToUse);
        consumerToClose = consumerToUse;
      }
      
      List&amp;lt;Message&amp;gt; messages = new ArrayList&amp;lt;Message&amp;gt;();

      int count = 0;
      Message message = null;
      // Attempt to receive messages with the consumer
      do {
        message = receiveMessage(consumerToUse);
        if (message != null) {
          messages.add(message);
        }
      }
      // Exit loop if no message was received in the time out specified, or
      // if the max batch size was met
      while ((message != null) &amp;amp;&amp;amp; (++count &amp;lt; batchSize));

      if (messages.size() &amp;gt; 0) {
        // Only if messages were collected, notify the listener to consume the same.
        try {
          doExecuteListener(sessionToUse, messages);
          sessionToUse.commit();
        }
        catch (Throwable ex) {
          handleListenerException(ex);
          if (ex instanceof JMSException) {
            throw (JMSException) ex;
          }
        }
        return true;
      }

      // No message was received for the period of the timeout, return false.
      noMessageReceived(invoker, sessionToUse);
      return false;
    }
    finally {
      JmsUtils.closeMessageConsumer(consumerToClose);
      JmsUtils.closeSession(sessionToClose);
      ConnectionFactoryUtils.releaseConnection(conToClose, getConnectionFactory(), true);
    }
  }

  protected void doExecuteListener(Session session, List&amp;lt;Message&amp;gt; messages) throws JMSException {
    if (!isAcceptMessagesWhileStopping() &amp;amp;&amp;amp; !isRunning()) {
      if (logger.isWarnEnabled()) {
        logger.warn("Rejecting received messages because of the listener container "
          + "having been stopped in the meantime: " + messages);
      }
      rollbackIfNecessary(session);
      throw new JMSException("Rejecting received messages as listener container is stopping");
    }

    @SuppressWarnings("unchecked")
    SessionAwareBatchMessageListener&amp;lt;Message&amp;gt; lsnr = (SessionAwareBatchMessageListener&amp;lt;Message&amp;gt;) getMessageListener();

    try {
      lsnr.onMessages(session, messages);
    }
    catch (JMSException ex) {
      rollbackOnExceptionIfNecessary(session, ex);
      throw ex;
    }
    catch (RuntimeException ex) {
      rollbackOnExceptionIfNecessary(session, ex);
      throw ex;
    }
    catch (Error err) {
      rollbackOnExceptionIfNecessary(session, err);
      throw err;
    }
  }
  
  @Override
  protected void checkMessageListener(Object messageListener) {
    if (!(messageListener instanceof SessionAwareBatchMessageListener)) {
      throw new IllegalArgumentException("Message listener needs to be of type ["
        + SessionAwareBatchMessageListener.class.getName() + "]");
    }
  }
 
  @Override
  protected void validateConfiguration() {
    if (batchSize &amp;lt;= 0) {
      throw new IllegalArgumentException("Property batchSize must be a value greater than 0");
    }
  }
}
&lt;/pre&gt;There is a demonstration example in the code attached which shows how messages can be received in batch and processed on the consumer.&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span"&gt;&lt;b&gt;&lt;span class="Apple-style-span"&gt;2. Proxy pattern for JMS Messaging Sending&lt;/span&gt;&lt;span class="Apple-style-span"&gt;:&lt;/span&gt;&lt;/b&gt;&lt;/span&gt; &lt;br /&gt;
Recently I have been seeing quite a few REST Clients that support a&amp;nbsp;Proxy pattern and wanted to experiment to see whether the same can be&amp;nbsp;applied to JMS as well.&lt;br /&gt;
&lt;br /&gt;
The RESTful system has some similarities with JMS:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;&amp;nbsp;Resource location can be compared to JMS Destination&lt;/li&gt;
&lt;li&gt;&amp;nbsp;Mime type can be compared to JMS Message Type&lt;/li&gt;
&lt;/ol&gt;So if we defined a couple of annotations, one for Destination JNDI and a second for MessageType, a proxy interface could look like the following:&lt;br /&gt;
&lt;pre class="java" name="code"&gt;public interface MessageSender {
    @DestinationJndi("com.welflex.barqueue")
    @MessageType(ObjectMessage.class)
    public void sendObjectMessage(String s);

    @DestinationJndi("com.welflex.baz.queue")
    @MessageType(TextMessage.class)
    public void sendStringMessage(String s);

    @DestinationJndi("com.welflex.boo.queue")
    @MessageType(MapMessage.class)
    public void sendMapMessage(Map&amp;lt;String, Object&amp;gt; map);
  }
&lt;/pre&gt;We could then create a Proxy based of the above interface and send messages as shown below:&lt;br /&gt;
&lt;pre class="java" name="code"&gt;public void testMethod() {
    SendExecutor executor = new ActiveMQSendExecutor("vm://localhost", "foo", "bar");
    MessageSender s = ProxyFactory.create(MessageSender.class, executor);
    s.sendObjectMessage("Foo");
    s.sendStringMessage("Bar");
    
    Map&amp;lt;String, Object&amp;gt; m = new HashMap&amp;lt;String, Object&amp;gt;();

    m.put("name", "Sanjay");
    m.put("age", 23);
    m.put("salary", 12313131.213F);    

    s.sendMapMessage(m);  
}  
&lt;/pre&gt;I am not explaining the details of how the proxy is created as the same is available in the downloadable example. One can easily swap out the &lt;i&gt;ActiveMQSendExecutor&lt;/i&gt; with a &lt;i&gt;WebLogicSendExecutor&lt;/i&gt;, &lt;i&gt;OpenJMSSendExecutor&lt;/i&gt; or any other JMS Provider implementation. &lt;br /&gt;
&lt;br /&gt;
So there are many questions that arise with the above:&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;What about controlling the message properties? Well, the same applies to header properties that one would need to handle with REST Proxy clients. One can define an execution interceptor to provide the same :-)&lt;/li&gt;
&lt;li&gt;JMS is so simple; is another layer of abstraction really worth it? Well I agree, mostly, but if all a client needs to do is send a particular type of message and we can abstract away the boiler plate why not? Sure there is some initial development in creating the send executors. Once done with the same, its as easy as annotating an interface and dispatching :-)&lt;/li&gt;
&lt;li&gt;What about bytes message and other types? Have not handled the same.&amp;nbsp;&lt;/li&gt;
&lt;/ol&gt;Clearly there are more questions here. The above is just one of my Frankenstein experiments that I thought I'd share :-)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span"&gt;3. Examples:&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
Examples that utilize the above code are available in the provided example. A sample batch consumer is demonstrated that persists Person entries to a HSQL database using Hibernate. The batch size of messages consumed is 200 at a time and on every hundred records, Hibernate flushes the session.&lt;br /&gt;
&lt;br /&gt;
Examples of the Proxy class usage is also demonstrated for sending different types of messages.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://home.comcast.net/~acharya.s/java/messageproxy.zip"&gt;Download a Maven Example from HERE.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4667121987470696359-6289389161328090724?l=sleeplessinslc.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OidcY/~4/uEQu5e1vUpE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sleeplessinslc.blogspot.com/feeds/6289389161328090724/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4667121987470696359&amp;postID=6289389161328090724" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/6289389161328090724?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/6289389161328090724?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OidcY/~3/uEQu5e1vUpE/batchmessagelistenercontainer-using.html" title="BatchMessageListenerContainer using Spring and MessageProxies" /><author><name>Sanjay Acharya</name><uri>http://www.blogger.com/profile/01933976956977901677</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="28" src="http://3.bp.blogspot.com/-QuUnYIQQ4Ck/Txo3-4hza9I/AAAAAAAABBQ/QMZO-wT7v6A/s220/profile.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://sleeplessinslc.blogspot.com/2010/04/batchmessagelistenercontainer-using.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0AAQH0-cCp7ImA9WxBbGEo.&quot;"><id>tag:blogger.com,1999:blog-4667121987470696359.post-3905943738979298172</id><published>2010-03-16T21:36:00.005-06:00</published><updated>2010-03-17T18:22:21.358-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-17T18:22:21.358-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Debugging Memory" /><category scheme="http://www.blogger.com/atom/ns#" term="MAT Eclipse" /><category scheme="http://www.blogger.com/atom/ns#" term="Java Memory Leaks Usual Suspects" /><category scheme="http://www.blogger.com/atom/ns#" term="Visual VM" /><category scheme="http://www.blogger.com/atom/ns#" term="Java Memory Leaks" /><title>Sanjay in Memory Land - Java Memory Leaks and Tools for Detection</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/HfD9Zk3erVdCOPVKo5AT_NdokPA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HfD9Zk3erVdCOPVKo5AT_NdokPA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/HfD9Zk3erVdCOPVKo5AT_NdokPA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/HfD9Zk3erVdCOPVKo5AT_NdokPA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Finally, something to write about apart from REST and JMS :-). Tim Burton's  Alice in Wonderland has been released and I am anxious to take my kids to the same, till then this BLOG can serve to curb my fantasies :-)&lt;br /&gt;
&lt;br /&gt;
Java has garbage collection right? So can a program developed in Java have a memory leak? Isn't this one the favorite questions of interviewers? In this BLOG I would like to capture information about JVM leaks, diagnosis and how to fix/prevent the same. As always, if this helps someone, great, else it will help me at some point in the future as reference material ;-)&lt;br /&gt;
&lt;br /&gt;
Life is wonderful, the application we have been working for months has been deployed, deadlines have been met, cheers have been exchanged at the local hangout. All of a sudden, a call on your phone, a person from the network and operations teams with bad news to bear. "&lt;b&gt;&lt;i&gt;Your app just crashed with an OutOfMemory error.&lt;/i&gt;&lt;/b&gt;" Shxx!  Think of this more as a preparation for the inevitable, everyone needs to meet their NOC person while they are pissed at some time or another :-).&lt;br /&gt;
&lt;br /&gt;
So what could have happened? Before getting into the same, some insight on JVM memory and the types of References is a must. I could get into the same but it would be rather redundant as a    &lt;a href="http://blog.codecentric.de/en/2010/01/java-outofmemoryerror-1-akt-das-java-memory-modell-stellt-sich-vor/"&gt;very nice article explaining the same by Mirko Novakovic&lt;/a&gt; is available on the code centric blog. It is a must read prior to continuing with this BLOG. Please familiarize yourselves with the different generations and memory model. The following figure will serve to help with the different areas of memory available:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;In the above shown figure:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_SqKefSIXc5Y/S6A9lLFZpoI/AAAAAAAAAmE/C1pYCj19Wzs/s1600-h/spaces.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="82" src="http://4.bp.blogspot.com/_SqKefSIXc5Y/S6A9lLFZpoI/AAAAAAAAAmE/C1pYCj19Wzs/s640/spaces.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;EDEN is the place where all objects are created&lt;/li&gt;
&lt;li&gt;SS0 and SS1 are survivor spaces where objects are promoted to&lt;/li&gt;
&lt;li&gt;OLD represents Old Gen for long living objects that have survived many GC cycles&lt;/li&gt;
&lt;li&gt;PERM &amp;nbsp;is PERM Space where Class and Static information lies&lt;/li&gt;
&lt;/ul&gt;One topic that requires a brief mention for completeness is the different Reference Types in Java. &amp;nbsp;I would definitely recommend a read of &lt;a href="http://weblogs.java.net/blog/enicholas/archive/2006/05/understanding_w.html"&gt;Understanding Weak References &amp;nbsp;by Ethan Nicholas&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Reference Types:&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;1. Strong Reference:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
A Strong reference is your regular reference that you use all the time. For example &lt;i&gt;Integer number = new Integer(230)&lt;/i&gt;; Number is strong reference to an object on the heap. &amp;nbsp;During development we are typically dealing with strong references.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://java.sun.com/javase/7/docs/api/java/lang/ref/WeakReference.html"&gt;&lt;b&gt;2. Weak Reference:&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
A Weak Reference is not as strong as the "Strong Reference". Duh, Obviously! A Weak Reference to an object does not prevent it from being garbage collected. In other words, if a reference to an Object is only a "Weak Reference" to it, then the same is eligibile for garbage collection. &lt;br /&gt;
&lt;br /&gt;
For example, in the figure shown below, Object A is not eligible for GC as there is a strong reference to it:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_SqKefSIXc5Y/S5sPBLuPdnI/AAAAAAAAAlM/3cwmiJ8qZrY/s1600-h/weakrefnotelig.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="166" src="http://1.bp.blogspot.com/_SqKefSIXc5Y/S5sPBLuPdnI/AAAAAAAAAlM/3cwmiJ8qZrY/s400/weakrefnotelig.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;However, if you look at the following figure you will notice that Object A only has a WeakReference to it thus making Object A eligible for garbage collection:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_SqKefSIXc5Y/S5sPW76lBdI/AAAAAAAAAlU/-epkT802-aQ/s1600-h/weakrefelig.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="175" src="http://2.bp.blogspot.com/_SqKefSIXc5Y/S5sPW76lBdI/AAAAAAAAAlU/-epkT802-aQ/s400/weakrefelig.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;One implementation of a WeakReference in &lt;i&gt;java.util&lt;/i&gt; is the &lt;a href="http://java.sun.com/javase/7/docs/api/java/util/WeakHashMap.html"&gt;WeakHashMap&lt;/a&gt;. In the case of the WeakHashMap, the keys are Weak and values are not. If a key of the map loses its object to garbage collection, then the key is considered reclaimed as well. WeakHashMaps tend to work well when using the Listener or Observer pattern. Many a time we add a listener and never deregister the same. One important thing to keep in mind is that the WeakReferences are &lt;b&gt;NOT&lt;/b&gt; Serializable as it is possible that the objects contained could vanish due to garbage collection occurring.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://java.sun.com/javase/7/docs/api/java/lang/ref/SoftReference.html"&gt;&lt;b&gt;3. Soft Reference:&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
A soft reference is very much like the WeakReference, however the Garbage collector is less likely to throw the object referenced by the Soft Reference away. Weakly referenced objects will be collected by the GC, however as long as the memory is available, Soft References continue to exist. The same makes them excellent for Caches.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://java.sun.com/javase/7/docs/api/java/lang/ref/PhantomReference.html"&gt;&lt;b&gt;4. Phantom Reference:&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Unlike the Weak and SoftReference who exhibit similar behavior only separated by timing and need, the Phantom Reference is totally a different beast. Note that the javadoc on the PhantomReference states that the get() method always returns null. The primary use of such a reference is only to determine when it gets enqueued into a reference queue. One rarely would find the need to use PhantomReferences and therefore I am not going to discuss them further.&lt;br /&gt;
&lt;br /&gt;
Now that we have looked at Reference Types in Java, lets move onto a popular question asked by interviewers.  "&lt;i&gt;An Object A has a reference to Object B and Object B has a reference to Object C which has a reference to Object A. Due to the circuilarity do we have a memory leak?&lt;/i&gt;" &lt;br /&gt;
Well, I do not think that cyclic references are necessarily great but just because a circular reference exists, it does not mean we have a leak present. Consider the following figure:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_SqKefSIXc5Y/S5ry6ksKvgI/AAAAAAAAAks/-pQc9uX1S7g/s1600-h/gcroot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="238" src="http://1.bp.blogspot.com/_SqKefSIXc5Y/S5ry6ksKvgI/AAAAAAAAAks/-pQc9uX1S7g/s400/gcroot.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;In the scenario mentioned above, Objects A, B and C cannot be garbage collected as long as there is at least one ROOT reference to one of the objects. &amp;nbsp;Object A and Object B have ROOT references to them. I like to think of ROOT references as Spring or Wires that are holding the objects in memory by the JVM. If all of the springs attached to the objects are dropped, then the object and its connected graph have no ability to survive. It does not matter how many interconnection they possess, if all root references to the object are gone, the graph is eligible for collection as shown below:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/_SqKefSIXc5Y/S5rzPeU4AVI/AAAAAAAAAk0/_Z4nPmhDZSY/s1600-h/gc.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="220" src="http://2.bp.blogspot.com/_SqKefSIXc5Y/S5rzPeU4AVI/AAAAAAAAAk0/_Z4nPmhDZSY/s400/gc.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
When using memory analyzer tools, you will hear the term GC Root. One of the popular analyzer tools, Yourkit has this definition of the GCRoot and the types of GC Roots:&lt;br /&gt;
"&lt;i&gt;The so-called GC (Garbage Collector) roots are objects special for garbage collector. Garbage collector collects these objects that are not GC roots and are not accessible by references from GC roots. There are several kinds of GC roots. One object can belong to more than one kind of roo&lt;/i&gt;t. " - &lt;a href="http://www.yourkit.com/docs/net45/help/gc_roots.jsp"&gt;Yourkit Site&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Some other terms, I would like to familiarize you with is the Dominator and the and Dominator tree. Both sound powerful, I think of bosses when I hear this, whether at home or work ;-). An object is considered a dominator of another object, if and only iff, it has the sole reference to the dominated object. Consider the figure shown below:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_SqKefSIXc5Y/S5r7DwTJ41I/AAAAAAAAAlE/XqENfiQnOpQ/s1600-h/dominator.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="337" src="http://1.bp.blogspot.com/_SqKefSIXc5Y/S5r7DwTJ41I/AAAAAAAAAlE/XqENfiQnOpQ/s400/dominator.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;In the figure shown above, object B is the dominator of object D. However, B and C cannot be considered the dominator's of E as they both have references to E. Object C on the other hand is the dominator of F and G.  Dominator's are important in memory analysis as, if all reference to a dominator are removed then the entire dominator tree becomes available for garbage collection. For example, if reference to C is removed, then the graph of objects, C, F and G are all eligible for garbage collection. &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;My 2c on how Garbage Collection works:&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Garbage collection involves heap walking from GC Roots. A Mark-Sweep algorithm will mark objects objects that are eligible for collection with the Sweep part picking up the same. &lt;br /&gt;
&lt;br /&gt;
GC's are typically classified as minor and major. A minor gc is typically invoked when &lt;i&gt;Eden&lt;/i&gt; space gets filled and the collector sweeps through eden and survivor spaces while promoting objects that have survived some gc cycles older generations. Minor GC's are rapid and hardly interfere with the VM functioning.&lt;br /&gt;
&lt;br /&gt;
Major GC's are invoked when Old Gen starts accumulating objects and growing. All spaces are&lt;br /&gt;
collected when a major GC runs. Note that Perm Gen will also be collected during a major GC. When a major GC occurs, other activities of the JVM get suspended. In other words, its a stop the world event of sorts. &lt;br /&gt;
&lt;br /&gt;
One can get information on Garbage collection using the following flags to the JVM on startup.&lt;br /&gt;
&lt;pre name="code"&gt;-XX:+PrintGC Print messages at garbage collection. 
-XX:+PrintGCDetails Print more details at garbage collection. 
-XX:+PrintGCTimeStamps Print timestamps at garbage collection.
&lt;/pre&gt;An example output of the above is:&lt;br /&gt;
&lt;pre name="code"&gt;3.480: [Full GC [PSYoungGen: 44096K-&amp;gt;25531K(88704K)] [PSOldGen: 139579K-&amp;gt;158080K(220608K)] 183675K-&amp;gt;183611K(309312K) [PSPermGen: 1700K-&amp;gt;1700K(16384K)], 0.8611160 secs] 
[Times: user=0.76 sys=0.08, real=0.86 secs] 
4.504: [Full GC [PSYoungGen: 44608K-&amp;gt;0K(88704K)] [PSOldGen: 190848K-&amp;gt;218908K(287680K)] 235456K-&amp;gt;218908K(376384K) [PSPermGen: 1700K-&amp;gt;1700K(16384K)], 1.3089360 secs] 
[Times: user=1.19 sys=0.12, real=1.31 secs] 
5.862: [GC [PSYoungGen: 44608K-&amp;gt;44672K(100992K)] 263516K-&amp;gt;263580K(388672K), 0.2592090 secs] [Times: user=0.50 sys=0.00, real=0.26 secs] 
6.169: [GC [PSYoungGen: 89280K-&amp;gt;56384K(112896K)] 308188K-&amp;gt;308364K(400576K), 0.5695990 secs] [Times: user=0.95 sys=0.07, real=0.57 secs] 
6.739: [Full GC [PSYoungGen: 56384K-&amp;gt;20609K(112896K)] [PSOldGen: 251980K-&amp;gt;287680K(338624K)] 308364K-&amp;gt;308289K(451520K) [PSPermGen: 1700K-&amp;gt;1700K(16384K)], 2.3075900 secs] 
[Times: user=1.52 sys=0.18, real=2.31 secs] 
&lt;/pre&gt;With the above information, let us look at some of the usual suspects of memory leaks:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;The Usual Leak Suspects:&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/en/9/9c/Usual_suspects_ver1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://upload.wikimedia.org/wikipedia/en/9/9c/Usual_suspects_ver1.jpg" width="268" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;1. The HTTP Session when Working with Web Applications memory:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
The HTTP Session object is one place that is often abused as storage area for user information. It is often used as a dumpster of information that lives beyond the scope of a single request. Request state, data that survives more than a single call, i.e., conversational state. Another common scenario is when the HttpSession is used as a cache of sorts, where data once read for a user session is stored for the life time of the user session.  Sometimes these Sessions are specified to be kept alive for a very long period of time. In cases mentioned above, the data in the sessions linger and hold references to object graphs for extended periods of time. If there are a number of sessions involved, it's simple enough to do the math for the memory footprint.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;2. Class Static References:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Classes that have static variables such as maps and lists that are often populated with information but never cleaned up. Classes find themselves placed in Perm Gen and these will last as long as their class loader is referencing them. Sometimes, like in the case of the HTTP Session, objects are placed onto these static collections and never removed thus growing the heap.&lt;br /&gt;
&lt;pre class="java" name="code"&gt;public class MyStatic {
   private static final Map&amp;lt;String, Object&amp;gt; data = new HashMap&amp;lt;String, Object&amp;gt;();
   private MyStatic() {}
   public void add(String key, Object val) { data.put(key, val);}
   public Object get(String key) {return data.get(key);}
}
&lt;/pre&gt;&lt;br /&gt;
&lt;a href="http://java.sun.com/javase/7/docs/api/java/lang/ThreadLocal.html"&gt;&lt;b&gt;3. Thread Local:&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
The ThreadLocal pattern has some benefits where data is placed in a ThreadLocal by one method to be accessible other methods on the thread. If this data is however not cleared out upon completing the operation with the thread and the thread itself if pooled, leaks start appearing.&lt;br /&gt;
This is a common scenario one would find when dealing with a Web Application where a ThreadLocal  storage is used for one reason or another. The threads in the container are pooled so after the execution of one request the thread is restored back to the pool. If the data placed in the ThreadLocal is not cleared after the execution of the request, it will continue to linger. As a best practice, I would recommend that you clear the same.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;4. Object Pooling:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Object Pooling is one pattern that needs to be handled with care. In earlier days of the JVM, people tended to pool the objects to benefit from performance gains. Performance gains of Object Pooling are highly questionable with current JVM optimizations. Objects that are pooled tend to make it to Old Gen by surviving many garbage collection cycles and linger there as there are strong references to the same. Note that this even effects GC times as if one has Young Gen objects that have references to these old Gen Objects. Pooling really expensive resources such as Database connections, JMS artifacts might be a good idea. In general however, pooling regular objects could prove detrimental rather than beneficial. I would recommend being wary of Object Pooling.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;5. Not closing expensive objects:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Objects like connections tend to hold onto other expensive artifacts like Sockets and Streams. These objects usually have a &lt;i&gt;close&lt;/i&gt;() method to relieve the resources allocated. If not releived and the top level object is in Old Gen for example, then until a full GC occurs, these would tend to linger. Some resources tend to keep file handles open, often leading to exhaution of the same. Maybe some of you have witnessed the "&lt;i&gt;Too many open file handles&lt;/i&gt;" error? &lt;br /&gt;
&lt;br /&gt;
For example, I recently ran into a case where we did not run out of JVM memory but as resources were not being released until GC kicked in, file system handles related to Sockets were held on resulting in exhaustion of the same from the perspective of the file system.  As a tip, if one runs out of file handles when on a *Nix environment, consider using &lt;a href="http://en.wikipedia.org/wiki/Lsof"&gt;lsof&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Netstat"&gt;netstat&lt;/a&gt; if the symptoms point to network based file handles to determine what is happening. The case mentioned might be of system resources being exhausted and not the JVM memory, however IMO they are indicative of a significant destructive leak.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;6. Interned String in the Perm Gen:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
One pattern used since long before is to call &lt;i&gt;intern&lt;/i&gt;() on Strings. &lt;a href="http://mindprod.com/jgloss/interned.html"&gt;Read more about the same at mindprod&lt;/a&gt;. Interning a String results in it making its way into Perm Gen. The &lt;i&gt;java.lang.String&lt;/i&gt; class maintains a pool of strings. When the &lt;i&gt;intern&lt;/i&gt;() method is invoked, the method checks the pool to see if an equal string is already in the pool. If there is, then the intern method returns it; otherwise it adds the string to the pool.&lt;br /&gt;
&lt;br /&gt;
Some XML parsers in particular tend to &lt;i&gt;intern&lt;/i&gt;() strings in an attempt to optimize. A large amount of interned Strings however will be detected in a memory dump where you can view the Perm Gen. Note that &lt;i&gt;interned&lt;/i&gt;() strings will be garbage collected, however, they do add to the Perm gen footprint.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;7. Badly referenced Anonymous Classes:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Anonymous classes are often used to exchange blocks of code between objects. One truth about the Anonymous class is that it has a reference to the instance that created it thus ensuring that as long as the anonymous class has a Root reference to it, the parent object cannot be garbage collected. A common case of this is the registering of listeners to an object that are never de-registered as listeners when no longer required. &lt;br /&gt;
&lt;pre class="java" name="code"&gt;public class A {
  public void someMethod(B b) {
    b.register(new Runnable() {
      public void run() {
        ...
      }
    });
  }
}
public class B {
  private final List Runnable&amp;gt; runnables = new ArrayList&amp;lt;Runnable&amp;gt;();
  public void register(Runnable r) {
    runnables.add(r);
  }
}
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;8. Proxy Classes in Perm Gen:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Frameworks such as &lt;a href="http://cglib.sourceforge.net/"&gt;cglib&lt;/a&gt;, &lt;a href="http://www.csg.is.titech.ac.jp/~chiba/javassist/"&gt;javassist&lt;/a&gt; etc are used to generate Proxy classes. These Proxy Classes find themselves into Perm Gen and too many of these being generated lead to Perm Gen out of memory errors. Perm Gen, &lt;b&gt;lets just bump it up and the problem will go away.&lt;/b&gt; Sure that works some times, especially when your code has changed loading a lot more classes, but there are times when it will only come back to haunt you. For example, we recently encountered a case where classes were dynamic ones which were being generated with the instantiation of a particular object every time, this was an incorrect use of the API but the result was increased use of Perm Gen due to the proliferation of proxy classes. Increasing the PermGen might have cured the problem but only temporarily until further further instantiation of the object would have resulted in more classes being put into Perm Gen and a JVM fatality. As an example, with the bad method (uses javassist) shown below, where classes are constantly being created in Perm Gen, repeated invocation of this bad method will cause the perm gen to grow: &lt;br /&gt;
&lt;pre class="java" name="code"&gt;public SomeClass createInstanceOfSomeClass() {
  ProxyFactory f = new ProxyFactory();
  f.setSuperclass(SomeClass.class);
  MethodHandler mi = new MethodHandler() {
     public Object invoke(Object self, Method m, Method proceed,
      Object[] args) throws Throwable {
        return proceed.invoke(self, args);  // execute the original method.
     }
  };
  f.setFilter(new MethodFilter() {
    public boolean isHandled(Method m) {
     return !m.getName().equals("finalize");
    }
  });

  Class&amp;lt;?&amp;gt; c = f.createClass();
  SomeClass p = (SomeClass) c.newInstance();
 ((ProxyObject) p).setHandler(mi);
  return p;
}
&lt;/pre&gt;As an example of Perm gen could grow, see the graph below of the same with the end result being runing out of Perm Gen and receiving the nasty message about the same:&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_SqKefSIXc5Y/S5xZKHbJiAI/AAAAAAAAAlc/sMhPaiKhxJA/s1600-h/Screenshot.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;&lt;img border="0" height="331" src="http://4.bp.blogspot.com/_SqKefSIXc5Y/S5xZKHbJiAI/AAAAAAAAAlc/sMhPaiKhxJA/s640/Screenshot.png" width="640" /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;9. Freak Load or Query:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
During your testing you have followed the standard path with regards to load, be it loading data from a database or parsing an XML file into a DOM tree, what have you. Ever so often, there is a freak scenario that you have not expected that spikes the memory so badly that you run out of memory. Some of these cases are when a badly designed query leads to the loading of a large amount of data into the heap or a file is uploaded for which you are building an XML DOM Tree that is gigantic. These are examples of large dominator tree's that will definitely consume your heap. Always consider the case of extreme's during your design and development. In particular, ask yourself questions such as; "&lt;i&gt;What if some one uploads a bad file?&lt;/i&gt;" or  "&lt;i&gt;What will happen to this query as it is not bounded or paged and subsequently a large result set is loaded?&lt;/i&gt;"&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;10. Other Cases:&lt;/b&gt;&lt;br /&gt;
There are definitely more cases than the above mentioned. For example, J2EE containers that do no unload classes correctly, and hot deploy's increasing Perm Gen as a result. &amp;nbsp;Your cases will be unique and I would love to hear about the same.&lt;br /&gt;
&lt;br /&gt;
Anyway, as an developer or Architect the following are what I feel one can benefit from, please note the same&amp;nbsp;are not rules or musts but some personal recommendations based of my experiences.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Memory Leak Detection and Analysis:&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;1. Defensive Development:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
When developing code, always keep thinking of how an object you create is going to be used. When working with large data sets, think of accidental or one of cases which could load considerable data into your memory. Consider always limiting your loaded data to definite bounds with paging.  Pick what data you need. When working with XML, consider whether you need to load an entire DOM tree or use STAX. Consider tools like Find Bugs to detect unnecessary circularities in your code.&lt;br /&gt;
&lt;br /&gt;
I would recommend always questioning a variable that is added to an object and its purpose. Does the class really need to be stateful in the context or can it be stateless? Will this class be used by multiple threads at the same time? I am not advocating that classes that have state are bad, that would be quite agaisnt my O-O beliefs :-), I am only asking you to question "how" the same at runtime by your library or by others using your library would be used. In addition, a pattern that every developer knows and a favorite answer on an interview question, "&lt;i&gt;What patterns have you used?&lt;/i&gt;"; is often the &lt;b&gt;singleton&lt;/b&gt;. Singletons often serving to act as a store or cache of data should be questioned and their proliferation controlled as they live for the lifetime of the VM unless explicitly unloaded and can acheive dumpster status. Singletons are &lt;b&gt;NOT&lt;/b&gt; necessarily EVIL, I use them all the time at work. It is however possible for them to be misused, example a singleton that has a Map of key value pairs whose information keeps growing over time, clearly you have something to think about here. The same applies if you are using a Dependency container like spring and design objects to have singleton scope rather than prototype scope.&lt;br /&gt;
&lt;br /&gt;
Also watch for the HTTP Session and what goes in there.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;2. Active Monitoring:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Clearly detecting early is the way to go. Monitor your application once deployed, err, actually even before. One has many tools at ones disposal to obtain information as to how your application behaves with memory.&lt;br /&gt;
&lt;br /&gt;
Waiting till production only to find a memory leak is not desirable by any means. Baking in memory profiling as part of your releases would be great. &lt;br /&gt;
&lt;br /&gt;
Set up monitoring at all possible places of your application. For HttpSession issues, consider having a &lt;a href="http://adderpit.com/jdk/j2eedocs/api/javax/servlet/http/HttpSessionAttributeListener.html"&gt;HttpSessionAttributeListener&lt;/a&gt; that monitors the objects added to the HttpSession and displays the same. One can easily use a decorator such as &lt;a href="http://www.opensymphony.com/sitemesh/"&gt;sitemesh&lt;/a&gt; for dev with a flag turned on to display the same. In fact a former colleague of mine had implemented the same to actively detect memory issues. When in different test environments and production, make sure you have alert thresholds setup to notify you regarding memory problems. If in a test environment, have your testers run Visual VM and keep an eye on the graph as they perform their tests. The testers do not need to be skilled in memory management, wouldn't hurt if they are :-), but only trained in the trends indicative of abnormal memory patterns.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;3. Post Mortem or Post Traumatic Evaluation:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
So you have all the bases covered, tested the stuff the best you can but find an OOM in production. What should you do? Roll back to the previous version that did not have the error? Sure if you can, but it would be better if you can determine the problem prior to doing the same. &lt;br /&gt;
&lt;br /&gt;
One question to ask, did you have the flag "&lt;i&gt;-XX:+HeapDumpOnOutOfMemoryError&lt;/i&gt;"?  When the flag is enabled, upon a Heap OOM, one automatically gets a dump.  The flag does not affect your runtime performance so it is benign.&lt;br /&gt;
&lt;br /&gt;
A first reaction might be just to bump up the memory on the VM an re-start. However, note that the same might work in certain cases while only delaying the inevitable on some others. &lt;br /&gt;
&lt;br /&gt;
It is very important to determine the type of error you find and use memory analyzer tools to determine the offending problem. If you have the option of getting heap dump snapshots do the same and compare and detect dominator tree's, whats in perm gen etc. Sampling, sampling, sampling! When getting any data, consider getting the same at different intervals for sampling. The same can really help in detecting changes in the memory over time.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Free Tools to help with your memory analysis:&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://visualvm.dev.java.net/"&gt;&lt;b&gt;1. Visual VM&lt;/b&gt;&lt;/a&gt;:&lt;br /&gt;
Visual VM is a visual interface for viewing, troubleshooting and profiling applications running on a JVM. Many of the previous stand alone tools like JConsole, jstat, jstack, jmap are part of the tool. In addition, the tool is built to support plugins for extensions and support. I have found visualvm a great tool to view the memory, take snapshots and compare the same. Visual vm is now also part of the JDK. The following for example represents a graph from visualvm that demonstrate the ever increasing Old Gen that leads to an eventual Out of Memory.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_SqKefSIXc5Y/S57whqO-N6I/AAAAAAAAAl0/XQLYccbenfU/s1600-h/visualvm.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="255" src="http://1.bp.blogspot.com/_SqKefSIXc5Y/S57whqO-N6I/AAAAAAAAAl0/XQLYccbenfU/s400/visualvm.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;a href="http://www.eclipse.org/mat"&gt;&lt;b&gt;2. MAT&lt;/b&gt;&lt;/a&gt;:&lt;br /&gt;
Eclipse MAT is a memory analyzer tool from the eclipse community. A stand alone version and a plugin for eclipse are available. This is really great tool for analyzing heap dumps. It is extremely fast in parsing a heap dump and providing valuable reports. In particular some of these reports help diagnose leak suspects for you as well. For example consider the following bad program where a map is constantly being added to and grows over time. Actually this is the same code that generated the Old Gen accumulation graph in the previous figure of visual vm:&lt;br /&gt;
&lt;pre class="java" name="code"&gt;public class StaticHolder {
  private static final StaticHolder instance = new StaticHolder();
  private Map&amp;lt;Integer, Integer&amp;gt; map = new HashMap&amp;lt;Integer, Integer&amp;gt;();
  private StaticHolder() {}
  public static StaticHolder instance() {
    return instance;
  }
  
  public void add(Integer key, Integer value) {
    map.put(key, value);
  }

  public static void main(String args[]) throws InterruptedException {
    for (int i = 0; i &amp;lt; 10000000; i++) {
     StaticHolder.instance().add(i, i);
     Thread.sleep(5);
    }
  }
}
&lt;/pre&gt;If you get a heap dump of the running program and open the same using MAT. You can run a leak suspect reports to find it pointing to the location of the leak as shown below: &lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_SqKefSIXc5Y/S57wJXVtajI/AAAAAAAAAlk/6sGHgZpHPho/s1600-h/leaksuspects.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="617" src="http://3.bp.blogspot.com/_SqKefSIXc5Y/S57wJXVtajI/AAAAAAAAAlk/6sGHgZpHPho/s640/leaksuspects.png" width="640" /&gt;&lt;/a&gt;&lt;a href="http://3.bp.blogspot.com/_SqKefSIXc5Y/S57wSZJ5keI/AAAAAAAAAls/CO5GddE40DM/s1600-h/leaksuspect.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="419" src="http://3.bp.blogspot.com/_SqKefSIXc5Y/S57wSZJ5keI/AAAAAAAAAls/CO5GddE40DM/s640/leaksuspect.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
There is a &lt;a href="http://dev.eclipse.org/blogs/memoryanalyzer/2008/04/21/immortal-objects-or-how-to-find-memory-leaks/"&gt;very nice article on the MAT&lt;/a&gt; site on how to find memory leaks that someone using this tool ought to read.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://kenai.com/projects/btrace"&gt;&lt;b&gt;3. BTrace&lt;/b&gt;&lt;/a&gt;:&lt;br /&gt;
&lt;br /&gt;
Btrace is a tracing tool for the running JVM. Similar to DTrace for Solaris. It involves instrumenting the classes of the target application and introducing tracing code. It looks very promising but there appears to be certain known issues with the code that could cause JVM crashes during the instrumentation. That looks scary but hey atleast the same is documented on their WIKI, what about other tools that you either buy or get free, do they guarantee no crashes? That said, it is pretty easy to use. One develops java classes using the BTrace API, these classes are then compiled and run using the btrace agent to inspect the JVM.&lt;br /&gt;
&lt;br /&gt;
The BTrace API itself has a lot of options and stock profiling code samples available to the developer at their &lt;a href="http://kenai.com/projects/btrace/pages/UserGuide"&gt;WIKI&lt;/a&gt; which I found quite informative.  I have personally not used the tool on any production JVMs but I definitely can see the potential in being able to apply probes to gain understanding of the VM. I ran some of their traces on sample code and was quite pleased with the things I could do. This is a project to keep an eye out for.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;4. Command Line Tools at your disposal:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
As part of the JDK are bundled many independent tools that can be run on &lt;br /&gt;
the command line for aiding debugging memory. &lt;br /&gt;
&lt;b&gt;a.&amp;nbsp;&lt;a href="http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jps.html"&gt;jps&lt;/a&gt;&lt;/b&gt; - This tool can be used to determine the process Id of JVM's running.&lt;br /&gt;
This tool was introduced as of JDK 1.5&lt;br /&gt;
&lt;br /&gt;
&lt;pre name="code"&gt;# list pid and short java main class name
C:\&amp;gt;jps
2008 Jps
2020 Bootstrap

# list pid and fully-qualified java main class
$jps -l
5972 sun.tools.jps.Jps
5457 org.netbeans.Main

# pid, full main class name, and application arguments
$jps -lm
5955 sun.tools.jps.Jps -lm
5457 org.netbeans.Main --userdir /home/sacharya/.visualvm/1.2.2 --branding visualvm

# pid and JVM options
$jps -v
5984 Jps -Dapplication.home=/usr/local/jdk/jdk1.6.0_18 -Xms8m
5457 Main -Djdk.home=/usr/local/jdk/jdk1.6.0_18 -Dnetbeans.system_http_proxy=DIRECT -Dnetbeans.system_http_non_proxy_hosts= -Dnetbeans.dirs=./bin/../tools/visualvm_122/bin/..//visualvm:./bin/../tools/visualvm_122/bin/..//profiler3: -Dnetbeans.home=/home/sacharya/tools/visualvm_122/platform11 -Xms24m -Xmx192m -Dnetbeans.accept_license_class=com.sun.tools.visualvm.modules.startup.AcceptLicense -Dsun.jvmstat.perdata.syncWaitMs=10000 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/sacharya/.visualvm/1.2.2/var/log/heapdump.hprof
&lt;/pre&gt;&lt;br /&gt;
&lt;b&gt;&lt;a href="http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jstat.html"&gt;b. jstat:&lt;/a&gt;&lt;/b&gt;&lt;br /&gt;
jstat is a monitoring tool that allows you to obtain sample data periodically&lt;br /&gt;
from a local or remote VM.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jmap.html"&gt;&lt;b&gt;c. jmap&lt;/b&gt;&lt;/a&gt;&lt;br /&gt;
jmap is one of the tools that anyone who is working with memory issues should be&lt;br /&gt;
familiar with.&lt;br /&gt;
&lt;br /&gt;
jmap is used to print heap memory details of a given process. With jmap you&lt;br /&gt;
can get a view of the heap of live and unreachable objects. For example,&lt;br /&gt;
executing the following will give you all the live objects in the JVM: &lt;br /&gt;
&lt;pre name="code"&gt;$jmap -histo:live &amp;lt;pid&amp;gt;
&lt;/pre&gt;where as the following will give you will give you unreachable objects as well:&lt;br /&gt;
&lt;pre name="code"&gt;$jmap -histo &amp;lt;pid&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
One can take a heap dump using jmap using the following command after which the same can be analyzed in MAT or Visual VM:&lt;br /&gt;
&lt;pre name="code"&gt;$jmap -dump:live,file=heap.hprof,format=b &amp;lt;pid&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
I have not mentioned any of the commercial tools available for memory analysis such as JProbe or Yourkit in detail. I have used &lt;a href="http://www.quest.com/jprobe/"&gt;JProbe&lt;/a&gt; at a previous work place to great effect but never played with Yourkit. One feature I liked about JProbe was the ability to show object graphs and work with the same in determining dominators and roots. These tools definitely serve a market and I need to investigate the same.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Optimizing or Tuning Memory:&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
One can definitely tune the memory used by your JVM to specific needs. There are so many options that one can provide to the JVM it is mind boggling.  I must admit that I have absolutely 0 experience as far as memory tuning goes apart from increasing max heap and perm gen :-(. It would be easy to say, &lt;i&gt;tune it in a case by case basis&lt;/i&gt; as a smart architect would. I however choose to point you to the different VM options that you have at your disposal should the need arise &lt;a href="http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp"&gt;http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp&lt;/a&gt; I would at some time like to investigate how different ratio's effect the performance of a VM but that is beyond the scope of my rant.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Concluding:&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
This BLOG is primarily driven by my experiences during my career. There are specialists out there who are extremely skilled in the area of memory debugging and tuning. One such person that I have been fortunate to cross path with is &lt;a href="http://kensipe.blogspot.com/"&gt;Ken Sipe&lt;/a&gt;&amp;nbsp;,another is my current boss.&amp;nbsp;Ken has had considerable experience in debugging mission critical applications to find and fix their memory issues. His knowledge of the Java memory model is esoteric. Ken had recently spoken in the last Java One conference on debugging your production VM, the same was extremely well received. If there was one presentation I would have liked to attend it would have been his. That said, the slides of the &lt;a href="http://www.slideshare.net/kensipe/debugging-your-production-jvm"&gt;same are available at Slide Share&lt;/a&gt;. If any of my understanding is inaccurate, I would appreciate input as always. "No Silent Disagreements!" is my motto after reading about Kayak, a BLOG to follow.&lt;br /&gt;
&lt;br /&gt;
In conclusion, I would say, if you are at a pub after your deploy sipping your favorite drink and you get a call from the NOC, simply do not answer and ruin the moment! Kidding of course ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4667121987470696359-3905943738979298172?l=sleeplessinslc.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OidcY/~4/AqK9piHqR6I" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sleeplessinslc.blogspot.com/feeds/3905943738979298172/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4667121987470696359&amp;postID=3905943738979298172" title="11 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/3905943738979298172?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/3905943738979298172?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OidcY/~3/AqK9piHqR6I/sanjay-in-memory-land-java-memory-leaks.html" title="Sanjay in Memory Land - Java Memory Leaks and Tools for Detection" /><author><name>Sanjay Acharya</name><uri>http://www.blogger.com/profile/01933976956977901677</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="28" src="http://3.bp.blogspot.com/-QuUnYIQQ4Ck/Txo3-4hza9I/AAAAAAAABBQ/QMZO-wT7v6A/s220/profile.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_SqKefSIXc5Y/S6A9lLFZpoI/AAAAAAAAAmE/C1pYCj19Wzs/s72-c/spaces.png" height="72" width="72" /><thr:total>11</thr:total><feedburner:origLink>http://sleeplessinslc.blogspot.com/2010/03/sanjay-in-memory-land-java-memory-leaks.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUYCRX0-eyp7ImA9WxBUGEk.&quot;"><id>tag:blogger.com,1999:blog-4667121987470696359.post-3171740861707064432</id><published>2010-03-05T20:35:00.001-07:00</published><updated>2010-03-05T20:46:04.353-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-05T20:46:04.353-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Jersey google protocol buffers" /><category scheme="http://www.blogger.com/atom/ns#" term="Google Protocol Buffers" /><category scheme="http://www.blogger.com/atom/ns#" term="REST protocol buffers" /><title>RESTful Representation with Google Protocol Buffers and Jersey</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/LLXzFlbjTxvywlVv5yMeTLgu5RM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LLXzFlbjTxvywlVv5yMeTLgu5RM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/LLXzFlbjTxvywlVv5yMeTLgu5RM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LLXzFlbjTxvywlVv5yMeTLgu5RM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;When working with a RESTful system, one has the option of consuming&amp;nbsp;different types of representations of the same resource. That is one of the beauties of a RESTful system IMO.&lt;br /&gt;
&lt;br /&gt;
In many cases, especially from the SOAP Based services stack, XML has been&amp;nbsp;the representation type of choice for information interchange. &amp;nbsp;XML was never really intended to be &amp;nbsp;high performance representation and when working with Java and XML, one often sees performance penalties experienced with mashalling/un-marshalling the payload and size of transfer that are rather undesirable.&lt;br /&gt;
&lt;br /&gt;
There have been other formats that have gained popularity such as &lt;a href="http://www.json.org/"&gt;JSON&lt;/a&gt; which&amp;nbsp;work really well with Java Script and Ajax. For those desiring a comparison&amp;nbsp;between selecting JSON or XML, its only a google search away.&lt;br /&gt;
&lt;br /&gt;
That said, both the above mentioned formats are not binary formats. There&amp;nbsp;are many binary format options to available for users. One of these is&amp;nbsp;&lt;a href="http://code.google.com/p/protobuf/"&gt;google protocol buffers&lt;/a&gt; which the focus of this blog.&lt;br /&gt;
&lt;br /&gt;
Why am I blogging about Protcol buffers now? Well, recently I saw a &lt;a href="http://www.infoq.com/presentations/RESTful-Web-Services-Orbitz"&gt;presentation&lt;/a&gt; on how &lt;a href="http://www.orbitz.com/"&gt;Orbitz&lt;/a&gt; shifted from using &lt;a href="http://community.java.net/jini"&gt;JINI&lt;/a&gt; to RESTful services with&amp;nbsp;Google Protocol Buffers as their representation type to success. &amp;nbsp;Protocol Buffers allowed them to meet their performance needs, versioning needs and language/platform compatibility needs really well. &amp;nbsp;Since then, I had to try the same :-)&lt;br /&gt;
&lt;br /&gt;
Ted Neward has a &lt;a href="http://blogs.tedneward.com/2008/07/11/So+You+Say+You+Want+To+Kill+XML.aspx"&gt;very nice article about XML and his take on Protocol buffers&lt;/a&gt; where&amp;nbsp;he digs into binary formats, pro-cons etc. I recommend a read of his posting.&lt;br /&gt;
&lt;br /&gt;
Regarding performance metrics of using Java Externalizable, google protocol buffers, XML, JSON,&amp;nbsp;Thrift, Avro etc look at the&lt;a href="http://code.google.com/p/thrift-protobuf-compare/"&gt; thrift-protobuf comparison google code page&lt;/a&gt; for more details. In addition, &lt;a href="http://www.eishay.com/2008/11/serialization-protobuf-vs-thrift-vs.html"&gt;Wondering Around&lt;/a&gt; by Eishay Smith is a great read on the comparisons.&lt;br /&gt;
&lt;br /&gt;
So all I have here is working example of using Protocol Buffers with Jersey&amp;nbsp;and Spring. Like it my previous examples, I am using the same orders/product&amp;nbsp;model.&lt;br /&gt;
&lt;br /&gt;
I start with definitions of the contract. One defines the messages exchanged in &amp;nbsp;&lt;i&gt;.proto&lt;/i&gt; files. Wow,&amp;nbsp;&lt;b&gt;&lt;i&gt;YAIDL&lt;/i&gt;&lt;/b&gt; (Yet Another Interface Definition Language) here. True, but contracts need to be exchanged and there has to be a way to do the same especially when dealing with platform/language neutrality and B2B exchanges. I must say that I found the IDL rather easy to understand and use with my limited understanding so far. &amp;nbsp;One of the beauties of protocol buffers is their considerations for backward compatibility of contracts. &amp;nbsp;There is an eclipse plugin is available for editing &lt;i&gt;.proto&lt;/i&gt; files as well at &lt;a href="http://code.google.com/p/protoclipse"&gt;http://code.google.com/p/protoclipse&lt;/a&gt;. &amp;nbsp;With that said, I have two &lt;i&gt;.proto&lt;/i&gt; files, one for Order definition and a second for the Products as shown below:&lt;br /&gt;
Orders.proto&lt;br /&gt;
&lt;pre name="code"&gt;package orders;

option java_package = "com.welflex.orders.proto.dto";
option java_outer_classname= "OrderProtos";
option optimize_for = SPEED;

message LineItem {
 optional int64 id =1;
 required int64 itemId = 2;
 required string itemName = 3;
 required int32 quantity = 4;
}

message Order {
   optional int64 id = 1;
   repeated LineItem lineItems = 2;   
}
&lt;/pre&gt;Products.proto&lt;br /&gt;
&lt;pre name="code"&gt;package products;

option java_package = "com.welflex.products.proto.dto";
option java_outer_classname= "ProductProtos";
option optimize_for = SPEED;

message Product {
   required int32 id = 1;
   required string name = 2;
   required string description = 3;   
}

message ProductList {
   repeated Product productDto = 1;   
}
&lt;/pre&gt;I have defined the above files in the common module at&lt;i&gt; src/main/protobuf&lt;/i&gt; and when the maven compiler runs, it will generate equivalent Java Code based of the proto files which can then be used to create messages from consuming java code. The plugin is basically executing the "&lt;b&gt;protoc&lt;/b&gt;" compiler to do the same. One can choose to create equivalent C ++ code if required or Python etc etc. However, the same is beyond the scope of this BLOG. With the above definition, &lt;i&gt;OrderProtos.java&lt;/i&gt; is generated during the maven build at &lt;i&gt;target/generated-sources/protoc/com/welflex/orders/proto/dto/OrderProtos.java&lt;/i&gt;. In the file, you will find the individual message which extend &lt;i&gt;com.google.protos.GeneratedMessage&lt;/i&gt;. These objects are shared by the client and service code.&lt;br /&gt;
&lt;br /&gt;
The generated java code uses the Builder Pattern with method chaining to make it really easy to set the necessary properties and build the protocol buffer message. For example, the Order Message can be built as shown below:&lt;br /&gt;
&lt;pre class="java" name="code"&gt;OrderProtos.Order order = OrderProtos.Order.newBuilder().setId(12313L)
     .addLineItem(OrderProtos.LineItem.newBuilder().setId(8913L)
                    .setItemId(123).setItemName("Foo Bar").setQuantity(21).build()).build();
&lt;/pre&gt;&lt;br /&gt;
For getting the Web Service to work with Jersey, based of another blog I mention later, I defined a custom Provider for marshalling/un-marshalling the Message. What amazes me is the ease of providing custom providers in JAX-RS. Big fan here :-). Message Body Reader and Message Body Writer classes are shown below that assist with the marshalling:&lt;br /&gt;
&lt;pre class="java" name="code"&gt;@Provider
@Component
@Consumes(AlternateMediaType.APPLICATION_XPROTOBUF)
public class ProtobufMessageReader implements MessageBodyReader&amp;lt;Message&amp;gt; {
  public boolean isReadable(Class&amp;lt;?&amp;gt; type, Type genericType, Annotation[] annotations,
    MediaType mediaType) {
    return Message.class.isAssignableFrom(type);
  }

  public Message readFrom(Class&amp;lt;Message&amp;gt; type, Type genericType, Annotation[] annotations,
    MediaType mediaType, MultivaluedMap&amp;lt;String, String&amp;gt; httpHeaders, InputStream entityStream) throws IOException,
    WebApplicationException {
    try {
      Method newBuilder = type.getMethod("newBuilder");
      GeneratedMessage.Builder&amp;lt;?&amp;gt; builder = (GeneratedMessage.Builder&amp;lt;?&amp;gt;) newBuilder.invoke(type);
      return builder.mergeFrom(entityStream).build();
    }
    catch (Exception e) {
      throw new WebApplicationException(e);
    }
  }
}
@Provider
@Component
@Produces(AlternateMediaType.APPLICATION_XPROTOBUF)
public class ProtobufMessageWriter implements MessageBodyWriter&amp;lt;Message&amp;gt; {
  public boolean isWriteable(Class&amp;lt;?&amp;gt; type, Type genericType, Annotation[] annotations,
    MediaType mediaType) {
    return Message.class.isAssignableFrom(type);
  }

  public long getSize(Message m, Class&amp;lt;?&amp;gt; type, Type genericType, Annotation[] annotations,
    MediaType mediaType) {
    return m.getSerializedSize();
  }

  public void writeTo(Message m, Class&amp;lt;?&amp;gt; type, Type genericType, Annotation[] annotations,
    MediaType mediaType, MultivaluedMap&amp;lt;String, Object&amp;gt; httpHeaders, OutputStream entityStream) throws IOException,
    WebApplicationException {
    entityStream.write(m.toByteArray());
  }
}
&lt;/pre&gt;With the above complete, the rest of the code is pretty similar to what I have done in previous BLOGS and therefore am not mentioning the same again. We now have the necessary artifacts to exchange the Protocol Buffer messages over HTTP.&lt;br /&gt;
&lt;br /&gt;
The steps to get this example working are as follows:&lt;br /&gt;
&lt;b&gt;1&lt;/b&gt;.&lt;a href="http://home.comcast.net/~acharya.s/java/binaryprotocols.zip"&gt; Download the code from HERE&lt;/a&gt;&lt;br /&gt;
&lt;b&gt;2. &lt;/b&gt;Install the maven plugin and thus Protocol Buffers:&lt;br /&gt;
&amp;gt;svn co http://protobuf.googlecode.com/svn/branches/maven-plugin/tools/maven-plugin&lt;br /&gt;
&amp;gt;cd maven-plugin&lt;br /&gt;
&amp;gt;wget -O pom.xml 'http://protobuf.googlecode.com/issues/attachment?aid=8860476605163151855&amp;amp;name=pom.xml'&lt;br /&gt;
&amp;gt;mvn install&lt;br /&gt;
&lt;br /&gt;
If the above does not work, you might want to try looking at the &lt;a href="http://stackoverflow.com/questions/1578456/integrate-protocol-buffers-into-maven2-build"&gt;Stack Overflow Posting&lt;/a&gt; where I got this from.&lt;br /&gt;
&lt;b&gt;3. &lt;/b&gt;Execute "&lt;b&gt;mvn install&lt;/b&gt;" from the root level of the project to see an integration test that will run the life cycle from client to server using Protocol buffers and not XML or JSON :-)&lt;br /&gt;
&lt;br /&gt;
This example is highly inspired by the &amp;nbsp;&lt;a href="http://www.javarants.com/2008/12/27/using-jax-rs-with-protocol-buffers-for-high-performance-rest-apis/"&gt;fantastic maven example by Sam Pullara at Java Rants&lt;/a&gt;&amp;nbsp;on integrating Jersey, Protocol Buffers and Maven. My example is of course tailored to any readers visiting this site ;-) The Products resource returns formats of JSON, XML and Protocol buffers for those interested in trying the same out. &lt;br /&gt;
&lt;br /&gt;
Clearly, one has multiple choices regarding their representation types, the beauty of REST lies in the fact that one does not have to choose one over the other but allow for coexistence. &amp;nbsp;There are many factors that one would consider when choosing the format of their representation, some of the things I can think of in no particular order of importance,&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Performance - Marshalling/Un-Marshalling and transport footprint&lt;/li&gt;
&lt;li&gt;Integration with different platforms/different languages&lt;/li&gt;
&lt;li&gt;Testability and visibility - binary formats hide this&lt;/li&gt;
&lt;li&gt;Versioning of services to ensure backward compatibility&lt;/li&gt;
&lt;li&gt;B2B integration&lt;/li&gt;
&lt;/ul&gt;I wonder whether there will be an effort to support annotations of Java Objects so that they may be transformed into &lt;i&gt;.proto &lt;/i&gt;files, ala, JAXB Annotations in the future. So where next, simple, need to look at &lt;a href="http://hadoop.apache.org/avro/"&gt;Avro&lt;/a&gt; and &lt;a href="http://incubator.apache.org/thrift/"&gt;Thrift&lt;/a&gt; ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4667121987470696359-3171740861707064432?l=sleeplessinslc.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OidcY/~4/bAqG-a1MBlc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sleeplessinslc.blogspot.com/feeds/3171740861707064432/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4667121987470696359&amp;postID=3171740861707064432" title="10 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/3171740861707064432?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/3171740861707064432?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OidcY/~3/bAqG-a1MBlc/restful-representation-with-google.html" title="RESTful Representation with Google Protocol Buffers and Jersey" /><author><name>Sanjay Acharya</name><uri>http://www.blogger.com/profile/01933976956977901677</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="28" src="http://3.bp.blogspot.com/-QuUnYIQQ4Ck/Txo3-4hza9I/AAAAAAAABBQ/QMZO-wT7v6A/s220/profile.jpg" /></author><thr:total>10</thr:total><feedburner:origLink>http://sleeplessinslc.blogspot.com/2010/03/restful-representation-with-google.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUANQH87eCp7ImA9Wx9aF08.&quot;"><id>tag:blogger.com,1999:blog-4667121987470696359.post-2617756740486157390</id><published>2010-02-27T19:29:00.032-07:00</published><updated>2011-03-09T19:23:11.100-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-03-09T19:23:11.100-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Restlet Client" /><category scheme="http://www.blogger.com/atom/ns#" term="REST Clients in Java" /><category scheme="http://www.blogger.com/atom/ns#" term="Jersey Client" /><category scheme="http://www.blogger.com/atom/ns#" term="jax-rs" /><category scheme="http://www.blogger.com/atom/ns#" term="REST Client Frameworks" /><category scheme="http://www.blogger.com/atom/ns#" term="RESTEasy Client" /><category scheme="http://www.blogger.com/atom/ns#" term="Apache Wink Client" /><title>REST Client Frameworks - Your options</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/b2EzxDOMJq0L-twljV8PJjmbUH8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/b2EzxDOMJq0L-twljV8PJjmbUH8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/b2EzxDOMJq0L-twljV8PJjmbUH8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/b2EzxDOMJq0L-twljV8PJjmbUH8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;In previous blogs, I have discussed how the different frameworks for REST work, client and server side. In particular, I have investigated different JAX RS vendors such as Jersey, RESTEasy and Restlet JAX-RS and an implementation that is not JAX-RS as well, i.e., Core Restlet whose API pre-dated the JAX RS specification. I am currently looking at different JAX RS vendor implements for client side support. The JAX RS specification does not include a client side API and different JAX RS vendors have proceeded to create their own API's for the same. The framework one selects for the client and service ends do not have to be the same. For example, one could have a RESTful service running using Restlet while having a client developed in RESTEasy that consumes the same. In most cases, one will typically be satisfied with using the same client framework as one is using for the service development in order to be consistent and potentially be able to re-use artifacts in both areas if the framework permits the same. &lt;br /&gt;
That said, I have been looking at the following vendors for the Client side API and implementation as my needs require me to.&lt;br /&gt;
&lt;ul&gt;&lt;li align="left"&gt;&lt;a href="https://jersey.dev.java.net/"&gt;Jersey&lt;/a&gt; - A JAX RS reference implementation from Oracle/Sun.&lt;/li&gt;
&lt;li align="left"&gt;&lt;a href="http://www.jboss.org/resteasy"&gt;RESTEasy&lt;/a&gt; - A JAX RS reference implementation by JBoss.&lt;/li&gt;
&lt;li align="left"&gt;&lt;a href="http://www.restlet.org/documentation/2.0/tutorial"&gt;Restlet&lt;/a&gt; - A pioneer of sorts that has support for Client Side REST calls&lt;/li&gt;
&lt;li align="left"&gt;&lt;a href="http://cxf.apache.org/"&gt;CXF&lt;/a&gt; - An apache project that is a merger of XFire and Celtix. Provides a JAX RS implementation and JAX WS as well.&lt;/li&gt;
&lt;li align="left"&gt;&lt;a href="http://incubator.apache.org/wink/"&gt;Apache Wink&lt;/a&gt; - A JAX RS implementation that has a client and server side api that has had a 1.0 release just recently&lt;/li&gt;
&lt;li align="left"&gt;&lt;a href="http://www.springsource.org/"&gt;Spring 3.0 &lt;/a&gt;- Spring provides a RestTemplate, quite like the JmsTemplate and HibernateTemplate in its support of REST clients.&lt;/li&gt;
&lt;li align="left"&gt;&lt;a href="http://hc.apache.org/httpclient-3.x/"&gt;Apache HTTPClient&lt;/a&gt; or &lt;a href="http://hc.apache.org/"&gt;Http Components&lt;/a&gt; - Direct use of HTTP API - Down and dirty.&lt;/li&gt;
&lt;/ul&gt;As an evaluator, I would look for the following things in a Client framework:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;strong&gt;User Base &lt;/strong&gt;- Documentation, Support, Community, Release cycles, Age of solutio&lt;strong&gt;n&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Easy of API for RESTful operations &lt;/strong&gt;- URL Parameter substitution, HTTP verbs, Proxy support&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dryness of the API&lt;/strong&gt; - Certain frameworks allow for components such as contracts developed for the service to be re-used in the client&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Http Connection Control &lt;/strong&gt;- Ability to do connection pooling, connection reaping and controlling lower level HTTP connection settings such as connection time out if required&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Safety of the API &lt;/strong&gt;-  It is possible to "leak" connections. This occurs when connections are not restored properly to the pool.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Support for different Provider types &lt;/strong&gt;-  JAXB, JSON, Atom, Yaml and others while providing hookins to introduce new provider types.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Interception of a requests&lt;/strong&gt; - For security and ability to add additional information, for example to HTTP headers&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deployment footprint &lt;/strong&gt;-  number of dependencies the library brings.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Error Response Handling&lt;/strong&gt; - Ease of handling alternate response types apart from standard expected responses, for example how the framework supports exception throwing.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Performance&lt;/strong&gt; - Efficiency of Provided Converters such as JAXB, JSON, Memory foot print etc&lt;/li&gt;
&lt;/ul&gt;The above list represent things that one would look for while evaluating a solution. What I aim to do with this blog is provide a maven project that utilizes these client framework thus allowing evaluators to investigate the different solutions. I will put forth my opinions as well.&lt;br /&gt;
When dealing with connections, it is often desirable to keep alive Http Connections. The &lt;a href="http://hc.apache.org/httpclient-3.x/" title="Apache HTTP Client"&gt;Apache Http Client&lt;/a&gt; has for sometime now provided a library that facilitates connection keep alive, connection reaping and safe release of connections. It is almost the defacto underlying Http Client library for Http operations. The standard Http support for the core jdk is limited in its offering. Apache Http Client recently underwent a re-haul of their architecture to clean out areas of their base while providing performance enhancements. Using Http Client directly has some limitations though where one would need to build converters for standard media types like JAXB, JSON, Atom etc. RESTful client libraries like RESTEasy, Jersey, Apache Wink and Restlet have a RESTful API layer on top of Apache Http Client that eases the development of RESTful clients.&lt;br /&gt;
I am working with a Maven project that has a service that uses Jersey while having clients from different frameworks consume the same. The code is NOT doing any benchmarking of any sort, it can however be used to if required. What the code instead does is demonstrate the different clients and their API's. It also demonstrates the use of Proxies where applicable.&lt;br /&gt;
The service developed is very similar to the ones I have used in previous blogs where a client can obtain product information and then perform &lt;em&gt;CRUD&lt;/em&gt; operations on Orders. Subsequently, from the clients perspective, there are two clients. Order Clients and Product Clients. Some of the client frameworks being discussed have the concept of annotation driven proxies that allow for easy development; for those frameworks, I have provided proxy clients in the examples as well.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://4.bp.blogspot.com/_SqKefSIXc5Y/S4nzw-9JuuI/AAAAAAAAAjw/CyTb5rE_ab0/s1600-h/restclients.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img alt="" border="0" id="BLOGGER_PHOTO_ID_5443149647512713954" src="http://4.bp.blogspot.com/_SqKefSIXc5Y/S4nzw-9JuuI/AAAAAAAAAjw/CyTb5rE_ab0/s320/restclients.png" style="cursor: hand; cursor: pointer;" /&gt;&lt;/a&gt;&lt;br /&gt;
All the clients of the example, implement one of the following two interfaces,&lt;br /&gt;
&lt;strong&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; OrdersClientIF&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;public interface OrdersClientIF { 
public static final String ORDERS_RESOURCE = "/orders";
 /**
  * Create an order.
  */
  public OrderDto create(OrderDto dto) throws OrderValidationException, OrderException;

  /**
   * Update an existing order
   */
  public void update(OrderDto dto) throws OrderNotFoundException, OrderValidationException,    OrderException;

  /**
   * Retreive an Order
   */
  public OrderDto get(Long orderId) throws OrderNotFoundException, OrderException;

  /** 
   * Deletes an order
   */
  public void delete(Long orderId) throws OrderException;
}
&lt;/pre&gt;&lt;br /&gt;
&lt;strong&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;ProductsClientIF&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;public interface ProductsClientIF {
public static final String PRODUCTS_RESOURCE = "/products";
  /** 
   * @return A set of Products
   */
  public Set&amp;lt;ProductDto&amp;gt; getProducts();
}
&lt;/pre&gt;&lt;br /&gt;
&lt;strong&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;1. Apache CXF:&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;
Apache CXF is a full fledged JAX RS implementation with a client side api as well. It is a framework for JAX-RS and JAX-WS. A client API is provided in three forms, proxy based, HTTP-Centric and XML-centric. Apache Cxf however does not use HTTP Components or Apache HTTP Client. More information on their Client API can be viewed at &lt;a href="http://cxf.apache.org/docs/jax-rs.html#JAX-RS-ClientAPI"&gt;http://cxf.apache.org/docs/jax-rs.html#JAX-RS-ClientAPI&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;a. Proxy Based:&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;public class ApacheCxfProxiedOrdersClient implements OrdersClientIF {
  /**
   * Proxy Definition
   */
  private static interface OrderCxfIF {
    @GET
    @Consumes(MediaType.APPLICATION_XML)
    @Path(ORDERS_RESOURCE + "/{id}")
    public OrderDto get(@PathParam("id") String id);

    @POST
    @Produces(MediaType.APPLICATION_XML)
    @Consumes(MediaType.APPLICATION_XML)
    @Path(ORDERS_RESOURCE)
    public OrderDto create(OrderDto dto);

    @PUT
    @Produces(MediaType.APPLICATION_XML)
    @Path(ORDERS_RESOURCE + "/{id}")
    public void update(@PathParam("id") String id, OrderDto dto);

    @DELETE
    @Path(ORDERS_RESOURCE + "/{id}")
    public void delete(@PathParam("id") String id);
}
....

public OrderDto create(OrderDto dto) throws OrderValidationException, OrderException {
  try {
    return JAXRSClientFactory.create(baseUri, OrderCxfIF.class).create(dto);
  }
  catch (WebApplicationException e) {
    if (e.getResponse().getStatus() == Status.BAD_REQUEST.getStatusCode()) {
      throw new OrderValidationException(e.getMessage());
    }
    throw new OrderException(e.getMessage());
  }
}
...
@Override
public OrderDto get(Long orderId) throws OrderNotFoundException, OrderException {
  try {
    return JAXRSClientFactory.create(baseUri, OrderCxfIF.class).get(String.valueOf(orderId));
  }
  catch (WebApplicationException e) {
    if (e.getResponse().getStatus() == Status.NOT_FOUND.getStatusCode()) {
      throw new OrderNotFoundException(e.getMessage());  
    }
    throw new OrderException(e.getMessage());
  }
}
..
}
&lt;/pre&gt;With the Proxy based API one can re-use server side artifacts for the client side as well. The API looks pretty straight forward to use and if requiring more control, one can also utilize the WebClient for more detailed operations such as setting header or content type. For handling exceptions, the Cxf site suggests the using the &lt;em&gt;ResponseExceptionMapper&lt;/em&gt;. I however could not get the same to be registered and working. The documentation on the same appeared sparse. If one does not define a &lt;em&gt;ResponseExceptionMapper&lt;/em&gt;, then when a failure occurs, a &lt;em&gt;WebApplicationException&lt;/em&gt; is thrown. One can utilize the same to re-throw appropriate exceptions and consume alternate return types.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;b. HTTP-Centric:&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;public class ApacheCxfOrdersClient implements OrdersClientIF {
....
  public OrderDto create(OrderDto dto) throws OrderValidationException, OrderException {
    try {
       return WebClient.create(baseUri).path(ORDERS_RESOURCE).accept(MediaType.APPLICATION_XML)
         .invoke(HttpMethod.POST, dto, OrderDto.class);
    }
    catch (WebApplicationException e) {
      if (e.getResponse().getStatus() == Status.BAD_REQUEST.getStatusCode()) {
        throw new OrderValidationException(e.getMessage());
      } 
      throw new OrderException(e.getMessage());
    }
  }
....
  public OrderDto get(Long orderId) throws OrderNotFoundException, OrderException {
    try {
      return   WebClient.create(baseUri).path(ORDERS_RESOURCE).path(String.valueOf(orderId)).accept(
         MediaType.APPLICATION_XML).invoke(HttpMethod.GET, null, OrderDto.class); 
    }
    catch (WebApplicationException e) {
      if (e.getResponse().getStatus() == Status.NOT_FOUND.getStatusCode()) {
        throw new OrderNotFoundException(e.getMessage());
      }
      throw new OrderException(e.getMessage());
    }
  }
}
&lt;/pre&gt;&lt;br /&gt;
With the HTTP Centric client, one uses &lt;em&gt;WebClient&lt;/em&gt; instances. As in the case of the Proxy, one can catch the &lt;em&gt;WebApplicationException&lt;/em&gt; in the case of failure responses for Exception management.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;2. RESTEasy:&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
RESTEasy is a JBoss project that is a fully certified JAX-RS implementation. The client side framework supports the Proxy style model and a HTTP centric model as well. The client side framework utilizes Apache HTTP Client 3.X and has support for 4.X as well thus one has the ability to easily control connection parameters and pooling. The last time I read about the framework, both Http Client versions are supported but the HttpClient 4 has not been validated as well as the 3 version. The same might have changed since then. It is very easy to set one or the other though. Another nice feature is that an interface can be shared between the client and server. Requests can also nicely be intercepted via an implementation of &lt;em&gt;org.jboss.resteasy.spi.interception.ClientExecutionInterceptor&lt;/em&gt; to add addition information to the header etc.  More information on their Client API can be viewed from the web site &lt;a href="http://www.jboss.org/file-access/default/members/resteasy/freezone/docs/1.2.GA/userguide/html/RESTEasy_Client_Framework.html"&gt;http://www.jboss.org/file-access/default/members/resteasy/freezone/docs/1.2.GA/userguide/html/RESTEasy_Client_Framework.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;a. Proxy Based:&lt;/span&gt;&lt;/strong&gt; &lt;br /&gt;
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;public class ResteasyProxiedOrdersClient implements OrdersClientIF {
  private static interface RestEasyIF {
    @GET
    @Consumes(MediaType.APPLICATION_XML)
    @Path(ORDERS_RESOURCE + "/{id}")
    public OrderDto get(@PathParam("id") Long id);

    @POST
    @Produces(MediaType.APPLICATION_XML)
    @Consumes(MediaType.APPLICATION_XML)
    @Path(ORDERS_RESOURCE)
    public OrderDto create(OrderDto order);

    @PUT
    @Produces(MediaType.APPLICATION_XML)
    @Consumes(MediaType.APPLICATION_XML)
    @Path(ORDERS_RESOURCE + "/{id}")
    public void update(@PathParam("id") Long id, OrderDto dto);

    @DELETE
    @Path(ORDERS_RESOURCE + "/{id}")
    public void delete(@PathParam("id") Long orderId);
  }

  static {
    RegisterBuiltin.register(ResteasyProviderFactory.getInstance());
    // Execution interceptor registration
    ResteasyProviderFactory.getInstance().registerProvider(ExecutionInterceptor.class);
  }

  private final ClientExecutor clientExecutor;
  private final RestEasyIF delegate;

  public ResteasyProxiedOrdersClient(String baseUri) {
  ...
    clientExecutor = new ApacheHttpClient4Executor(helper.getHttpClient());
    delegate = ProxyFactory.create(RestEasyIF.class, baseUri, clientExecutor);
  }

  public OrderDto create(OrderDto dto) throws OrderValidationException, OrderException {
    try {
      return delegate.create(dto);
    }
    catch (ClientResponseFailure failure) {
      if (failure.getResponse().getStatus() == Status.BAD_REQUEST.getStatusCode()) {
        throw new OrderValidationException(failure.getMessage());
      }
      throw new OrderException(failure.getMessage());
    }
  }

  public OrderDto get(Long orderId) throws OrderNotFoundException, OrderException {
    try {
      return delegate.get(orderId);
    }
    catch (ClientResponseFailure e) {
      if (e.getResponse().getStatus() == Status.NOT_FOUND.getStatusCode()) {
        throw new OrderNotFoundException("Order Not found");
    }
    throw new OrderException(e.getMessage());
  }
 }
}
&lt;/pre&gt;&lt;br /&gt;
One of the gripes that I had while working with the version of the RESTEasy Proxy is I could not understand why I had to provide an &lt;em&gt;@Consumes&lt;/em&gt; annotation on the interface for an update operation that returns "void" and is a PUT HTTP method. The Cxf client did not have that requirement and I feel it redundant to have to specify the same. &lt;br /&gt;
Upon failure of an invocation, a&lt;em&gt; ClientResponseFailure&lt;/em&gt; is thrown which can then be interrogated to throw any custom exception you desire. I must admit, one thing I have not tested is whether on not, upon receiving a ClientResponseFailure if the response body is not read, will the underlying HttpClient connection be safely released by RESTEasy proxy code for re-use or is there a potential to leak a connection? This is worth investigating if looking at the same.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;b. HTTP Centric or Manual Client Request API:&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;public class ResteasyOrdersClient implements OrdersClientIF {
  ...
  private final ClientExecutor clientExecutor;

  static {
    RegisterBuiltin.register(ResteasyProviderFactory.getInstance());
    ResteasyProviderFactory.getInstance().registerProvider(ExecutionInterceptor.class);
  }

  public ResteasyOrdersClient(String baseUri) {
    ..
    helper = new HttpClientFourHelper();
    clientExecutor = new ApacheHttpClient4Executor(helper.getHttpClient());
  }

  public OrderDto create(OrderDto dto) throws OrderValidationException, OrderException {
    ClientResponse response = null;
    try {
      ClientRequest request = new ClientRequest(ORDERS_URI, clientExecutor);
      response = request.body(MediaType.APPLICATION_XML, dto).post();

      if (response.getStatus() 
            == javax.ws.rs.core.Response.Status.BAD_REQUEST.getStatusCode())  {
        throw new OrderValidationException(response.getEntity(String.class));
      }
      return response.getEntity(OrderDto.class);
    }
    catch (OrderValidationException e) {
      throw e;
    }
    catch (Exception e) {
      throw new OrderException(e.getMessage());
    }
    finally {
      // Safe release of connection/stream
     if (response != null) {
       response.releaseConnection();
     }
    }
  }
  ...
  public OrderDto get(Long orderId) throws OrderNotFoundException, OrderException {
    ClientRequest request = new ClientRequest(ORDERS_URI + "/{id}",
     clientExecutor).pathParameter("id", orderId);
    ClientResponse response = null;
    try {
      response = request.accept(MediaType.APPLICATION_XML).get();
      if (response.getStatus() 
           == javax.ws.rs.core.Response.Status.NOT_FOUND.getStatusCode()) {
        throw new OrderNotFoundException("Order Not found");
      }
      return response.getEntity(OrderDto.class);
    }
    catch (OrderNotFoundException e) {
      throw e;
    }
    catch (Exception e) {
      throw new OrderException(e.getMessage());
    }
    finally {
      if (response != null) {
        response.releaseConnection();
      }
    }
 }
....
}
&lt;/pre&gt;&lt;br /&gt;
With the manual API, one has considerable control on the request object such as setting headers etc. One difference to note that unlike in the case of the Proxy Client, in the event of a failure response, a &lt;em&gt;ClientResponseFailure&lt;/em&gt; exception is not thrown. One would need to explicitly work with the &lt;em&gt;ClientResponse&lt;/em&gt; object to discern the same and throw any custom exceptions desired. With the manual client, one has the ability to explicitly release the down stream connection to prevent leaks.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;3. Restlet:&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Restlet is one of the earliest frameworks for RESTful services ever developed if not the earliest. It has a very mature API and implementation and provides multiple ways of working with RESTful services. There is the core API which pre-dates the JAX-RS specification while also having a JAX-RS implementation. They have a mature client API that with their upcoming 2.0 release will utilize HttpClient 4.0. The control over the HTTP Client is a bit hard to get to as the API tends to hide the same. However, their API does allow for most HTTP Client control one would imagine. Again, there are two ways in which one can work with the Restlet client framework, either using Proxy Client or via direct HTTP centric API. Restlet documentation can be viewed at&lt;a href="http://www.restlet.org/documentation/2.0/tutorial"&gt; http://www.restlet.org/documentation/2.0/tutorial&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;a. Proxy Based:&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;public class RestletProxiedOrdersClient implements OrdersClientIF {
  // Proxy interface
  public static interface OrdersResource {
    @Get
    public OrderDto getOrder();

    @Post
    public OrderDto create(OrderDto dto);

    @Put
    public void update(OrderDto dto);

    @Delete
    public void delete();
  }
  ....

  public OrderDto create(OrderDto orderDto) 
    throws OrderValidationException, OrderException {  
    try {
      ClientResource cr = new ClientResource(ORDERS_URI);
      OrdersResource res = cr.wrap(OrdersResource.class);

      OrderDto result = res.create(orderDto);
      return result;
    }
    catch (ResourceException e) {
      if (e.getStatus().equals(Status.CLIENT_ERROR_BAD_REQUEST)) {
        throw new OrderValidationException(e.getMessage());
      }
      throw new OrderException("Unexpected Error:" + e.getStatus());
    }
  }
  ...
  public OrderDto get(Long orderId) throws OrderNotFoundException, OrderException {
    ClientResource cr = new ClientResource(ORDERS_URI + "/" + orderId);
    OrdersResource res = cr.wrap(OrdersResource.class);
    try {
      return res.getOrder();
    }
    catch (ResourceException e) {
      if (e.getStatus().equals(Status.CLIENT_ERROR_NOT_FOUND)) {
        throw new OrderNotFoundException(e.getMessage());
      }
      throw new OrderException("Unexpected Error:" + e.getStatus());
   }
 }
..
}
&lt;/pre&gt;&lt;br /&gt;
Exception management is handled by catching a &lt;em&gt;ResourceException&lt;/em&gt; and throwing any custom exception desired. One area that requires further investigation is how to safely release a HTTP Connection when using HTTP Client as the underlying transport and ClientResource with the Proxy. Again, this is an area one would need to dig into if control of HTTP Client parameters is required along with safe release of pooled connections. For more information on the same look at &lt;a href="http://n2.nabble.com/Client-Timeout-on-ClientResource-post-method-td3690842.html" title="Restlet forum"&gt;http://n2.nabble.com/Client-Timeout-on-ClientResource-post-method-td3690842.html.&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;b. HTTP Centric or Manual Client Request API:&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;public class RestletOrdersClient implements OrdersClientIF {
  private final Client client;
  ....
  public RestletOrdersClient(String baseUri) {
    client = new Client(new Context(), Protocol.HTTP);
    ..
  }

  public OrderDto create(OrderDto orderDto) throws OrderValidationException, OrderException {
    Response response = null;

    try {
      response = client.post(ORDERS_URI, new JaxbRepresentation&amp;lt;OrderDto&amp;gt;(orderDto));

      if (response.getStatus().isSuccess()) {
        return new JaxbRepresentation&amp;lt;OrderDto&amp;gt;(response.getEntity(), OrderDto.class).getObject();
      }
      else if (response.getStatus().equals(Status.CLIENT_ERROR_BAD_REQUEST)) {
        throw new OrderValidationException("Error validating order");
      }
      else {
        throw new OrderException("Error processing order:" + response.getStatus());
      }
    }
    catch (OrderValidationException e) {
      throw e;
    }
    catch (IOException e) {
      throw new OrderException("Unexpected:" + e);
    }
    finally {
      // Explicit safe release of response
      if (response != null) {
        response.release();
      }
    }
  }

  public OrderDto get(Long orderId) throws OrderNotFoundException, OrderException {
    Response response = null;

    try {
      response = client.get(ORDERS_URI + "/" + orderId);
      if (response.getStatus().isSuccess()) {
        return new JaxbRepresentation&amp;lt;OrderDto&amp;gt;(response.getEntity(), OrderDto.class).getObject();
      }
      else if (response.getStatus().equals(Status.CLIENT_ERROR_NOT_FOUND)) {
        throw new OrderNotFoundException("Order Not Found");
      }
        throw new OrderException("Unknown error processing order:" + response.getStatus());
    }
    catch (IOException e) {
      throw new OrderException(e.getMessage());
    }
    finally {
      if (response != null) {
        response.release();
      }
    }
  }
}
&lt;/pre&gt;&lt;br /&gt;
The direct Client API is very straight forward as well. With the safe release of Http Connections accounted for and control of the HTTP Client parameters, the Restlet client is a very powerful proven client side implementation.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;4. Apache Wink:&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Apache Wink is a complete implementation of the JAX-RS specification while providing a client side API to communicate with RESTful services. The framework is relatively new with 1.0-incubating version available at the time of this blog. Apache Wink allows you to work with Http Client and thus control all the lower level operations easily. Unlike the above mentioned frameworks, there is currently no Proxy based client support for Apache Wink. That said, their client API flows very well and is easy to understand and use. An implementation of their &lt;em&gt;ClientHandler&lt;/em&gt; interface allows one to easily intercept requests for custom header or security while also providing an avenue to throw custom exceptions based of alternate failure responses. Documentation on the Apache Wink client can be viewed at &lt;a href="http://incubator.apache.org/wink/1.0/html/6%20Apache%20Wink%20Client.html"&gt;http://incubator.apache.org/wink/1.0/html/6%20Apache%20Wink%20Client.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;public class ApacheWinkOrdersClient implements OrdersClientIF {
  private final RestClient restClient;
  ...
  public ApacheWinkOrdersClient(String baseUri) {
    ClientConfig config = new ApacheHttpClientConfig(helper.getHttpClient());
    // Exception handler can also be used as an intercepting filter
    config.handlers(new ExceptionHandler());
    restClient = new RestClient(config);   
  }

  public OrderDto create(OrderDto dto) throws OrderValidationException, OrderException {
    try {
      return restClient.resource(UriBuilder.fromUri(baseUri)
            .path(ORDERS_RESOURCE).build()).contentType(MediaType.APPLICATION_XML)
            .accept(MediaType.APPLICATION_XML).post(OrderDto.class, dto);
    }
    catch (ClientRuntimeException e) {
      if (e.getCause() instanceof OrderValidationException) {
         throw ((OrderValidationException) e.getCause());
      }
      else if (e.getCause() instanceof OrderException) {
         throw ((OrderException) e.getCause());
      }
      throw e;
    }   
  }
  ...
  public OrderDto get(Long orderId) throws OrderNotFoundException, OrderException {
    try {
      return restClient.resource(UriBuilder.fromUri(baseUri)
        .path(ORDERS_RESOURCE).path("{id}").build(orderId)).accept(MediaType.APPLICATION_XML)
        .get(OrderDto.class);
    }
    catch (ClientRuntimeException e) {
      if (e.getCause() instanceof OrderNotFoundException) {
        throw ((OrderNotFoundException) e.getCause());
      }
     else if (e.getCause() instanceof OrderException) {
        throw ((OrderException) e.getCause());
     }
     throw e;
   }   
  }
  ....
  private static final class ExceptionHandler implements ClientHandler {
    public ClientResponse handle(ClientRequest request, HandlerContext context) throws Exception {
      // Filter for example for standard headers
      request.getHeaders().add("foo", "bar");

      ClientResponse cr = context.doChain(request);
      if (cr.getStatusCode() == Status.NOT_FOUND.getStatusCode()) {
        throw new OrderNotFoundException(cr.getMessage());
      }
      else if (cr.getStatusCode() == Status.BAD_REQUEST.getStatusCode()) {
        throw new OrderValidationException(cr.getMessage());
      }
      else if (cr.getStatusCode() == Status.SERVICE_UNAVAILABLE.getStatusCode()) {
        throw new OrderException(cr.getMessage());
      }
      return cr;
   }
 }
}
&lt;/pre&gt;&lt;br /&gt;
&lt;strong&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;5. Jersey:&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Jersey is sun's implementation of the JAX-RS specification. Jersey like other frameworks provides for a client side framework as well. Jersey supports Apache HTTP Client via a totally separate implementation and artifact. Currently the support exists for HttpClient 3.X, whether 4.X will be incorporated is up in the air. One can choose to write custom code to do the same if Http Client 4.X is the direction one wishes to employ. Jersey does not have the concept of Proxy clients currently. However, their API flows very well with their standard client. Their use of Filters on the client side enables easy interception of requests for customization while providing safe release of any connections used. Information on jersey and their client API can be found at&lt;a href="https://jersey.dev.java.net/"&gt; https://jersey.dev.java.net/&lt;/a&gt;&lt;br /&gt;
&lt;pre class="java" name="code"&gt;public class JerseyOrdersClient implements OrdersClientIF {
  ....
  public JerseyOrdersClient(String baseUri) {
    ..
    ApacheHttpClientHandler handler = new ApacheHttpClientHandler(helper.getHttpClient());
    client = new ApacheHttpClient(handler);
    // Filter allows for intercepting request
    client.addFilter(new RequestFilter());
  }
  ...
  public OrderDto create(OrderDto dto) throws OrderValidationException, OrderException {
    ClientResponse response = null;
    try {
      response = client.resource(baseUri).path(ORDERS_RESOURCE).entity(dto,
        MediaType.APPLICATION_XML).post(ClientResponse.class);
      throwExceptionIfNecessary(response);
      return response.getEntity(OrderDto.class);
    }
    finally {
      if (response != null) {
        response.close();
      }
    }
  }
  ...
  public OrderDto get(Long orderId) throws OrderNotFoundException, OrderException {
    ClientResponse response = null;
    try {
      response = client.resource(baseUri).path(ORDERS_RESOURCE)
       .path(String.valueOf(orderId)).accept(MediaType.APPLICATION_XML)
       .get(ClientResponse.class);

      if (response.getStatus() == Status.OK.getStatusCode()) {
        return response.getEntity(OrderDto.class);
      }
      else if (response.getStatus() == Status.NOT_FOUND.getStatusCode()) {
        throw new OrderNotFoundException(response.getEntity(String.class));
      }
      else if (response.getStatus() == Status.SERVICE_UNAVAILABLE.getStatusCode()) {
        throw new OrderException(response.getEntity(String.class));
      }
      throw new OrderException("Unexpected");
   }
   finally {
     if (response != null) {
       response.close();
     }
   }
 }
 ....
 private static final class RequestFilter extends ClientFilter {
   public ClientResponse handle(ClientRequest cr) throws ClientHandlerException {
      MultivaluedMap&amp;lt;String, Object&amp;gt; map = cr.getHeaders();
      map.add("foo", "bar");
      return getNext().handle(cr);
   }   
 }
}
&lt;/pre&gt;&lt;br /&gt;
&lt;strong&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;6. Spring RestTemplate:&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
Aah, what do I say. My favorite framework in the whole wide world is now supporting REST with their 3.X release. Like the popular &lt;em&gt;HibernateTemplate&lt;/em&gt;, &lt;em&gt;JdbcTemplate&lt;/em&gt; we now have &lt;em&gt;RestTemplate&lt;/em&gt; with Spring. Spring supports server side JAX-RS and a client API to consume the service with the RestTemplate. RestTemplate can be configured to work with HttpClient 3.X and thus have control over lower level HTTP parameters and pooling pretty easily. The RestTemplate like other thoughtful Spring implementations is based of callbacks where safe release of resources is important. The RestTemplate has simple methods for commonly used HTTP operations while providing the call back mechanism when one desires more control. I must however mention with great restraint that going the call back route is not an easy task and requires considerable customization. This becomes important if you wish to customize the header properties etc. Error handling is easily accomplished with an extention of &lt;em&gt;ResponseErrorHandler&lt;/em&gt;. Further information on the RestTemplate can be viewed at the following location &lt;a href="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/remoting.html#rest-client-access"&gt;http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/remoting.html#rest-client-access&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="java" name="code"&gt;public class SpringOrdersClient implements OrdersClientIF {
  private final RestTemplate template;
  ....
  public SpringOrdersClient(String baseUri) {
    ...
    ClientHttpRequestFactory requestFactory
       = new CommonsClientHttpRequestFactory(helper.getHttpClient());
    template = new RestTemplate(requestFactory);
    // Set Error handler
    template.setErrorHandler(new ErrorHandler());
  }

  public OrderDto create(OrderDto orderDto) throws OrderValidationException, OrderException {
    return template.postForObject(ORDERS_URI, orderDto, OrderDto.class);      
  }

  public OrderDto get(Long orderId) throws OrderNotFoundException, OrderException {
    return template.getForObject(ORDERS_URI + "/{id}", OrderDto.class,
        Collections.singletonMap("id", String.valueOf(orderId)));
  }
  ....
  private static final class ErrorHandler implements ResponseErrorHandler {
    @Override
    public boolean hasError(ClientHttpResponse response) throws IOException {
      if (response.getStatusCode().series().compareTo(Series.SUCCESSFUL) == 0) {
        return false;
      }
      return true;
    }

    public void handleError(ClientHttpResponse response) throws IOException {
       if (response.getStatusCode().equals(HttpStatus.NOT_FOUND)) {
          throw new OrderNotFoundException("Order Not Found");
       } else if (response.getStatusCode().equals(HttpStatus.BAD_REQUEST)) {
          throw new OrderValidationException("Error validating order");
       } else {
          throw new OrderException("Unexpected error:" + response.getStatusText());
       }
    }  
  }
}
&lt;/pre&gt;&lt;br /&gt;
&lt;strong&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Running the Examples:&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
The example is available as JDK 6.X project that uses maven. An integration test is provided that uses each of the different mentioned clients to communicate the very same life cycle test for CRUD operations with the RESTful service. Once you have a maven environment, execute "mvn install" from the root level of the project to see the entire project build and execute the integration test where each of the clients are demonstrated. For those interested, you could use the clients to determine benchmarks, test for memory foot print, what have you.&lt;br /&gt;
&lt;a href="http://home.comcast.net/~acharya.s/java/restclients.zip"&gt;Download the source from HERE&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: medium;"&gt;&lt;strong&gt;Parting Thoughts:&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;
I hope the above examples are of use to someone evaluating REST frameworks for their project and would like to witness each of them in action. I have been a REST fanatic ever since introduced to the architectural style and simply enjoy playing with frameworks and tools that present themselves. It would have been nice if during jsr 311 the expert body had defined a client side api as well. I beleive a future JSR is expected for a client API to JAX-RS.&lt;br /&gt;
One can details about each of the above mentioned projects and metrics about the same such as commiters, activity, maturing etc from &lt;a href="http://www.ohloh.net/" title="Oh Loh"&gt;Oh Loh&lt;/a&gt;.  That said, I would like to share my 2c on the above frameworks. Note that these are my own 2c that I am pulling out of my b..t and is not in any way my employers views or thoughts on the matter.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Apache Cxf:&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;strong&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;The one word that comes to mind when I view this framework is BLOAT. It seems to bring in so many dependencies that are of no use if ones goal is simply to work with REST. Their documentation on the REST clients API was not the best with broken links. It is my understanding that they do not support Apache HTTP Client and there is no drive to do the same. If a team is supporting JAX-WS and JAX-RS, maybe their framework works in synergy. You will notice that among all the frameworks mentioned above, I never bothered to support an example of CXF, the primary reason for the same is my disillusionment with their documentation and WIKI where I encountered broken links and partial information. I also ran into an issue where I needed to have HttpServletRequest on the client as a dependency.&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;RestEasy:&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;
In RestEasy, you have me as a fan. I really like the effort put into the framework by its owner Bill Burke and his team. Their proxy solution is very enticing and will serve to address most RESTful consumers. I might be pipe dreaming here but never the less, I recall reading somewhere that the RESTEasy's implementation of the client library will be serving as the foundation of the client side equivalent of JSR 311. Active development, with support for ASYNC HTTP along with good documentation is what they bring to the table. It is an especially notable consideration to use RESTEasy if re-use across service and client for "contract" purposes is desired. One additional point of note is the philosphy that RestEasy employs regarding backward compatibilty. They seem very concious regarding the direction they employ with change to ensure backward compatibility.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Restlet:&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;strong&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Restlet is an established and proven framework. One of the things I particularly like about Restlet is that their community is very active in offering assitance to those in need. If you post a question on their mailing list, you can almost be guaranteed a response as long as the question is within answerable parameters. They are very quality concious as well. One gripe that I do have have with Restlet is that they have chosen to break compatiblity between their 1.1.X series of releases when moving to their 2.0.X series without a transitionary phase.&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;
The selling point of Restlet as a client API is their transparent API and simplicitly, coupled with their helpful community.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;Apache Wink:&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;
YAJAXRS (Yet another JAX-RS implementation) is my initial reaction when thinking of Apache Wink. However, when I look further, although comparitively immature in the space, they have a solid offering in WINK. If you are looking for a light weight JAX-RS implementation, look no further. Their client API utilizes Http Client 4.0 to effect and in my tests with the API, it found it really fast and performant. Their API is simple, transparent and effective. Their documentation is however sparse and I wonder regarding their longevity when compared with the big hitters such as jersey, restlet and resteasy.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;jersey:&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;
jersey, as I said in a previous blog, home town of the boss, rocks. What appeals to me is the simplicity of the API, the adoption, the community and decent documentation regarding the API. Their support for Http Client 3.X is present. I am certain they will support 4.X soon.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;spring:&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;strong&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Its hard to say anything about spring without seeming biased in favor. Spring's RestTemplate is as solid as can be expected. Their standard call back based approach for safe release of resources works well even for the REST template. If one is using Spring-mvc and their REST support, very few reasons would drive me to consider an alternative framework for the client. One among them is definitely finer grained control, another is Http Client 4.X support. Documentation is sparse on RestTemplate as well. But one has a community to back up on. There might a bit of up front customizations, standard call back etc that an adopter might create but once done I feel that it would be a easy to work with the RestTemplate.&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;
&lt;strong&gt;&lt;span class="Apple-style-span" style="font-weight: normal;"&gt;Clearly one has many choices in selecting a client side framework for RESTful HTTP. In most cases it probably makes sense to use the same framework for the service and client end. Then again, if you are only a consumer of a service you have multiple choices among those shown above as well as the option of using Apache HTTP Client or Components directly and bypassing the higher level frameworks.  For some, integrating with the spring framework is important and all the above frameworks have means of integration points, both on the service and client sides. Support for Client Proxies is something one might want to consider as they tend to simplify the programming model. Further if Resource definitions can be shared among client server, that can be quite useful in being DRY (Don't repeat yourself) and provide means for contract definition. For those interested in performance and tuning of the HTTP Connections, using a framework that allows you to manage connection pooling and other parameters is definitely the way to go. One should also look at the maturity, user base, support, back ward compatibility support when making a selection. Are there other options apart from the above mentioned? In addition, any recommendations based of personal experience with the above mentioned client frameworks is always welcomed.&lt;/span&gt;&lt;/strong&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4667121987470696359-2617756740486157390?l=sleeplessinslc.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OidcY/~4/6J1PSgBYq04" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sleeplessinslc.blogspot.com/feeds/2617756740486157390/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4667121987470696359&amp;postID=2617756740486157390" title="7 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/2617756740486157390?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/2617756740486157390?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OidcY/~3/6J1PSgBYq04/rest-client-frameworks-your-options.html" title="REST Client Frameworks - Your options" /><author><name>Sanjay Acharya</name><uri>http://www.blogger.com/profile/01933976956977901677</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="28" src="http://3.bp.blogspot.com/-QuUnYIQQ4Ck/Txo3-4hza9I/AAAAAAAABBQ/QMZO-wT7v6A/s220/profile.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_SqKefSIXc5Y/S4nzw-9JuuI/AAAAAAAAAjw/CyTb5rE_ab0/s72-c/restclients.png" height="72" width="72" /><thr:total>7</thr:total><feedburner:origLink>http://sleeplessinslc.blogspot.com/2010/02/rest-client-frameworks-your-options.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0MMRXg_cCp7ImA9WxBVF08.&quot;"><id>tag:blogger.com,1999:blog-4667121987470696359.post-5583400798686063272</id><published>2010-02-17T18:49:00.039-07:00</published><updated>2010-02-20T22:18:04.648-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-20T22:18:04.648-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Coherence and JMS" /><category scheme="http://www.blogger.com/atom/ns#" term="JMS Message Ordering" /><category scheme="http://www.blogger.com/atom/ns#" term="Hibernate Optimistic locking" /><category scheme="http://www.blogger.com/atom/ns#" term="Caching" /><title>Message Ordering in JMS - Using Coherence and Hibernate</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/8N6_YievHXee9Qx1WkeqUXHVxpo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8N6_YievHXee9Qx1WkeqUXHVxpo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/8N6_YievHXee9Qx1WkeqUXHVxpo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8N6_YievHXee9Qx1WkeqUXHVxpo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;div&gt;As I continue to work with JMS and WebLogic, I wonder about Message Ordering. I have looked for strategies and best practices and have finally done some experimentation that I would like to share.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One of the common patterns when working with Enterprise Integration and Messaging is the Competing Consumer Design Pattern. The same is explained very well in the book &lt;a href="http://www.eaipatterns.com/CompetingConsumers.html"&gt;"Enterprise Integration Patterns" by Hohpe and Woolf&lt;/a&gt;. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.eaipatterns.com/img/CompetingConsumers.gif"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 493px; height: 371px;" src="http://www.eaipatterns.com/img/CompetingConsumers.gif" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As shown above we have consumers that are competing for messages on the queue. As each consumer can process out a message, the consumers scale out horizontally and improve the performance while at the same time guaranteeing high availability.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For the sake of discussion, consider that by some stroke of chance the messages 2 and 3 are for the same item, simply published one after another. With the competing consumer pattern, it is possible that message 3 gets processed before message 2 resulting in an erroneous information propagated to downstream systems such as a database thus compromising the integrity of the data.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One of the ways to prevent this scenario from happening is using a single consumer as shown in the figure below where messages in the queue will be consumed (maybe persisted to the database) in serial order by the consumer:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_SqKefSIXc5Y/S33kBdoLZhI/AAAAAAAAAjI/oV9FCqhKUCk/s1600-h/singleconsumer.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 493px; height: 250px;" src="http://4.bp.blogspot.com/_SqKefSIXc5Y/S33kBdoLZhI/AAAAAAAAAjI/oV9FCqhKUCk/s320/singleconsumer.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5439754638717576722" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One problem with this approach is that now we have compromised on the availability and performance of the system as we have only a single consumer performing the task. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The JMS Specification is clear that a messaging system must deliver message in FIFO (First in-First out) order to consumers. However, the specification is silent regarding ordering when related to re-delivery of a message. In the case of a single consumer if there is a problem processing the message and it gets rolled back due to say a problem with the underlying database which the consumer is communicating with, then most providers will not attempt to redeliver the message immediately but do so after a configurable delay. Between this delay, if the database problem is cured and the consumer picks Message 3 and processes the same, then when Message 2 is delivered and processed, the downstream database would contain stale data. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One could say that any rejected message should be placed at the very front of the queue. However, if the message was a poison message and the logic to detect the same and dequeue the message were not built in the consumer, then putting the message back to the front of the queue would render the queue non-consumable, unless there is retry count configured in which case the poison message could be expired or placed in a dead letter queue after the retry count. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A strategy that can be employed where the ordering of the message would not really matter is to use the message queue simply as a notifier with the consumers going back to the source system to get the most current record to process as shown in the figure below:&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_SqKefSIXc5Y/S33kfH-7AtI/AAAAAAAAAjQ/dW7r40BjEao/s1600-h/backtosource.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 493px; height: 250px;" src="http://3.bp.blogspot.com/_SqKefSIXc5Y/S33kfH-7AtI/AAAAAAAAAjQ/dW7r40BjEao/s320/backtosource.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5439755148303467218" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;In the example shown above, the producer sends a message to the queue that is only a notifier with the "RECORD_ID" of the record from the source database. The consumer upon receiving the message goes back to the source database to obtain the payload information and then process the message. By doing so, regardless of the messaging order, the most recent payload for a record is selected.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The above approach works great when one does have access to the source system and represents a tight coupling in the system. From a performance perspective, we save on the size of messages and the fact that only selects need to be issued on the source system. Further there is something to say about the simplicity of the solution. It however crumbles when the consuming end of the application does not have access to the source system resource to obtain the latest data for the record in question.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So what can we do to ensure that we process in the correct order and also have high availability and performance at the same time ? Please note that I my focus is only on the consumption ordering of the message in the consumer system. Regarding production of messages, ordering of placement and strategies is something I am not covering. That said, I am making an assumption that on the production end of the system messages will always be made available in order. Following on this assumption, I am taking the liberty of assuming that the JMS Time stamp uniquely identifies the messages in the order they were sent. Note that this assumption can be wrong but for keeping my examples tractable I am taking this liberty.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That said, I can see two strategies that could be employed. There maybe others that I would love to hear about as well. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;1. Database Optimistic Lock based Versioning:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Every JMS Message sent has a time stamp associated with it. If the down stream database that the consumer accesses can maintain a table of RECORD_ID-LAST_UPDATE_DATE then by using Optimistic Versioning one can reject records whose time stamps are older than the one in the database. One can use Pessimistic locking as well, however for high scalable systems, Optimistic locking is definitely preferred.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;With an optimistic locking solution employed, only if a record is more recent than the database would the message be processed. If all that one is doing is updating a downstream table with information after any business processing, then you might be able to tag a time stamp column to the table to serve the same purpose. Look at the figure below where both competing consumers are attempting to update the same table which has a last time stamp column for optimistic locking:&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_SqKefSIXc5Y/S33lOE3WGYI/AAAAAAAAAjY/aODI2vjjWd8/s1600-h/competingdb.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 493px; height: 250px;" src="http://2.bp.blogspot.com/_SqKefSIXc5Y/S33lOE3WGYI/AAAAAAAAAjY/aODI2vjjWd8/s320/competingdb.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5439755954920233346" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;In the above shown example, let us say we are receiving updates to existing PERSON records. If M1 and M1' represents updates to the same person with M1 issued at time t and M1' issued at t + dT then, if C1 is the first one to update the Person, then all is good as C2 will update shortly and the record will have the most current value. If C2 updates the database record first and C1 tries to update, it will fail as the JMS time stamp on M1 is older than what is in the database for the Person. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I used &lt;a href="https://www.hibernate.org/"&gt;Hibernate&lt;/a&gt; and &lt;a href="http://hsqldb.org/"&gt;HSQL&lt;/a&gt; to test this out. Hibernate has a feature for &lt;a href="http://docs.jboss.org/hibernate/core/3.3/reference/en/html/transactions.html"&gt;optimistic automatic versioning&lt;/a&gt; for detached objects. In order to employ the same, one has to use a Version property. The Version property cannot be set programatically but is auto-updated by Hibernate. For this reason the JMS Time stamp passed in cannot be used to version but can be used as part of the optimistic strategy.&lt;/div&gt; I have a Person object that represents the database model and it looks like the following:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;@Entity&lt;br /&gt;@Table(name = "PERSON")&lt;br /&gt;public class Person {&lt;br /&gt; @Id&lt;br /&gt; @AccessType(value = "property")&lt;br /&gt; private Long recordId;&lt;br /&gt;&lt;br /&gt; @Column(name = "FIRST_NAME", nullable = false)&lt;br /&gt; private String firstName;&lt;br /&gt;&lt;br /&gt; @Column(name = "LAST_NAME", nullable = false)&lt;br /&gt; private String lastName;&lt;br /&gt;&lt;br /&gt; @Temporal(TemporalType.TIMESTAMP)&lt;br /&gt; @Column(name = "JMS_TIMESTAMP", nullable = false)&lt;br /&gt; private Date jmsTimestamp;&lt;br /&gt;&lt;br /&gt; @Version&lt;br /&gt; @Column(name = "OPT_VER", nullable = false)&lt;br /&gt; @AccessType(value = "property")&lt;br /&gt; private Long version;&lt;br /&gt;...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Using this code shown above, and the corresponding Data access tier, one can witness optimistic locking in action where messages are rejected or consumed as shown in the output below. Record 13 was rejected as there was a previous record in the database with a newer JMS Time stamp. Record 12 is accepted as although there is an existing record with ID 12, the time stamp on the database record is older than the JMS Time stamp of the message:&lt;br /&gt;&lt;pre name="code"&gt;&lt;br /&gt;18:58:27 ERROR - com.welflex.activemq.AbstractListener.onMessage(35) | Rejecting the Stale Record [13]&lt;br /&gt;com.welflex.exception.StaleObjectException: Stale Record. Database time for the record is [1266631107150], attempted to update with older timestamp [1266614643023]&lt;br /&gt;at com.welflex.hibernate.dao.PersonDaoImpl.saveOrUpdate(PersonDaoImpl.java:27)&lt;br /&gt;at com.welflex.service.PersonServiceImpl.savePerson(PersonServiceImpl.java:29)&lt;br /&gt;at ...&lt;br /&gt;18:58:28 INFO - com.welflex.activemq.AbstractListener.onMessage(32) | Successfully processed Record with ID [12]&lt;br /&gt;......&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;b&gt;2. Cache based Pessimistic Lock based Versioning:&lt;/b&gt;&lt;br /&gt;&lt;div&gt;In this strategy, I have employed &lt;a href="http://www.oracle.com/technology/products/coherence/index.html"&gt;Coherence from Oracle&lt;/a&gt; for the demonstration. The strategy employed is that when a message arrives it attempts to acquire a coherence lock for the record in question, upon obtaining the lock a check is performed to see if the corresponding date associated with the record is older than the date of the message being worked on. If the cached record is older, then the process is completed. In the case of the example the resulting operation is updating the record in the database.  If the cached record in Coherence was older, then the message is rejected. In either case, the lock is release for the next record. A clear example of Pessimistic locking here. Coherence might allow for optimistic locking and transactions but I have not experimented with the same as yet. A figure demonstrating the strategy is shown below where a record is only updated to the database if the Cache lock is successfully acquired:&lt;/div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_SqKefSIXc5Y/S39XszKj-iI/AAAAAAAAAjg/dasse1YUXo4/s1600-h/coherence.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 493px; height: 250px;" src="http://4.bp.blogspot.com/_SqKefSIXc5Y/S39XszKj-iI/AAAAAAAAAjg/dasse1YUXo4/s320/coherence.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5440163302047218210" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One thing to note with this solution, if there are many records, then one would need to be careful regarding how often the cache is expired of its entities. The  decision of the same could be made if one has some idea on the frequency in which duplicates could be expected. Another point to note is that if all the node's in the cache collapse, and there were message's that were rolled back to be delivered later, unless the cache is primed or restored in some fashion, the solution could fail.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The code for the pessimistic locking in the cache is shown below:&lt;/div&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public &amp;lt;T, E extends Exception&amp;gt; T doCacheAction(String cacheKey, Long timeStamp,&lt;br /&gt;    CacheAction&amp;lt;T, E&amp;gt; action) throws E {&lt;br /&gt; try {&lt;br /&gt;  idCache.lock(cacheKey, -1);&lt;br /&gt;  Long cacheTime = (Long) idCache.get(cacheKey);&lt;br /&gt;  if (cacheTime == null || timeStamp.longValue() &gt; cacheTime.longValue()) {&lt;br /&gt;    T result = action.doAction();&lt;br /&gt;    idCache.put(cacheKey, timeStamp);&lt;br /&gt;    return result;&lt;br /&gt;  }&lt;br /&gt;  throw new StaleObjectException("Coherence Cached Date [" + cacheTime&lt;br /&gt;     + "] for Record    [" + cacheKey + "] is newer than passed in time ["&lt;br /&gt;     + timeStamp + "]. Rejecting the record....");&lt;br /&gt;  }&lt;br /&gt;  finally {&lt;br /&gt;   idCache.unlock(cacheKey);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;When an example is run, one can witness the following where Record 10 is successfully processed while record 13 (no wonder) is rejected:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;19:24:35 INFO - com.welflex.activemq.AbstractListener.onMessage(32) | Record updated :10&lt;br /&gt;19:24:35 ERROR - com.welflex.activemq.AbstractListener.onMessage(35) | Rejecting the Stale Record [13]&lt;br /&gt;com.welflex.exception.StaleObjectException: Coherence Cached Date [1266632674247] for Record [13] is newer than passed in time [1266632673051]. Rejecting the record....&lt;br /&gt;at com.welflex.service.CoherenceCacheServiceImpl.doCacheAction(CoherenceCacheServiceImpl.java:36)&lt;br /&gt;at com.welflex.activemq.CacheMessageListener.doWithMessage(CacheMessageListener.java:28)&lt;br /&gt;at com.welflex.activemq.AbstractListener.onMessage(AbstractListener.java:31)&lt;br /&gt;at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:543)&lt;br /&gt;&lt;/pre&gt;&lt;b&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;The Sample Code:&lt;/span&gt;&lt;/b&gt;&lt;div&gt;Attached herewith is a &lt;a href="http://maven.apache.org/"&gt;maven&lt;/a&gt; project that demonstrates the above concepts. The example sends messages of a fixed number of record id's to an &lt;a href="http://activemq.apache.org/"&gt;Active MQ&lt;/a&gt; queue and has consumers that demonstrate optimistic or pessimistic locking to reject or accept messages. &lt;a href="http://www.springsource.org/"&gt;Spring&lt;/a&gt;, the only framework that has my undying admiration is used only for its Listener Container.  The Coherence cache in the tests does not demonstrate a clustered cache but the same can be experimented with easily using the code provided. The tests will demonstrate both the cases mentioned above and should be runnable out of the box. I have taken some liberties with Hibernate, JMS and Coherence so don't bother pinning me to the stake for the same, I could care less, I have pinned myself in advance...;-)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://home.comcast.net/~acharya.s/java/messageordering.zip"&gt;Download the code from HERE &lt;/a&gt;and execute "&lt;b&gt;mvn test&lt;/b&gt;" to see the demonstration of locking/unlocking.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;Parting Thoughts:&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;1. Single Consumer:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;The single consumer approach seems to be the most widespread pattern, whether in EJB/MDB land or otherwise for most message ordering solutions. It however is not a very scalable one. Further, if used, I believe it will have to maintain some state as well regarding previous messages received as it would need to deal with messages that were re-delivered.  A posting on the &lt;a href="http://www.theserverside.com/discussions/thread.tss?thread_id=9217"&gt;Server side regarding EJB/MDB and ordering of messages&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;2. The "&lt;/b&gt;&lt;i&gt;&lt;b&gt;Going back to the Source&lt;/b&gt;&lt;/i&gt;&lt;b&gt;" pattern:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;The pattern is acceptable clearly if you have access to the source. In terms of simplicity it is definitely the best possible solution to the problem. All the JMS Message becomes is an event notifier with a record id. I must however say that from a purely emotional perspective, it just feels ugly due to the tight coupling between the producer and consumer ends of the application. Again, note that it will not work when the consumer cannot access the source system.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;3. Database based ordering:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;Database for message ordering works well when you have control on the schema. If working with a legacy system, this can prove an impediment.  Apart from not having a dependency on the source system, one advantage to the database approach  is that due to the persistent nature of the data, surviving failures and message rollbacks will work really well which might prove a problem with a Caching solution.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;4.  Caching based ordering:&lt;/b&gt;&lt;/div&gt;&lt;div&gt;The caching based solution works when one does not have access to a datastore and cannot introduce database versioning. I am not certain how this will perform when the messages are varied, i.e., many records and have not experimented with cache priming or recovery. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Both in the case of the Database and the Caching based solution, the expectancy is definitely that each message contains a identifier of a record, where it is a synthetic id or natural id or a complex unique key that can differentiate it from other messages as its the identifier that is primal for the locking strategies to work.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It is also possible that message ordering is not an issue for many cases as one can always build a data integrity validating process to ensure integrity after the fact or depend on the fact that a future update will fix the data integrity issue if present. Another case maybe for manual intervention to fix the one off issues. Do however note that it does become an issue if real time information is required.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If the message updates are for inserts or creations, then ordering is hardly an issue. If they are updates of information then ordering becomes more important. In cases where incremental updates and their order needs to be preserved is important, then the above mentioned locking strategies will not work. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The book I mentioned talks for re-sequencing of messages and restoring order, I am however not convinced that performance will not be impacted by the same.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Oracle &lt;a href="http://en.wikipedia.org/wiki/Oracle_WebLogic_Server"&gt;WebLogic&lt;/a&gt;has a message ordering solution in the form of &lt;a href="http://download.oracle.com/docs/cd/E12840_01/wls/docs103/jms/uoo.html"&gt;Unit Of Order&lt;/a&gt;. However, from experiments we have found that for a clustered highly available environment, the solution does not work. For any questions on the same, mail or post.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As always, for each use case there is a specific solution that will work...I would love to hear about people's experiences with message ordering or just any thoughts. If however you are trying to promote your jewelery site, please don't post here :-)&lt;/div&gt;&lt;div&gt;  &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4667121987470696359-5583400798686063272?l=sleeplessinslc.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OidcY/~4/ZOhAn7ObQAk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sleeplessinslc.blogspot.com/feeds/5583400798686063272/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4667121987470696359&amp;postID=5583400798686063272" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/5583400798686063272?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/5583400798686063272?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OidcY/~3/ZOhAn7ObQAk/message-ordering-in-jms-using-coherence.html" title="Message Ordering in JMS - Using Coherence and Hibernate" /><author><name>Sanjay Acharya</name><uri>http://www.blogger.com/profile/01933976956977901677</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="28" src="http://3.bp.blogspot.com/-QuUnYIQQ4Ck/Txo3-4hza9I/AAAAAAAABBQ/QMZO-wT7v6A/s220/profile.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_SqKefSIXc5Y/S33kBdoLZhI/AAAAAAAAAjI/oV9FCqhKUCk/s72-c/singleconsumer.png" height="72" width="72" /><thr:total>2</thr:total><feedburner:origLink>http://sleeplessinslc.blogspot.com/2010/02/message-ordering-in-jms-using-coherence.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU8CQ3gyeSp7ImA9WxBXF0o.&quot;"><id>tag:blogger.com,1999:blog-4667121987470696359.post-6327279714452374738</id><published>2010-01-28T21:35:00.009-07:00</published><updated>2010-01-29T08:11:02.691-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-29T08:11:02.691-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Defensive Programming" /><category scheme="http://www.blogger.com/atom/ns#" term="Immutability" /><title>Defensive Programming in Java</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/2An0lgHL6gvTsOWrzLub8xaktp8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2An0lgHL6gvTsOWrzLub8xaktp8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/2An0lgHL6gvTsOWrzLub8xaktp8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/2An0lgHL6gvTsOWrzLub8xaktp8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Something crossed my mind today and I thought of Blogging about it. Defensive programming seems to be running in my decaying grey cells :-).&lt;br /&gt;Consider the following best practice,&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public class Foo {&lt;br /&gt;   public void doSomething() {&lt;br /&gt;      Date date;&lt;br /&gt;      Bar b = new Bar(date);&lt;br /&gt;      ....&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class Bar {&lt;br /&gt;   private Date date;&lt;br /&gt;   public Bar(Date date) {&lt;br /&gt;     // Create a based of the provided date&lt;br /&gt;     this.date = immutable(date);&lt;br /&gt;   } &lt;br /&gt;   ...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In the above example, Bar is being safe, it is ensuring that the Date object even if passed and changed subsequently externally, will be safely used within Bar.&lt;br /&gt;&lt;br /&gt;What I ask, is that, when working with external API, shouldn't the caller be safe as well regarding the objects it passes around ?&lt;br /&gt;&lt;br /&gt;As an example, when one works with Streams, Sockets, Connections etc, I am of the opinion that the creator or opener of the Resource should be the one to close it. For example,&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public class Foo {&lt;br /&gt;  public void someOperation() {&lt;br /&gt;    OutputStream os = ...;&lt;br /&gt;    try {&lt;br /&gt;      doSomething(os);&lt;br /&gt;      ....&lt;br /&gt;      // Do some other stuff with the stream&lt;br /&gt;      doSomethingElse(os);&lt;br /&gt;    } finally {&lt;br /&gt;      os.close();&lt;br /&gt;    }    &lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  public void doSomething(OutputStream os) {&lt;br /&gt;    Bar b = new Bar(os);&lt;br /&gt;    try {&lt;br /&gt;      bar.process();&lt;br /&gt;    } finally {&lt;br /&gt;       // Closes Bar and as a side effect closes os&lt;br /&gt;       bar.close();&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now for the sake of discussion let us assume that Bar uses the Stream, but it also has a close() method associated with it. The behavior of the close() method could be to close the output stream that we created in Foo. As Bar is a third party software, one would not know the behavior of the close() method without looking at Bar's javadoc or actual code (might require decompilation). For the sake of discussion, let us say that   Bar is the following code:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public class Bar {&lt;br /&gt; private OutputStream os;&lt;br /&gt;&lt;br /&gt; public Bar(OutputStream os) {&lt;br /&gt;   this.os = os;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; public void process() {&lt;br /&gt;   ....&lt;br /&gt; }&lt;br /&gt; ...&lt;br /&gt; public void close() {&lt;br /&gt;   close(os);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Clearly our Foo code would fail as Bar's close() method is closing out the provided stream and rendering it unusable for the code in Foo. At this time, the close() of Bar method does not do anything else apart from closing the provided stream. Can we rely on the same being the only operation performed by the close() code in the future? Can we safely agree that as long as we do not call the close() method on Bar, our code in Foo is good? Can we safely walk away knowing that we don't call the close() method on Bar?&lt;br /&gt;&lt;br /&gt;One concern that I see is that if we do not call close() on Bar and should tomorrow a new version of Bar get included in the build that is binary compatible but has other additional resources it releases as part of the close() method, what happens then ?  Maybe leakage of some sort? &lt;br /&gt;&lt;br /&gt;For example let us say that the next version of Bar does some socket management internally as well as shown below,&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public class Bar {&lt;br /&gt;  private Socket s;&lt;br /&gt;  private OutputStream os;&lt;br /&gt;  public Bar(OutputStream os) {&lt;br /&gt;    this.os = os;&lt;br /&gt;    this.s = new Socket(...);&lt;br /&gt;  }&lt;br /&gt;  ...&lt;br /&gt;  public void close() {&lt;br /&gt;    close(os);&lt;br /&gt;    close(s);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Third party implementation cannot be guaranteed unless the documentation certifies the same. We cannot imagine that the behavior of the close() method will not require the closing of addition resources opened by Bar.&lt;br /&gt;&lt;br /&gt;So how does one be defensive in development in this case ? As defensive programmers, what if we provided a stream to Bar that even if Bar attempted to close() the stream, the operation would have no effect? &lt;br /&gt;&lt;br /&gt;The same could be achieved using decorator or maybe a &lt;a href="http://java.sun.com/j2se/1.4.2/docs/guide/reflection/proxy.html"&gt;Dynamic Proxies&lt;/a&gt; where we allow every other method to go through but prevent the closing of the provided stream by Bar. &lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public class Foo {&lt;br /&gt;  public void someOperation() {&lt;br /&gt;    OutputStream os = ...;&lt;br /&gt;    Bar b = new Bar();&lt;br /&gt;    // Created proxy will do nothing on close() method call&lt;br /&gt;    OutputStream proxy = createProxy(os);&lt;br /&gt;    try {&lt;br /&gt;      doSomething(proxy);&lt;br /&gt;      ....&lt;br /&gt;      doSomethingElse(proxy);&lt;br /&gt;    } finally {&lt;br /&gt;      os.close();&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  public void doSomething(OutputStream os) {&lt;br /&gt;    Bar b = new Bar(os);&lt;br /&gt;    try {&lt;br /&gt;      bar.process();&lt;br /&gt;    } finally {&lt;br /&gt;      // This operation now will honor the close but&lt;br /&gt;      // prevent the closing of our stream as the proxy will&lt;br /&gt;      // intercept and do nothing on the call to close()&lt;br /&gt;      bar.close();&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In the above example, the caller Foo is being careful and guaranteeing the integrity of the Stream, a way of immutability.  I am probably being too dramatic. At the same time, I think there is value in being defensive. I also think that things work well when the creator is the destroyer :-).  BTW this is coded entirely developed using BLOG SPOT's editor...wonder how many mistakes I have made...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4667121987470696359-6327279714452374738?l=sleeplessinslc.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OidcY/~4/DefHv49oTOw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sleeplessinslc.blogspot.com/feeds/6327279714452374738/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4667121987470696359&amp;postID=6327279714452374738" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/6327279714452374738?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/6327279714452374738?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OidcY/~3/DefHv49oTOw/defensive-programming-in-java.html" title="Defensive Programming in Java" /><author><name>Sanjay Acharya</name><uri>http://www.blogger.com/profile/01933976956977901677</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="28" src="http://3.bp.blogspot.com/-QuUnYIQQ4Ck/Txo3-4hza9I/AAAAAAAABBQ/QMZO-wT7v6A/s220/profile.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://sleeplessinslc.blogspot.com/2010/01/defensive-programming-in-java.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUACRHs5fCp7ImA9WxBXFEo.&quot;"><id>tag:blogger.com,1999:blog-4667121987470696359.post-8423985595570583017</id><published>2010-01-25T19:32:00.005-07:00</published><updated>2010-01-25T20:49:25.524-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-25T20:49:25.524-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="REST Conflating Models" /><category scheme="http://www.blogger.com/atom/ns#" term="RESTful URIs" /><title>RESTful HTTP and the Representation</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/na1z_tNVDSyyNdzddEqtZpZ9jY8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/na1z_tNVDSyyNdzddEqtZpZ9jY8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/na1z_tNVDSyyNdzddEqtZpZ9jY8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/na1z_tNVDSyyNdzddEqtZpZ9jY8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;I was looking at a &lt;a href="http://jacobian.org/writing/rest-worst-practices/"&gt;BLOG posting&lt;/a&gt; by Jacob Kaplan-Moss and found his Conflating models and resources an interesting point. When working with a technology like Hibernate, if we were to have an Object like SuperHero, when retreiving the same, where do we stop the retreival and let lazy loading kick in? For example, &lt;/p&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;&lt;br /&gt;class SuperHero {&lt;br /&gt; private List&amp;lt;Power&amp;gt; powers;&lt;br /&gt; private Set&amp;lt;Superhero&amp;gt; superBuddies;&lt;br /&gt; private Set&amp;lt;Colleague&amp;gt; colleagues;&lt;br /&gt; private Set&amp;lt;Trophy&amp;gt; trophies;&lt;br /&gt; ....&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Do we load every thing when load "Superman"? That would be quite a lot of data. What Hibernate does is use proxies that will lazily load each attribute only when asked for. One could also perform queries such that only parts of the information are returned.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;If one were working in a RESTful system, when one accessed the resource, /superheroes/superman what should one get back? Would we expect the entire Superman representation? In a deeply nested model, the cost of returning such data can be considerable. I think it is important to consider the idea of lazy loading when working in REST as well and especially the word "State Transfer". I imagine one would typically want to navigate a RESTful system through different states or URLS if in HTTP. For example,&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="xml"&gt;&lt;br /&gt;/superheroes/superman&lt;br /&gt;/superheroes/superman/powers&lt;br /&gt;/superheroes/superman/powers/heatvision&lt;br /&gt;/superheroes/superman/superBuddies&lt;br /&gt;/superheroes/superman/superBudies/Green%20Lantern&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;etc etc&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Every Representation along the way providing information that is sufficient enough to represent the resource being queried with links to additional immediate resources. This improves the "linkedness" of your application and allows one to traverse your application by entering and leaving different states. Should you need to represent superman in his entierity, then a resource to the equivalent of /superheroes/superman/full can serve to load the shebang of information :-)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4667121987470696359-8423985595570583017?l=sleeplessinslc.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OidcY/~4/CqfUK7Wz7iE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sleeplessinslc.blogspot.com/feeds/8423985595570583017/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4667121987470696359&amp;postID=8423985595570583017" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/8423985595570583017?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/8423985595570583017?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OidcY/~3/CqfUK7Wz7iE/restful-http-and-representation.html" title="RESTful HTTP and the Representation" /><author><name>Sanjay Acharya</name><uri>http://www.blogger.com/profile/01933976956977901677</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="28" src="http://3.bp.blogspot.com/-QuUnYIQQ4Ck/Txo3-4hza9I/AAAAAAAABBQ/QMZO-wT7v6A/s220/profile.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://sleeplessinslc.blogspot.com/2010/01/restful-http-and-representation.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEQAQ3w6fyp7ImA9WxBTE04.&quot;"><id>tag:blogger.com,1999:blog-4667121987470696359.post-3280151579219674350</id><published>2009-12-08T20:57:00.003-07:00</published><updated>2009-12-08T21:19:02.217-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-08T21:19:02.217-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Google Chrome for Linux" /><title>Google Chrome for Linux Rocks</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ZWNt_Q5lqk550RDWAvPt4Jg5L3k/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ZWNt_Q5lqk550RDWAvPt4Jg5L3k/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ZWNt_Q5lqk550RDWAvPt4Jg5L3k/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ZWNt_Q5lqk550RDWAvPt4Jg5L3k/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;a href="ttp://www.google.com/chrome?platform=linux&amp;amp;hl=en"&gt;Google Chrome for Linux Beta&lt;/a&gt; is available. I am currently trying the same on my 64 bit Ubuntu. It is sweet to say the least, pages render so much faster for me when compared to my Firefox installation. I do however keep seeing a message saying the 64 bit flash plugin crashed, although I am able to view You tube without a problem. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The Chrome Browser was able to import my setting from Firefox with the only clause that firefox not be running at the time of the import.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Have high hopes for this browser now that they have support for plugins. I just need a decent delicious plugin right now. A Google Chrome fan, next I want to try out &lt;a href="http://www.virtualbox.org/"&gt;Virtual Box&lt;/a&gt; VM and see if I can play with &lt;a href="http://googleblog.blogspot.com/2009/07/introducing-google-chrome-os.html"&gt;Google Chrome OS&lt;/a&gt;.  I am only trying Virtual Box due to certain installation pains that I am having with VMWare that I need to spend some time fixing :-)..&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4667121987470696359-3280151579219674350?l=sleeplessinslc.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OidcY/~4/WY1bDSYEPts" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sleeplessinslc.blogspot.com/feeds/3280151579219674350/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4667121987470696359&amp;postID=3280151579219674350" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/3280151579219674350?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/3280151579219674350?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OidcY/~3/WY1bDSYEPts/google-chrome-for-linux-rocks.html" title="Google Chrome for Linux Rocks" /><author><name>Sanjay Acharya</name><uri>http://www.blogger.com/profile/01933976956977901677</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="28" src="http://3.bp.blogspot.com/-QuUnYIQQ4Ck/Txo3-4hza9I/AAAAAAAABBQ/QMZO-wT7v6A/s220/profile.jpg" /></author><thr:total>1</thr:total><feedburner:origLink>http://sleeplessinslc.blogspot.com/2009/12/google-chrome-for-linux-rocks.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUcCRn4zcCp7ImA9WxNbFU8.&quot;"><id>tag:blogger.com,1999:blog-4667121987470696359.post-5322815673467081095</id><published>2009-11-17T22:41:00.002-07:00</published><updated>2009-11-17T22:44:27.088-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-17T22:44:27.088-07:00</app:edited><title>Quite Interesting, need to get my own quote someday</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/rChQAtv70U-Vf9If_F3UUwJxdP8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rChQAtv70U-Vf9If_F3UUwJxdP8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/rChQAtv70U-Vf9If_F3UUwJxdP8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rChQAtv70U-Vf9If_F3UUwJxdP8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;The 25 Best Quotes from Tech History. Think of my colleagues at work will enjoy the one on JINI.  My favourite quote of course lies with HAL.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.computerworld.com/s/article/9141008/25_best_quotes_from_tech_history"&gt;http://www.computerworld.com/s/article/9141008/25_best_quotes_from_tech_history&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4667121987470696359-5322815673467081095?l=sleeplessinslc.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OidcY/~4/UhLH0Dnjccs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sleeplessinslc.blogspot.com/feeds/5322815673467081095/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4667121987470696359&amp;postID=5322815673467081095" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/5322815673467081095?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/5322815673467081095?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OidcY/~3/UhLH0Dnjccs/quite-interesting-need-to-get-my-own.html" title="Quite Interesting, need to get my own quote someday" /><author><name>Sanjay Acharya</name><uri>http://www.blogger.com/profile/01933976956977901677</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="28" src="http://3.bp.blogspot.com/-QuUnYIQQ4Ck/Txo3-4hza9I/AAAAAAAABBQ/QMZO-wT7v6A/s220/profile.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://sleeplessinslc.blogspot.com/2009/11/quite-interesting-need-to-get-my-own.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUMGRn4_eSp7ImA9WxNUEEk.&quot;"><id>tag:blogger.com,1999:blog-4667121987470696359.post-8283030766166391644</id><published>2009-10-31T20:16:00.006-06:00</published><updated>2009-10-31T20:43:47.041-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-31T20:43:47.041-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Ubuntu Karmic" /><category scheme="http://www.blogger.com/atom/ns#" term="Windows 7" /><title>Ubuntu Karmic and Windows 7</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/6E4QTdfaTHIXGI8N4Y_FFXpO2N4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6E4QTdfaTHIXGI8N4Y_FFXpO2N4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/6E4QTdfaTHIXGI8N4Y_FFXpO2N4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/6E4QTdfaTHIXGI8N4Y_FFXpO2N4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Did two upgrades this weekend. Upgraded a laptop from Vista to Windows 7 and a desktop from &lt;a href="http://www.ubuntu.com/"&gt;Ubuntu&lt;/a&gt; Jaunty to Karmic, both 64 bit. Pleased with both upgrades so far.  Vista was one of MS biggest lows as far as their OS version goes, Windows 7 seems more peppier in general so far.&lt;br /&gt;&lt;br /&gt;I have been very pleased with Ubuntu ever since I installed the same. Have previously been a user of &lt;a href="http://www2.mandriva.com"&gt;Mandriva&lt;/a&gt;, &lt;a href="http://fedoraproject.org/"&gt;Fedora&lt;/a&gt; and &lt;a href="http://www.opensuse.org/en/"&gt;Suse&lt;/a&gt;.  Found mandriva comprehensive in its software offering but not very stable. I feel that Suse may be great to compete with Redhat on the server market but is no where as user friendly as Ubuntu. What I like about Ubuntu is that its pretty solid, convenient and just so easy to use.  It detects the need for propriety drivers and installs in a breeze. Have dual monitor support without any xorg.conf tweaking. Printer, web cam all worked out of the box. Have it now running Skype as well without a problem.&lt;br /&gt;&lt;br /&gt;After installing Ubuntu, I followed the following &lt;a href="http://theindexer.wordpress.com/2009/10/25/to-do-list-after-installing-ubuntu-9-10-aka-karmic-koala/"&gt;BLOG on a TODO&lt;/a&gt; list that really helped.&lt;br /&gt;Anyway, got rid of the standard 1948 created Gnome menu in favour of &lt;a href="http://wiki.awn-project.org/"&gt;AWN&lt;/a&gt; and now my desktop rocks.&lt;br /&gt;&lt;br /&gt;A note for those installing eclipse 64 bit. One will find that clicking on some buttons does not work and one has use the keyboard actions to activate the buttons. The way around this problem is to set the following "&lt;span style="font-style: italic;"&gt;export GDK_NATIVE_WINDOWS=true&lt;/span&gt;" prior to launching eclipse.&lt;br /&gt;&lt;br /&gt;On the Windows 7 front, I prefer using Chrome over firefox or IE as its so much more faster on many sites that I frequent. The upgrade from Dell from Vista to Win 7 was pretty simple. Cannot watch youtube on 64 bit IE yet due to 64 flash plugin not available (no so on my Ubuntu though :-)) Don't get me wrong, I don't have anything against Win 7 (except $$$) but when compared with what &lt;span style="font-weight: bold;"&gt;FREE&lt;/span&gt; brings, I find it difficult to justify the extra $$$. I however do need to a Win machine due to the fact that there is no software for the iphone of any value on Linux and that there are sites that I go to such as CWTV to watch videos requiring Win or Mac.  Another seller for the Win 7 is my few PC games that I have. BTW, I did not buy Win 7, its a free upgrade option.&lt;br /&gt;&lt;br /&gt;The Mrs also is happy with Ubuntu...and as long as she is happy, I am as well :-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4667121987470696359-8283030766166391644?l=sleeplessinslc.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OidcY/~4/MXj2rekKulg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sleeplessinslc.blogspot.com/feeds/8283030766166391644/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4667121987470696359&amp;postID=8283030766166391644" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/8283030766166391644?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/8283030766166391644?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OidcY/~3/MXj2rekKulg/ubuntu-karmic-and-windows-7.html" title="Ubuntu Karmic and Windows 7" /><author><name>Sanjay Acharya</name><uri>http://www.blogger.com/profile/01933976956977901677</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="28" src="http://3.bp.blogspot.com/-QuUnYIQQ4Ck/Txo3-4hza9I/AAAAAAAABBQ/QMZO-wT7v6A/s220/profile.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://sleeplessinslc.blogspot.com/2009/10/ubuntu-karmic-and-windows-7.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0IMSHk8fyp7ImA9WxNVE0g.&quot;"><id>tag:blogger.com,1999:blog-4667121987470696359.post-4177003207527319025</id><published>2009-10-16T21:37:00.036-06:00</published><updated>2009-10-23T20:33:09.777-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-23T20:33:09.777-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Exceptions with REST" /><category scheme="http://www.blogger.com/atom/ns#" term="Restlet JAXB" /><category scheme="http://www.blogger.com/atom/ns#" term="Restlet Spring 2.0" /><category scheme="http://www.blogger.com/atom/ns#" term="Restlet 2.0" /><title>Exceptions in RESTful HTTP with Restlet and JAXB</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/TTtzOyhcJiPRvYIsPeskr8nu9mY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TTtzOyhcJiPRvYIsPeskr8nu9mY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/TTtzOyhcJiPRvYIsPeskr8nu9mY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/TTtzOyhcJiPRvYIsPeskr8nu9mY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;REST, or rather, RESTful HTTP and how exceptions can be handled therein is what this posting is about.&lt;br /&gt;&lt;br /&gt;For those of us who have worked with SOAP and faults, we are familiar with how exceptions are handled. SOAP Stacks upon encountering an exception will throw a SOAP fault which is then marshalled into an exception on the consumer end of the service. SOAP faults in a way provide a protocol over standard HTTP.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;When working with REST we have the concept of Resources and their Representations. An exception in a RESTful architecture is really a tuple of an HTTP Status Code and a Representation that describes the same.&lt;br /&gt;&lt;br /&gt;The HTTP Status code in themselves are quite indicative, delving a bit into the same:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;1XX Series - Informational - Request received and continuing processing&lt;/li&gt;&lt;li&gt;2XX Success - Action received, understood and accepted&lt;/li&gt;&lt;li&gt;3XX Redirection - Further action required to complete the request&lt;/li&gt;&lt;li&gt;4XX Client Error - Request is badly formatter or the server cannot process the request&lt;/li&gt;&lt;li&gt;5XX Server Error - Server failure on a a potentially valid request&lt;/li&gt;&lt;/ul&gt;When working with architectures that have Java on both ends of a Service, shying away from Exception handling is IMHO a self imposed handicap. In a RESTful system, one would typically have an expected representation of a resource and in the event of exceptions, have them represented as alternate results along with the appropriate error codes. The &lt;a href="http://jcp.org/en/jsr/detail?id=311"&gt;JAX-RS&lt;/a&gt; specification has the concept of a WebServiceException.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What I am trying to do in this BLOG is a demonstrate how exception handling can be accomplished with a framework like Restlet. I am not demonstrating a specification by any means or a wrapper protocol.  For the sake of this demonstration, I will be using &lt;a href="http://www.restlet.org/"&gt;Restlet&lt;/a&gt; and &lt;a href="http://java.sun.com/developer/technicalArticles/WebServices/jaxb/"&gt;JAXB.&lt;/a&gt; In particular, the example will rely on the &lt;a href="http://java.sun.com/javase/6/docs/api/javax/xml/bind/annotation/adapters/XmlAdapter.html"&gt;XmlAdapter&lt;/a&gt;s of JAXB extensively coupled with the Java Reflection API and Annotations. The XmlAdapters serve to translate to and from Exceptions to JAXB Representions&lt;/div&gt;&lt;br /&gt;The scope of this example is as follows:&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;span style="font-weight: bold;"&gt;a. Exceptions supported are of a particular type and its subclasses only:&lt;/span&gt;&lt;br /&gt;Exceptions are restricted to &lt;span style="font-style: italic;"&gt; WebServiceException&lt;/span&gt; and its sub classes. In addition, the &lt;span style="font-style: italic;"&gt;WebServiceException&lt;/span&gt; is a &lt;span style="font-style: italic;"&gt;RuntimeException&lt;/span&gt;. No checked exceptions. Any exceptions thrown by a Restlet Resource that are not an instance of &lt;span style="font-style: italic;"&gt;WebServiceException&lt;/span&gt; will be converted to the same prior to being marshalled. Any &lt;span style="font-style: italic;"&gt;WebServiceException&lt;/span&gt; marshalled, must have a JAXB Object associated with it.&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;@XmlJavaTypeAdapter(WebServiceExceptionAdapter.class)&lt;br /&gt;public class WebServiceException extends RuntimeException {&lt;br /&gt;// Http Status code&lt;br /&gt;private int status;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;// This class extends WebServiceException but has the same body as&lt;br /&gt;// WebServiceException. For this reason, there is no special XmlAdapter required.&lt;br /&gt;public class OrderException extends WebServiceException {&lt;br /&gt;..&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;&lt;span style="font-weight: bold;"&gt;b. XML as the media type for Transferring Exceptions:&lt;/span&gt;&lt;br /&gt;XML is the sole media type supported for exceptions in this example. Note that it is quite trivial to change the same to accommodate additional media types like JSON etc if required. Every Exception's representation is wrapped around with a &lt;span style="font-style: italic; font-weight: bold;"&gt;WebServiceExceptionWrapperDto&lt;/span&gt;. The same is to allow for sub typing. Note that the &lt;span style="font-weight: bold;"&gt;targetException&lt;/span&gt; will be marshalled by an appropriate XmlAdapter at Runtime.&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;@XmlType(name = "ExceptionWrapper", propOrder = { "targetException" })&lt;br /&gt;@XmlRootElement&lt;br /&gt;public class WebServiceExceptionWrapperDto&amp;lt;E extends WebServiceException&amp;gt; {&lt;br /&gt;@XmlElement(name = "targetException", required = true)&lt;br /&gt;public E targetException;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style="font-weight: bold;"&gt;c. Rich Exceptions:&lt;/span&gt;&lt;br /&gt;Exceptions that can be richer, i.e., more than just message, cause and stack. For example validation messages, codes, inner objects etc.  A simple example of the same is shown below where the OrderValidationException contains a description and a custom validation error code. The same could easily have been a complex object if required:&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;@XmlJavaTypeAdapter(OrderValidationExceptionAdapter.class)&lt;br /&gt;public class OrderValidationException extends WebServiceException {&lt;br /&gt;// A code representing the error&lt;br /&gt;private int validationCode;&lt;br /&gt;&lt;br /&gt;// A description indicating the cause of the validation error&lt;br /&gt;private String validationMessage;&lt;br /&gt;...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;// Note that the OrderValidationException Adapter is behaving like a Template method pattern&lt;br /&gt;// Base marshalling to an exception is handled by the parent class with the child only providing&lt;br /&gt;// specific additions. The methods marshall() and unmarshall() are implemented in the parent class&lt;br /&gt;// and will populate the base properties of the Exception and representation accordingly&lt;br /&gt;public class OrderValidationExceptionAdapter extends&lt;br /&gt;AbstractExceptionXmlAdapter&amp;lt;OrderValidationExceptionDto,OrderValidationException&amp;gt; {&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;public OrderValidationException toException(OrderValidationException created,&lt;br /&gt;  OrderValidationExceptionDto dto) throws Exception {&lt;br /&gt;&lt;br /&gt; created.setValidationCode(dto.validationCode);&lt;br /&gt; created.setValidationMessage(dto.validationMessage);&lt;br /&gt; return created;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;@Override&lt;br /&gt;public OrderValidationExceptionDto toRepresentation(OrderValidationExceptionDto created,&lt;br /&gt;  OrderValidationException t) throws Exception {&lt;br /&gt;&lt;br /&gt; created.validationCode = t.getValidationCode();&lt;br /&gt; created.validationMessage = t.getValidationMessage();&lt;br /&gt; return created;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;&lt;span style="font-weight: bold;"&gt;d. Control over which parts of an Exception are marshalled:&lt;/span&gt;&lt;br /&gt;Provide server stack, cause and message to client. At the same time, ability to prevent certain exceptions from transmitting stack. One might or might not want to marshall server stack in certain cases. The same will be accomplished via an annotation that resides on an Exception  thrown. Note that the same can be enhanced for further control. In the example shown below, throwing of the &lt;span style="font-style: italic;"&gt;BarException&lt;/span&gt; will not result in the marshalling of the stack or cause:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;/**&lt;br /&gt;* Foo Exception when thrown should not include server stack and any cause&lt;br /&gt;*/&lt;br /&gt;@ExceptionMarshallingParams(includeStack=false, marshallCause=false)&lt;br /&gt;public class BarException extends WebServiceException {&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;e. Simple mechanism to throw exceptions on the Client:&lt;/span&gt;&lt;br /&gt;Clients are aware of the Exceptions that can be expected from a Service and can expect them to be thrown appropriately. For example:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public OrderDto createOrder(OrderDto order) throws OrderValidationException, OrderException {&lt;br /&gt;JaxbRepresentation&amp;lt;OrderDto&amp;gt; orderRep = new JaxbRepresentation&amp;lt;OrderDto&amp;gt;(order);&lt;br /&gt;Response response = client.post(baseUri + ORDERS_RESOURCE_URI, orderRep);&lt;br /&gt;if (response.getStatus().isSuccess()) {&lt;br /&gt;orderRep = new JaxbRepresentation&amp;lt;OrderDto&amp;gt;(response.getEntity(), OrderDto.class);&lt;br /&gt;try {&lt;br /&gt; return orderRep.getObject();&lt;br /&gt;}&lt;br /&gt;catch (IOException e) {&lt;br /&gt;throw new OrderException(e.getMessage(), e, response.getStatus());&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// Not a Response we expected..throw one of the following exceptions expected instead&lt;br /&gt;throw ExceptionUtil&lt;br /&gt;.getWebServiceException(response.getEntity(), OrderValidationException.class,  OrderException.class);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public class ExceptionUtil {&lt;br /&gt;...&lt;br /&gt;public static WebServiceException getWebServiceException(Representation xmlRep,&lt;br /&gt;  Class... expectedExceptions) {&lt;br /&gt; StringBuilder packages = new StringBuilder(20);&lt;br /&gt; packages.append(WebServiceException.class.getPackage().getName());&lt;br /&gt;&lt;br /&gt; for (Class clazz : expectedExceptions) {&lt;br /&gt;   String ctxPath = getContextPath(clazz);&lt;br /&gt;   packages.append(":").append(ctxPath);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; JaxbRepresentation&amp;lt;WebServiceExceptionWrapperDto&amp;lt;WebServiceException&amp;gt;&amp;gt; wsRep&lt;br /&gt;   = new JaxbRepresentation&amp;lt;WebServiceExceptionWrapperDto&amp;lt;WebServiceException&amp;gt;&amp;gt;(&lt;br /&gt;     xmlRep, packages.toString());&lt;br /&gt; try {&lt;br /&gt;   return wsRep.getObject().targetException;&lt;br /&gt; }&lt;br /&gt; catch (IOException e) {&lt;br /&gt;   throw new RuntimeException("Error unmarshalling exception", e);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;...&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Note that it would have been nice if we could specify the exceptions that a method could throw using generics. That feature however is restricted to a single exception type and thus accommodating checked exceptions are hard.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;f. Resource Classes throw Exceptions on failed code states:&lt;/span&gt;&lt;br /&gt;Resource classes will be able to throw any type of &lt;span style="font-style: italic;"&gt;WebServiceException&lt;/span&gt; and have it marshalled to the client. The Resource classes must however ensure they populate the Exception with the appropriate Http Status Code. For example, an &lt;span style="font-style: italic;"&gt;OrderResource&lt;/span&gt; on create might throw an &lt;span style="font-style: italic;"&gt;OrderNotValidException&lt;/span&gt; or an &lt;span style="font-style: italic;"&gt;OrderException&lt;/span&gt; when a POST operation is invoked on it. At the same time, a GET on the &lt;span style="font-style: italic;"&gt;OrderResource&lt;/span&gt; might throw a &lt;span style="font-style: italic;"&gt;OrderNotFoundException&lt;/span&gt;.&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public class OrderResource extends ServerResource {&lt;br /&gt;@Post("xml")&lt;br /&gt;public OrderDto createOrder(OrderDto dto)  {&lt;br /&gt; try {&lt;br /&gt;   dto = persistOrder(dto);&lt;br /&gt;   setStatus(Status.SUCCESS_CREATED);&lt;br /&gt;   return dto;&lt;br /&gt; } catch (OrderValidationException ove) {&lt;br /&gt;   ove.setStatus(Status.CLIENT_ERROR_BAD_REQUEST);&lt;br /&gt;   throw ove;&lt;br /&gt; }&lt;br /&gt; catch (OrderException e) {&lt;br /&gt;   getResponse().setStatus(Status.SERVER_ERROR_INTERNAL);&lt;br /&gt;   throw e;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;@Get("xml")&lt;br /&gt;public OrderDto getOrder() {&lt;br /&gt; ....&lt;br /&gt; Order order = null;&lt;br /&gt; try {&lt;br /&gt;   order = orderService.getOrder(orderId);&lt;br /&gt; }&lt;br /&gt; catch (OrderNotFoundException nfe) {&lt;br /&gt;   nfe.setStatus(Status.CLIENT_ERROR_NOT_FOUND);&lt;br /&gt;   throw nfe;&lt;br /&gt; }&lt;br /&gt; return (OrderDto) beanMapper.map(order, OrderDto.class);&lt;br /&gt;}&lt;br /&gt;....&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public class HealthResource extends ServerResource {&lt;br /&gt;private static int counter = 0;&lt;br /&gt;@Get&lt;br /&gt;public String isHealthy() {&lt;br /&gt;  // Simply to prove a point....&lt;br /&gt;  switch (counter) {&lt;br /&gt;    case 0:&lt;br /&gt;      counter++;&lt;br /&gt;      // Throw a WebServiceException&lt;br /&gt;      throw new WebServiceException("System is unhealthy", Status.CLIENT_ERROR_UNAUTHORIZED);&lt;br /&gt;&lt;br /&gt;    case 1:&lt;br /&gt;      counter++;&lt;br /&gt;      // throw a RuntimeExeception..this will be transparently marshalled&lt;br /&gt;      throw new RuntimeException("Some unexpected exception thrown as a Runtime");&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  getResponse().setStatus(Status.SUCCESS_OK);&lt;br /&gt;  return "OK YEAH!";&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;g. Marshalling of exceptions occurs via a Restlet Status Service:&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;A custom extension of the Restlet Status Service is responsible for marshalling all thrown Exceptions. The same is shown below:&lt;br /&gt;&lt;pre name="code" class="java"&gt;&lt;br /&gt;public class JaxbExceptionStatusService extends StatusService {&lt;br /&gt;....&lt;br /&gt;public Status getStatus(Throwable throwable, Request request, Response response) {&lt;br /&gt;  Throwable cause = throwable.getCause();&lt;br /&gt;  WebServiceException exception;&lt;br /&gt;  String contextPath = ExceptionUtil.BASE_EXCEPTION_PACKAGE;&lt;br /&gt;&lt;br /&gt;  if (cause == null || !(cause instanceof WebServiceException)) {&lt;br /&gt;    // If not a WebService Exception then throw a WebService Exception&lt;br /&gt;    exception = new WebServiceException(..., Status.SERVER_ERROR_INTERNAL); &lt;br /&gt;   }  else {&lt;br /&gt;     exception = (WebServiceException) cause;&lt;br /&gt;     String clazzContext = ExceptionUtil.getContextPath(cause.getClass());&lt;br /&gt;&lt;br /&gt;     if (!contextPath.equals(cause.getClass().getPackage().getName())&lt;br /&gt;        &amp;amp;&amp;amp; !clazzContext.equals(contextPath)) {&lt;br /&gt;       contextPath = contextPath + ":" + clazzContext;&lt;br /&gt;     }&lt;br /&gt;&lt;br /&gt;     if (exception.getStatus() == 0) {&lt;br /&gt;       exception.setStatus(Status.SERVER_ERROR_INTERNAL);&lt;br /&gt;     }&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   // Create the Exception Wrapper&lt;br /&gt;   WebServiceExceptionWrapperDto&amp;lt;WebServiceException&amp;gt; exceptionWrapper = new         WebServiceExceptionWrapperDto&amp;lt;WebServiceException&amp;gt;();&lt;br /&gt;   exceptionWrapper.targetException = exception;&lt;br /&gt;&lt;br /&gt;   JaxbRepresentation&amp;lt;WebServiceExceptionWrapperDto&amp;lt;?&amp;gt;&amp;gt; rep = new    JaxbRepresentation&amp;lt;WebServiceExceptionWrapperDto&amp;lt;?&amp;gt;&amp;gt;(&lt;br /&gt;     exceptionWrapper);&lt;br /&gt;&lt;br /&gt;   rep.setContextPath(contextPath);&lt;br /&gt;   response.setEntity(rep);&lt;br /&gt;   return Status.valueOf(exception.getStatus());&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I have included &lt;a href="http://home.comcast.net/%7Eacharya.s/java/RestletException.zip"&gt;herewith a Maven example&lt;/a&gt; that will demonstrate the client, service and exception management in use. The maven module titled "exceptionnmodule" contains the exception handling code. The integration will demonstrate different exceptions that are thrown by the server and re-thrown by the client code. In particular, you can see the the following abilities of the framework:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;a.&lt;/span&gt; Ability to throw a simple RuntimeException from the Service and see it marshalled/unmarshalled as WebServiceException&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;b.&lt;/span&gt; Ability to throw an instance of  WebServiceException&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;c. &lt;/span&gt;Ability to throw an exception that is a subtype of WebServiceException but without any addition body. For example, the OrderException.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;d.&lt;/span&gt; Ability to throw a sub type of the WebServiceException that has additional body elements. For example,  OrderValidationException.&lt;br /&gt;&lt;br /&gt;One can witness the server stack, cause, HTTP Status, specific exception types. Simply run a "&lt;span style="font-weight: bold;"&gt;mvn install&lt;/span&gt;" from the top level project.&lt;br /&gt;&lt;br /&gt;Although the example uses Restlet 2.0, the framework has no dependencies on the same. There might be many areas for improvement in the concept and I would like to hear about them if a reader of this blog has ideas. Also, in this example, I have used code from a posting by Ian Robertson on Artima regarding &lt;a href="http://www.artima.com/weblogs/viewpost.jsp?thread=208860"&gt;Reflecting Generics&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Finally, I don't know how this BLOG will format. I am trying something new, I hope it woiks!&lt;br /&gt;&lt;br /&gt;&lt;a href="http://home.comcast.net/%7Eacharya.s/java/RestletException.zip"&gt;Download the Code HERE!&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4667121987470696359-4177003207527319025?l=sleeplessinslc.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OidcY/~4/mjXP4Y91v8Y" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sleeplessinslc.blogspot.com/feeds/4177003207527319025/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4667121987470696359&amp;postID=4177003207527319025" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/4177003207527319025?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/4177003207527319025?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OidcY/~3/mjXP4Y91v8Y/exceptions-in-restful-http-with-restlet.html" title="Exceptions in RESTful HTTP with Restlet and JAXB" /><author><name>Sanjay Acharya</name><uri>http://www.blogger.com/profile/01933976956977901677</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="28" src="http://3.bp.blogspot.com/-QuUnYIQQ4Ck/Txo3-4hza9I/AAAAAAAABBQ/QMZO-wT7v6A/s220/profile.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://sleeplessinslc.blogspot.com/2009/10/exceptions-in-restful-http-with-restlet.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU8GQHYzfyp7ImA9WxNSFUw.&quot;"><id>tag:blogger.com,1999:blog-4667121987470696359.post-7226916108904703456</id><published>2009-08-26T19:25:00.026-06:00</published><updated>2009-08-28T21:50:21.887-06:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-08-28T21:50:21.887-06:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Restlet 2.0 Maven example" /><category scheme="http://www.blogger.com/atom/ns#" term="Restlet ConverterService" /><category scheme="http://www.blogger.com/atom/ns#" term="Restlet 2.0" /><title>Restlet 2.0 example using Spring, Maven, Annotations and a Custom Converter</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/knX_PPfeuj-atEfAUkl1GFtachk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/knX_PPfeuj-atEfAUkl1GFtachk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/knX_PPfeuj-atEfAUkl1GFtachk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/knX_PPfeuj-atEfAUkl1GFtachk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Its been some time since I posted regarding REST. &lt;a href="http://www.restlet.org"&gt;Restlet&lt;/a&gt; 2.0 is on its way, I figured its time I &lt;a href="http://sleeplessinslc.blogspot.com/2008/04/rest.html"&gt;updated the example I had created some time ago&lt;/a&gt; to a Restlet 2.0 milestone release. If you are continuing to read this BLOG, I would recommend a read of the Restlet 1.1 BLOG I mentioned prior to reading this one.&lt;br /&gt;&lt;br /&gt;So whats new with Restlet 2.0? A &lt;a href="http://wiki.restlet.org/developers/172-restlet/226-restlet.html"&gt;read of the Resource API refactoring page&lt;/a&gt; is recommended.&lt;br /&gt;&lt;br /&gt;One of the major features that I liked about &lt;a href="http://jcp.org/en/jsr/detail?id=311"&gt;JAX-RS&lt;/a&gt; over the core Restlet API while working with the former is that it is annotation driven versus class driven. Automatic content negotiation and the calling of the appropriate method in your Server Resource class for different Content-Types is really best left to the container. A method intended to serve content should not have &lt;span style="font-style:italic;"&gt;if/else&lt;/span&gt;  blocks for different content, something one would need to do in Restlet 1.1. Restlet 2.0 seems to take the same into consideration by providing the "&lt;span style="font-weight:bold;"&gt;best of both worlds&lt;/span&gt;"&lt;br /&gt;&lt;br /&gt;There were major changes that occurred on Restlet version 1.2 that the team at Restlet decided to change the release to a 2.0. Further details of the change can be obtained at &lt;a href="http://blog.noelios.com/2009/05/27/restlet-2-0-m3-released/"&gt;http://blog.noelios.com/2009/05/27/restlet-2-0-m3-released/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Restlet 2.0 has a major change in the way &lt;span style="font-style:italic;"&gt;Resources&lt;/span&gt; are viewed. In particular a split into a &lt;span style="font-style:italic;"&gt;ClientResource&lt;/span&gt; and a &lt;span style="font-style:italic;"&gt;ServerResource&lt;/span&gt;. Details of the same can be viewed on the &lt;a href="http://wiki.restlet.org/developers/172-restlet/226-restlet.html"&gt;Restlet Resource API refactoring WIKI page&lt;/a&gt;. In addition, there has been a refactoring of certain core classes to different packages. I also noticed that the Restlet API and Restlet engine are shipped as a single jar &lt;span style="font-style:italic;"&gt;org.restlet.jar&lt;/span&gt;. I could not find the &lt;span style="font-style:italic;"&gt;com.neolios&lt;/span&gt; packages any more.  Finally, there is a jse and j2ee edition of Restlet available.&lt;br /&gt;&lt;br /&gt;So, eager to try out the Restlet 2.0 annotations, I reworked my example to use Restlet 2.0 while simplifying the Spring integration present. &lt;br /&gt;&lt;br /&gt;Compared to my previous example, I have reduced my Spring &lt;span style="font-style:italic;"&gt;applicationContext.xml&lt;/span&gt; to be more thinner by using a more annotated approach. &lt;br /&gt;&lt;hr/&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;context:component-scan base-package=&amp;quot;com.welflex&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;/context:component-scan&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;!--  Spring Application. Note there are no mapping of resources here --&amp;gt;&lt;br /&gt;&amp;lt;bean id=&amp;quot;application&amp;quot; class=&amp;quot;org.restlet.Application&amp;quot;&amp;gt;&lt;br /&gt;  &amp;lt;property name=&amp;quot;name&amp;quot; value=&amp;quot;orderApplication&amp;quot;&amp;gt;&amp;lt;/property&amp;gt;&lt;br /&gt;  &amp;lt;property name=&amp;quot;root&amp;quot; ref=&amp;quot;root&amp;quot; /&amp;gt;&lt;br /&gt;   &amp;lt;!-- Added to handle Exceptions centrally --&amp;gt;&lt;br /&gt;  &amp;lt;property name=&amp;quot;statusService&amp;quot; ref=&amp;quot;applicationStatusService&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;bean id=&amp;quot;root&amp;quot; name=&amp;quot;router&amp;quot; class=&amp;quot;com.welflex.order.rest.SpringBeanRouter&amp;quot;/&amp;gt;&lt;br /&gt;&amp;lt;bean id=&amp;quot;beanMapper&amp;quot;&lt;br /&gt; class=&amp;quot;net.sf.dozer.util.mapping.DozerBeanMapper&amp;quot;&amp;gt;&lt;br /&gt;  &amp;lt;property name=&amp;quot;mappingFiles&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;list&amp;gt;&lt;br /&gt; &amp;lt;value&amp;gt;dozerBeanMapping.xml&amp;lt;/value&amp;gt;&lt;br /&gt;    &amp;lt;/list&amp;gt;&lt;br /&gt;&amp;lt;/property&amp;gt;&lt;br /&gt;&amp;lt;/bean&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;hr&gt;&lt;br /&gt;The OrdersResource has changed to:&lt;br /&gt;&lt;hr/&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;@&lt;font color="#2040a0"&gt;Component&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;value&lt;/font&gt; &lt;font color="4444FF"&gt;=&lt;/font&gt; &lt;font color="#008000"&gt;&amp;quot;/orders&amp;quot;&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;@&lt;font color="#2040a0"&gt;Scope&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;value&lt;/font&gt; &lt;font color="4444FF"&gt;=&lt;/font&gt; &lt;font color="#2040a0"&gt;BeanDefinition&lt;/font&gt;.&lt;font color="#2040a0"&gt;SCOPE_PROTOTYPE&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;strong&gt;public&lt;/strong&gt; &lt;strong&gt;class&lt;/strong&gt; &lt;font color="#2040a0"&gt;OrdersResource&lt;/font&gt; &lt;strong&gt;extends&lt;/strong&gt; &lt;font color="#2040a0"&gt;ServerResource&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;  ......&lt;br /&gt;  @&lt;font color="#2040a0"&gt;Post&lt;/font&gt;&lt;br /&gt;  &lt;strong&gt;public&lt;/strong&gt; &lt;font color="#2040a0"&gt;JaxbRepresentation&lt;/font&gt;&lt;font color="4444FF"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#2040a0"&gt;OrderDTO&lt;/font&gt;&lt;font color="4444FF"&gt;&amp;gt;&lt;/font&gt; &lt;font color="#2040a0"&gt;createOrder&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;Representation&lt;/font&gt; &lt;font color="#2040a0"&gt;rep&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;    ...&lt;br /&gt;    &lt;strong&gt;return&lt;/strong&gt; &lt;strong&gt;new&lt;/strong&gt; &lt;font color="#2040a0"&gt;JaxbRepresentation&lt;/font&gt;&lt;font color="4444FF"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#2040a0"&gt;OrderDTO&lt;/font&gt;&lt;font color="4444FF"&gt;&amp;gt;&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;MediaType&lt;/font&gt;.&lt;font color="#2040a0"&gt;APPLICATION_XML&lt;/font&gt;, &lt;font color="#2040a0"&gt;dto&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;      &lt;br /&gt;  &lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;hr/&gt;&lt;br /&gt;Note that the &lt;span style="font-style:italic;"&gt;OrderResource&lt;/span&gt; class now extends &lt;span style="font-style:italic;"&gt;ServerResource&lt;/span&gt; unlike in my previous example which extended the &lt;span style="font-style:italic;"&gt;Resource&lt;/span&gt; class. Also note that the mapping of the resources to paths are defined in the &lt;span style="font-style:italic;"&gt;OrderResource&lt;/span&gt; class itself unlike in the xml file in my previous example. The POST method, called &lt;span style="font-style:italic;"&gt;createOrder()&lt;/span&gt; accepts and returns XML. The return type is a &lt;span style="font-style:italic;"&gt;JaxbRepresentation&lt;/span&gt;. If we desired, we could have another method in the code that accepts JSON content and returns JSON content that is titled &lt;span style="font-style:italic;"&gt;createJSONRepresentation()&lt;/span&gt;. Depending on the content type requested, the appropriate method would be called. This is much better than having an if/else block in an&lt;span style="font-style:italic;"&gt; acceptRepresentation(Variant v)&lt;/span&gt; method.&lt;br /&gt;&lt;br /&gt;Take a look at the Products Resource, that returns a JSON representation when a GET method is invoked. Note that this method will only return JSON content. &lt;br /&gt;&lt;hr&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;@&lt;font color="#2040a0"&gt;Component&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;value&lt;/font&gt; &lt;font color="4444FF"&gt;=&lt;/font&gt; &lt;font color="#008000"&gt;&amp;quot;/products&amp;quot;&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;@&lt;font color="#2040a0"&gt;Scope&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;value&lt;/font&gt; &lt;font color="4444FF"&gt;=&lt;/font&gt; &lt;font color="#2040a0"&gt;BeanDefinition&lt;/font&gt;.&lt;font color="#2040a0"&gt;SCOPE_PROTOTYPE&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;strong&gt;public&lt;/strong&gt; &lt;strong&gt;class&lt;/strong&gt; &lt;font color="#2040a0"&gt;ProductsResource&lt;/font&gt; &lt;strong&gt;extends&lt;/strong&gt; &lt;font color="#2040a0"&gt;ServerResource&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;  ......&lt;br /&gt;  @&lt;font color="#2040a0"&gt;Get&lt;/font&gt;&lt;br /&gt;  &lt;strong&gt;public&lt;/strong&gt; &lt;font color="#2040a0"&gt;JsonRepresentation&lt;/font&gt; &lt;font color="#2040a0"&gt;getProducts&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;   .....&lt;br /&gt;   &lt;strong&gt;return&lt;/strong&gt; &lt;strong&gt;new&lt;/strong&gt; &lt;font color="#2040a0"&gt;JsonRepresentation&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;jsonString&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;  &lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;hr&gt;&lt;br /&gt;Pretty nice, I would say. To spoil the party, one of the things I liked about the JAXRS implementations was that I could annotate a Resource with the media type it supported and if it were a JAXB object it would automatically marshall the XML, if it were JSON, it would automatically marshal the same as well. &lt;br /&gt;&lt;br /&gt;The same can be accomplished in Restlet by using a Converter Service that converts a java object to and from a media type. There are plans for adding &lt;a href="http://restlet.tigris.org/issues/show_bug.cgi?id=855"&gt;JAXB converters amongst others in 2.0 M5&lt;/a&gt;. In short, by using a Converter Service, I would like the &lt;span style="font-style:italic;"&gt;createOrder()&lt;/span&gt; method to have the following signature, i.e., method returns a JAXB Object, however the container knows how to marshal that into XML back to the caller:&lt;br /&gt;&lt;hr/&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;@&lt;font color="#2040a0"&gt;Post&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#008000"&gt;&amp;quot;xml&amp;quot;&lt;/font&gt;&lt;font color="4444FF"&gt;:&lt;/font&gt;&lt;font color="#008000"&gt;&amp;quot;xml&amp;quot;&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;strong&gt;public&lt;/strong&gt; &lt;font color="#2040a0"&gt;OrderDTO&lt;/font&gt; &lt;font color="#2040a0"&gt;createOrder&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;OrderDTO&lt;/font&gt; &lt;font color="#2040a0"&gt;inOrder&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;  &lt;strong&gt;return&lt;/strong&gt; &lt;font color="#2040a0"&gt;outOrderDTO&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;  &lt;br /&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;hr/&gt;&lt;br /&gt;So what about the &lt;span style="font-style:italic;"&gt;ClientResource&lt;/span&gt; class? How does that work? Well with Restlet 2.0, one can continue to use the Restlet &lt;span style="font-style:italic;"&gt;Client&lt;/span&gt; class or use the &lt;span style="font-style:italic;"&gt;ClientResource&lt;/span&gt; class. The &lt;span style="font-style:italic;"&gt;ClientResource&lt;/span&gt; is not thread safe. An example of how the &lt;span style="font-style:italic;"&gt;ClientResource&lt;/span&gt; can be used is shown below in the &lt;span style="font-style:italic;"&gt;OrderClientImpl&lt;/span&gt; class:&lt;br /&gt;&lt;hr/&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;strong&gt;public&lt;/strong&gt; &lt;strong&gt;class&lt;/strong&gt; &lt;font color="#2040a0"&gt;OrderClientImpl&lt;/font&gt; &lt;strong&gt;implements&lt;/strong&gt; &lt;font color="#2040a0"&gt;OrderClient&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;  &lt;strong&gt;private&lt;/strong&gt; &lt;strong&gt;static&lt;/strong&gt; &lt;strong&gt;final&lt;/strong&gt; &lt;font color="#2040a0"&gt;String&lt;/font&gt; &lt;font color="#2040a0"&gt;ORDERS_RESOURCE_URI&lt;/font&gt; &lt;font color="4444FF"&gt;=&lt;/font&gt; &lt;font color="#008000"&gt;&amp;quot;/orders&amp;quot;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;  &lt;strong&gt;private&lt;/strong&gt; &lt;strong&gt;final&lt;/strong&gt; &lt;font color="#2040a0"&gt;String&lt;/font&gt; &lt;font color="#2040a0"&gt;baseUri&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;  &lt;strong&gt;public&lt;/strong&gt; &lt;font color="#2040a0"&gt;OrderClientImpl&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;String&lt;/font&gt; &lt;font color="#2040a0"&gt;baseUri&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;    &lt;strong&gt;this&lt;/strong&gt;.&lt;font color="#2040a0"&gt;baseUri&lt;/font&gt; &lt;font color="4444FF"&gt;=&lt;/font&gt; &lt;font color="#2040a0"&gt;baseUri&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;  &lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;  &lt;strong&gt;public&lt;/strong&gt; &lt;font color="#2040a0"&gt;OrderDTO&lt;/font&gt; &lt;font color="#2040a0"&gt;createOrder&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;OrderDTO&lt;/font&gt; &lt;font color="#2040a0"&gt;order&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt; &lt;strong&gt;throws&lt;/strong&gt; &lt;font color="#2040a0"&gt;IOException&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;    &lt;font color="#2040a0"&gt;ClientResource&lt;/font&gt; &lt;font color="#2040a0"&gt;ordersResource&lt;/font&gt; &lt;font color="4444FF"&gt;=&lt;/font&gt; &lt;strong&gt;new&lt;/strong&gt; &lt;font color="#2040a0"&gt;ClientResource&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;baseUri&lt;/font&gt; &lt;font color="4444FF"&gt;+&lt;/font&gt; &lt;font color="#2040a0"&gt;ORDERS_RESOURCE_URI&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;    &lt;strong&gt;try&lt;/strong&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;      &lt;strong&gt;return&lt;/strong&gt; &lt;font color="#2040a0"&gt;ordersResource&lt;/font&gt;.&lt;font color="#2040a0"&gt;post&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;order&lt;/font&gt;, &lt;font color="#2040a0"&gt;OrderDTO&lt;/font&gt;.&lt;strong&gt;class&lt;/strong&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;    &lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;    &lt;strong&gt;catch&lt;/strong&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;ResourceException&lt;/font&gt; &lt;font color="#2040a0"&gt;e&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;      &lt;strong&gt;throw&lt;/strong&gt; &lt;strong&gt;new&lt;/strong&gt; &lt;font color="#2040a0"&gt;IOException&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;e&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;    &lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;  &lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;  &lt;strong&gt;public&lt;/strong&gt; &lt;strong&gt;void&lt;/strong&gt; &lt;font color="#2040a0"&gt;updateOrder&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;OrderDTO&lt;/font&gt; &lt;font color="#2040a0"&gt;order&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt; &lt;strong&gt;throws&lt;/strong&gt; &lt;font color="#2040a0"&gt;OrderException&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;    &lt;font color="#2040a0"&gt;JaxbRepresentation&lt;/font&gt;&lt;font color="4444FF"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#2040a0"&gt;OrderDTO&lt;/font&gt;&lt;font color="4444FF"&gt;&amp;gt;&lt;/font&gt; &lt;font color="#2040a0"&gt;orderCmd&lt;/font&gt; &lt;font color="4444FF"&gt;=&lt;/font&gt; &lt;strong&gt;new&lt;/strong&gt; &lt;font color="#2040a0"&gt;JaxbRepresentation&lt;/font&gt;&lt;font color="4444FF"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#2040a0"&gt;OrderDTO&lt;/font&gt;&lt;font color="4444FF"&gt;&amp;gt;&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;        &lt;font color="#2040a0"&gt;MediaType&lt;/font&gt;.&lt;font color="#2040a0"&gt;APPLICATION_XML&lt;/font&gt;, &lt;font color="#2040a0"&gt;order&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;    &lt;font color="#2040a0"&gt;ClientResource&lt;/font&gt; &lt;font color="#2040a0"&gt;ordersResource&lt;/font&gt; &lt;font color="4444FF"&gt;=&lt;/font&gt; &lt;strong&gt;new&lt;/strong&gt; &lt;font color="#2040a0"&gt;ClientResource&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;baseUri&lt;/font&gt; &lt;font color="4444FF"&gt;+&lt;/font&gt; &lt;font color="#2040a0"&gt;ORDERS_RESOURCE_URI&lt;/font&gt; &lt;font color="4444FF"&gt;+&lt;/font&gt; &lt;font color="#008000"&gt;&amp;quot;/&amp;quot;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;      &lt;font color="4444FF"&gt;+&lt;/font&gt; &lt;font color="#2040a0"&gt;String&lt;/font&gt;.&lt;font color="#2040a0"&gt;valueOf&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;order&lt;/font&gt;.&lt;font color="#2040a0"&gt;getOrderId&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;    &lt;strong&gt;try&lt;/strong&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;      &lt;font color="#2040a0"&gt;ordersResource&lt;/font&gt;.&lt;font color="#2040a0"&gt;put&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;orderCmd&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;    &lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;    &lt;strong&gt;catch&lt;/strong&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;ResourceException&lt;/font&gt; &lt;font color="#2040a0"&gt;e&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;      &lt;strong&gt;throw&lt;/strong&gt; &lt;strong&gt;new&lt;/strong&gt; &lt;font color="#2040a0"&gt;OrderException&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#008000"&gt;&amp;quot;Order Update Failed&amp;quot;&lt;/font&gt;, &lt;font color="#2040a0"&gt;e&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;    &lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;  &lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;  &lt;strong&gt;public&lt;/strong&gt; &lt;font color="#2040a0"&gt;OrderDTO&lt;/font&gt; &lt;font color="#2040a0"&gt;getOrder&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;Long&lt;/font&gt; &lt;font color="#2040a0"&gt;orderId&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt; &lt;strong&gt;throws&lt;/strong&gt; &lt;font color="#2040a0"&gt;OrderNotFoundException&lt;/font&gt;, &lt;font color="#2040a0"&gt;IOException&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;     ....&lt;br /&gt;  &lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;  &lt;strong&gt;public&lt;/strong&gt; &lt;strong&gt;void&lt;/strong&gt; &lt;font color="#2040a0"&gt;deleteOrder&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;Long&lt;/font&gt; &lt;font color="#2040a0"&gt;orderId&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt; &lt;strong&gt;throws&lt;/strong&gt; &lt;font color="#2040a0"&gt;OrderException&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;    ....&lt;br /&gt;  &lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;hr&gt;&lt;br /&gt;I quite like the use of &lt;span style="font-style:italic;"&gt;ClientResource&lt;/span&gt; versus the Restlet &lt;span style="font-style:italic;"&gt;Client&lt;/span&gt; as I feel its more RESTful, i.e., talking to a Resource using HTTP verbs. However, again we witness the JAXB representation creeping in as we saw with the service due to the lack of a converter.&lt;br /&gt;&lt;br /&gt;I decided to create my own Converter for JAXB to see if I can get it to work and simplify the code base. One of the things I wanted to add just for my pleasure is a way to propagate server stack traces to the client. This is &lt;span style="font-weight:bold;"&gt;NOT&lt;/span&gt; what one would typically include in a representation of a resource as one would not want clients getting details of the working of a server, however, as this is my playground, anything goes ;-). After some tinkering, the following is my Jaxb Converter, it assumes that all JAXB root level objects have the annotation&lt;span style="font-weight:bold;"&gt; @XmlRootElement&lt;/span&gt;:&lt;br /&gt;&lt;hr/&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;strong&gt;public&lt;/strong&gt; &lt;strong&gt;class&lt;/strong&gt; &lt;font color="#2040a0"&gt;CustomXmlConverter&lt;/font&gt; &lt;strong&gt;extends&lt;/strong&gt; &lt;font color="#2040a0"&gt;XmlConverter&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;  ......&lt;br /&gt;  @&lt;font color="#2040a0"&gt;Override&lt;/font&gt;&lt;br /&gt;  &lt;strong&gt;public&lt;/strong&gt; &lt;font color="#2040a0"&gt;List&lt;/font&gt;&lt;font color="4444FF"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#2040a0"&gt;Class&lt;/font&gt;&lt;font color="4444FF"&gt;&amp;lt;&lt;/font&gt;?&lt;font color="4444FF"&gt;&amp;gt;&lt;/font&gt;&lt;font color="4444FF"&gt;&amp;gt;&lt;/font&gt; &lt;font color="#2040a0"&gt;getObjectClasses&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;Variant&lt;/font&gt; &lt;font color="#2040a0"&gt;source&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;    &lt;font color="#2040a0"&gt;List&lt;/font&gt;&lt;font color="4444FF"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#2040a0"&gt;Class&lt;/font&gt;&lt;font color="4444FF"&gt;&amp;lt;&lt;/font&gt;?&lt;font color="4444FF"&gt;&amp;gt;&lt;/font&gt;&lt;font color="4444FF"&gt;&amp;gt;&lt;/font&gt; &lt;font color="#2040a0"&gt;result&lt;/font&gt; &lt;font color="4444FF"&gt;=&lt;/font&gt; &lt;strong&gt;super&lt;/strong&gt;.&lt;font color="#2040a0"&gt;getObjectClasses&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;source&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;    &lt;font color="#2040a0"&gt;result&lt;/font&gt; &lt;font color="4444FF"&gt;=&lt;/font&gt; &lt;font color="#2040a0"&gt;addObjectClass&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;result&lt;/font&gt;, &lt;font color="#2040a0"&gt;JaxbRepresentation&lt;/font&gt;.&lt;strong&gt;class&lt;/strong&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;    &lt;font color="#2040a0"&gt;result&lt;/font&gt; &lt;font color="4444FF"&gt;=&lt;/font&gt; &lt;font color="#2040a0"&gt;addObjectClass&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;result&lt;/font&gt;, &lt;font color="#2040a0"&gt;Object&lt;/font&gt;.&lt;strong&gt;class&lt;/strong&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;    &lt;strong&gt;return&lt;/strong&gt; &lt;font color="#2040a0"&gt;result&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;  &lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;  @&lt;font color="#2040a0"&gt;Override&lt;/font&gt;&lt;br /&gt;  &lt;strong&gt;public&lt;/strong&gt; &lt;font color="#2040a0"&gt;List&lt;/font&gt;&lt;font color="4444FF"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#2040a0"&gt;VariantInfo&lt;/font&gt;&lt;font color="4444FF"&gt;&amp;gt;&lt;/font&gt; &lt;font color="#2040a0"&gt;getVariants&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;Class&lt;/font&gt;&lt;font color="4444FF"&gt;&amp;lt;&lt;/font&gt;?&lt;font color="4444FF"&gt;&amp;gt;&lt;/font&gt; &lt;font color="#2040a0"&gt;source&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;    &lt;font color="#2040a0"&gt;List&lt;/font&gt;&lt;font color="4444FF"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#2040a0"&gt;VariantInfo&lt;/font&gt;&lt;font color="4444FF"&gt;&amp;gt;&lt;/font&gt; &lt;font color="#2040a0"&gt;result&lt;/font&gt; &lt;font color="4444FF"&gt;=&lt;/font&gt; &lt;strong&gt;super&lt;/strong&gt;.&lt;font color="#2040a0"&gt;getVariants&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;source&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;    &lt;strong&gt;if&lt;/strong&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;source&lt;/font&gt;.&lt;font color="#2040a0"&gt;getAnnotation&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;XmlRootElement&lt;/font&gt;.&lt;strong&gt;class&lt;/strong&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt; &lt;font color="4444FF"&gt;!&lt;/font&gt;&lt;font color="4444FF"&gt;=&lt;/font&gt; &lt;strong&gt;null&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;      &lt;font color="4444FF"&gt;|&lt;/font&gt;&lt;font color="4444FF"&gt;|&lt;/font&gt; &lt;font color="#2040a0"&gt;source&lt;/font&gt;.&lt;font color="#2040a0"&gt;isAssignableFrom&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;JaxbRepresentation&lt;/font&gt;.&lt;strong&gt;class&lt;/strong&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;      &lt;font color="#2040a0"&gt;result&lt;/font&gt; &lt;font color="4444FF"&gt;=&lt;/font&gt; &lt;font color="#2040a0"&gt;addVariant&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;result&lt;/font&gt;, &lt;font color="#2040a0"&gt;VARIANT_APPLICATION_ALL_XML&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;      &lt;font color="#2040a0"&gt;result&lt;/font&gt; &lt;font color="4444FF"&gt;=&lt;/font&gt; &lt;font color="#2040a0"&gt;addVariant&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;result&lt;/font&gt;, &lt;font color="#2040a0"&gt;VARIANT_APPLICATION_XML&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;      &lt;font color="#2040a0"&gt;result&lt;/font&gt; &lt;font color="4444FF"&gt;=&lt;/font&gt; &lt;font color="#2040a0"&gt;addVariant&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;result&lt;/font&gt;, &lt;font color="#2040a0"&gt;VARIANT_TEXT_XML&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;    &lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;    &lt;strong&gt;return&lt;/strong&gt; &lt;font color="#2040a0"&gt;result&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;  &lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;  @&lt;font color="#2040a0"&gt;SuppressWarnings&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#008000"&gt;&amp;quot;unchecked&amp;quot;&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;  @&lt;font color="#2040a0"&gt;Override&lt;/font&gt;&lt;br /&gt;  &lt;strong&gt;public&lt;/strong&gt; &lt;font color="4444FF"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#2040a0"&gt;T&lt;/font&gt;&lt;font color="4444FF"&gt;&amp;gt;&lt;/font&gt; &lt;font color="#2040a0"&gt;T&lt;/font&gt; &lt;font color="#2040a0"&gt;toObject&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;Representation&lt;/font&gt; &lt;font color="#2040a0"&gt;source&lt;/font&gt;, &lt;font color="#2040a0"&gt;Class&lt;/font&gt;&lt;font color="4444FF"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#2040a0"&gt;T&lt;/font&gt;&lt;font color="4444FF"&gt;&amp;gt;&lt;/font&gt; &lt;font color="#2040a0"&gt;target&lt;/font&gt;, &lt;font color="#2040a0"&gt;UniformResource&lt;/font&gt; &lt;font color="#2040a0"&gt;resource&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt; &lt;strong&gt;throws&lt;/strong&gt; &lt;font color="#2040a0"&gt;IOException&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;    &lt;br /&gt;    .....    &lt;br /&gt;    &lt;strong&gt;if&lt;/strong&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;target&lt;/font&gt;.&lt;font color="#2040a0"&gt;getAnnotation&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;XmlRootElement&lt;/font&gt;.&lt;strong&gt;class&lt;/strong&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt; &lt;font color="4444FF"&gt;!&lt;/font&gt;&lt;font color="4444FF"&gt;=&lt;/font&gt; &lt;strong&gt;null&lt;/strong&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;      &lt;br /&gt;      &lt;strong&gt;return&lt;/strong&gt; &lt;strong&gt;new&lt;/strong&gt; &lt;font color="#2040a0"&gt;JaxbRepresentation&lt;/font&gt;&lt;font color="4444FF"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#2040a0"&gt;T&lt;/font&gt;&lt;font color="4444FF"&gt;&amp;gt;&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;source&lt;/font&gt;, &lt;font color="#2040a0"&gt;target&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;.&lt;font color="#2040a0"&gt;getObject&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;    &lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;    &lt;strong&gt;throw&lt;/strong&gt; &lt;strong&gt;new&lt;/strong&gt; &lt;font color="#2040a0"&gt;IllegalStateException&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#008000"&gt;&amp;quot;Should not have got here&amp;quot;&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;  &lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;  @&lt;font color="#2040a0"&gt;Override&lt;/font&gt;&lt;br /&gt;  &lt;strong&gt;public&lt;/strong&gt; &lt;font color="#2040a0"&gt;Representation&lt;/font&gt; &lt;font color="#2040a0"&gt;toRepresentation&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;Object&lt;/font&gt; &lt;font color="#2040a0"&gt;source&lt;/font&gt;, &lt;font color="#2040a0"&gt;Variant&lt;/font&gt; &lt;font color="#2040a0"&gt;target&lt;/font&gt;, &lt;font color="#2040a0"&gt;UniformResource&lt;/font&gt; &lt;font color="#2040a0"&gt;resource&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt; &lt;strong&gt;throws&lt;/strong&gt; &lt;font color="#2040a0"&gt;IOException&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;    &lt;font color="#2040a0"&gt;Representation&lt;/font&gt; &lt;font color="#2040a0"&gt;result&lt;/font&gt; &lt;font color="4444FF"&gt;=&lt;/font&gt; &lt;strong&gt;null&lt;/strong&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;    &lt;strong&gt;if&lt;/strong&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;source&lt;/font&gt;.&lt;font color="#2040a0"&gt;getClass&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;.&lt;font color="#2040a0"&gt;getAnnotation&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;XmlRootElement&lt;/font&gt;.&lt;strong&gt;class&lt;/strong&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt; &lt;font color="4444FF"&gt;!&lt;/font&gt;&lt;font color="4444FF"&gt;=&lt;/font&gt; &lt;strong&gt;null&lt;/strong&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;      &lt;font color="#2040a0"&gt;result&lt;/font&gt; &lt;font color="4444FF"&gt;=&lt;/font&gt; &lt;strong&gt;new&lt;/strong&gt; &lt;font color="#2040a0"&gt;JaxbRepresentation&lt;/font&gt;&lt;font color="4444FF"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#2040a0"&gt;Object&lt;/font&gt;&lt;font color="4444FF"&gt;&amp;gt;&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;source&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;    &lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;    &lt;strong&gt;else&lt;/strong&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;      &lt;font color="#2040a0"&gt;result&lt;/font&gt; &lt;font color="4444FF"&gt;=&lt;/font&gt; &lt;strong&gt;super&lt;/strong&gt;.&lt;font color="#2040a0"&gt;toRepresentation&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;source&lt;/font&gt;, &lt;font color="#2040a0"&gt;target&lt;/font&gt;, &lt;font color="#2040a0"&gt;resource&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;    &lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;    &lt;strong&gt;return&lt;/strong&gt; &lt;font color="#2040a0"&gt;result&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;  &lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;  .....&lt;br /&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;hr&gt;&lt;br /&gt;Great, so we have a Converter, how do we make Restlet use this converter for XML. In my &lt;span style="font-weight:bold;"&gt;common&lt;/span&gt; maven module (shared between client and web), I define a file in &lt;span style="font-style:italic;"&gt;META-INF/services/org.restlet.engine.converter.ConverterHelper&lt;/span&gt;, and in that file, I have a single entry defining my custom converter. Now when the client and service code use the &lt;span style="font-style:italic;"&gt;common&lt;/span&gt; library, they will use the Custom Converter I have defined for JAXB.&lt;br /&gt;Thus, to illustrate the change, my new resources for Orders and Order are shown below:&lt;br /&gt;&lt;hr/&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;@&lt;font color="#2040a0"&gt;Component&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;value&lt;/font&gt; &lt;font color="4444FF"&gt;=&lt;/font&gt; &lt;font color="#008000"&gt;&amp;quot;/orders&amp;quot;&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;@&lt;font color="#2040a0"&gt;Scope&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;value&lt;/font&gt; &lt;font color="4444FF"&gt;=&lt;/font&gt; &lt;font color="#2040a0"&gt;BeanDefinition&lt;/font&gt;.&lt;font color="#2040a0"&gt;SCOPE_PROTOTYPE&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;strong&gt;public&lt;/strong&gt; &lt;strong&gt;class&lt;/strong&gt; &lt;font color="#2040a0"&gt;OrdersResource&lt;/font&gt; &lt;strong&gt;extends&lt;/strong&gt; &lt;font color="#2040a0"&gt;ServerResource&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt; &lt;br /&gt; ..... &lt;br /&gt; @&lt;font color="#2040a0"&gt;Post&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#008000"&gt;&amp;quot;xml&amp;quot;&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;  &lt;strong&gt;public&lt;/strong&gt; &lt;font color="#2040a0"&gt;OrderDTO&lt;/font&gt; &lt;font color="#2040a0"&gt;createOrder&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;OrderDTO&lt;/font&gt; &lt;font color="#2040a0"&gt;dto&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;     ....&lt;br /&gt;     &lt;strong&gt;return&lt;/strong&gt; &lt;font color="#2040a0"&gt;createdOrderDto&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;  &lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;  ...&lt;br /&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;@&lt;font color="#2040a0"&gt;Component&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;value&lt;/font&gt; &lt;font color="4444FF"&gt;=&lt;/font&gt; &lt;font color="#008000"&gt;&amp;quot;/orders/{id}&amp;quot;&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;@&lt;font color="#2040a0"&gt;Scope&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;value&lt;/font&gt; &lt;font color="4444FF"&gt;=&lt;/font&gt; &lt;font color="#2040a0"&gt;BeanDefinition&lt;/font&gt;.&lt;font color="#2040a0"&gt;SCOPE_PROTOTYPE&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;strong&gt;public&lt;/strong&gt; &lt;strong&gt;class&lt;/strong&gt; &lt;font color="#2040a0"&gt;OrderResource&lt;/font&gt; &lt;strong&gt;extends&lt;/strong&gt; &lt;font color="#2040a0"&gt;ServerResource&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;  @&lt;font color="#2040a0"&gt;Put&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;value&lt;/font&gt; &lt;font color="4444FF"&gt;=&lt;/font&gt; &lt;font color="#008000"&gt;&amp;quot;xml&amp;quot;&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;  &lt;strong&gt;public&lt;/strong&gt; &lt;strong&gt;void&lt;/strong&gt; &lt;font color="#2040a0"&gt;updateOrder&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;OrderDTO&lt;/font&gt; &lt;font color="#2040a0"&gt;orderDTO&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;    &lt;strong&gt;try&lt;/strong&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;      &lt;font color="#2040a0"&gt;String&lt;/font&gt; &lt;font color="#2040a0"&gt;id&lt;/font&gt; &lt;font color="4444FF"&gt;=&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;String&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt; &lt;font color="#2040a0"&gt;getRequest&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;.&lt;font color="#2040a0"&gt;getAttributes&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;.&lt;font color="#2040a0"&gt;get&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#008000"&gt;&amp;quot;id&amp;quot;&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;      &lt;font color="#2040a0"&gt;orderDTO&lt;/font&gt;.&lt;font color="#2040a0"&gt;setOrderId&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;Long&lt;/font&gt;.&lt;font color="#2040a0"&gt;parseLong&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;id&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;      &lt;font color="#2040a0"&gt;persistOrder&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;orderDTO&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;    &lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;    &lt;strong&gt;catch&lt;/strong&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;RuntimeException&lt;/font&gt; &lt;font color="#2040a0"&gt;e&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;      &lt;font color="#2040a0"&gt;getResponse&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;.&lt;font color="#2040a0"&gt;setStatus&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;Status&lt;/font&gt;.&lt;font color="#2040a0"&gt;CLIENT_ERROR_BAD_REQUEST&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;      &lt;strong&gt;throw&lt;/strong&gt; &lt;strong&gt;new&lt;/strong&gt; &lt;font color="#2040a0"&gt;OrderException&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#008000"&gt;&amp;quot;Failed to update an order&amp;quot;&lt;/font&gt;, &lt;font color="#2040a0"&gt;e&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;    &lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;  &lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;    .....&lt;br /&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;hr&gt;&lt;br /&gt;We are no longer returning Representations in the above code. Quite similar to JAXRS, wouldn't you say ;-)? On the Client end, the OrderClientImpl no longer deals with Representations but only OrderDTOs as shown below:&lt;br /&gt;&lt;hr/&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;strong&gt;public&lt;/strong&gt; &lt;strong&gt;class&lt;/strong&gt; &lt;font color="#2040a0"&gt;OrderClientImpl&lt;/font&gt; &lt;strong&gt;implements&lt;/strong&gt; &lt;font color="#2040a0"&gt;OrderClient&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;  ....&lt;br /&gt;&lt;br /&gt;  &lt;strong&gt;public&lt;/strong&gt; &lt;font color="#2040a0"&gt;OrderDTO&lt;/font&gt; &lt;font color="#2040a0"&gt;createOrder&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;OrderDTO&lt;/font&gt; &lt;font color="#2040a0"&gt;order&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt; &lt;strong&gt;throws&lt;/strong&gt; &lt;font color="#2040a0"&gt;OrderException&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;    &lt;font color="#2040a0"&gt;ClientResource&lt;/font&gt; &lt;font color="#2040a0"&gt;ordersResource&lt;/font&gt; &lt;font color="4444FF"&gt;=&lt;/font&gt; &lt;strong&gt;new&lt;/strong&gt; &lt;font color="#2040a0"&gt;ClientResource&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;baseUri&lt;/font&gt; &lt;font color="4444FF"&gt;+&lt;/font&gt; &lt;font color="#2040a0"&gt;ORDERS_RESOURCE_URI&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;strong&gt;try&lt;/strong&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;      &lt;strong&gt;return&lt;/strong&gt; &lt;font color="#2040a0"&gt;ordersResource&lt;/font&gt;.&lt;font color="#2040a0"&gt;post&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;order&lt;/font&gt;, &lt;font color="#2040a0"&gt;OrderDTO&lt;/font&gt;.&lt;strong&gt;class&lt;/strong&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;    &lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;    &lt;strong&gt;catch&lt;/strong&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;ResourceException&lt;/font&gt; &lt;font color="#2040a0"&gt;e&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;      &lt;strong&gt;throw&lt;/strong&gt; &lt;strong&gt;new&lt;/strong&gt; &lt;font color="#2040a0"&gt;OrderException&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#008000"&gt;&amp;quot;Error Creating an Order&amp;quot;&lt;/font&gt;, &lt;font color="#2040a0"&gt;e&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;    &lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;  &lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;  &lt;strong&gt;public&lt;/strong&gt; &lt;strong&gt;void&lt;/strong&gt; &lt;font color="#2040a0"&gt;updateOrder&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;OrderDTO&lt;/font&gt; &lt;font color="#2040a0"&gt;order&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt; &lt;strong&gt;throws&lt;/strong&gt; &lt;font color="#2040a0"&gt;OrderException&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;    &lt;font color="#2040a0"&gt;ClientResource&lt;/font&gt; &lt;font color="#2040a0"&gt;ordersResource&lt;/font&gt; &lt;font color="4444FF"&gt;=&lt;/font&gt; &lt;strong&gt;new&lt;/strong&gt; &lt;font color="#2040a0"&gt;ClientResource&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;baseUri&lt;/font&gt; &lt;font color="4444FF"&gt;+&lt;/font&gt; &lt;font color="#2040a0"&gt;ORDERS_RESOURCE_URI&lt;/font&gt; &lt;font color="4444FF"&gt;+&lt;/font&gt; &lt;font color="#008000"&gt;&amp;quot;/&amp;quot;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;      &lt;font color="4444FF"&gt;+&lt;/font&gt; &lt;font color="#2040a0"&gt;String&lt;/font&gt;.&lt;font color="#2040a0"&gt;valueOf&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;order&lt;/font&gt;.&lt;font color="#2040a0"&gt;getOrderId&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;    &lt;strong&gt;try&lt;/strong&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;      &lt;font color="#2040a0"&gt;ordersResource&lt;/font&gt;.&lt;font color="#2040a0"&gt;put&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;order&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;    &lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;    &lt;strong&gt;catch&lt;/strong&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#2040a0"&gt;ResourceException&lt;/font&gt; &lt;font color="#2040a0"&gt;e&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt; &lt;font color="4444FF"&gt;&lt;strong&gt;{&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;br /&gt;      &lt;strong&gt;throw&lt;/strong&gt; &lt;strong&gt;new&lt;/strong&gt; &lt;font color="#2040a0"&gt;OrderException&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;(&lt;/strong&gt;&lt;/font&gt;&lt;font color="#008000"&gt;&amp;quot;Order Update Failed&amp;quot;&lt;/font&gt;, &lt;font color="#2040a0"&gt;e&lt;/font&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;)&lt;/strong&gt;&lt;/font&gt;&lt;font color="4444FF"&gt;;&lt;/font&gt;&lt;br /&gt;    &lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;  &lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="4444FF"&gt;&lt;strong&gt;}&lt;/strong&gt;&lt;/font&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;hr/&gt;&lt;br /&gt;&lt;br /&gt;I like the simplicity of the above and cannot wait to see the release of Restlet 2.0 that has the additional converters built in. &lt;br /&gt;&lt;br /&gt;For those interested, I have a &lt;a href="http://home.comcast.net/~acharya.s/java/Restlet2.0-jaxb-converter.zip"&gt;maven project example available for download&lt;/a&gt;. The project provided uses the custom JAXB converter. To execute the project, one would need to use JDK1.6.X and maven 2.0.9 or higher. To view an integration test in action execute, "&lt;span style="font-style:italic;"&gt;mvn install&lt;/span&gt;" from the root level of the project. The result should be something like:&lt;br /&gt;&lt;hr/&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;-------------------------------------------------------&lt;br /&gt; T E S T S&lt;br /&gt;-------------------------------------------------------&lt;br /&gt;Running com.welflex.order.IntegrationTest&lt;br /&gt;log4j:WARN No appenders could be found for logger (com.welflex.client.ProductClientImpl).&lt;br /&gt;log4j:WARN Please initialize the log4j system properly.&lt;br /&gt;Aug 28, 2009 8:59:55 PM org.restlet.engine.http.StreamClientHelper start&lt;br /&gt;INFO: Starting the HTTP client&lt;br /&gt;20:59:55 DEBUG - com.welflex.order.rest.ProductsResource.getProducts(44) | Getting Products in JSON Format&lt;br /&gt;Number of Available Products:3&lt;br /&gt;Product Id:663123&lt;br /&gt;Product Id:9912123&lt;br /&gt;Storing the order...&lt;br /&gt;Aug 28, 2009 8:59:55 PM org.restlet.engine.http.StreamClientHelper start&lt;br /&gt;INFO: Starting the HTTP client&lt;br /&gt;20:59:56 DEBUG - com.welflex.order.rest.OrdersResource.createOrder(45) | Call to post an order:..........&lt;br /&gt;Updating the order...&lt;br /&gt;Order successfully&lt;br /&gt;Retrieving the order...&lt;br /&gt;Deleting the order..&lt;br /&gt;20:59:56 DEBUG - com.welflex.order.rest.OrderResource.getOrder(86) | Requested order with id:5499731937442305515&lt;br /&gt;20:59:56 DEBUG - com.welflex.order.rest.ApplicationStatusService.getStatus(21) | In Order Status Service :class org.restlet.resource.ResourceException&lt;br /&gt;Expected Order to not be found. Look at the server stack we got back&lt;br /&gt;com.welflex.exception.OrderNotFoundException: Error obtaining Order&lt;br /&gt; at com.welflex.client.OrderClientImpl.getOrder(OrderClientImpl.java:60)&lt;br /&gt; at com.welflex.order.IntegrationTest.testLifeCycle(IntegrationTest.java:131)&lt;br /&gt; at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)&lt;br /&gt; at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)&lt;br /&gt; at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)&lt;br /&gt; at java.lang.reflect.Method.invoke(Method.java:597)&lt;br /&gt; at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;hr&gt;&lt;br /&gt;More on Restlet 2.0 once its released. For now, maybe I should probably look toward cleaning up the JaxbConverter and submitting it to Restlet or better still head in the search of kindred spirits, if you know what I mean ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4667121987470696359-7226916108904703456?l=sleeplessinslc.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/OidcY/~4/2qwFzGmxBkM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://sleeplessinslc.blogspot.com/feeds/7226916108904703456/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4667121987470696359&amp;postID=7226916108904703456" title="8 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/7226916108904703456?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4667121987470696359/posts/default/7226916108904703456?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/OidcY/~3/2qwFzGmxBkM/restlet-20-example-using-spring-maven.html" title="Restlet 2.0 example using Spring, Maven, Annotations and a Custom Converter" /><author><name>Sanjay Acharya</name><uri>http://www.blogger.com/profile/01933976956977901677</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="28" src="http://3.bp.blogspot.com/-QuUnYIQQ4Ck/Txo3-4hza9I/AAAAAAAABBQ/QMZO-wT7v6A/s220/profile.jpg" /></author><thr:total>8</thr:total><feedburner:origLink>http://sleeplessinslc.blogspot.com/2009/08/restlet-20-example-using-spring-maven.html</feedburner:origLink></entry></feed>

