JBoss.orgCommunity Documentation

Errai

Errai Reference Guide

Legal Notice

Abstract

This is the Errai Reference Guide.


Preface
1. Document Conventions
2. Feedback
1. Introduction
1.1. What is it?
1.2. Required software
2. Messaging
2.1. Messaging Overview
2.2. Messaging API Basics
2.3. Handling Errors
2.4. Single-Response Conversations & Psuedo-Synchronous Messaging
2.5. Broadcasting
2.6. Client-to-Client Communication
2.7. Asynchronous Message Tasks
2.8. Repeating Tasks
2.9. Sender Inferred Subjects
2.10. Message Routing Information
2.11. Queue Sessions
2.11.1. Lifecycle
2.11.2. Scopes
3. Remote Procedure Calls (RPC)
3.1. Making calls
3.2. Handling exceptions
4. Serialization
4.1. Serialization of external types
5. Dependency Injection
5.1. Container Wiring
5.2. Wiring server side components
6. Configuration
6.1. Appserver Configuration
6.2. ErraiApp.properties
6.3. ErraiService.properties
6.3.1. errai.dispatcher.implementation
6.3.2. errai.async_thread_pool_size
6.3.3. errai.async.worker_timeout
6.3.4. errai.authentication_adapter
6.3.5. errai.require_authentication_for_all
6.3.6. errai.auto_discover_services
6.3.7. errai.auto_load_extensions
6.4. Dispatcher Implementations
6.4.1. SimpleDispatcher
6.4.2. AsyncDispatcher
6.5. Servlet Implementations
6.5.1. DefaultBlockingServlet
6.5.2. GrizzlyCometServlet
6.5.3. JBossCometServlet
6.5.4. JettyContinuationsServlet
6.5.5. StandardAsyncServlet (Errai 2.0)
6.5.6. TomcatCometServlet
6.5.7. WeblogicAsyncServlet
7. Debugging Errai Applications
8. Development Proxy
9. Downloads
10. Sources
11. Reporting problems
12. Errai License
A. Revision History

Errai requires a JDK version 6 or higher and depends on Apache Maven to build and run the examples, and for leveraging the quickstart utilities.

Launching maven the first time

Please note, that when launching maven the first time on your machine, it will fetch all dependencies from a central repository. This may take a while, because it includes downloading large binaries like GWT SDK. However, subsequent builds are not required to go through this step and will be much faster.

This section covers the core messaging concepts of the ErraiBus messaging framework.

ErraiBus forms the backbone of the Errai framework's approach to application design. Most importantly, it provides a straight-forward approach to a complex problem space. Providing common APIs across the client and server, developers will have no trouble working with complex messaging scenarios from building instant messaging clients, stock tickers, to monitoring instruments. There's no more messing with RPC APIs, or unweildy AJAX or COMET frameworks. We've built it all in to one, consice messaging framework. It's single-paradigm, and it's fun to work with.

The MessageBuilder is the heart of the messaging API in ErraiBus. It provides a fluent / builder API, that is used for constructing messages. All three major message patterns can be constructed from the MessageBuilder .

Components that want to receive messages need to implement the MessageCallback interface.

But before we dive into the details, let look at some use cases first.

Sending Messages with the Client BusIn order to send a message from a client you need to create a Message and send it through an instance of MessageBus . In this simple example we send it to the subject 'HelloWorldService'.

In the above example we build and send a message every time the button is clicked. Here's an explanation of what's going on as annotated above:

Recieving Messages on the Server Bus / Server ServicesEvery message has a sender and at least one receiver. A receiver is as it sounds--it receives the message and does something with it. Implementing a receiver (also referred to as a service) is as simple as implementing our standard MessageCallback interface, which is used pervasively across, both client and server code. Let's begin with server side component that receives messages:

He we declare an extremely simple service. The @Service annotation provides a convenient, meta-data based way of having the bus auto-discover and deploy the service.

Sending Messages with the Server BusIn the following example we extend our server side component to reply with a message when the callback method is invoked. It will create a message and address it to the subject ' HelloWorldClient ':

The above example shows a service which sends a message in response to receiving a message. Here's what's going on:

Receiving Messages on the Client Bus/ Client ServicesMessages can be received asynchronously and arbitriraily by declaring callback services within the client bus. As ErraiBus maintains an open COMET channel at all times, these messages are delivered in real time to the client as they are sent. This provides built-in push messaging for all client services.

In the above example, we declare a new client service called "BroadcastReceiver" which can now accept both local messages and remote messages from the server bus. The service will be available in the client to receive messages as long the client bus is and the service is not explicitly de-registered.

ConversationsConversations are message exchanges which are between a single client and a service. They are a fundmentally important concept in ErraiBus, since by default, a message will be broadcast to all client services listening on a particular channel.

When you create a reply with an incoming message, you ensure that the message you are sending back is received by the same client which sent the incoming message. A simple example:

Note that the only difference between the example in the previous section (2.4) and this is the use of the createConversation() method with MessageBuilder.

Asynchronous messaging necessitates the need for asynchronous error handling. Luckily, support for handling errors is built directly into the MessageBuilder API, utilizing the ErrorCallback interface. In the examples shown in previous exceptions, error handing has been glossed over with aubiquitous usage of the noErrorHandling() method while building messaging. We chose to require the explicit use of such a method to remind developers of the fact that they are responsible for their own error handling, requiring you to explicitly make the decision to forego handling potential errors.

As a general rule, you should always handle your errors . It will lead to faster and quicker identification of problems with your applications if you have error handlers, and generally help you build more robust code.

The addition of error handling at first may put off developers as it makes code more verbose and less-readable. This is nothing that some good practice can't fix. In fact, you may find cases where the same error handler can appropriately be shared between multiple different calls.

The error handler is required to return a boolean value. This is to indicate whether or not Errai should perform the default error handling actions it would normally take during a failure. You will almost always want to return true here, unless you are trying to explicitly surpress some undesirably activity by Errai, such as automatic subject-termination in conversations. But this is almost never the case.

Errai further provides a subject to subscribe to for handling global errors on the client (such as a disconnected server bus or an invalid response code) that occur outside a regular application message exchange. Subscribing to this subject is useful to detect errors early (e.g. due to failing heartbeat requests). A use case that comes to mind here is activating your application's offline mode.

A repeating task is sent using one of the MessageBuilder's repeatXXX() methods. The task will repeat indefinitely until cancelled (see next section).

The above example sends a message very 1 second with a message part called "time" , containing a formatted time string. Note the use of the withProvided() method; a provided message part is calculated at the time of transmission as opposed to when the message is constructed.

Cancelling an Asynchronous TaskA delayed or repeating task can be cancelled by calling the cancel() method of the AsyncTask instance which is returned when creating a task. Reference to the AsyncTask object can be retained and cancelled by any other thread.

Every message that is sent between a local and remote (or server and client) buses contain session routing information. This information is used by the bus to determine what outbound queues to use to deliver the message to, so they will reach their intended recipients. It is possible to manually specify this information to indicate to the bus, where you want a specific message to go.

The utility class org.jboss.errai.bus.server.util.ServerBusUtils contains a utility method for extracting the String-based SessionID which is used to identify the message queue associated with any particular client. You may use this method to extract the SessionID from a message so that you may use it for routing. For example:

The SessionID can then be stored in a medium, say a Map, to cross-reference specific users or whatever identifier you wish to allow one client to obtain a reference to the specific SessionID of another client. In which case, you can then provide the SessionID as a MessagePart to indicate to the bus where you want the message to go.

By providing the SessionID part in the message, the bus will see this and use it for routing the message to the relevant queue.

Now you're routing from client-to-client!

It may be tempting however, to try and include destination SessionIDs at the client level, assuming that this will make the infrastructure simpler. But this will not achieve the desired results, as the bus treats SessionIDs as transient. Meaning, the SessionID information is not ever transmitted from bus-to-bus, and therefore is only directly relevant to the proximate bus.

The ErraiBus maintains it's own seperate session management on-top of the regular HTTP session management. While the queue sessions are tied to, and dependant on HTTP sessions for the most part (meaning they die when HTTP sessions die), they provide extra layers of session tracking to make dealing with complex applications built on Errai easier.

ErraiBus supports a high-level RPC layer to make typical client-server RPC communication easy on top of the bus. While it is possible to use ErraiBus without ever using this API, you may find it to be a more useful and concise approach to exposing services to the clients.

Please note that this API has changed since version 1.0. RPC services provide a way of creating type-safe mechanisms to make client-to-server calls. Currently, this mechanism only support client-to-server calls, and not vice-versa.

Creating a service is straight forward. It requires the definition of a remote interface, and a service class which implements it. See the following:

@Remote

public interface MyRemoteService {
  public boolean isEveryoneHappy();
}

The @Remote annotation tells Errai that we'd like to use this interface as a remote interface. The remote interface must be part of of the GWT client code. It cannot be part of the server-side code, since the interface will need to be referenced from both the client and server side code. That said, the implementation of a service is relatively simple to the point:

@Service

public class MyRemoteServiceImpl implements MyRemoteService {
  public boolean isEveryoneHappy() {
    // blatently lie and say everyone's happy.
    return true;
  }
}

That's all there is to it. You use the same @Service annotation as described in Section 2.4. The presence of the remote interface tips Errai off as to what you want to do with the class.

Errai supports serialization within the same scope and limitations as the default GWT RPC serialization rules. In order to expose your domain objects to the bus so they can be exported across the bus, you must annotate them with the org.jboss.errai.bus.server.annotations.ExposeEntity annotation. The presence of this annotation will cause Errai's GWT compiler extensions to generate marshall/demarshall stubs for the annotated objects at compile-time.

For example:

@ExposeEntity

public class User implements java.io.Serializable {
  private int userId;
  public int getUserId() {
    return userId;
  }
  public void setUserId(int userId) {
    this.userId = userId;
  }
  [...]
}

Note

All exposed entities must follow Java Bean convensions, and must be in the classpath both at compile-time and at runtime. Compile-time access to the entities is required since the creation of the marshalling/demarshalling proxies involves code generation.

The core Errai IOC module implements a subset of the JSR-330 Dependency Injection specification for in-client component wiring.

Dependency injection (DI) allows for cleaner and more modular code, by permitting the implementation of decoupled and type-safe components. By using DI, components do not need to be aware of the implementation of provided services. Instead, they merely declare a contract with the container, which in turn provides instances of the services that component depends on.

A simple example:

public class MyLittleClass {

  private final TimeService timeService;
  @Inject
  public MyLittleClass(TimeService timeService) {
    this.timeService = timeService;
  }
  public void printTime() {
    System.out.println(this.timeService.getTime());
  }
}

In this example, we create a simple class which declares a dependency using @Inject for the interface TimeService . In this particular case, we use constructor injection to establish the contract between the container and the component. We can similarly use field injection to the same effect:

public class MyLittleClass {

  @Inject
  private TimeService timeService;
  public void printTime() {
    System.out.println(this.timeService.getTime());
  }
}

Best Practices

Although field injection results in less code, a major disadvantage is that you cannot create immutable classes using the pattern, since the container must first call the default, no argument constructor, and then iterate through its injection tasks, which leaves the potential – albeit remote – that the object could be left in an partially or improperly initialized state. The advantage of constructor injection is that fields can be immutable (final), and invariance rules applied at construction time, leading to earlier failures, and the guarantee of consistent state.

In contrast to Gin , the Errai IOC container does not provide a programmatic way of creating and configuring injectors. Instead, container-level binding rules are defined by implementing a Provider , which is scanned for an auto-discovered by the container.

A Provider is essentially a factory which produces dependent types in the container, which defers instantiation responsibility for the provided type to the provider implementation. Top-level providers use the standard javax.inject.Provider<T> interface.

Types made available as top-level providers will be available for injection in any managed component within the container.

Out of the box, Errai IOC implements three default top-level providers:

  • org.jboss.errai.ioc.client.api.builtin.MessageBusProvider : Makes an instance of MessageBus available for injection.

  • org.jboss.errai.ioc.client.api.builtin.RequestDispatchProvider : Makes an instance of the RequestDispatcher available for injection.

  • org.jboss.errai.ioc.client.api.builtin.ConsumerProvider : Makes event Consumer<?> objects available for injection.

Implementing a Provider is relatively straight-forward. Consider the following two classes:

TimeService.java

public interface TimeService {

  public String getTime();
}

TimeServiceProvider.java

@IOCProvider

@Singleton
public class TimeServiceProvider implements Provider<TimeService> {
  @Override
  public TimeService get() {
    return new TimeService() {
      public String getTime() {
        return "It's midnight somewhere!";
      }
    };
  }
}

If you are familiar with Guice, this is semantically identical to configuring an injector like so:

Guice.createInjector(new AbstractModule() {

  public void configure() {
    bind(TimeService.class).toProvider(TimeServiceProvider.class);
  }
 }).getInstance(MyApp.class);

As shown in the above example code, the annotation @IOCProvider is used to denote top-level providers.

The classpath will be searched for all annotated providers at compile time.

Important

Top-level providers are treated as regular beans. And as such may inject dependencies – particularly from other top-level providers – as necessary.

This section contains information on configuring Errai.

Depending on what application server you are deploying on, you must provide an appropriate servlet implementation if you wish to use true, asynchronous I/O. See Section 6.5, “Servlet Implementations” for information on the available servlet implementations.

Here's a sample web.xml file:

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
  version="2.5">

  <servlet>
    <servlet-name>ErraiServlet</servlet-name>
    <servlet-class>org.jboss.errai.bus.server.servlet.DefaultBlockingServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>ErraiServlet</servlet-name>
    <url-pattern>*.erraiBus</url-pattern>
  </servlet-mapping>

  <context-param>
    <param-name>errai.properties</param-name>
    <param-value>/WEB-INF/errai.properties</param-value>
  </context-param>

  <context-param>
    <param-name>login.config</param-name>
    <param-value>/WEB-INF/login.config</param-value>
  </context-param>

  <context-param>
    <param-name>users.properties</param-name>
    <param-value>/WEB-INF/users.properties</param-value>
  </context-param>

</web-app>

he ErraiService.properties file contains basic configuration for the bus itself.

Example Configuration:

Errai has several different implementations for HTTP traffic to and from the bus. We provide a universally-compatible blocking implementation that provides fully synchronous communication to/from the server-side bus. Where this introduces scalability problems, we have implemented many webserver-specific implementations that take advantage of the various proprietary APIs to provide true asynchrony.

These included implementations are packaged at: org.jboss.errai.bus.server.servlet .

Errai includes a bus monitoring application, which allows you to monitor all of the message exchange activity on the bus in order to help track down any potential problems It allows you to inspect individual messages to examine their state and structure.

To utilize the bus monitor, you'll need to include the _errai-tools _ package as part of your application's dependencies. When you run your application in development mode, you will simply need to add the following JVM options to your run configuration in order to launch the monitor: -Derrai.tools.bus_monitor_attach=true


The monitor provides you a real-time perspective on what's going on inside the bus. The left side of the main screen lists the services that are currently available, and the right side is the service-explorer, which will show details about the service.

To see what's going on with a specific service, simply double-click on the service or highlight the service, then click "Monitor Service...". This will bring up the service activity monitor.


The service activity monitor will display a list of all the messages that were transmitted on the bus since the monitor became active. You do not need to actually have each specific monitor window open in order to actively monitor the bus activity. All activity on the bus is recorded.

The monitor allows you select individual messages, an view their individual parts. Clicking on a message part will bring up the object inspector, which will allow you to explore the state of any objects contained within the message, not unlike the object inspectors provided by debuggers in your favorite IDE. This can be a powerful tool for looking under the covers of your application.

Proxied access to external containersUsually GWT developement happens in hosted mode and then, later on, the GWT app is turned into a webapp (*.war) that can be deployed on a target container (app server, servlet engine). This works quiet well for closed systems that don't depend on additional resources the target container provides. A typical resource would be a DataSource for access to a relational database.

Instead of pulling these resources into the hosted mode servlet engine (jetty, read-only JNDI) or creating mock objects for any resources that cannot be run in hosted mode, we offer you a much more simple way to work with external resources: Simply proxy all requests that occur in hosted mode to an external target container:


The proxy is implemented a yet another servlet that you need to add to the web.xml that's being sed in hosted mode:

The web.xml proxy declaration contains two notable elements: A reference to the proxy configuration file and a URL pattern, where the proxy can found. While the later shouldn't be changed (the bus bootstraps on this URL), you need to change the proxy config according to your needs:

You would need to change the host, port and webcontext ('my-gwt-app' in this case) to reflect the location of the external container. 'passthrough' simply means that any request to 'proxy/in.erraiBus' will go to 'container/my-gwt-app/in.erraiBus'. This already indicates that you need to have the server side part of your GWT application, already running on the target container. The most simple way to achieve this, is to build a the complete webapp, deploy it and ignore the UI parts that may be available on the server.

The distribution packages can be downloaded from jboss.org http://jboss.org/errai/Downloads.html

Errai is currently managed using Github. You can clone our repositories from http://github.com/errai .

If you run into trouble don't hesitate to get in touch with us:

Errai is distributed under the terms of the Apache License, Version 2.0. See the full Apache license text .

Revision History
Revision