Friday, October 3, 2008

Deploying RestEasy in Tomcat 6.0

Since I was successful deploying Jersey to Tomcat 6.0, I decided to check out RestEasy from JBoss. One issue I ran into with Jersey was it's inability to XML serialize a collection of objects. This is bug ID is 18, and it is fixed for the 1.0 release (however a beta of this does not appear to be available yet), but I decided to see if RestEasy (a non-reference implementation) has the same issue.

UPDATE I have discovered from some testing that neither XML nor JSON is currently supported as a return type for a Collection/List of items. An issue has been filed for RestEasy for JSON (RESTEASY-134) with an RC1 delivery, however I did not see one for XML.

Here are the steps I used to get this working:

  1. Download RestEasy from the JBoss website: http://www.jboss.org/resteasy/
  2. Follow the steps 2 to 4 of my previous blog Deploying Jersey in Tomcat 6.0
  3. Download and create a Eclipse library for JavaAssist. Include this in your WEB project (or provide the javaassist.jar for Tomcat)
  4. Create a new RestEasy library in eclipse which contains the content of the rest easy installation lib location. You can probably skip a few of the jars if you do not need all the functionality (such as jyaml.jar and possibly mail.jar)
  5. Modify your web.xml for your project to include the following (this comes right from the sample web.xml in the rest easy install):

    <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>TestWeb</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> <context-param> <param-name>resteasy.scan</param-name> <param-value>true</param-value> </context-param> <!-- set this if you map the Resteasy servlet to something other than /* <context-param> <param-name>resteasy.servlet.mapping.prefix</param-name> <param-value>/resteasy</param-value> </context-param> --> <!-- if you are using Spring, Seam or EJB as your component model, remove the ResourceMethodSecurityInterceptor --> <context-param> <param-name>resteasy.resource.method-interceptors</param-name> <param-value> org.jboss.resteasy.core.ResourceMethodSecurityInterceptor </param-value> </context-param> <listener> <listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class> </listener> <servlet> <servlet-name>Resteasy</servlet-name> <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class> </servlet> <servlet-mapping> <servlet-name>Resteasy</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> </web-app>
  6. Start your tomcat in Eclipse and you should be good to go!

Thursday, October 2, 2008

Deploying Jersey in Tomcat 6.0

Jersey is a reference implementation for the JAX-RS (JSR-311) for building RESTful Web services. It is nearing approval with the JSR committees. While there are many wikis and articles in using Jersey with Netbeans (downloading the Netbeans 6.1 EE package includes everything you need for JSR-311), there was very little information on using Tomcat 6.0 with Jersey. After piecing together several blogs, I was able to get a simple resource working in Tomcat using JSR-311.

The following are the steps I used to get this working:

  1. Download and unjar the Jersey distribution (I used 0.8) from https://jersey.dev.java.net/ to a location on your system (lets call it JERSEY_HOME for this article).
  2. Download and install the Java-WS distribution (I used 2.1) from https://jax-ws.dev.java.net/. (lets call it JAXWS_HOME for this article).
  3. Rama Pulavarthi wrote a blog (in fact the key for me) in configuring tomcat to reference the Jersey distribution jars. To summarize, in TOMCAT_HOME/conf/catalina.properties modify the shared.loader property entry to point to your JAXWS_HOME/lib/*.jar. Mine looks like this:

    shared.loader=C:/dev/jaxws-ri/lib/*.jar
  4. Create a new Dynamic Web Project in Eclipse using Tomcat 6.0 as the application server.
  5. Create a new library in which you add the following JARs:
    1. JERSEY_HOME/lib/asm-3.1.jar
    2. JERSEY_HOME/lib/jersey.jar
    3. JERSEY_HOME/lib/jsr311-api.jar
  6. Next modify the web.xml to include the adaptor for jersey. Most of the Blogs refer to a different class than what appears in 0.8 I am not certain which is the right class, only the following works for me (and the documented one is not available throught the downloads!):

    <servlet> <servlet-name>ServletAdaptor</servlet-name> <servlet-class>com.sun.jersey.impl.container.servlet.ServletAdaptor</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>ServletAdaptor</servlet-name> <url-pattern>/resources/*</url-pattern> </servlet-mapping> <session-config> <session-timeout>30</session-timeout> </session-config>
  7. If you start Tomcat, you will see the following error:

    com.sun.jersey.api.container.ContainerException: The ResourceConfig instance does not contain any root resource classes.

    This error is due to not providing any root RESTful resources.

  8. Create a new class and include the following:

    import javax.ws.rs.GET; import javax.ws.rs.ProduceMime; import javax.ws.rs.Path; @Path("/test") public class TestResource { @GET @ProduceMime("text/html") public String getMessage( ) { return "hello"; } }
  9. Start and test the application with the following url:

    http://localhost:8080/appName/resources/test

    and you should see a hello in your web-browser.

Making your servlet application URLs more Restful

If you are a developer who likes to work with Java you may have come to know REST and Restful Web Services. The real advantage of REST is its ability to get rid of some of the "webspeak" and make your URLs a little more platform independent. As a client developer it is much nicer to make a request to http://somehost/Application/stamp/5533 to retrieve stamp 5533 than the traditional http://somehost/Application/servlet/StampServlet?id=5533. Theoretically you could rewrite your application services layer without modifying the client. If you are not familiar with REST and Restful Web Services, a good dissertation on this can be found here by Roger L. Costello.

So all of this is nice, but how can we apply this to a servlet-based Web Application? There are projects out there such as the Java Restlet API, and while I think this is good, it does mean essentially having a non-servlet compatible solution (since the Restlet takes the place of a servlet). Instead, you can take advantage of some of the REST themes by using servlet-based Web Applications following these steps:

  • We want to write a Rest-like servlet for accessing Stamps. We have a servlet of the class StampServlet which is mapped in the web.xml of our servlet container as stamp. This would look like the following:
    <servlet> <description>Servlet for processing Stamp Restful requests</description> <servlet-name>stamp</servlet-name> <servlet-class>org.javad.stamp.servlet.StampServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>stamp</servlet-name> <url-pattern>/stamp/*</url-pattern> </servlet-mapping>

    The key here is the /* in the url-pattern of the servlet-mapping. This will mean any URI that is received that starts with "stamp" will send it to the StampServlet, but we can use any of the information on the URI chain to help direct the servlet to process the request in a Restful way. For example, if we are retrieving the details of a stamp our URL would look like:
    http://hostname/StampApp/stamp/563

    Using the GET method, where the ID of the stamp in this case is 563. If this was a modify function, the URL would look similar only a method of PUT would be used.
  • REST uses many of the less-popular methods of HTTP. In particular the PUT and DELETE methods. Fortunately, the HttpServlet class does implement these with the doPut(HttpServletRequest,HttpServletResponse) and doDelete(HttpServletRequest,HttpServletResponse) methods. If you are not comfortable using these methods (for example the HttpServlet Javadoc does mention PUT for use in placing files on the server like FTP), we can make our URLs be a little less Restful, but still Restlike by using POST method and inserting a keyword after the ID of the object in question. I should note, that for some applications like GWT, using protocols other than POST or GET is difficult. In GWT we can attach a header value (X-HTTP-Method-Override) to indicate we'd like to use DELETE, but it is still sent to the POST method receiver initially. In this case, using a POST method URL along with the method override header we can still have a Restful URL that would look like the following:
    <form action="http://hostname/StampApp/stamp/563" method="POST"> </form>

    More practical would be the use in an AJAX application using the XMLHttpRequest in Javascript (since we can override the X-HTTP-Method-Override header:
    var req = new XMLHttpRequest(); req.open( "POST", "http://hostname/StampApp/stamp/563" ); req.setRequestHeader("X-HTTP-Method-Override","DELETE"); req.send();
  • URL Construction is great, but how do I make use of this in my servlet doPOST( )? Since we mapped the servlet with a /*, anything to the right of the stamp in the URI is treated as part of the PathInfo. Therefore within your doPOST() method, you can request the path-info and take the appropriate action. Similar to the following:
    protected void doPost(HttpServletRequest request, HttpServletResponse response) { String pathInfo = request.getPathInfo(); Method method = request.getHeader("X-HTTP-Method-Override"); if( pathInfo.isEmpty() ) { createNewStamp( ); // purely a POST } else if( method != null && pathInfo != null) { long id = Integer.parseInt( pathInfo.split("/")[0]); if ("DELETE".equalsIgnoreCase( method ) ) { doDelete(request,response); // or call deleteStamp(id); } else if ( "PUT".equalsIgnoreCase( method )) { doPut( request, response ); // or call modifyStamp(id); } else { // if there are further elements in the pathInfo call the appropriate code... } } else { log("POST method called for stamp details without Method Override header. Use GET method to retrieve stamp details or specify a Method Override header."); } }

While this is not perfect, it is certainly easier to program a client to a URI like stamp/563 than the traditional way of stamp?id=563&action=DELETE. In the above example, it is likely that the code for servicing an action like Delete is in a specified method, so instead of trying to call the doDelete( ) simply a call to deleteStamp(id) would probably be more appropriate. Using this technique allows you to support both methods of processing your objects in a consistent way, while being flexible in support for the client technology. While it does muck up your doPost() methods a little bit this is a minor tradeoff for more readable URIs.

I should also mention that additional values in the pathInfo are used in Rest to indicate additional actions to take place against that object. For example:

http://hostname/StampApp/stamp/563/catalogues

With a method of GET would refer to a request to retrieve the catalogues for the stamp with the ID 563. In this situation having a controller (such as that provided by the Restful application) would definitely help in forwarding these to the correct service. Depending on the complexity of your application, you may be able to simply do this internally within your servlet such as in the else case mentioned above, however for more than a few actions this can be complex. Especially if catalogues (using the example above) can exist outside of the context of a stamp. This would mean you'd have to provide a servlet or some application that can process catalogues and find a way to tie the stamp servlet with the catalogue servlet. The worst case I can think of in my application would be trying to get all of the stamps that are in a country, filtered by an album in a stamp collection. This might look like:
http://hostname/StampApp/collection/56/album/25/country/76/stamps

As you can see, this is not quite as readable. Since I can also get stamps by album or simply by collection I might be more prone to simple request the stamps for collection 56 and then take on the album/country ids as queryString data:

http://hostname/StampApp/collection/56/stamps?album=25&country=76

Not pure Rest, but Rest-like. If I truly did want to retain the Restful URI, I would likely write a controller which returned stamps, and if the pathInfo of the GET request for the collection servlet contained stamps in it I would directly call it passing the pathInfo and then allow the controller to decide how to filter the URI (in my case I have a StampFilter object which accepts the three objects and calls the appropriate JPA Query based on the filter setup so this would be quite easy for me to do).

Monday, September 29, 2008

Remote Assistance - Not always able to connect

I ran into a situation where I could not connect to my fathers PC using Remote Assistance. Now, given that he lives about 3000 miles away it is essential that I am able to connect with Remote Assistance to help him with miscellanious activities. I discovered that the Remote Assistance files are really nothing more than XML, and upon edting the XML I realized there was a series of invalid IPs in the UPLOADDATA block's RPTICKET attribute. Upon removing the invalid IPs I was able to immediately connect. I am not sure where they all came from (some were the obvious local IPs behind his firewall).

ExtJS ComboBox - Act like HTML Select

At first I struggled to get my ExtJS ComboBoxes to act like a straight HTML Select. In my application, I have a grid which loads the data into a store via AJAX. Later, create or edit dialogs display which contain a combobox of items represented by the store. Rather than load these again from the server, I wanted to reuse the data from the store. The problem I had is selecting a value in the dialog would filter the grid using the same filter. It appeared that ExtJS was applying the filter on the store rather than the view components. My original solution involved creating an array of items after the store had been loaded and passing this array to a combobox constructor. After further research, I was mistaken and the following needs to be done to make the ExtJS Combobox components would as a separate filter like an HTML Select:

  1. Provide a hiddenId option to the ComboBox constructor.
  2. Set the triggerAction to 'all'. Doing so essentially clears the filter and will treat the combobox like it is querying from the store separately.
  3. Ensure the mode is set to 'local'.

Here is an example of a configuration:

org.javad.CatalogueHelper = { getCatalogueSelection : function(id, options) { options = options || {}; // initialize if undefined var catalogues = new Ext.form.ComboBox(Ext.applyIf(options, { id: id, // Passed in id to create composite fields. fieldLabel: 'Catalogue', allowBlank : false, hiddenName: id + '-selected', name : id, mode:'local', editable: false, valueField: 'id', // from store, what to store in FORM displayField: 'displayString', // Value to display in Select store: org.javad.CatalogueStore, hiddenId: id + '-value', width: 200, triggerAction: 'all', // key to clear filter selectOnFocus: true })); return catalogues; } };

Tuesday, August 26, 2008

JPA and Optional Associations

I was writing some unit tests to test a few of my queries and noticed they were failing to return results (even though the resultant rows were clearly in the database). Looking into my changes, the only differences was that I recently added the EclipseLink eclipselink.join-fetch for two one-to-many relationships. From looking at the resultant SQL, it became clear what the problem was. By adding these join-fetch statements, my query became more efficient (since I didn't have subsequent row-by-row lazy fetches later), but it also became invalid in some circumstances. In particular, the fetch join added some AND statements to the WHERE clause whereby the foreign key id was equal to the primary table id. However if the many-side relationship is empty, then this statement will not return any rows. I think the way around this would be to box the AND statement in a compound OR statement with an exists condition. Currently to my knowledge the JPA implementations do not support this, and I am going to research whether or not this is achievable by manually modifying the join-fetch statement.

Friday, August 22, 2008

Refactoring Followup - Strange Side Effect

While I was quick to point out that my refactoring of my services end up being a little bit painful on the Swing Heavy-client side, when it came time to refactor my web-services client (currently a series of dedicated servlets used by my mobile devices) it was surprisingly a clean update. Why was this? What lesson can I pull from this. The main one was that the web-services code was very specific in its function which was mainly to parse the query parameters and marshall the appropriate calls to the service to obtain the results. Since I already had tests around the services calls, the main work I had to do with the refactor was re-insert a lot of the XML JAXB annotations to produce the appropriate XML output.

As an aside, while looking at MoXY with EclipseLink, I noticed their tools to assist in providing a true WebServices implementation. This might be an area to look into adopting (in providing a true JAX-WS implementation).

Friday, August 15, 2008

Refactoring: Biting off more than you can chew?

So as most can assert from reading my blog I have developed a stamp tracking software "suite" of tools. The core of this was based off a JPA implementation which was recently moved to EclipseLink. With some of the new tools available to Eclipse for use with JPA (in particular Dali), I decided to think about reorganizing my services and trying to streamline some of my code (Using MappedSuperClasses as abstract parents for example). I focussed on my StampModel module which had a pretty decent unit test coverage of around 80% (some of the code not covered include error handling and a lot of my upgrade code) and was also where all of my entities existed. I even created a bugzilla entry for this work so that I could track my progress. I estimated it would take me no more than 12 hours. Well, 30+ hours later I finally have repackaged, rewritten or revamped the module (and database tables). For the first time in nearly a week I was able to open my Swing based editor last night and manage my collection. I still have some outstanding issues, but my refactoring is pretty much complete. There are a couple of lessons I took away from this.
  1. Never assume how long it will take. Invariably something will come up (and I have to admit the Olympics coverage may have pulled my attention away from eclipse on occasion).
  2. When I started refactoring I relied on my unit tests and decided to make updates to the Swing client after refactoring was completed. This was a mistake as often I had to think back to what the update was rather than making the change immediately (I am thinking along the lines of repackaging, changing initialization code etc.) Overall these changes tended to be pretty simplistic (change package X to package Y) but occasionally a DAO that I did not particularly like in the previous module was changed. In one occasion, the new DAO did not really fit and I had to rewrite some controller code (but at least it is better now).
  3. Part of my refactoring was to move my entities which were annotated to be orm.xml based. I should have done this first without changing the data-model. Changing the database schema along with moving the entities to orm.xml created a lot of thrashing to work through.

Tuesday, August 5, 2008

Certifications even for the experienced?

Those of you who know me know that I sometimes shun the world of academia. Not that I do not think education is useful. I do. I am the current holder of two bachelor degrees and numerous certifications and I can honestly say they have proven useful in my career. But too often I see a candidate interviewing at my company who has years of academic training (multiple bachelor degrees, masters degrees, certifications up the wazoo), but they can not solve a simple puzzle put in front of them, or they display a complete lack of communication skills. After I was Java certified in 2003, I decided that I would take additional Java certifications to advance my knowledge. To date this has not happened, largely because my life is considerably busier and I much prefer to tinker and explore technologies than read the official way of doing something. Attending conferences has also been a pleasure to increase my awareness of new technologies.

Recently while being disposed, I was flipping though a copy of the Web Component Developer prep-book put out by Manning some years ago. It was a decent book, and as I flipped through the pages I found myself reading up on the techologies that I used on a daily basis, as well as advise my teams in their use. I feel in general, dispite the maturity of many Web Component pieces (such as Servlet, TAGs and EL), I feel many developers really do not understand why they are using them, or when to use one technology (for example TAGs) over another (such as Servlets). I proposed to the team that reading a book on such a subject matter might prove useful for their benefit. As a technology leader, I therefore felt it only appropriate that I study and become a Sun Certified Web Component Developer.

So this leads me to the conclusion that I suppose I need to engage in the duties of reading a book (for this current challenge I have chosen Head First Servlets & JSP from O'Reilly covering the 2nd edition), preparing myself and actually taking the exam. Based on my study habits, the best motivator I can think of is to schedule the exam now, that way I have to be prepared prior to the actual "writing" of the exam.

Sunday, July 27, 2008

Automatically recording Create/Update Timestamps with JPA

Now that I am using Bugzilla to track various bugs and enhancements for my projects, I finally got around to addressing this issue of "Provide the ability to record the create/update timestamp." for my stamp objects. This seems simple enough, and most database applications record this information, however by default this is not something that is automated by the JPA frameworks (unlike the Primary Key with the @Id annotation). Let us first examine the ways we could accomplish this:
  1. Provide a database trigger to try and insert the timestamps automatically.
  2. Manually set them (or have each persistent service set them) before performing a persist() operation with an EntityManager.
  3. Use aspects to dynamically insert the timestamp.
  4. Provide an EntityListener which automatically sets the creation/modification timestamp at persist time
  5. .

Obviously the first solution is very database specific and is not really tied to the JPA code. The second solution is likely to be error prone and easily missed. The final solution is the best way to handle his. Daniel Pfeifer provides an excellent walkthrough of this technique in his blog here. I have a few comments on this. First off, the concept of an entity listener, does not follow the normal "implement this interface" convention. An entity listener is any POJO class which contains one or more methods in the format:
public void someMethod( Object obj )


It should be noted that there are javax.persistence annotations for each of the JPA lifecycle states. In the case of create timestamps, annotating a method with @PrePersist will allow it to be used to provide the creation timestamp. For the modify timestamp, annotating a method with @PreUpdate will call this method on persisting an entity which was previously persisted. The entity listener can be registered either in the orm.xml file (as described by Daniel Pfeifer) or one the Entity class itself using the annotation @EntityListeners( class ... ). Personally I prefer this technique as it allows me to programatically tie a class with its behavior (such as storing timestamps on create/update) without having an external configuration. Using an external configuration in several modules, and unit tests quickly becomes muttled in that you forget to update the file under test etc. It also increases the developer's awareness of this association, and to be candid, it is unlikely that I really want to swap out the persistence timestamp handling at package time with a different solution. Since the annotation is applied to an abstract @MappedSuperClass annotated class, any implementing classes will automatically inherit this behavior. I might change my stance on this approach in the future, but at least for this this seems to be the right way to approach this.