Errai: The browser as a platform

Friday, April 27, 2012

Errai IOC: DI in the Browser (Part 2)

In the last post, we got our feet a little bit wet by exploring the basics of Errai's dependency injection framework, which we call Errai IOC. In this post, we're going to continue the dive by taking a look at producers and bean life-cycles.

Statically wiring up your application is one thing. But what if you want to create managed beans dynamically at runtime? Or what if you want to control what beans get injected based on the runtime environment?

Look no further.

Dependent Scoped Beans

Out of the box, Errai supports two basic scopes: the singleton scope, and the dependent scope. For the sake of consistency, CDI's @ApplicationScope is aliased to the singleton scope within the context of the client application.

Most developers should be familiar with the concept of a singleton, and should easily come to understand what it's use on a bean implies; scoping a bean to a singleton scope will result in there being exactly one instance of that bean created during the lifecycle of the application. 

The dependent scope is a little bit different. It is a scope which is dependent on the scope, and by extension, the lifecycle of the bean which it is injected to. But it also has the property of producing a new instance of the bean for every different injection context.

When it comes to developing UI applications in the browser around beans, this becomes a fairly important -- and natural -- way to accomplish component reuse.

For example, we might wish to create an application component which is newly instantiated every time a user performs a certain action -- like a dialog box popping up.

@Dependent
public class MyDialogBox {
  @Inject SomeBean bean;
  @PostConstruct
  private void init() {
    // do stuff
  }
  
  public void show() {
    // do stuff to show dialog box.
  }


  public void hide() {
    // do stuff to hide dialog box.
  }
 
  @PreDestroy
  private void destroyBean() {
    hide();
  }
}

So we create @Dependent scoped bean. Now, unlike the singleton scope, this bean will not be instantiated by the container unless it is injected into another bean, or it is explicitly created from an instance factory or the bean manager.

Let's take a look at how we might go about that.

@Singleton
public class MySingletonBean() {
  @Inject Instance<MyDialogBox> dialogBoxInstance;

  // ... assume we've done some UiBinder stuff here ...
  @UiHandler
  void onOpenDialogClick(ClickHandler handler) {
    MyDialogBox myDialogBox = dialogBoxInstance.get();  
    myDialogBox.show();
  }
}

In this example we have injected an instance of javax.enterprise.inject.Instance parameterized with the bean type we'd like it to provide.  In this case, since MyDialogBox is dependent scoped, every single time dialogBoxInstance.get() is called, a new instance of the bean, fully wired will be created.

And just as it's been created by the bean manager, it can also be destroyed by the bean manager. Resources that the bean obtains from the container, can automatically be de-allocated cleanly through explicitly garbaging the bean.

Errai IOC actually provides it's own mechanism which is different from CDI for doing this, to make interaction with the BeanManager for ad-hoc disposal easier in client code. It is the org.jboss.errai.ioc.client.api.Disposer interface. It works pretty much the same as Instance, in that you inject it, parameterized with the bean it represents:

@Singleton
public class MySingletonBean() {
  // .. //
  @Inject Disposer<MyDialogBox> dialogBoxDisposer;
  void closeDialogBox(MyDialogBox dialogBox) {
    dialogBoxDisposer.dispose(dialogBox);
  }
}

If you refer back to our implementation of MyDialogBox, you will notice that we have indicated a @PreDestroy method, which is to be called by the bean manager when the bean is destroyed.  In that case, we just had it call its own hide() method to make the point. But the effects of disposing of a bean are far more than just calling that method. Any other beans that were created as a result of constructing that bean will also be destroyed implicitly. And any observer methods, bus service endpoints, and such will automatically be deregistered. Thus, using the bean manager to create and destroy your beans, gives you the advantage of having a standard way to manage and dispose of resources as build out your application.

Producers

This is cool, but what happens when we want to dynamically choose what instances to return to created beans at runtime? Enter the producer.

Producers produce beans. Could that be put more concisely? They essentially allow you to offload control of bean instance creation from the bean manager itself, into logic you so choose. Let's take a look at a basic example:

@Singleton
public class MyProducerBean() {

  @Produces @Singleton
  private NotificationHandler produceNotificationHandler() {
    if (Browser.supportsWebkitNotification()) {
      return new HTML5WebkitNotificationHandler();
    }
    else {
      return new SimpleNotificationHandler();
    }
  }
}

This is a contrived example. Don't go looking for any class called Browser.  But contrived or not, it's probably the sort of thing you'd find yourself wanting to do in the world of web applications.

Here, we've created a producer method by annotating it with the @javax.enterprise.inject.Produces annotation. But we've also annotated the method with the @Singleton annotation. This tells the container that it should call the method exactly once at runtime and cache the instance result in the bean manager, and return that same instance to all injection points. Not specifying a scope, implies the producer is dependent-scoped, as we talked about in our previous section.

In this example, we are checking to see if our browser support WebKit desktop notifications. If it does, we return an instance of the HTML5WebkitNotificationHandler which implements the NotificationHandler interface and obviously knows how to produce desktop notifications. In the alternative, we return a SimpleNotificationHandler. Perhaps it provides window alerts. I'll let you speculate on what the fallback functionality is here.

The bottom line is that other parts of the application which want to provide notifications now only need to @Inject NotificationHandler into their beans, providing a good separation of concerns.  The components need only refer to the interface without knowledge of the actual implementation. That's the power of the DI pattern.

So that's the basics of producers.

In the next installment of this series, we'll look at bean alternatives and qualifiers.

Saturday, April 14, 2012

Back in Bengaluru

For those in Bangalore area, I'll be talking at GIDS 2012 this coming week. Which will be a great opportunity to come check out what we've been working on this past year.

This talk comes on the heels of our last official beta release (beta4) before our scheduled release candidate for 2.0 So I'm pretty excited to show people what's been cooking.

If there's people in the Bangalore area who can't make GIDS but are interested in Errai, by all means ping me here on the blog and we'll see if we can arrange a meet-up.

I'm also excited to continue my blog series on CDI in the Browser -- which I will do, as soon as I make landfall back home in a week or so. Stay tuned.

Saturday, March 24, 2012

Errai IOC: DI in the Browser (Part 1)

A central facet of the Errai programming model is the use of dependency injection (DI). The preferred programming model is a subset of the JSR-299 Context and Dependency Injection specification.

This is not the only DI solution for GWT. Gin is clearly the popular choice among GWT developers. But there are a few reasons you might want to consider looking into Errai as a good choice for doing dependency injection in your client code.

As we have gravitated towards standardizing around CDI, we have thus moved towards more container-oriented applications. Whereas, the Gin/Guice model aims to do absolutely no magic, we aim to at least give you a sprinkle of fairy dust to help eliminate boilerplate and help make your application more modular.

The first evidence of just a little bit of fairy dust occurs when you create your first GWT EntryPoint in Errai.

@EntryPoint
public class MyErraiEntryPoint {
   // class body here.
}

This is a little bit different than you may be used to with a GWT project -- instead of actually implementing the GWT EntryPoint interface, we have annotated a normal bean as our entry point bean.

The only thing that was necessary to accomplish this, was to have Errai IOC added as a module in our GWT project.

The cool thing is, MyErraiEntryPoint is a fully managed bean. We can inject other beans into it, and we can do lifecycle events like @PostConstruct on it.  Let's update our example:
@EntryPoint
public class MyErraiEntryPoint {
  @PostConstruct
  public void sayHello() {
    Window.alert("Hello, there!");
  }
}

We added an arbitrarily named method sayHello() to our class and added a @PostConstruct annotation.

@PostConstruct is a standard lifecycle annotation which is part of the javax.annotation.* package. It is supported in EJBs, CDI Beans, and by Errai IOC, naturally.  Its contract guarantees that the container will call the method before the bean is put into production, and only after all dependency injection tasks have been satisfied.

Thus, it provides a good way of doing things that need to be done at the startup of your application after the container has wired all the beans.

Errai goes a little bit further, building on the @PostConstruct idea, and adding a similar but distinct lifecycle annotation known as @AfterInitialization, for which there is no real analogue in CDI proper. In the case of @AfterInitialization calls, the method is guaranteed to be called only after all framework extensions (the message bus, RPC services, etc) have entered a ready state.

It turns out this is necessary, since the asynchronous nature of JavaScript in the browser means that your application will almost always finish wiring itself up before fancy things like WebSockets have been negotiated and are ready to start receiving messages.

So if right out of the gate we need to talk to the server, we can modify our bean again:

@EntryPoint
public class MyErraiEntryPoint {
  @Inject MessageBus bus;
  @AfterInitialization
  public void sayHelloToServer() {
    MessageBuilder.createMessage()
      .toSubject("ServerService")
      .command("SayHello")
      .done().sendNowWith(bus);
  }
}

So we've built an entire application that loads, and the first thing that happens is it sends a message to the server over the ErraiBus. That doesn't seem like much. But the only boilerplate code we've written are annotations.

This nice, concise, programming model is all made possible by the use of dependency injection and all the services built around the container.

But this is just scratching the surface. In the next part of this series we'll explore working with producers and dependent scoped beans!

Friday, March 16, 2012

Errai Marshalling and the Builder Pattern

My previous post was about the Errai Marshalling framework and its facilities for working with immutable types. In that post, I laid out how to use Errai's @MapsTo annotation to create entity instances via a public constructor or—as is often advantageous—a public static factory method.

But as an entity class grows to accommodate a real-world-use-case, a third approach to creating instances of immutable types becomes more and more appealing: the builder pattern.

If you use the builder pattern exactly as laid out by Joshua Bloch, Errai's marshalling system will be unable to infer a property mapping for the entity's constructor:

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

@Portable
public final class OrientationSensorReading {

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

  // ERROR: Errai Marshalling does not know what to do with this constructor
  private OrientationSensorReading(Builder builder) {
    this.observationTime = new Date(builder.observationTime.getTime());
    this.x = builder.x;
    this.y = builder.y;
    this.z = builder.z;
  }

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

  public static class Builder {
    private Date observationTime = new Date();
    private double x;
    private double y;
    private double z;

    public Builder time(Date time) { this.observationTime = time; return this; }
    public Builder x(double x) { this.x = x; return this; }
    public Builder y(double y) { this.y = y; return this; }
    public Builder z(double z) { this.z = z; return this; }

    public OrientationSensorReading build() {
      return new OrientationSensorReading(this);
    }
  }
}

You could work around this issue by implementing a custom marshaller (these are explained in in the Errai reference guide). But that's a burden: it's extra, external code you have to revisit every time you add or remove a property on your entity type.

A better approach is to adopt a modified version of Bloch's builder pattern. Instead of giving the class a constructor that takes the Builder as its sole parameter, create one big constructor that takes every single property, each of which annotated with a @MapsTo annotation. This constructor does triple duty as the target of Builder.build(), the target of Errai's de-marshaller, and a place to hang directions for Errai's marshaller generator. Now you have the builder pattern, and you haven't given up the convenience of Errai's automatic marshaller generation:

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; }

  public static class Builder {
    private Date observationTime = new Date();
    private double x;
    private double y;
    private double z;

    public Builder time(Date time) { this.observationTime = time; return this; }
    public Builder x(double x) { this.x = x; return this; }
    public Builder y(double y) { this.y = y; return this; }
    public Builder z(double z) { this.z = z; return this; }

    public OrientationSensorReading build() {
      return new OrientationSensorReading(observationTime, x, y, z);
    }
  }
}

Yes, it's a little bit more verbose than Bloch's approach. But the client code using the builder is identical, and the integrity of the immutable type is in no way compromised. And it's still all in the same file, and far less verbose than a handwritten custom marshaller.

Future Work

There's always room for improvement. In particular, I'd like the option of making the entity constructor (the one with the @MapsTo annotations) package private. This would enforce usage of the builder, which is less error prone than the constructor. That's why you went to the trouble of creating a builder in the first place, right? This is in our issue tracker as ERRAI-234.

Additionally, the contract of Errai's @Portable annotation is that all nested classes of a @Portable class are also portable. This means Errai will generate marshallers for your Builder subclasses. Although this is harmless in the above examples, it becomes a problem when your builders have mandatory fields expressed as constructor parameters. We're tracking this issue as ERRAI-233. The workaround for now is to include a public no-args constructor in any such Builders.

Tuesday, March 6, 2012

Large scale application development with GWT and Errai

Development teams collaborating on the same codebase are always faced with the challenge of keeping their source code maintainable as it evolves and grows over time. By choosing GWT to implement your web application you already gain the benefit of having IDE support for client-side code refactorings. This is a distinct advantage, but how should a GWT application be designed to allow for the collaboration of large teams and stay maintainable over the course of time?

The Model-View-Presenter (MVP) pattern provides an answer to this. Applying the MVP pattern in GWT applications is described in this two-part article: Large scale application development and MVP

In this post, I will demonstrate a modified version of the example code of this article series to show how Errai makes implementing a MVP application in GWT even easier and how Errai helps to further decouple the individual components. The source code of the modified example can be found on GitHub: https://github.com/csadilek/errai-mvp-demo

So, let's take a look at the individual components used in MVP and the modifications and improvements made to it using Errai.

The Model

The business objects used in this example (Contact and ContactDetail) remain more or less unchanged. The @Portable annotation was added to mark them as serializable by Errai. Errai marshalling was designed for maximum flexibility and to impose as few limitations to serializable classes as possible (see our documentation for details). The classes do not need to (but may of course) implement java.io.Serializable.

The View

The views contain only UI layout code. They have no knowledge of the model, other views, transitions and contain no application logic. Errai can improve view implementations by providing the ability to inject UiBinders.

 Without Errai:


public class EditContactView extends Composite implements EditContactPresenter.Display {  

  interface EditContactViewUiBinder extends UiBinder<Panel, EditContactView> {}
  private static EditContactViewUiBinder uiBinder =  
      GWT.create(EditContactViewUiBinder.class);

  ...
}

With Errai:


public class EditContactView extends Composite implements EditContactPresenter.Display {

  @Inject 
  UiBinder<Panel, EditContactView> uiBinder;

  ...
}

The Presenter

The presenters contain all the application logic: view transitions, RPCs, etc. In the original example, the RPC proxies, the event bus and the view instances are passed to the presenters as constructor arguments. Using Errai, we can now inject all these components.


@Dependent
public class EditContactPresenter implements Presenter {
  public interface Display {
    ...
  }

  @Inject
  private Caller<ContactsService> contactsService;

  @Inject
  private HandlerManager eventBus;

  @Inject
  private Display display;

  ...
}

This might seem like a minor improvement at first, but once your application grows this will become more than handy. Let's say you come to a point where all your presenters need an additional RPC proxy. Without dependency injection, you would have to change all constructors and all call sites!

The GWT/RPC proxy was replaced with an Errai RPC proxy (the injected Caller). Errai RPC does not require an asynchronous interface nor a servlet based service implementation on the server. It can even be used to invoke methods on a server-side CDI bean (see our documentation for details).

The Application Controller

The application controller handles logic that is not specific to any presenter and also deals with history management and view transitions. It needs access to the event bus (which again we can inject using Errai IOC) to react on application events that trigger view transitions.


@ApplicationScoped
public class AppController implements Presenter, ValueChangeHandler<String> {
  @Inject
  private HandlerManager eventBus;
  
  @Inject
  private IOCBeanManager manager;

  ...
}

It also needs to be able to create new presenter instances when the browser's history stack changes. To create new managed instances of presenters, we use Errai's client-side bean manager that will make sure all the injection points of presenters are satisfied and the instance is ready to use.


public void onValueChange(ValueChangeEvent<String> event) {
    String token = event.getValue();
    if (token != null) {
      Presenter presenter = null;

      if (token.equals("list")) {
        IOCBeanDef<ContactsPresenter> bean = manager.lookupBean(ContactsPresenter.class);
        if (bean != null) {
          presenter = bean.getInstance();
        }
      } else if (token.equals("add") || token.equals("edit")) {
        IOCBeanDef<EditContactPresenter> bean = 
            manager.lookupBean(EditContactPresenter.class);
        if (bean != null) {
          presenter = bean.getInstance();
        }
      }

      if (presenter != null) {
        presenter.go(container);
      }
    }
  }

The EntryPoint

Since Errai allows us to use dependency injection for all the required components, the main difference here is that we no longer have to pass the RPC proxies and the event bus instance to the app controller which in turn would have to forward it to the presenters and views.

The @Produces method provides the event bus instance to all the event bus injection points in all the presenters. The application controller itself is also just injected and started as soon as the app is finished initializing (@AfterInitialization).


@EntryPoint
public class Contacts {

  private HandlerManager eventBus = new HandlerManager(null);

  @Inject
  private AppController appController;

  @AfterInitialization
  public void startApp() {
    appController.go(RootPanel.get());
  }

  @Produces
  private HandlerManager produceEventBus() {
    return eventBus;
  }
}

So to sum it up, Errai's IOC container helps implementing the MVP pattern by further decoupling the individual components and by alleviating boilerplate code for UiBinders and RPC proxies.

Future Work 

An extension that we are currently working on is the @MockFor annotation that can be used to replace an injected type with a mocked type for unit testing. During tests, a presenter could then get the mocked view injected in place for the actual view for example. The presenters can then be tested using a plain JUnit test instead of an integration test.

@MockFor(EditContactsView.class)
public class EditContactsMockView implements EditContactPresenter.Display { 
  ...
}

As always, feedback is welcome and appreciated!