1 2 3 4 Previous Next


59 posts

In the first blog entry of this series, we showed how to configure a message body reader (MBR) on an instance of Client. Specifically, our example required the registration of an MBR to convert an application/json representation of the Money bean. 

Client client = ClientFactory.newClient();

As stated in that blog entry, a Client instance can be used to create one or more instances of Target, which in turn, can be used to create and execute one or more requests. As we shall see shortly, targets can be used to create other targets as well. An interesting aspect of the API is that configurations can be inherited by descendants: thus, a target will inherit a client or another target's configuration and a request will inherit a target's configuration. Inheriting a configuration from a parent object creates a deep copy, so updates to descendants' configurations have no impact on a parent's configuration. 

From the point of view of the Client API, instances of Client are heavyweight while instances of Target are lightweight. Generally speaking, a single instance of Client should be created and configured with the providers that are needed for the targets created from it. Different targets can be created with different configurations to access the various services needed by the application. Lastly, a particular request can be further configured if so required. Lets take a look at an example in which two targets are created, one from a Client and one from another Target

// Get client and register MyProvider1
Client client = ClientFactory.newClient(); 

// Create atm and register MyProvider2
// Inherits MyProvider1 from client
Target atm = client.target("http://.../atm"); 

// Create balance and register MyProvider3
// Inherits MyProvider1, MyProvider2 from atm
Target balance = atm.path("balance"); // new instance 

In this example, an instance of Client is created and a provider registered; a target atm is created from it and a second provider registered and, finally, a target balance is created from atm with a third provider. Note that instances of Target are immutable with respect to their URI (but not their configurations!), thus the call to atm.path("balance") creates a new instance. 

Configuration of an individual request takes an extra step given that request creation and request configuration operate on different method chains. For example,

Invocation.Builder b = client.target("http://.../atm/withdrawal") 
                  .queryParam("card", "111122223333") 
                  .queryParam("pin", "9876") 
Money mon = b.post(text("50.0"), Money.class);

In addition to provider registration, a Configuration object can be used to set properties (name-value pairs) as well as features. A feature is a user-provided class implementing the Feature interface that can be used to register providers, properties and other features as a single unit. We will take a look at features in later blog.


JAX-RS 2.0 - Client API Blog

Posted by spericas Oct 13, 2011

The Early Draft for JAX-RS 2.0 (JSR 339) has recently been submitted for publication. There are number of interested features in the new draft, and I'd like to start with the new Client API. The Client API is used to access Web resources. It provides a higher-level API than HttpURLConnection, and perhaps more importantly, integration with JAX-RS providers.

Let us start by defining a simple ATM service using JAX-RS:

public class AtmService {

    public String balance(@QueryParam("card") String card,
                          @QueryParam("pin") String pin) {

    public Money withdrawal(@QueryParam("card") String card,
                            @QueryParam("pin") String pin, Double amount) {

 This web resource class defines a simple ATM service with two subresources to retrieve an account's balance and to withdraw money. Accessing these resources requires the client to provide a card number and a PIN. Naturally, the withdrawal subresource also requires the client to provide an amount. The actual implementation of the service isn't important for our purposes.

 The entry point to the Client API is the Client class. Using this class we can create one or more Target instances. From each Target instance we can create one or more requests. The fluency of the API somewhat blurs all these steps, but it's important to understand them in order to write better code. The following code snippet can be used to check an account's balance:

Client client = ClientFactory.newClient();

String bal = client.target("http://.../atm/balance")
                   .queryParam("card", "111122223333")
                   .queryParam("pin", "9876")

 In this example, the target is created from a URI and later extended by adding two query parameters. After that, a request is obtained and a resource's representation selected, namely "text/plain". Finally, the HTTP access method is specified (GET) as well as the Java type to be used for the response. Note that JAX-RS provides a built-in Message Body Reader (MBR) to convert a "text/plain" representation into a Java String, so no further configuration is required.

The following code shows how to interact with the withdrawal subresource:

Money mon = client.target("http://.../atm/withdrawal") 
                  .queryParam("card", "111122223333") 
                  .queryParam("pin", "9876") 
                  .post(text("50.0"), Money.class);

Note that the post() method has two parameters: the request entity and the Java type to be used for the response. The variant text() is a convenient way to specify an entity of type "text/plain" while at the same time providing a value for it, i.e. the string "50.0". The execution of this request will require the conversion of the Java string "50.0" into a "text/plain" representation, for which a built-in Message Body Writer or MBW is already provided by JAX-RS, as well as a MBR to convert a representation of type "application/json" into an instance of the Money class. 

Given that the Money class is not known to the JAX-RS runtime, the application must provide an MBR for it. This can be done by accessing a configuration object. Most of the Client API classes are configurable; let us show how to register this provider using our Client instance.

Client client = ClientFactory.newClient();

 As we shall see in later blog entries, registration of providers is also possible on targets and requests, and perhaps even more interestingly, configurations can be inherited.


It's been several months since my last blog! I have recently re-joined the Glassfish team at Oracle and I'm currently looking at Web tier technologies like Web sockets and HTML5. In this blog, I'd like to show you a simple Web application in which you can control an HTML5 video object remotely. The basic idea is to intercept video events like 'play', 'pause' and 'seeked' and remote them using Web Sockets to control another player. Although there may be some use cases for an application like this (such as coaching), the real objective of this exercise is to show the low latency of the Web sockets implementation in Glassfish. So let's get started!

Here is a screenshot of the application:

A Web socket is nothing more than a socket connection that can be established between a (modern) Web browser and a Web container. It provides a low-latency, bi-directional communication "parallel" to the HTTP channel. It is Ajax/Comet on steroids. No hacks, no jumping through loops, nothing. It has the potential of redefining what we understand as a Web application lifecycle given it's low latency and always connected characteristics (but more about this on a future blog).

Our Web application comprises of a single page and some JavaScript code. We use JSF 2.0 facelets to define the main page:

 <html ...>
      <p>Let's share this video:</p>
      <p><h5:video height="360" controls="true" src="PBIRbest.m4v"/></p>
      <h:outputScript library="js" name="json2.js" target="head"/>
      <h:outputScript library="js" name="app.js" target="head"/>

 The tag h5:video is defined by the following custom JSF component:

<html ...>
    <cc:attribute name="src" required="true"/>
    <cc:attribute name="controls" required="false"/>
    <cc:attribute name="width" required="false"/>
    <cc:attribute name="height" required="false"/>
   <video src="#{cc.attrs.src}" controls="#{cc.attrs.controls}" 
      width="#{cc.attrs.width}" height="#{cc.attrs.height}"></video>

 Defining a new h5:video tag (instead of using HTML5's video tag directly) is not a requirement for the application, but it does provide a clear separation and makes the example more readable (a separate component can be used to insert additional JavaScript code, if needed). Note the inclusion of the JavaScript libraries: json2.js and app.js. The former provides us with JSON.stringify() and JSON.parse(); the latter is where our client-side code resides. Let's have a look at that.

 Let us define a JavaScript function that returns a network object (i.e., a closure). This network object has two methods: initialize() and send(). The former opens a Web socket and registers listeners for incoming messages; the latter is for sending outgoing messages.

var network = function (websocket) {
    return {
        initialize: function() {
            var url = 'ws://' + document.location.host + document.location.pathname + 'videosharing';
            websocket = new WebSocket(url);
            websocket.name = APP.id;
            websocket.onopen = function() { };
            websocket.onmessage = function (evt) {
                var command = JSON.parse(evt.data);
                if (command.type == "pause") {
                } else if (command.type == "play") {
                } else if (command.type == "seeked") {
                } else {
                    alert("Unknown command " + command);
            websocket.onclose = function() { };
        send: function(shape) {

 First, a Web socket is created from a URL constructed using the main page's host, pathname and "/videosharing". Notice the use of the "ws://" protocol. Next, listeners for onopen, onmessage and onclose events are registered. The onmessage listener parses an incoming command, determines its type and calls the appropriate method in out application object APP. This is how UI events are remoted. The send() method is used to remote events that are local to this window instance. 

The network's initialize() method is called by APP.initialize(). This method also registers listeners for all local video events for remoting purposes as shown next.

    initialize: function () {

        var video = APP.getVideo();
            function (event) { 
                var command = { type: "play" };
            function (event) {
                var command = { type: "pause" };
            function (event) {
                var command = { type: "seeked",
                                currentTime: APP.getVideo().currentTime };

Note how commands are constructed, stringified and remoted using to the network object. All commands have a type field; the 'seeked' command also includes a currentTime field in order to seek remote video objects to the correct location. The rest of the client code is uninteresting so lets look at the server side pieces.

 The server side API provided in Glassifish 3.1 for Web sockets is straightforward. First, we extend the class WebSocketApplication and override methods createSocket() and onMessage() as shown next.

public class VideoSharingApplication extends WebSocketApplication {

    public WebSocket createSocket(NetworkHandler handler,
            WebSocketListener... listeners) throws IOException {
        return new VideoSharingWebSocket(handler, listeners);

    public void onMessage(WebSocket socket, DataFrame frame) throws IOException {
        final String data = frame.getTextPayload();
        for (WebSocket webSocket : getWebSockets()) {
            try {
                if (socket != webSocket) {
            } catch (IOException e) {

The onMessage() method handles socket frames by extracting the data in the frame and broadcasting it to all other Web socket clients. The createSocket() method simply creates an instance of our app's Web socket which, in this application, it is very simple.

public class VideoSharingWebSocket extends BaseServerWebSocket {
    public VideoSharingWebSocket(NetworkHandler handler,
            WebSocketListener... listeners) {
        super(handler, listeners);

The last piece in this puzzle is the registration of our application in the WebSocketEngine. This can be accomplished using the init() method in a servlet as shown below.

public class WebSocketsServlet extends HttpServlet {

    private final VideoSharingApplication app = new VideoSharingApplication();

    public void init(ServletConfig config) throws ServletException {
            config.getServletContext().getContextPath() + "/videosharing", app);

Of note, this server-side API is still evolving and is subject to change and improvements in upcoming versions of Glassfish. A source bundle for this sample is attached and includes a NetBeans 6.9.1 project file. You must use Glassfish Server Open Source Edition 3.1 and a browser that supports Web sockets (as well as the codec for the video that you use!). In my project, I include an MPEG-4 video and Safari 5.X on a Mac. 


The Sun Mobility Platform Telematics demo, co-developed by Oracle and Sun, was showcased at Oracle Open World this week. It was shown as part of a presentation on Monday and at the Berkeley DB (BDB) booth for the rest of the week. The demo shows a simulation of vehicles synchronizing events collected on a local database (BDB) to a back-end Oracle database. Events collected from vehicle sensors are stored in an embedded BDB database and periodically synchronized; in addition, critical events are reported immediately using the dynamic capabilities of the Mobility Platform. A JavaFX front-end was developed to increase the demo's coolness factor.

Vehicle sensors generate 3 types of events: INFORMATIONAL, DIAGNOSTICS and CRITICAL. All events are recorded in an embedded BDB database in the vehicle and synchronized periodically using the Sun Mobility Platform (SyncML over HTTP). Critical events are reported immediately to the server which responds synchronously by acknowledging the event. After some processing time (a random factor in the simulation) the server contacts the vehicle with an action associated with a previously acknowledged critical event. This communication is done using restful WS (Jersey) and HTTP. The vehicle uses the lightweight HTTP server in JDK 6; the Mobility Platform gateway runs on either Glassfish or Weblogic.  


It is just a matter of time when all the vehicles on the road will be connected to their factories and service centers. When there will be no need to make an appointment with a service center to diagnose a problem. Instead, problems will be diagnosed well ahead of time based on the data collected by the vehicles and parts will be ready at a service center when the vehicle arrives ...

Please contact us at  mep-feedback@sun.com if you would like to get more details including an early access version of the latest Mobility Platform software for evaluation.


The Mobility Platform team has been working on a number of new features and enhancements since the release of GlassFish Mobility Platform v1.1 in February 2009. One of those features is the ability to run the Mobility Platform software on top of Glassfish ESB. There is a clear synergy between the Mobility Platform and Glassfish ESB. The former is about mobilizing the enterprise, while the latter is about integration of enterprise and legacy information systems. By running the Mobility Platform on top of Glassfish ESB, as opposed to just Glassfish, it is possible to write enterprise connectors that sit on the enterprise bus and can mobilize all sorts of information systems.

The Mobility Platform v1.1 supports two types of enterprise connectors: based on ECBO or JAX-RS. ECBO connectors are deployed as Java EE connectors and are co-located with the sync engine on a Glassfish instance. JAX-RS connectors are web applications that can be deployed on any Glassfish instance and interface with the sync engine via a JAX-RS connector bridge (which is a Java EE connector written using the ECBO). To enable integration with the ESB service bus, we have developed a new connector bridge for JAX-WS. This connector translates ECBO requests into JAX-WS requests to a connector implemented as a web service endpoint. The exact details of this web service definition is beyond the scope of this blog; it suffices to say that the web service defines a method for each of the four CRUD (create, retrieve, update and delete) operations involved in a synchronization session.

Given that enterprise connector is now simply a SOAP-based web service, it is possible to implement it using tools and languages available in Glassfish ESB. In particular, it is possible to use BPEL and the excellent graphical tools in Glassfish ESB to develop an enterprise connector. In what follows, will we'll investigate the development of a MusicDb connector using these tools. For more information on the MusicDb connector please refer to this blog entry.

Every enterprise connector implemented in BPEL will need access a serialization service, which is specific to each connector, and is responsible for serializing and deserializing business objects according to the contract that was agreed with client applications. The serialization service is implemented as a web service and listed as a partner link in the BPEL process. In addition, since the MusicDb connector stores business objects in a relational database, there is a database binding component (BC) which is also partner link in the BPEL process definition. The overall flow of the process is: loop until the terminate message is received and execute commands using the serialization service and the database binding component as needed to implement the semantics of each message. The following is a graphical representation of this BPEL process:


The box on the left represents the WSDL implemented by all enterprise connectors that use JAX-WS. The two boxes on the right correspond to the database binding component and the serialization service, from top to bottom. The middle box is a graphical representation of the BPEL process flow outlined above.

If you are interested in trying out any of these new features and providing feedback, please contact us at mep-feedback@sun.com and we can provide an early access release of the Mobility Platform for a limited evaluation period.

As many of you out there, I wanted to explore the world of JavaFX. After looking at a few demos here and there, I decided it was time to write some code; there is simply no better way to learn a new technology like this than writing something. A quick glance over the language primitives and programming model made my decision very easy: a simple video game was best choice to learn JavaFX!

I am not a game programmer, but just like many of you, I wrote a couple of simple games in the past. So it took some GIFs from an old game (which are share by most Space Invader-like games out there!) and put together a very simple game in 400+ likes of JavaFX code. I was amazed by the result. JavaFX is a incredible powerful platform, so I decided to share with you the source code to hopefully encourage you to get started as well. Here's what the game looks like:


It should be pretty easy to port this game to JavaFX Mobile, but I haven't had the time myself (so if you do it, please send it to me!). The controls are straightforward: UP ARROW, DOWN ARROW, LEFT ARROW, RIGHT ARROW and SPACE (fire).

I believe the source code is pretty easy to read, so I hope a quick glance at it we'll get you intrigued and help you get started. Have fun!


This is a follow-up to the blog "Developing SGMP Connectors using JAX-RS" where I focus on how to deploy an SGMP connector developed using JAX-RS. Once again, rather than bore you with words, I will attempt to entertain you with a screencast. The screencast will show you how to build your connector using Netbeans and how to deploy and configure your connector using the GlassFish admin console.


Last week we announced the availability of version 1.1 of the Sun GlassFish Mobility Platform (SGMP), formerly known as Mobile Enterprise Platform (MEP). In the previous version, a connector could only be developed using the ECBO API; in this new version, a connector can also be developed using JAX-RS. The attached screencast shows how to develop a JAX-RS connector using Netbeans 6.5 and Maven. Next time we'll focus on how to deploy a JAX-RS connector.


In case you missed it, the call is open for JavaOne 2009 submissions and the deadline is December 19th, 2008. Contrary to the last few years, the conference will be in early June in 2009, so there's plenty of time for your travel plans but not a lot of time to prepare your abstracts!

One of the topics listed in the announcement is Mobility. This includes core ME technologies, platforms, languages, etc. and also enterprise mobility, a topic that I'm particularly interested these days. So whether you implemented your enterprise mobility solution using the Sun Java System Mobile Enterprise Platform or in some other way, we'd like to hear from you. Let's make the enterprise mobility track shine at JavaOne in 2009!

In the two installments of this series we've looked at the architecture of a MEP connector, discussed the main abstractions of the ECBO (Enterprise Connector Business Object) API and showed an example of a MusicAlbum business object. In this third part, we'll focus on the MusicAlbumProvider class which is needed to complete the implementation of the connector to access music albums from a JDBC database.

The complete source code for the MusicDB enterprise connector is included in the MEP client bundle available for download here. In the directory where you unzipped the client bundle, look for it under sjsmep-client-1_0-fcs/samples/ecbo/.

As explained earlier in this series, the ECBO API provides two essential abstractions: BusinessObject and BusinessObjectProvider. Due to the nature of the synchronization process, every enterprise connector must provide the ability to CRUD (create, retrieve, update and delete) business objects. The BusinessObject abstraction provides support for CUD, i.e. each object provides the ability to create, update and delete itself as shown in Part II. The R operation, or retrieve, is implemented by the BusinessObjectProvider. Here is the implementation of the R operation in MusicAlbumProvider, a class extending BusinessObjectProvider.

    public List<MusicAlbum> getBusinessObjects() {
        Statement stmt = null;
        List<MusicAlbum> albums = null;
        try {
            stmt = sqlConnection.createStatement();
            // Read all music albums and store them in array
            albums = new ArrayList<MusicAlbum>();
            ResultSet rs = stmt.executeQuery(
                    "SELECT * FROM album WHERE username = '" + username + "'");
            while (rs.next()) {
                MusicAlbum album = new MusicAlbum(this);
                album.setDatePublished(rs.getString(3).replace("-", ""));
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        } finally {
            if (stmt != null) {
                try { stmt.close(); } catch (Exception e) { /* ignore !*/ }
        return albums;

The getBusinessObjects() method simply queries the database for all albums that are owned by the user that logged in into the connector and returns them as a List<MusicAlbum>.

In addition to providing support for the R operation, a business object provider being the entry point to the connector, should also provide implementations for the lifecycle methods initialize() and terminate(). These methods are called at the beginning and at the end of a synchronization session. In most connectors, these methods are used to connect to and disconnect from an enterprise system; in the MusicDB connector, in particular, they are used to connect and disconnect from the database as shown below.

    public void initialize() {
        try {
            Context jndiContext = new InitialContext();
            DataSource ds = (DataSource) jndiContext.lookup(MUSICDB_JNDI_DATASOURCE);
            sqlConnection = ds.getConnection();
        } catch (Exception ex) {
            throw new RuntimeException(ex);
    public void terminate() {
        try {
            if (sqlConnection != null) {
        } catch (Exception e) {
            throw new RuntimeException(e);

Contextual information related to the active synchronization session (e.g., session id or user logged in) can be access via calling getSessionContext(). Finally, each connector may define its own transaction manager by overriding the method getTransactionManager(). For more information on these features, the reader is referred to the MEP online documentation.

If you're interested in developing a MEP connector, I suggest that you start by using Maven's MEP Connector Archetype (JAR). If you're a Netbeans user, simply go to File -> New Project -> Maven -> Maven Project and select it from the list. Happy synching!

Filter Blog

By date: