Errai: The browser as a platform

Wednesday, February 22, 2012

Errai Marshalling: Good for Immutable Types

There are already dozens of well-known serialization frameworks for Java, but Errai needs one that works with code that's been translated to JavaScript via the GWT compiler. For serialization frameworks, GWT presents special challenges: reflection only goes as deep as class literals and Object.getClass(). No dynamic method calls; no dynamic field reads and writes; no dynamic creation of arbitrary types of objects.

So we decided the best way forward for Errai was to build our own annotation-driven marshalling framework based on code generation. My favourite part about this is that we got to design it from the ground up to support immutable types.

First, here's a basic mutable Bean that can be serialized and deserialized by Errai Marshalling:

import java.util.Date;
import org.jboss.errai.common.client.api.annotations.Portable;

@Portable
public class OrientationSensorReading {

  private Date observationTime;
  private double x;
  private double y;
  private double z;

  public Date getObservationTime() { return observationTime; }
  public void setObservationTime(Date observationTime) {
    this.observationTime = observationTime;
  }
  
  public double getX() { return x; }
  public void setX(double x) { this.x = x; }

  public double getY() { return y; }
  public void setY(double y) { this.y = y; }
  
  public double getZ() { return z; }
  public void setZ(double z) { this.z = z; }
}

Pretty easy, right? Just annotate it with @Portable, and OrientationSensorReading objects will be marshallable on both the client and the server. Notice that the java.util.Date instance didn't require any special treatment. In fact, all GWT-translatable types in the standard Java library (including Exceptions) are handled by Errai Marshalling out-of-the-box. Likewise, you can nest instances and collections of any Portable entity types you have declared in your project's codebase.

But wait! This type is a natural candidate for immutability. Once we've taken a sample from an accelerometer, this reading should never change. Here's an immutable variant of the above that works with Errai Marshalling:

import java.util.Date;
import org.jboss.errai.common.client.api.annotations.Portable;
import org.jboss.errai.marshalling.client.api.annotations.MapsTo;

@Portable
public final class OrientationSensorReading {

  private final Date observationTime;
  private final double x;
  private final double y;
  private final double z;

  public OrientationSensorReading(
      @MapsTo("observationTime") Date observationTime,
      @MapsTo("x") double x,
      @MapsTo("y") double y,
      @MapsTo("z") double z) {
    this.observationTime = new Date(observationTime.getTime());
    this.x = x;
    this.y = y;
    this.z = z;
  }

  public Date getObservationTime() { return new Date(observationTime.getTime()); }
  public double getX() { return x; }
  public double getY() { return y; }
  public double getZ() { return z; }
}

Note the @MapsTo annotations on the constructor arguments. These specify the names of the Bean properties the arguments map to. This is necessary because–unfortunately–the names of method and constructor parameters are not preserved in Java class files. I believe the advantage of having truly immutable objects where they make sense in your code will more than make up for this inconvenience.

Errai marshalling also understands the factory method pattern recommended by Josh Bloch in Effective Java. This is also an Errai Marshalling compatible type:


import java.util.Date;
import org.jboss.errai.common.client.api.annotations.Portable;
import org.jboss.errai.marshalling.client.api.annotations.MapsTo;

@Portable
public class OrientationSensorReading {

  private final Date observationTime;
  private final double x;
  private final double y;
  private final double z;

  private OrientationSensorReading(
      Date observationTime, double x, double y, double z) {
    this.observationTimenew Date(observationTime.getTime());
    this.x = x;
    this.y = y;
    this.z = z;
  }

  public static OrientationSensorReading newInstance(
      @MapsTo("observationTime") Date observationTime,
      @MapsTo("x") double x,
      @MapsTo("y") double y,
      @MapsTo("z") double z) {
    return new OrientationSensorReading(observationTime, x, y, z);
  }

  public Date getObservationTime() { return new Date(observationTime.getTime()); }
  public double getX() { return x; }
  public double getY() { return y; }
  public double getZ() { return z; }
}

In this case, because Errai Marshalling simply calls your static method when it needs a particular instance of a type, you can return whatever you want. For example, you can build in an instance cache and guarantee there are no duplicates floating around with the same values. Or you could obtain instances via GWT.create() and take advantage of code splitting in your marshallable types. This kind of flexibility is wonderful.

But what about JAXB? Errai brings Java EE 6 to the browser, and JAXB is part of Java EE 6, right? Well, we would like to implement JAXB on the client eventually, but Errai Marshalling was much quicker to implement and it offers a more compact API that's well-suited to the immediate needs of Errai:
  • JAXB is a much larger API than Errai Marshalling needs. Much of the complexity of JAXB lies in the ability to control the XML representation of the object graph. This is essential if you are mapping Java objects to a predefined XML schema, but a lot of dead weight if you aren't.
  • JAXB does not support marshalling instances of immutable types; Errai Marshalling does.
  • JAXB is primarily intended for XML; Errai Marshalling is primarily intended for JSON.
Note also that Errai Marshalling and JAXB annotations can happily coexist. It's not an either/or choice. In most cases, it suffices to stick "@Portable" on an existing JAXB entity class, and you get the best of both worlds.

Monday, February 20, 2012

WebSockets with Errai

Another new feature in Errai 2.0 is the addition of WebSockets support for the ErraiBus. It provides a transparent COMET-to-WebSockets session upgrade mechanism within the bus itself. This means, that no changes are required to your existing Errai code to take advantage of WebSockets. When enabled, all bus traffic (CDI events, RPC, Bus Messages) will all be routed over the WebSocket channel.

WebSocket support is still not very up-to-snuff in the world of Java Servlet containers and even web browsers. Therefore, our existing WebSocket support is technically considered experimental.

But when it comes to the open source community, there's never any shortage of people willing to play. And we'd love it for you to give the feature a spin.

The WebSocket server is a built-in feature of ErraiBus 2.0. Therefore all you really need to do, metaphorically speaking, is flip the switch to turn it on. You do this by adding the following line to your ErraiService.properties file:

errai.bus.enable_web_socket_server=true

Now startup your app, and use a compatible browser (like Chrome or Firefox) and connect to your app. Then, open up your JavaScript console and check to see that it actually worked:



Hey, check it out! Errai opened a web socket. You can actually see more information about the connection state itself by executing the JavaScript function errai_status() from the console:



You may notice something curious here, however: the WebSocket server is running on port 8085 not port 8080 with the rest of the appserver. This is simply because currently, due to lack of standardized support in Java Servlet containers (although there is an effort afoot to remedy this), we currently run the WebSocket server as a sideband server.

This, of course, is not ideal and it's something that we at JBoss are working to address in an internal cross-project effort. I hope to be making some interesting announcements about that over the next year.

But that's not the end of the world, of course. There are front-end proxy solutions which can be used to remedy this problem and munge the servicing of the WebSocket onto the same public-facing port -- the facilities of which are usually good practice for any application server environment in any case.

Anyways, I'd love to hear back from the community on this.

Mike, out.

Friday, February 17, 2012

Doing things in the right order

A serious problem that we've faced internally in making a framework like Errai work nicely is the sometimes unpredictability of the order in which client-side services initialize. Non-GWT client-side developers working with jQuery often run into a similar problem.

For a long time, we've had various mechanisms to manage this problem. Well, it's really the same mechanism spread across many components -- "post-init" callback events.

It's a good pattern, works good and it's intuitive enough to work with. But with Errai 2.0, we've added a set of new features when working inside Errai IOC/CDI. We lovingly call them "Lifecycle Tools" in our new documentation for them, which you can find here.

It's easy enough to register callbacks and wait to be called back to. But since Errai has heavy emphasis on dependency injection, this problem seemed ripe for a nice, clean, don't-call-us-we'll-call-you approach.

So, when you have a client side bean -- and I use @Singleton here for maximum compatibility if you're not using CDI -- you can merely declare a startup dependency on your component by, well, injecting a startup dependency!



@Singleton

public class MyClientBean {

  @Inject InitBallot<MyClientBean> ballot;



  @PostConstruct

  public void doVote() {

    // do lots of initializy stuff.

    

    ballot.voteForInit();

  }

}



This code ensures that initialization of framework services will need to be delayed until it can do whatever work needs to be done. The parameterizing of the InitBallot is the way in which we categorize the dependency. You don't actually have to use the declaring classname. But the dependency must be unique. For instance InitBallot<Foo> will create a dependency on the class Foo. This is purely symbolic. But if the service fails to dial home with a voteForInit() call, in the bootstrap error message, it will be Foo that will be reported as the failed dependency. So keep that in mind.

Doing Stuff After...

There's of course the other obvious side to this coin. Which is wanting to do things only after you know all the framework services are initialized, happy, and doing their best Elvis dance. This job calls for our latest annotation, lovingly inspired by @PostConstruct, the wonderfully new and shiny @AfterInitialization annotation.

This is about as straight-forward as it gets. You create a method in your bean, and you... annotate it! When all the crazy things Errai does to bootstrap are done (bus federation, rpc proxies loaded, marshallers ready), your method will get called! It works like, and basically has all the same restrictions as @PostConstruct and so you use it like so:



@Singleton

public class MyClientBean {



  @AfterInitialization

  public void doStuffAfterInit() {

    // do lots of after-initialzy stuff!

  }

}



... And there's all there is to it!

The only downside is this feature is not in our 2.0.Beta1 release (Boo!). But it is in our latest 2.0-SNAPSHOT release, and will be in the 2.0.Beta2 release. So if you're daring you can use it now, or you can wait for Beta2 which is right around the corner.

Mike, out.

Thursday, February 16, 2012

A Quick Tour of Errai 2.0

A Quick Tour of Errai 2.0

The first beta of Errai 2.0, 2.0.Beta1, is now available! You can download the release in a zipfile, or–even simpler–use one of our archetypes to get started right away.

In this post, I will walk you through all the bits and pieces of the framework as it stands today, and I will wrap up with a peek at the future. But first, let's look at where and why we started this project, and what motivated us to take it where it is today.


The Past

Errai started with the vision that, as browsers become more and more capable computing platforms, the complexity of codebases we write for the browser will grow. Although the ECMAScript language has matured significantly over the years in terms of features, uniform behaviour across browsers, and speed of execution, it still remains true to its roots as a scripting language: loosely typed, little support for encapsulation, poor support for immutable types, and no direct linguistic support for namespaces. Perhaps most importantly, ECMAScript is a slippery target for refactoring and navigation tools.

The idea behind the Errai Framework is that we (Java developers) have already learned how to develop large code bases, managing their complexity with an array of tools and practices that are simply not available to us in other environments:
  • Completely safe refactorings such as rename, move, extract to method, and more
  • Typesafe code completion with popup API documentation
  • The ability to create truly immutable objects
  • Test-driven development using JUnit
  • IDEs that highlight dead code, unused methods, and unsafe casts
  • Static analysis with FindBugs, CheckStyle, and PMD
  • Advanced step-by-step debugging tools
Errai's vision is that we can and should apply these advantages to the increasingly intricate codebases we write for the client side of today's modern web applications.


The Present

With Errai 2.0, we're taking a big step toward the realization of Errai's vision: to provide a uniform, familiar, and well-tooled programming model across client and server. Yes, Errai 1.x provided a uniform programming model across client and server, providing its own publish/subscribe bus API and its own RPC API. Those APIs remain in place, but we now think of them as lower-level enablers. With Errai 2.0, we've begun implementing Java EE 6 APIs on top of the base APIs in Errai 2.0. So far, we support CDI in the client, as well as a JAX-RS client API.


High-level APIs in Errai 2.0

CDI in the Browser

With CDI in the browser, not only can you @Inject dependencies into your beans, but you can also @Observe events that occur both locally (on the client) as well as remotely (on the server.) Naturally, the inverse is true: events fired on the client are observable on the server. To be clear, all of the following are possible:
  • Client-local communication (fire and observe events within the browser)
  • Server-local communication (this is just traditional CDI eventing)
  • Server-to-client communication (Errai pushes server events to the client)
  • Client-to-server communication (Errai pushes events from the client to the server)
Underlying this feature is the good old Errai Bus, which will ensure that events are only routed across the wire if there are actually observers interested in that event on the other end of the connection. No HTTP traffic for local events.

Here's what it looks like:

Server Side
@ApplicationScoped
public class TickerService {

  @Inject
  private Event<Tick> tickEvent;

  private void sendTick() {
    tickEvent.fire(new Tick());
  }
} 
Client Side
@EntryPoint
public class TickerClient {
  public void tickHappened(@Observes Tick tick) {

    // update the UI with the new data
  }
}

To dig in further, use the Errai-CDI quickstart archetype to generate a project you can play with.

JAX-RS Client

New in Errai 2.0 is the JAX-RS client. This is a true JAX-RS client framework. It does not route messages over the Errai Bus; it makes direct AJAX (XMLHTTPRequest) calls to the JAX-RS resource methods on the server side. Of course, all the object marshalling is taken care of on both sides, just like with bus messaging.

Sticking with the theme of "familiar," you simply implement your server-side resources with standard JAX-RS annotations, and on the client, you use exactly the same code as you would use for Errai RPC calls. A great new feature with no new APIs!

Here's a taste:

Server Side
@Path("customers")
public interface CustomerService {
  @GET
  @Produces("application/json")
  public List<Customer> listAllCustomers();
}

public class CustomerServiceImpl implements CustomerService {
  @Override
  public List<Customer> listAllCustomers() {
    List<Customer> customers = CustomerDAO.getAll();
    Collections.sort(customers);
    return customers;
  }
}
Client Side
@EntryPoint
public class CustomerClient {
  @Inject
  private Caller<CustomerService> customerService;

  private void populateCustomersTable() {
    RemoteCallback<List<Customer>> listCallback =
          new RemoteCallback<List<Customer>>() {
      public void callback(List<Customer> customers) {
        addCustomersToTable(customers);
      }
    };
    customerService.call(listCallback).listAllCustomers();
  }
}

To dig in further, use the Errai JAX-RS archetype to generate a project.


Errai RPC

Errai RPC remains an important high-level API in Errai 2.0. And since it's identical to the JAX-RS client API at the call site, you are free to switch between Errai Bus and RESTful communication simply be re-annotating your server-side code. The client remains untouched. Here's how it looks (notice that the client code is identical to the JAX-RS example):

Server Side

@Remote
public interface CustomerService {
  public List<Customer> listAllCustomers();
}


@ApplicationScoped
@Service
public class CustomerServiceImpl implements CustomerService {
  @Override
  public List<Customer> listAllCustomers() {
    List<Customer> customers = CustomerDAO.getAll();
    Collections.sort(customers);
    return customers;
  }
}
Client Side

@EntryPoint
public class CustomerClient {
  @Inject
  private Caller<CustomerService> customerService;

  private void populateCustomersTable() {
    RemoteCallback<List<Customer>> listCallback =
          new RemoteCallback<List<Customer>>() {
      public void callback(List<Customer> customers) {
        addCustomersToTable(customers);
      }
    };
    customerService.call(listCallback).listAllCustomers();
  }
}

And like Errai CDI, client and server code are interchangeable. You could swap these client and server code snippets, or put both on the client, or both on the server, and they would sill be able to communicate with each other.

To try Errai RPC yourself, clone our Errai Kitchen Sink quickstart (note this quickstart also uses JPA, JAX-RS, CDI, and Bean Validation, and it's only set up to work in JBoss AS 7 at the moment.)


Lower-level APIs in Errai 2.0

Errai Bus and MessageBuilder

If you're familiar with Errai from the 1.x days, you'll already be familiar with the Errai Bus. The bus remains central to the workings of  most Errai high-level features, including CDI remote eventing and Errai RPC (JAX-RS is the exception; it's independent of the bus.)

Using the low-level Errai Bus API, you can send messages on a particular subject and register/deregister callbacks that receive messages on a particular subject. Naturally, the API for doing this on the client or the server is the same.

MessageBuilder is a fluent API for constructing (and optionally transmitting) Errai Bus messages. Although we're now leading with the higher-level APIs, MessageBuilder remains available as a convenient way to construct Errai Bus messages "by hand." Of course, the above-mentioned high-level communication features are actually using the MessageBuilder API on your behalf.

Server Side

@Service
public class HelloWorldService implements MessageCallback {
  public void callback(Message message) {
    MessageBuilder.createConversation(message)
      .subjectProvided()
      .withValue("Hello, World! The server's time is now " + new Date() + ".")
      .done().reply();
  }
}
Client Side

@EntryPoint
public class HelloWorldClient extends VerticalPanel {
  @Inject
  private MessageBus bus;

  void sendMessage() {
    MessageBuilder.createMessage()
        .toSubject("HelloWorldService")
        .withValue("Hello, There!")
        .done()
        .repliesTo(new MessageCallback() {
          public void callback(Message message) {
            responseLabel.setText(
                message.get(String.class, MessageParts.Value));
          }
        })
        .sendNowWith(bus);
  }
}

To play with a working project that uses MessageBuilder, just use the Errai Bus quickstart archetype.
Enabling Technologies

Errai-codegen

Because we use the GWT compiler to bring all this great stuff to the browser, and because GWT eschews runtime reflection in favour of up-front code generation, most Errai features are centred around generating Java source code to feed into GWT at compile time. Because we're such believers in the value of static type checking, we felt compelled to do something a little more structured than just spitting strings into a file and hoping that the result was a well-formed Java source file. Enter Errai's code generator.

Errai-codegen is a fluent API for generating Java source code. It provides static type checking and variable scope checking as it goes, and its promise to you is that it will not allow the creation of a class that can't compile. It also does a really nice job of formatting its output.

Do you generate Java code in any of your projects? Feel free to try out our code generator and let us know what you think. We'd love to hear from you!

Server Side (typically runs at compile time)

Context ctx = Context.create();
String s = StatementBuilder
            .create()
            .declareVariable("n", Integer.class, 10)
            .generate(ctx);

assertEquals("Integer n = 10;", s);

VariableReference n = ctx.getVariable("n");

assertEquals("n", n.getName());
assertEquals(MetaClassFactory.get(Integer.class), n.getType());
assertEquals(LiteralFactory.getLiteral(10), n.getValue());




Errai Marshalling

Every object sent across the Errai Bus, as well as the JSON representations sent and received by your JAX-RS resources, is represented as a JSON object. Errai provides a robust marshalling framework that aims to provide maximum flexibility while imposing minimum markup on your code.

Errai's Marshalling framework includes all of the following techniques, which you can mix and match as you like, based on where you place your annotations:
  • Private/default/protected/public field read & write
  • Setter and Getter property access
  • Provide all properties to the constructor - my favourite because it allows for marshalling properly immutable types
  • Out-of-the-box support for marshalling all JDK classes that are GWT translatable
  • Custom marshallers for those really hard-to-reach classes :)
Errai IoC

Although Errai supports dependency injection via CDI, CDI remains an optional module for now. If you choose not to use it, you can still use @Inject annotations to obtain references to Errai-provided dependencies such as Sender<?> and Caller<?>. And of course, this works the same in client code and server code.


The Future

Of course, we have our eyes on the horizon beyond Errai 2.0. The theme of our longer-term plans is to continue providing Java EE 6 functionality within the client, while providing a practical framework to keep your app running offline, when the server is unavailable.

JPA with Sync

For starters, you probably already have JPA annotations on your model objects. We plan to breathe life into them on the client side. Errai's JPA module will allow you to store and query your model objects locally on the client for speedy access and for storage and retrieval when the web server can't be contacted. We also plan to add features that will make data synchronization as painless as possible when the server does come back.


Shadow Services

Speaking of offline, I've already mentioned a couple of times that Errai Bus can deliver messages locally as well as remotely. When the server goes away, the local bus remains fully operational in the webpage. This means you can already create services within the client, and the calling code doesn't look any different: the bus itself makes the routing decisions.

We plan to take full advantage of this behaviour by having the client-side bus automatically deliver messages to local "shadow" services when the remote ones are unavailable. Combined with client-side JPA, we hope this will make for a really slick programming model for webapps that keep on tickin' when the server is unreachable.


JBoss Forge

We love Forge, and we can't wait to start using it to build Errai projects. Forge's existing JPA scaffolding will already help you quite a bit with an Errai app, but we can extend that further to make the necessary objects marshallable, and maybe even generate some UiBinder templates. Exciting times ahead!


And maybe you have some ideas! What other parts of the EE 6 suite of APIs do you wish you could use in client-side code? What tooling would make this even better? Come to our discussion forum and let's talk!