JavaOne 2010 – JAX-WS.Next: Future Directions and Community Input

September 21st, 2010 § Leave a Comment


I thought that I should mention an interesting BOF: JAX-WS.Next: Future Directions and Community Input. JAX-WS, as you know, is the worthy successor of JAX-RPC, improving on it in many ways and it has become increasingly important since most app servers are supporting web profiles. It is pretty much the standard way of doing web services in the Java EE/light EE world.
This session presented many ideas being explored by Sun/Oracle engineers in the RI v2.2.2, most notably how JAX-WS will now take advantage of the Servlet 3.0 spec (1 request can be serviced by many threads) and the wsdl pluggability (what you see on Tomcat 7 would become portable to other containers). It was stressed quite a few times that the ideas discussed in this BOF still need final approval from the JCP.
Some of the features being proposed:

  • Support for stateful web services for H/A (support for broken HTTP connections)
  • Schema validation: That’s a welcome addition as most people do it (not necessarily in the production environment) one way or another in one-off ways; the class would be annotated with the @SchemaValidation; this would ensure that input/output are properly validated
  • Official support for doc/literal wrapper style
  • The ability to close Proxy.close() and have a chance to clean up resources
  • WSDL 1.1 binding extensions for SOAP 1.2; this would allow the developer to run with the -extension
  • MTOM Policy support via @MTOM to allow for the optimized serialization of wsdl/messages; the policy itself gets published in the wsdl
  • Addressing policy: long-running operations would send the response in another HTTP Connection; also allow for anonymous/non-anonymous response mechanisms
  • Finally (and most important) support for asynchronous behavior on the server side; the client models would remain the same with a choice of polling or callback but the server side invoke method returns void (i.e. immediately) and does not block

Most of these features are already in Glassfish, WebSphere and WebLogic.

JavaOne 2010 – KeyNote

September 21st, 2010 § 2 Comments


I decided to attend the JavaOne KeyNote hoping to hear some important announcements even if the price to pay was pretty steep; you do have to sit after all in a huge auditorium and stoically listen to executives going through an incredibly boring, extremely well rehearsed (to the point of being comically predictable) and amazingly unassuming (a 5-minute intro concocted by Oracle lawyer warns you that nothing in this session should be considered as a commitment, rather these are just forward looking statements and all the assurances about deliveries/roadmaps/future versions are nothing but hopeful wishes) presentation. But there were a few points that could be taken away from this keynote.
So let’s start with the different JVMs: It was made clear that Sun HotSpot was the JVM of choice and actually a JRockit engineer demonstrated a “flight-recorder” type of tool that records the past n seconds of all events in your VM so they can be replayed and analyzed before a dramatic event. The JRockit Flight-Recorder itself targets the Sun HotSpot as well as the JRockit VM. You get the feeling that the two will converge and that HotSpot has the edge.
On the much anticipated JDK 7 issue Oracle promised two releases, one in 2011 and one in 2012, but again these dates should be taken with a grain of salt given all the legal disclaimers. Three projects were prominently listed: Project Coin (to increase the productivity), Project Jigsaw (to modularize the JDK which has grown too huge – startups, for example, would be faster) and Project Lambda (to add Lambda expressions, aka closures, to the Java language).

Oracle seemed very eager to stress their efforts to develop Java on all three platforms: The desktop, the server and on mobile devices. On the server side a couple of interesting announcements: Continuing the effort to support multiple languages (although project Da Vinci was not explicitly mentioned), efforts to simplify (again) EJBs (Web Beans 1.0), efforts to take JAX-WS further (to support server-side a synchronicity) and Dependency Injection to further the convergence with Spring (Rod Johnson and Bob Lee are the spec leads).

On the GUI front their was a JavaFX demo that was supposed to showcase its power as a 2D and 3D graphics platform; unfortunately the demo itself was pretty lame featuring an air hockey game with looks circa 1990, a Java coffe cup fuming and an animation built on top of a video. Adobe Flex, Nokia Qt and Microsoft WPF are probably not having nightmares over it as we speak. What’s worth noting, though, is that the JavaFX API will provide a uniform API for coders to produce desktop/native and web browser applications (i.e. produce HTML5, CSS and JavaScript code). The later is probably an admission of the success of Google GWT.

Bioware (the maker of Star Wars The Old Republic) was brought on-stage and the screens displayed dazzling graphics of the game being played. The funny thing was that Bioware does use Java (“Glassfish” and “JDK” were mentioned) but not for the sexy graphics: They use it mostly for players’ authentication and billing (sure someone needs to get paid).

All in all it seems that Oracle has grandiose plans for Java (the mobile platform with its billion of devices from regular Java-enabled cell phones to smart cards was emphasized over and over), Oracle also wanted to reassure the community about its commitment to open source (JDK7, the JavaFX controls, etc…) and finally Oracle wanted to prove that they own the full Java development stack, from the close partnership with Intel which produces code and GC profilers to the various platforms JVMs to the  development tools (NetBeans was cited a few times) . It looks good in presentations but it remains to be seen whether they can deliver on such an  aggressive roadmap and whether the community will not be scared by their licensing tactics. Many in the audiences had this dual feeling: They desperately wanted to embrace the message but at the same time were thinking of alternatives.  If Oracle delivers on its open-source promises, though, the Java platform can look forward to great days ahead.

JavaOne 2010 – about Mission-Critical Enterprise/Cloud Applications

September 20th, 2010 § Leave a Comment

I attended this morning Mission Critical Enterprise Cloud Applications presented by a cheerful Eugene Ciurana; the presentation can be found on his site and Eugene managed to make it entertaining. I will not repeat here the contents of the presentation by I will try to capture its spirit and what made it particularly interesting. Eugene was not really after explaining what a Cloud is or why you should be adopting the Cloud in the enterprise, rather he focused on the classical usage of the Cloud in a hybrid architecture. In the hybrid case, part of your application is pushed to the cloud and part is hosted in your data center. The cloud could take over the data center but that’s not necessarily happening in the immediate/medium term future for reasons outlined here:

  • SLA: As long as your SLA (Service Level Agreement) is reasonnable (say four nines as in 99.99% availablility) the cloud makes financial sense, beyond that the cloud becomes an expensive proposition
  • Uptime is not the same thing as availability! The cloud may give you the impression of excellent up-time but your overall system availability may have dependencies on critical components that are better left (for the time being) to the data center

Two important questions to ask yourself before embarking on an adventure with Cloud vendor:

  • What is the impact on business if the Cloud becomes unavailable?
  • How can I/the vendor recover from a disaster

On the other hand cloud architectures are quite diversified: Eugene mentioned PaaS (Platform as a Service) , SaaS (Software as a Service), IaaS (Infrastructure as a Service) and finally Private Clouds (buily on top of VMWare, Eucalyptus, etc…)

He noted that event-based applications tend to scale better in the Cloud, but I think that this is a general statement that’s true even outside the Cloud. Event-based applications are simply more decoupled, the producer need not know anything about the consumer and vice-versa. He also noted that all Cloud implementations seem to have the following four characteristics:

  1. Quick deployment of pre-packaged applications (typically an image that gets deployed again and again)
  2. Commoditized H/W : consider Amazon EC2 and S3, Google App Engine, Rackspace
  3. Pay as you consume billing system -> brought an interesting point from a CFO pt of view:  clouds become an operational expense
  4. Horizontal scalability is highly touted

The most interesting part of the presentation was a real-world study of a complex un-maintainable and un-scalable application that became hybridized with some functionality ported to the Cloud. The main feature of that re factoring effort was actually the introduction of an ESB (Mule)  in the data-center to allow the services to scale without being actually tied to the physical databases: all JDBC calls are placed on the bus and memcache is used to alleviate performance issues. The (calculated) side effect was the ability to easily accomplish data mining by intercepting all calls going through the ESB. In the cloud a  no-SQL datastore (such as S3) is used for write-once/consult type of access.  healhy mix of Java and Jython was introduced to speed up development time. The final stack was Tomcat – Mule – Spring.

As for load balancing,  it really depends on the vendor: Google App Engine uses a “mother-of-all-Servlets” for natural balancing while Amazon provides an explicit Elastic Load Balancer.

In conclusion it seemed that a hybrid solution represents the best compromise right now for most enterprises: Stateless/Computationally intensive services can safely reside in the cloud while your data can stay in your data center. As vendors start offering more legally-binding and stringent SLAs enterprises can start thinking of moving their infrastructure to the Cloud.

Going to JavaOne 2010

September 20th, 2010 § 2 Comments

Lab49 is at JavaOne 2010; I will be attending quite a few sessions from the Core Java Platform, Enterprise Service Architectures and the Cloud and Java EE Web Profile and Platform Technologies. Amazing track names… Anyway, it should be quite interesting, I will try to cover as much as I can in terms of sessions (technical presentations, keynotes and vendors’ offerings).

It’s Monday morning and the conference has already kicked in, I met a guy from Primavera who kindly gave me directions and explained that his software is the most popular project management software in the UK, they have been acquired by Oracle and so they deploy on WebLogic only, is this a sign of things to come?

Anyway, the first day is quite interesting;  I stopped by the Caucho booth and asked them to give me three reasons why they think that their web/app server is better than the competition (Apache, WebLogic, etc…). Alex, their engineer, volunteered four reasons:

  1. Very small stack trace which makes it incredibly useful when debugging; the main reason is that Resin’s internal are pretty much all written in-house as opposed to using every open-source library available out there
  2. Fast, really fast; they use JNI (optional) to expose the file handling and sockets components, written in C, to the application server
  3. Light-weight JEE through the support of web profiles
  4. Last and probably most important a unique clustering architecture that uses a fixed (3) number of of masters and an unlimited number of dynamic servers that allow you to scale horizontally

Next stop was Terracotta EhCache where I met Greg Luck (he presented at the Lab a few months ago, my friend Shawn Gandhi brought him in); Greg was extremely excited to present BigMemory which went public a couple of weeks ago, the official documentation is still being updated as we speak, basically it’s a way to store the cached data in a non-heap area to avoid a) the pauses due to GC b) the physical size limitations of the heap. Greg showed some impressive numbers based on stress test  with a BigMemory size of 40[Gb] where GC duration was constant (and practically zero) while a similar heap-based cache would have caused GC pauses of 260 [s].  Of course BigMemory is not a must for every application, particularly if your caching heap requirements are below 1 [Gb], in which case the serialization cost of BigMemory outweighs its advantages.

Next was a stop at JetBrains (cool t-shirt logo by the way: “I see dead code). I was given a preview of their latest Intellij IDEA (v 10) by one their friendly and knowledgeable engineer, Anna Kozlova: The IDE has full support for Scala and Clojure among other things. The Scala support, in particular, was quite impressive: Debugging, static analysis, code documentation lookup, refactoring, support for ScalaTest, seamless refactoring and code completion between inter-woven Java and Scala code, etc… It’s really worth a download.

I stopped at the bookstore located in the Hilton hotel and chatted with Andrew Lee Rubinger, author of Enterprise Java Beans 3.1 sixth edition. We discussed the merits of v3.1, the role of JPA and how EJBs can be used in an event-driven context (think MDB) through we agreed that this is not an EDA. He had interesting things to say since he is quite involved with the technologu at JBoss. Maybe we should bring him in for a talk at the Lab.

Clients like REST part 1

September 16th, 2010 § Leave a Comment

I do appreciate the versatility offered by REST-style web services when designing clients, and that’s precisely what I will be discussing in this series of posts. There is a lot to be said about a web-service approach such as REST where the client can use pretty much any HTTP-based API to retrieve/update/delete data. I will take you through the steps of defining a server-side Java class, use REST annotations to turn it into a web service and show you four ways to access such a service: Through the Apache Commons HTTP API, through the native J2SE API, through the JAX-WS API and finally through the Spring REST Client API.
This post is the first one of a mini-series:

Clients Like REST part 1 Apache HTTP Commons Client
Clients Like REST part 2 Native J2SE API Client
Clients Like REST part 3 JAX-WS client API

A few things to note:

  1. This is not about the proper design of the server-side code, I will probably devote another blog to explore best-practices in this area and comment on the use/misuse of Annotations
  2. This is not about the best protocol for data transport, again I could probably compare the merits of various data protocols for various cases/load usage/performance requirements in another blog
  3. This is about setting up four different (Java) clients to perform similar operations on the data using four different APIs, you are left to judge which one fits best your particular project
  4. The first part will illustrate a client using Apache Commons HttpClient, part 2 will illustrate a client simply using the J2SE API

Before proceeding let’s just say that in general I am not a huge fan of RESTful services. More precisely my issue with REST is the way organizations tend to implement REST services, not necessarily because of disagreements with the REST philosophy as described in Roy Fielding dissertation (I  really like chapter five). All too often REST is used as a lame excuse to expose some poorly designed functionality using XML-over-HTTP and pompously calling that “web services”. Of course, I cannot help but note that  many recent developments in REST try to precisely bridge the gap with SOAP, such as the usage of WSDL 2.0 to accommodate  contracts (see the good introduction at http://www.w3.org/TR/2007/REC-wsdl20-primer-20070626/)

Now back to the main point of this post: I will take you through the implementation of a simple car statistics web service which allows the client to invoke five operations: Get all basic statistics (top speed in mph, 0 to 60 time, 1/4 mile time and 60 to 0 stopping distance), get statistics for a particular car, add statistics for a new car, update the statistics of an existing car and delete a particular statistics. Hopefully this example will prove sufficiently sufficiently universal.

We’ll start by defining the server-side classes; as mentioned previously I will devote another blog to explore best-practices in this area, for now let’s just concentrate on the class definitions. First let’s define the main service interface describing the five operations and note that nothing in the code pertains to web services:

package com.apptotest.service;
public interface IAutoStatService {
    public AllAutoStatistics getAllAutoStatistics();

    public AutoStatistics updateAutoStatistics(AutoStatistics astats);

    public AutoStatistics addAutoStatistics(AutoStatistics astats);

    public AutoStatistics getAutoStatistics(Long id);

    public AutoStatistics deleteAutoStatistics(Long id);
}

Here is the definition of the AutoStatistics entity class, just note the presence of the @XmlRootElement(name=”AutoStatistics”) annotation. Since we’ll be using JAXB 2 in the background, the @XmlRootElement annotation in this context refers to both an XML Schema Type and a Global Element Definition of that type and the name attribute is the name of the Global Element Definition. By contrast a property or attribute of a class would be tagged with the @XmlElement annotation to indicate a Schema Element Definition. We are omitting here the namespace attribute in @XmlRootElement. Finally do note that I choose to override equals() and hashCode(), the reason will become obvious when we get at the client code towards the end of the post.

package com.apptotest.service;

import javax.xml.bind.annotation.XmlRootElement;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;

@XmlRootElement(name="AutoStatistics")
public class AutoStatistics {
    private String name;
    private Long id;
    private Float maxSpeed;
    private Float zeroToSixtyTimeInSecs;
    private Float quarterMileTimeInSecs;
    private Float sixtyToZeroDistanceInFt;

    public AutoStatistics() {}

    public AutoStatistics(String name, Long id, Float maxSpeed, Float zeroToSixtyTimeInSecs,
            Float quarterMileTimeInSecs, Float sixtyToZeroDistanceInFt) {
        this.name = name;
        this.id = id;
        this.maxSpeed = maxSpeed;
        this.zeroToSixtyTimeInSecs = zeroToSixtyTimeInSecs;
        this.quarterMileTimeInSecs = quarterMileTimeInSecs;
        this.sixtyToZeroDistanceInFt = sixtyToZeroDistanceInFt;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public Float getMaxSpeed() {
        return maxSpeed;
    }
    public void setMaxSpeed(Float maxSpeed) {
        this.maxSpeed = maxSpeed;
    }
    public Float getZeroToSixtyTimeInSecs() {
        return zeroToSixtyTimeInSecs;
    }
    public void setZeroToSixtyTimeInSecs(Float zeroToSixtyTimeInSecs) {
        this.zeroToSixtyTimeInSecs = zeroToSixtyTimeInSecs;
    }
    public Float getQuarterMileTimeInSecs() {
        return quarterMileTimeInSecs;
    }
    public void setQuarterMileTimeInSecs(Float quarterMileTimeInSecs) {
        this.quarterMileTimeInSecs = quarterMileTimeInSecs;
    }
    public Float getSixtyToZeroDistanceInFt() {
        return sixtyToZeroDistanceInFt;
    }
    public void setSixtyToZeroDistanceInFt(Float sixtyToZeroDistanceInFt) {
        this.sixtyToZeroDistanceInFt = sixtyToZeroDistanceInFt;
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder(17, 37).
            append(name).
            append(id).
            append(maxSpeed).
            append(zeroToSixtyTimeInSecs).
            append(quarterMileTimeInSecs).
            append(sixtyToZeroDistanceInFt).
            toHashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) { return false; }
        if (obj == this) { return true; }
        if (obj.getClass() != getClass()) { return false; }
        AutoStatistics rhs = (AutoStatistics) obj;
        return new EqualsBuilder().
            append(name, rhs.name).
            append(id, rhs.id).
            append(maxSpeed, rhs.maxSpeed).
            append(zeroToSixtyTimeInSecs, rhs.zeroToSixtyTimeInSecs).
            append(quarterMileTimeInSecs, rhs.quarterMileTimeInSecs).
            append(sixtyToZeroDistanceInFt, rhs.sixtyToZeroDistanceInFt).
            isEquals();
    }

    @Override
    public String toString() {
         return ToStringBuilder.reflectionToString(this);
    }
}

And here is the definition of the AllAutoStatistics entity class, note here that it provides a static snapshot of the Collection of AutoStatistics objects:

package com.apptotest.service;

import java.util.Collection;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="AllAutoStatistics")
public class AllAutoStatistics {
    private Collection allStats;

    public Collection getAllStats() {
        return allStats;
    }

    public void setAllStats(Collection allStats) {
        this.allStats = allStats;
    }
}

And here is the heart of the server-side code, the implementation of the IAutoStatService interface. A couple of points: The class is annotated with @Produces( { “application/json”, “application/xml” } ) which defines the media type(s) that the methods of a AutoStatServiceImpl can produce and with @Path( “/AutoStatService” ) which identifies the URI path that AutoStatServiceImpl will serve requests for.

package com.apptotest.service;

import java.util.HashMap;
import java.util.Map;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;

@Produces( { "application/json", "application/xml" } )
@Path("/AutoStatService")
public class AutoStatServiceImpl implements IAutoStatService {

    private static Map stats = new HashMap();

    /**
     * We mimic the effects of populating the collection from a database
     */
    public AutoStatServiceImpl() {
        AutoStatistics stat1 = new AutoStatistics("Acura TSX V6", 1000001L, 130F, 5.9F, 14.4F, 133F);
        stats.put(stat1.getId(), stat1);
        AutoStatistics stat2 = new AutoStatistics("Alfa Romeo 8C Competizione", 1000002L, 181F, 4.2F, 12.4F, 105F);
        stats.put(stat2.getId(), stat2);
        AutoStatistics stat3 = new AutoStatistics("Audi A5 2.0T Quattro", 1000003L, 130F, 6.2F, 14.8F, 130F);
        stats.put(stat3.getId(), stat3);
        AutoStatistics stat4 = new AutoStatistics("Cadillac CTS-V", 1000004L, 191F, 4.1F, 12.3F, 114F);
        stats.put(stat4.getId(), stat4);
        AutoStatistics stat5 = new AutoStatistics("Chevrolet Camaro SS Coupe", 1000005L, 155F, 5.9F, 4.6F, 119F);
        stats.put(stat5.getId(), stat5);
        AutoStatistics stat6 = new AutoStatistics("Nissan 370Z", 1000006L, 155F, 5.2F, 13.7F, 115F);
        stats.put(stat6.getId(), stat6);
    }

    @Override
    @POST
    @Path("/add")
    @Consumes( { "application/json", "application/xml" } )
    public AutoStatistics addAutoStatistics(AutoStatistics astats) {
        if (astats.getId() == null || astats.getId() == 0L || stats.keySet().contains(astats.getId())) {
            System.err.println("unable to add: " + astats);
            return null;
        } else {
            stats.put(astats.getId(), astats);
        }
        return astats;
    }

    @Override
    @DELETE
    @Path("/delete/{id}")
    public AutoStatistics deleteAutoStatistics(@PathParam("id") Long id) {
        stats.remove(id);
        return new AutoStatistics();
    }

    @Override
    @GET
    @Path("/all")
    public AllAutoStatistics getAllAutoStatistics() {
        AllAutoStatistics allStats = new AllAutoStatistics();
        allStats.setAllStats(stats.values());
        return allStats;
    }

    @Override
    @GET
    @Path("/autostats/{id}")
    public AutoStatistics getAutoStatistics(@PathParam("id") Long id) {
        return stats.get(id);
    }

    @Override
    @POST
    @Path("/edit")
    @Consumes( { "application/json", "application/xml" } )
    public AutoStatistics updateAutoStatistics(AutoStatistics astats) {
        if (stats.containsKey(astats.getId())) {
            stats.put(astats.getId(), astats);
            return astats;
        }
        return null;
    }
}

Once you have compiled and deployed your code (I used CXF 2.2) we can turn, at last, to the client. This post is about writing clients for RESTful services and I have chosen to start with the Apache Commons HttpClient because

  1. It is a fairly popular/stable HTTP API wrapper
  2. There is nothing in this API that is REST-specific or even Web Services-specific; this point is worth stressing, by properly setting up the @javax.ws.rs.Path annotation on the server class the client will be able to call the addAutoStatistics() operation, for example, simply by constructing a POST request in the form http://<host>:<port>/autoStats/AutoStatService/add
  3. It throws intelligent (read human readable) exceptions when an HTTP operation fails

You will note that the client code is wrapped in JUnit test cases; that’s because I want to explicitly show the success/failure of the operations. I also want to demonstrate the statelessness of the various operations, so setUp() and tearDown() come in handy. Now the unit testing framework in itself is quite irrelevant to this exercise but if you are just getting started with your client code then setting up test cases is indeed a good idea.

package com.apptotest.client;

import static org.junit.Assert.*;
import java.io.ByteArrayInputStream;
import java.util.Collection;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.DeleteMethod;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.codehaus.jackson.map.ObjectMapper;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

/**
 * We'll use Apache Commons HttpClient to connect and test the following
 * REST operations:
 * - POST
 * - DELETE
 * - GET
 * - PUT
 */
public class AutoStatServiceImplCommonsHttpClientTest {
    private static final String hostname = "http://localhost:7650/autoStats/AutoStatService";
    private HttpClient httpClient;
    private ObjectMapper mapper;

    @Before
    public void setUp() throws Exception {
        httpClient = new HttpClient();
        mapper = new ObjectMapper();
    }

    @After
    public void tearDown() throws Exception {}

    /**
     * corresponding to URL: http://localhost:7650/autoStats/AutoStatService/add
     * @throws Exception
     */
    @Test
    public final void testAddAutoStat() throws Exception {
        PostMethod post = new PostMethod(hostname + "/add");
        AutoStatistics mystat1 = new AutoStatistics("BMW 335d", 9000001L, 149F, 5.3F, 13.8F, 116F);
        String jsonValue = mapper.writeValueAsString(mystat1);
        RequestEntity requestEntity = new StringRequestEntity(jsonValue, "application/json", "UTF-8");
        post.setRequestEntity(requestEntity);
        int statusCode = httpClient.executeMethod(post);
        if (statusCode != HttpStatus.SC_OK) {
            fail("POST method failed: " + post.getStatusLine());
        } else {
            System.out.println("POST method succeeded: " + post.getStatusLine());
            byte[] httpResponse = post.getResponseBody();
            AutoStatistics respStat1 = mapper.readValue(new ByteArrayInputStream(httpResponse), AutoStatistics.class);
            assertNotNull(respStat1);
            assertEquals(mystat1, respStat1);
        }
        post.releaseConnection();
    }

    /**
     * corresponding to URL: http://localhost:7650/autoStats/AutoStatService/delete/{id}
     * where {id} gets expanded by the REST template
     * @throws Exception
     */
    @Test
    public final void testDeleteAutoStat() throws Exception {
        DeleteMethod delete = new DeleteMethod(hostname + "/delete/1000001");
        int statusCode = httpClient.executeMethod(delete);
        if (statusCode != HttpStatus.SC_OK) {
            fail("DELETE method failed: " + delete.getStatusLine());
        } else {
            System.out.println("DELETE method succeeded: " + delete.getStatusLine());
            byte[] httpResponse = delete.getResponseBody();
            AutoStatistics respStat = mapper.readValue(new ByteArrayInputStream(httpResponse), AutoStatistics.class);
            assertNotNull(respStat);
            assertEquals(new AutoStatistics(), respStat);
        }
        delete.releaseConnection();
    }

    /**
     * corresponding URL: http://localhost:7650/autoStats/AutoStatService/all
     * @throws Exception
     */
    @Test
    public final void testGetAutoStats() throws Exception {
        GetMethod get = new GetMethod(hostname + "/all");
        get.addRequestHeader("content-type", "application/json;charset=UTF-8");
        get.addRequestHeader("Content-Type", "application/json;charset=UTF-8");
        get.addRequestHeader("Accept", "application/json");

        int statusCode = httpClient.executeMethod(get);
        if (statusCode != HttpStatus.SC_OK) {
            fail("GET method failed: " + get.getStatusLine());
        } else {
            byte[] httpResponse = get.getResponseBody();
            AllAutoStatistics stats = mapper.readValue(new ByteArrayInputStream(httpResponse), AllAutoStatistics.class);
            assertNotNull(stats);
            assertNotNull(stats.getAllStats());
            Collection allStats = (Collection) stats.getAllStats();
            assertTrue(allStats.contains(new AutoStatistics("Alfa Romeo 8C Competizione", 1000002L, 181F, 4.2F, 12.4F, 105F)));
            assertTrue(allStats.contains(new AutoStatistics("Cadillac CTS-V", 1000004L, 191F, 4.1F, 12.3F, 114F)));
            for (AutoStatistics stat : allStats) {
                System.out.println(stat);
            }
        }
        get.releaseConnection();
    }

    /**
     * corresponding URL: http://localhost:7650/autoStats/AutoStatService/autostats/1000002
     * @throws Exception
     */
    @Test
    public final void testGetAutoStatAsXml() throws Exception {
        GetMethod get = new GetMethod(hostname + "/autostats/1000002");
        get.addRequestHeader("content-type", "application/xml;charset=UTF-8");
        get.addRequestHeader("Content-Type", "application/xml;charset=UTF-8");
        get.addRequestHeader("Accept", "application/xml");

        int statusCode = httpClient.executeMethod(get);
        if (statusCode != HttpStatus.SC_OK) {
            fail("GET method failed: " + get.getStatusLine());
        } else {
            byte[] httpResponse = get.getResponseBody();
            String strResponse = new String(httpResponse);
            System.out.println("response: " + strResponse);
            String expectedResponse = "1000002181.0Alfa Romeo 8C Competizione12.4105.04.2";
            assertTrue(strResponse.contains(expectedResponse));
        }
        get.releaseConnection();
    }

    /**
     * corresponding URL: http://localhost:7650/cxfweb_ajax/cxf/rest/AutoStatService/autostats/1000002
     * @throws Exception
     */
    @Test
    public final void testGetAutoStatAsJson() throws Exception {
        GetMethod get = new GetMethod(hostname + "/autostats/1000002");
        get.addRequestHeader("content-type", "application/json;charset=UTF-8");
        get.addRequestHeader("Content-Type", "application/json;charset=UTF-8");
        get.addRequestHeader("Accept", "application/json");

        int statusCode = httpClient.executeMethod(get);
        if (statusCode != HttpStatus.SC_OK) {
            fail("GET method failed: " + get.getStatusLine());
        } else {
            byte[] httpResponse = get.getResponseBody();
            AutoStatistics stat = mapper.readValue(new ByteArrayInputStream(httpResponse), AutoStatistics.class);
            System.out.println("response: " + stat);
            assertEquals("name", "Alfa Romeo 8C Competizione", stat.getName());
            assertEquals("id", 1000002L, stat.getId().longValue());
            assertEquals("maxSpeed", 181.0F, stat.getMaxSpeed().floatValue(), 0.0);
            assertEquals("zeroToSixtyTimeInSecs", 4.2F, stat.getZeroToSixtyTimeInSecs().floatValue(), 0.0);
            assertEquals("quarterMileTimeInSecs", 12.4F, stat.getQuarterMileTimeInSecs().floatValue(), 0.0);
            assertEquals("sixtyToZeroDistanceInFt", 105.0F, stat.getSixtyToZeroDistanceInFt().floatValue(), 0.0);
        }
        get.releaseConnection();
    }

    /**
     * corresponding URL: http://localhost:7650/autoStats/AutoStatService/edit
     * @throws Exception
     */
    @Test
    public final void testUpdateAutoStat() throws Exception {
        PutMethod put = new PutMethod(hostname + "/edit");
        AutoStatistics stat = new AutoStatistics("Audi A5 2.0T Quattro - Updated Http Commons", 1000003L, 130F, 6.2F, 14.8F, 130F);
        String jsonValue = mapper.writeValueAsString(stat);
        RequestEntity requestEntity = new StringRequestEntity(jsonValue, "application/json", "UTF-8");
        put.setRequestEntity(requestEntity);
        int statusCode = httpClient.executeMethod(put);
        if (statusCode != HttpStatus.SC_OK) {
            fail("PUT method failed: " + put.getStatusLine());
        } else {
            System.out.println("PUT method succeeded: " + put.getStatusLine());
            byte[] httpResponse = put.getResponseBody();
            AutoStatistics respStat = mapper.readValue(new ByteArrayInputStream(httpResponse), AutoStatistics.class);
            assertNotNull(respStat);
            assertEquals(stat, respStat);
        }
    }

}

The next installment will show you how to write a client using just the J2SE API.

Event Processing and Streaming Query Engines

August 27th, 2010 § 2 Comments

I  just went over a nice article in the January issue of the Communications of the ACM, Data In Flight by Julian Hyde (he maintains a great blog by the way). I think that it is a good read for anyone questioning the added value of Event Processing software in general and CEP (Complex Event Processing) in particular.

The author argues successfully that Streaming Query Engines are at the heart of Event Processing applications and quickly recaps their advantages over a relational database, for example, when processing events:

  • Event processing is rarely concerned with transactions, as such streaming query engines store queries only, not data, which makes them very efficient
  • Streaming query engines are concerned with the latest data and keep very little history in memory: This varies from a few seconds to at most a business day worth of data, which relieves the engine from the need to maintain a persistent storage and support ad-hoc querying  – of course this is just the typical usage, not a hard rule
  • Streaming query engines process data asynchronously to achieve the highest level of performance

It is worth noting here that stream-oriented languages are just one flavor of event processing languages. IBM WebSphere, for example, uses a rule-oriented language (WebSphere Business Events). Understandably the JBoss offering in this space (DROOLS Fusion) uses a rule-oriented language too. Just to be clear, these two products are event processing software, not BRMS (Business Rule Management System) software. They may use a rule-oriented language to act on events, but they differ from a BRMS product where a) rules are invoked by requests made from within the application (as opposed to event processing where the processing is triggered by the occurrence of events or situations) and where b) rules operate on the various states (see for example http://www.jboss.org/drools/drools-flow.html).

I did not conduct an exhaustive survey but from my own experience  I would venture to say that stream-oriented languages are the more popular ones out there to express event processing logic. That’s because they naturally lend themselves to express time constructs as a fundamental dimension of event processing. Stream-oriented languages do that by typically introducing time operators to SQL-like languages. Here is a list of a few vendors that went down this route:

The list above gives a flavor of the various Streaming Query Engines out there. There is enough value in the expressiveness of the languages alone to warrant  their adoption as opposed to rolling your own half-baked event processing solution based on, say, pattern matching of messages on a bus.  As soon as the rate of arrival/dissemination of the messages increases and the need to correlate between various out-of-order messages over variable windows becomes pressing I think that it makes sense to consider an event driven application.

WebSphere Business Events

Practical caching with Spring AOP

August 17th, 2010 § 1 Comment

In this post I will discuss a practical application of Spring AOP: Caching. Most tutorials/introductions to Spring AOP use logging to motivate the usage of Aspect Oriented Programming. While systematic logging is a valid concern, I am not quite sure that it would alone justify the introduction of AOP into your project. The AOP technique has, after all, serious implications:

  1. Maintenance/Code readability: While AOP can help reduce the clutter in the code by taking away repetitive statements, it can, by the same token, reduce the maintainability of your code (how well defined are your pointcuts?)
  2. Performance: Beans are typically proxied in Spring and this does have a negative performance impact

A strong argument can be made in favor of Spring AOP when some client requests need to be intercepted programmatically and returned from cache instead of being processed. This case seems to lend itself to an Around Advice where the request is inspected and a decision can be made on whether to produce the response from cache or fully compute it. This approach assumes, of course, that most requests are cache-candidates. One advantage of this approach is its non-intrusive approach: The code computing the response remains untouched.

I will take a very pragmatic approach by showing you the main steps in building the solution; you will see first hand why this problem fits so “naturally” within the realm of AOP. Any other approach would require an intercept of some kind, so you might as well use a solid third-party framework.

The first step would be to identify those methods in your code where the expensive processing of requests takes place. This step will in turn enable you to properly define your join points. Do note that Spring AOP allows you to define join points on methods only. You can then define in a declarative fashion the pointcuts matching those join points (think of poincuts as the embodiment of join points at run time).  The proper definition of join points is actually crucial since all subsequent calls to the identified methods will be advised!
I will use Spring 2.5 Annotations in this post, so the pointcut definition could be expressed as an annotation in your Advice class (I will get to the Advice class in a moment):

"execution (com.mypackage.MyClass.myMethod(..)) " +
 "&& args(request)"

In this example we have identified the method where the expensive processing of requests takes place to be myMethod() in class MyClass under the com.mypackage package. The pointcut designator is “execution”, as opposed to, say, “within”, “targets’”, etc… This choice of the “execution” pointcut designator is a practical one: It is the most common designator and it happens to suit this type of application.

The next step is to implement the Around Advice as a Spring 2.5 annotated Java class. I am listing a skeleton class that illustrates the main ideas:

  1. The class contains a cache attribute that gets injected by Spring
  2. The main method is called: doEvaluteExpensiveMethod(). Its first argument must be of type ProceedingJoinPoint and it must return an Object type.
  3. The call to pjp.proceed() is optional in Spring AOP but in this case it makes sense to call it
  4. Exception Handlind is very important here since a failure can alter the program flow

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Required;

@Aspect
public class AroundExpensiveProcessingAdvice {
    private SomeCache cache;

    /**
     * @param pjp
     * @param request
     * @return Object
     * @throws Throwable
     */
    @Around(value = execution (com.mypackage.MyClass.myMethod(..)) " +
	    "&& args(request),
            argNames = "pjp, arg0")
    public Object doEvaluteExpensiveMethod(ProceedingJoinPoint pjp, Map<String, String> request) throws Throwable {
	ClientResponse result = null;
        try {
	   // if request contains a specific key/value populate result from cache
           if (cache.containsKey(key) {
	      result = cache.get(key);
           }
        } catch (Exception e) {
            return  pjp.proceed();
        }

        if (result == null) {
            return  pjp.proceed();
        }
        return result;
    }

    /**
     * @param cache the cache to set
     */
    @Required
    public void setCache(SomeCache cache) {
        this.cache = cache;
    }
}

Finally the Advice must be Spring configured; I choose to use a Spring XML context file as follows:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"
       default-lazy-init="true">

    <aop:aspectj-autoproxy proxy-target-class="true"/>

    <bean id="my.service.QueryCache"
          class="wrapper.around.popular.cache.library"
          factory-method="getInstance" />

    <bean id="my.service.AroundExpensiveProcessingAdvice" class="AroundExpensiveProcessingAdvice">
        <property name="cache" ref="my.service.QueryCache" />
    </bean>
</beans>

A couple of notes about this context XML configuration file:

  1. In order to use <aop:aspectj-autoproxy> element you must include references to the Spring AOP schema file
  2. The proxy-target-class=”true” attribute is included just in case the target class of the Around Advice (com.mypackage.MyClass) is not an Interface, otherwise you can skip it
  3. The call to pjp.proceed() is optional in Spring AOP but in this case it makes sense to call it

That’s pretty much it; you can extend the example by using a Pointcut that applies to more than one method across more than one package etc… The main idea is to keep the caching aspect separate from the main processing code. The minute you want to stop advising the selected method(s) you can simply remove the bean entry corresponding to the Around Advice from the Spring XML context file.

My Take on ActionScript 3 shortcomings

February 22nd, 2010 § 1 Comment

I have been playing with ActionScript 3 lately and I will say upfront that I like it, it does what it’s supposed to do pretty well: Provide a thoughtfully designed language targeted specifically at the Flash platform.
But it has also been touted as an object oriented language with optional compile-type checking and so I had certain expectations when I took the language for a spin, with a eye towards developing large (as in a few thousand classes) application.

Here are my thoughts on what is missing and why I think those features should get implemented as the language matures and tries to appeal to a wider range of developers (think non-”traditional” one who have been working mostly on non rich web application application). By the way, I don’t consider myself a language expert and my opinion may evolve as I write more ActionScript code.

- No support for multi-threading. I feel that this is the most glaring shortcoming. I understand that it can get tricky for any language belonging to the JavaScript family (I guess it’s more appropriate to use ECMA family of languages here, or ECMA-compliant, but ECMA is a weird acronym that just doesn’t round right) to support threads when it’s meant to run within many browsers and on many different operating systems but this could be one of the main reasons why some enterprise projects may shy away from ActionScript 3. But then again AIR is a desktop solution, and still no threading. Maybe Adobe and the community should seriously reconsider this missing feature. haXe could be considered as a model (http://haxe.org/doc/neko/threads?lang=en)

- Limited native types. You just get 5 of them: String, Boolean, Number, int and uint. It may be an indication of the language purely dynamic origins where such considerations were not important. And what’s with the inconsistent use of cases: String and int (upper and lower)? I guess it’s for legacy reasons. You could argue that if you really need to make a distinction between double and float then maybe AS3 is not the right tool just as you could argue that for people who want to use AS3 for the visualization of complex analytics such a distinction does matter. There is a lot of room for debate here.

- No overloading allowed for constructors, methods, or even between a variable and a method. This is a limiting factor in larger OO applications. Overloading constructors, for example, greatly contributes to the usability of your class. On the other hand I do like the mandatory inclusion of the ‘override’ keyword in subclasses, in line with the trend of other languages (or Java’s @Override annotation; for Java it’s too late to enforce it as a keyword)

- No abstract classes, but there are interfaces. Again, that’s a missing piece in the arsenal of an OO language as interfaces are not exactly the same thing.

- Interfaces can only declare methods, not variables or constants. This restriction can be lived with, but why?

- An .as file must have only one externally visible (public or internal) class or function; this a compiler (mxmlc) restriction, not an AS3 restriction per se. This can become annoying for a file defining global utility functions.
It’s worth noting at this point that there are a few ActrionScript compilers out there, a tribute to the vitality of the community, but that’s a little bit off topic in a post titled “AS3 shortcomings”, isn’t it? So I’ll just add that MTASC is great, but specifically geared towards AS2 with no plans for AS3 as they announced that they are focusing on haXe (by the way they are the creators of haXe). I never tried swftools, though I should. Maybe this bullet point will prove invalid.

- No Generics, which gives the language a very pre-Java 5 feel. This is felt even more acutely given the many resemblances to the Java language. They could have been inspired by GJ, the work on STL, etc… For some reasons it has been left out. This may not be necessarily hurtful for people used to work with the AS3 Array class (it’s a heterogeneous collection of objects) but you do feel their absence when you are trying to write a method where arguments can be of a certain type and all of its descendants but no more, i.e. you don’t want to necessarily resort to the * notation.

- Speaking of Array, what’s with the delete operator? It does not really delete (for that you are better off using splice()). Maybe that’s what happens when you try too hard to come up with a unique syntax for your language. At this point I am tempted to say that we should just stick to the C++ syntax, but to each his own and this type of debate can easily degenerate into futility, so let’s leave it that: The ‘delete’ operator does not delete an array element (when used in the context of arrays), it merely sets the element value to undefined, and that’s misleading.

That’s it for now, I will probably post a follow up where I explain why I really like the event dispatching model and some of the language functional features.

Apache CXF How-Tos, well not exactly

October 27th, 2009 § 14 Comments

Apache CXF offers a very good JAX-WS implementation but the documentation is frustrating at best. There are invaluable advices in the CXF wiki but for someone trying to get started the lack of step-by-step setup advice can be frustrating. In this post I’ll try to give some hints to make the official documentation friendlier. We’ll start with JAXB-related topics.

Joe Morison, my colleague at Lab49, already posted an excellent article to address the CXF documentation shortcomings; in it he shows how to create a complete Maven project with a WSDL-first approach to set up CXF. His article will get you started in no time. You are now ready to resume reading the CXF wiki and experiment with more advanced features but as soon as you hit the article on building a simple JAX-WS service you hit a wall: The showcased HelloWorld web service advertises two use cases where one can pass an interface to a web method and one can return a Map from a web method, but apart from the javadoc nothing tells you how to proceed. I will go over the required JAXB annotations to allow you to build a consume the CXF wiki-advertised web service.

First let’s tackle the problem of passing an Interface to a web method.

/* Advanced usecase of passing an Interface in. JAX-WS/JAXB does
 * not support interfaces directly.  Special XmlAdapter classes need to
 * be written to handle them
 */
String sayHiToUser(User user);

As is this code will compile but will fail at runtime with a message similar to the following one:
jaxws.hello.server.User is an interface, and JAXB can’t handle interfaces.

One possible solution is to use the XmlJavaTypeAdater JAXB annotation to tell the stack that to use the implementation of the User Interface; this annotation is extremely useful as it allows you to custom marshal most Java objects into XML. Do note that the adapter class is a static inner class as opposed to an inner class because JAXB can’t handle non-static inner classes. Using a non-static inner class would result in a runtime exception similar to the following one:

jaxws.hello.server.UserImpl$UserAdapater is a non-static inner class, and JAXB can’t handle those.

Here is the code for the annotated interface:

package jaxws.hello.server;

import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlJavaTypeAdapter(UserImpl.UserAdapter.class)
public interface User {
 /**
 * @return
 */
 public abstract Long getId();

 /**
 * @return the name
 */
 public abstract String getName();
}

And here is the code for the implementing class containing the adapter:

package jaxws.hello.server;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlAdapter;

/**
* @author RRached
*/
@XmlType(name="UserType", propOrder = {"id", "firstName", "lastName"})
@XmlAccessorType(XmlAccessType.FIELD)
public class UserImpl implements User {
 @XmlElement(required=true)
 private Long id;
 @XmlElement(required=true)
 private String firstName;
 @XmlElement(required=true)
 private String lastName;
 /**
 *
 */
 public UserImpl() {}
 /**
 * @param id
 * @param firstName
 * @param lastName
 */
 public UserImpl(Long id, String firstName, String lastName) {
   this.id = id;
   this.firstName = firstName;
   this.lastName = lastName;
 }
 /* (non-Javadoc)
 * @see jaxws.server.hello.User#getId()
 */
 public Long getId() {
   return id;
 }
 /**
 * @return the firstName
 */
 public String getFirstName() {
   return firstName;
 }
 /**
 * @return the lastName
 */
 public String getLastName() {
   return lastName;
 }
 /* (non-Javadoc)
 * @see jaxws.hello.server.User#getName()
 */
 public String getName() {
   return firstName + " " + lastName;
 }
 /**
 *
 */
 protected static class UserAdapter extends XmlAdapter<UserImpl, User>{
   /* (non-Javadoc)
    * @see javax.xml.bind.annotation.adapters.XmlAdapter#marshal(java.lang.Object)
   */
   @Override
   public UserImpl marshal(User u) throws Exception {
     return (UserImpl)u;
   }
   /* (non-Javadoc)
    * @see javax.xml.bind.annotation.adapters.XmlAdapter#unmarshal(java.lang.Object)
    */
   @Override
   public User unmarshal(UserImpl v) throws Exception {
     return v;
   }
  }
}

A few thing to note about this code:

  • The XmlType annotation is used to tell JAXB that every UserImpl object will be serialized using a UserType type in the xsd schema; the propOrder specifies the order in which content is marshalled to XML and is unmarshalled from XML, as opposed to marshalling and unmarshalling in no specific order due to Java Reflection not making any guarantees about attributes’ order
  • The XmlAccessType.FIELD tells JAXB to bond all non-static non-transient fields to XML unless those fields are explicitly annotated with the XmlTransient annotation; this results in getter/setter pairs not getting automatically marshalled.
  • The UserAdapter is the adapter referred to in the User interface annotation (@XmlJavaTypeAdapter(UserImpl.UserAdapter.class)) and happens to be a (static) inner class because this example is a simple one with a one-to-one correspondence between the interface and the implementing class; nothing stops the adapter from being a full-fledged class
  • Every adapter needs to implements a marshall() and unmarshall() methods

Next let’s tackle the problem of returning a Map from a web method:

/* Map passing
 * JAXB also does not support Maps.  It handles Lists great, but Maps are
 * not supported directly.  They also require use of a XmlAdapter to map
 * the maps into beans that JAXB can use.
 */
@XmlJavaTypeAdapter(IntegerUserMapAdapter.class)
Map<Integer, User> getUsers();

This is how you could declare the users map in the HelloWorldImpl class:

@XmlJavaTypeAdapter(value=IntegerUserMapAdapter.class)
@XmlElement(name = "users")
private Map<Integer, User> users = new LinkedHashMap<Integer, User>();

Creating the IntegerUserMapAdapter class is a multi-stage process to ultimately flatten the Map into a XML-friendly structure; I choose to represent this particular map using the following class (notice that it is a regular POJO) but any other way (using an array, for example) will do:

package jaxws.hello.server;</code>

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlType;

/**
 * @author RRached
 *
 */
@XmlType(name="IntegerUserType")
@XmlAccessorType(XmlAccessType.FIELD)
public class IntegerUserType {
 // produce a wrapper XML element around this collection
 @XmlElementWrapper(name="userList")
 // map each member of this list to an XML element named appointment
 @XmlElement(name="users")
 private List<IntegerUser> users;
 /**
  *
  */
 public IntegerUserType() {}
 /**
  * @param map
  */
 public IntegerUserType(Map<Integer, User> map) {
   users = new ArrayList();
   Set<Entry<Integer, User>> set = map.entrySet();
   for (Entry<Integer, User> idUserEntry : set) {
      users.add(new IntegerUser(idUserEntry.getKey(), idUserEntry.getValue()));
   }
 }
 /**
  * @return the users
  */
 public List<IntegerUser> getUsers() {
   return users;
 }
 /**
  *
  */
 protected static class IntegerUser {
   @XmlElement(name="id")
   private Integer id;
   @XmlElement(name="user")
   private User user;
   /**
    *
    */
   protected IntegerUser() {}
   /**
    * @param id
    * @param user
    */
   protected IntegerUser(Integer id, User user) {
      this.id = id;
      this.user = user;
   }
   /**
    * @return {@link Integer}
    */
   protected Integer getId() {
      return id;
   }
   /**
    * @return {@link User}
    */
   protected User getUser() {
      return user;
   }
 }
}

  • The usage of the JAXB notation is optional but greatly helps in creating a clean schema; this way, when you’ll decide to use an XSD-first approach for your project, you’ll have a template. Nothing stops you from using a JAXBContext.newInstance() to stream the schema to an output file and starting cleanly by editing that XSD
  • A List is a commonly used strategy to flatten a Map
  • The no-ag constructor is a JAXB requirement

The last step is extending the XmlAdapter class to create the actual IntegerUserMapAdapter (you can certainly come up with more elegant names):

/**
 *
 */
package jaxws.hello.server;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.bind.annotation.adapters.XmlAdapter;

/**
 * @author RRached
 *
 */
public class IntegerUserMapAdapter extends XmlAdapter<IntegerUserType, Map<Integer, User> > {
 @Override
 public IntegerUserType marshal(Map<Integer, User> map) throws Exception {
   return new IntegerUserType(map);
 }

 @Override
 public Map<Integer, User> unmarshal(IntegerUserType type) throws Exception {
   Map map = new HashMap();
   List<IntegerUser> users = type.getUsers();
   for (IntegerUserType.IntegerUser idUser : users) {
      map.put(idUser.getId(), idUser.getUser());
   }
   return map;
 }
}

That’s it!
I will soon be adding more tips to complement the CXF wiki documentation.

JVM polyglot programming impressions

August 10th, 2009 § 5 Comments

I stole the title of this blog from this week’s Scala meetup “Polyglot Programming on the JVM”. I thought that the title was catchy but true. There are indeed a few hundred programming languages running on top of the JVM and while all of them may not thrive in a commercial sense, the three that were featured at this meetup have a healthy developers’ community built around them.

The meetup devoted about 30 minutes to present at a high level Groovy, Scala and Clojure. No need to go over each one, there are plenty of good and more or less detailed overviews lying around, I just wanted to write about the impressions that I was left with after listening to all three back-to-back presentations. It so happened that the style and tone used by each presenter reflect quite well the actual user community of each language.

The meetup started with Groovy, and the focus was immediately on the ease of use of the language,  it’s near complete backward compatibility with Java and then on its syntax succinteness, and on its support of a functional programming style. Towards the end of the allocated time we had an overview of Grails, the popular framework built on top of Groovy and rightfully so hailed as one of the most productive web app development frameworks ever. The presentation mixed slides with bold format characters and code snippets typed in the GroovyConsole, all in an informal but entertaining way.

Equally entertaining but in a much different stlye was the Scala presentation: Meticulously prepared slides with artistic fonts and backgrounds, and carefully selected code examples to showcase the language elegance and simultaneous support for Object Oriented programming, Functional programming and conciseness. There were no references to frameworks (such as Lift), the emphasis was on things such as algorithms and how to avoid iterating over Collections.

And then there was Clojure; more mysterious, with roots going back to the Lisp family of languages and their delicate intricacies. Quite a few black and white slides were devoted to the illustrious lineage followed by some that dwelved into features such as the language compactness and relevance to concurrent programming. The demo featured a flocking bird animation. But the answer to the question “what is the value added of Clojure” remained wonderfully vague.

It seems that there is indeed a room for all three of these languages, Java is not the answer to all problems (even Guy Steele will tell you that). These three langages appeal to different kinds of people and the back-to-back presentations, in an unintended way, illustrate this:

- Groovy seems to appelal to the more pragmatic crowd, thanks in large part to its Grails framework and its near complete backward compatibility with Java

- Scala seems to appeal to the more Functional/Computing crowd all the while running on the trusted and familar JVM

- Clojure seems to appeal to the more curious crowd; the tools are not there yet but it certainly can elicit interesting comments and draw functional programming advocates

Follow

Get every new post delivered to your Inbox.