JBoss.orgCommunity Documentation

Errai Reference Guide


1. Introduction
1.1. What is it?
1.2. Required software
1.3. Getting Started with Errai
1.3.1. Technology Primer
1.3.2. Creating your first project
1.3.3. Running and Debugging with GWT’s Super Dev mode
1.3.4. Running and Debugging in Eclipse using Maven tooling
1.3.5. Running and Debugging in your IDE using GWT tooling
1.3.6. A Gentle Introduction to CDI
2. Messaging
2.1. Messaging Overview
2.2. Messaging API Basics
2.2.1. Sending Messages with the Client Bus
2.2.2. Receiving Messages on the Server Bus / Server Services
2.2.3. Sending Messages with the Server Bus
2.2.4. Receiving Messages on the Client Bus/ Client Services
2.2.5. Local Services
2.3. Single-Response Conversations & Pseudo-Synchronous Messaging
2.4. Sender Inferred Subjects
2.5. Broadcasting
2.6. Client-to-Client Communication
2.6.1. Relay Services
2.7. Message Routing Information
2.8. Handling Errors
2.8.1. Handling global message transport errors
2.9. Asynchronous Message Tasks
2.10. Repeating Tasks
2.11. Queue Sessions
2.11.1. Lifecycle
2.11.2. Scopes
2.12. Wire Protocol (J.REP)
2.12.1. Payload Structure
2.12.2. Message Routing
2.12.3. Bus Management and Handshaking Protocols
2.13. Conversations
2.14. WebSockets
2.14.1. Configuring the sideband server
2.14.2. Deploying with JBoss AS 7.1.2 (or higher)
2.14.3. JSR-356 WebSocket support (Deploying to WildFly 8.0 or higher)
2.14.4. WebSocket Security
2.15. Bus Lifecycle
2.15.1. Turning Server Communication On and Off
2.15.2. Observing Bus Lifecycle State and Communication Status
2.16. Shadow Services
2.17. Debugging Messaging Problems
3. Dependency Injection
3.1. Container Wiring
3.2. Wiring server side components
3.3. Scopes
3.3.1. Dependent Scope
3.4. Built-in Extensions
3.4.1. Bus Services
3.4.2. Client Components
3.4.3. Lifecycle Tools
3.4.4. Timed Methods
3.5. Client-Side Bean Manager
3.5.1. Looking up beans
3.5.2. Availability of beans
3.6. Alternatives and Mocks
3.6.1. Alternatives
3.6.2. Test Mocks
3.7. Bean Lifecycle
3.7.1. Destruction of Beans
4. Errai CDI
4.1. Features and Limitations
4.1.1. Other features
4.2. Events
4.2.1. Conversational events
4.2.2. Local Events
4.2.3. Client-Server Event Example
4.3. Producers
4.4. Safe dynamic lookup
4.5. Deploying Errai CDI
5. Marshalling
5.1. Mapping Your Domain
5.1.1. @Portable and @NonPortable
5.1.2. Manual Mapping
5.1.3. Manual Class Mapping
5.1.4. Custom Marshallers
6. Remote Procedure Calls (RPC)
6.1. Creating an RPC Interface
6.2. Making calls
6.2.1. Proxy Injection
6.3. Handling exceptions
6.3.1. Global RPC exception handler
6.4. Client-side Interceptors
6.4.1. Annotating the Remote Interface
6.4.2. Implementing an Interceptor
6.4.3. Annotating the Interceptor (alternative)
6.4.4. Interceptors and IOC
6.5. Session and request objects in RPC endpoints
6.6. Batching remote calls
6.7. Asynchronous handling of RPCs on the server
7. Errai JAX-RS
7.1. Server-Side JAX-RS Implementation
7.2. Shared JAX-RS Interface
7.3. Creating Requests
7.3.1. Proxy Injection
7.4. Handling Responses
7.4.1. Handling Errors
7.5. Accesssing and aborting requests
7.6. Client-side Interceptors
7.6.1. Annotating the JAX-RS Interface
7.6.2. Implementing an Interceptor
7.6.3. Annotating the Interceptor (alternative)
7.6.4. Interceptors and IOC
7.7. Wire Format
7.8. Path
8. Errai JPA
8.1. Getting Started
8.1.1. META-INF/persistence.xml
8.1.2. Declaring an Entity Class
8.1.3. Entity Lifecycle States
8.1.4. Obtaining an instance of EntityManager
8.1.5. Named Queries
8.1.6. Entity Lifecycle Events
8.1.7. JPA Metamodel
8.1.8. JPA Features Not Implemented in Errai 2.4
8.1.9. Other Caveats for Errai 2.1 JPA
8.2. Errai JPA Data Sync
8.2.1. How To Use It
9. Data Binding
9.1. Getting Started
9.1.1. Bindable Objects
9.1.2. Initializing a DataBinder
9.2. Creating Bindings
9.3. Specifying Converters
9.3.1. Registering a global default converter
9.3.2. Providing a binding-specific converter
9.4. Property Change Handlers
9.5. Declarative Binding
9.5.1. Default, Simple, and Chained Property Bindings
9.5.2. Data Converters
9.5.3. Updating model values on UI text changes
9.5.4. Replacing a model object
9.6. Bean validation
9.6.1. Excluding Classes from Validation
10. Errai UI
10.1. Get started
10.2. Use Errai UI Composite components
10.2.1. Inject a single instance
10.2.2. Inject multiple instances (for iteration)
10.3. Create a @Templated Composite component
10.3.1. Basic component
10.3.2. Custom template names
10.3.3. Template providers
10.4. Create an HTML template
10.4.1. Select a template from a larger HTML file
10.5. Use other Widgets in a composite component
10.5.1. Annotate Widgets in the template with @DataField
10.5.2. Add corresponding attributes to the HTML template
10.6. How HTML templates are merged with Components
10.6.1. Example
10.6.2. Element attributes (template wins)
10.6.3. DOM Elements (component field wins)
10.6.4. Inner text and inner HTML (preserved when component implements HasText or HasHTML)
10.7. Event handlers
10.7.1. Concepts
10.7.2. GWT events on Widgets
10.7.3. GWT events on DOM Elements
10.7.4. Native DOM events on Elements
10.8. HTML Form Support
10.8.1. A Login Form that Triggers Browsers' "Remember Password" Feature
10.8.2. Using the Correct Elements in the Template
10.9. Data Binding
10.9.1. Default, Simple, and Chained Property Bindings
10.9.2. Binding of Lists
10.9.3. Data Converters
10.10. Nest Composite components
10.11. Extend Composite components
10.11.1. Template
10.11.2. Parent component
10.11.3. Child component
10.12. Stylesheet binding
10.12.1. Usage with Data Binding
10.13. Internationalization (i18n)
10.13.1. HTML Template Translation
10.13.2. TranslationKey and TranslationService
10.14. Extended styling with LESS
11. Errai UI Navigation
11.1. Getting Started
11.2. How it Works
11.2.1. Declaring a Page
11.2.2. Page Lifecycle
11.2.3. Page State Parameters
11.2.4. PushState Functionality
11.2.5. Declaring a Link with TransitionAnchor
11.2.6. Declaring a Manual Link
11.2.7. Following a Manual Link
11.2.8. Declaring a Link By UniquePageRole
11.2.9. Installing the Navigation Panel into the User Interface
11.2.10. Overriding the default Navigating Panel type
11.2.11. Handling Navigation Errors
11.2.12. Viewing the Generated Navigation Graph
12. Errai Cordova (Mobile Support)
12.1. Integrate with native hardware
13. Errai Security
13.1. Basic Model
13.2. Getting Started
13.2.1. Making Users
13.2.2. Authentication from the Client
13.3. RestrictedAccess
13.3.1. Simple Roles as Strings
13.3.2. Provided Roles
13.3.3. RPC Services
13.3.4. Page Navigation
13.3.5. Hiding UI Elements
13.4. Form Based Login
13.4.1. Errai Security Cookie
13.4.2. Errai User Host Page Filter
13.5. Using an Alternative to PicketLink
13.6. Using Keycloak for Authentication
13.6.1. How It Works (Overview)
13.6.2. Setup
14. Logging
14.1. What is slf4j?
14.2. Client-Side Setup
14.2.1. Errai Client-Side Log Handlers
14.2.2. Configuring Errai Client-Side Log Handlers
14.2.3. Format String
14.3. Server-Side Setup
14.4. Example Usage
14.5. Logger Names
15. Configuration
15.1. Errai Development Mode Configuration
15.1.1. Deployment in Development Mode (JBossLauncher)
15.1.2. Additional JBossLauncher Arguments
15.1.3. Deployment to an Application Server
15.2. Errai Offline Mode Configuration
15.3. ErraiApp.properties
15.3.1. As a Marker File
15.3.2. As a Configuration File
15.4. Messaging (Errai Bus) Configuration
15.4.1. Compile-time Dependencies
15.4.2. Disabling remote communication
15.4.3. Configuring an alternative remote remote bus endpoint
15.4.4. ErraiService.properties
15.4.5. Servlet Configuration
15.5. Errai JAX-RS Setup
15.5.1. Compile-time dependency
15.5.2. GWT Module
15.5.3. Configuration
15.6. Errai JPA
15.6.1. Compile-time Dependencies
15.6.2. GWT Module Descriptor
15.7. Errai JPA Data Sync
15.7.1. Compile-time Dependencies
15.7.2. GWT Module Descriptor
15.8. Errai Data Binding
15.8.1. Compile-time Dependencies
15.8.2. GWT module descriptor
15.8.3. Bootstrapping Data Binding without Errai IOC
15.9. Errai UI
15.9.1. Compile-time dependency
15.9.2. GWT Module Descriptor
15.10. Errai UI Navigation
15.10.1. Compile-time Dependencies
15.10.2. GWT Module Descriptor
15.11. Errai Cordova (Mobile Support)
15.11.1. Compile-time Dependencies
15.11.2. Cordova Maven Plugin
15.11.3. GWT Module Descriptor
15.11.4. Building with Errai Cordova
15.12. Errai Security
15.12.1. Compile-time dependency
15.12.2. GWT Module Descriptor
15.12.3. CDI and Interceptor Bindings
15.13. Errai Project Dependencies
15.13.1. Errai Messaging
15.13.2. Errai CDI
15.13.3. Errai IOC
15.13.4. Errai UI
15.13.5. Errai Navigation
15.13.6. Errai DataBinding
15.13.7. Errai JPA Client
15.13.8. Errai JPA Datasync
15.13.9. Errai JAXRS
15.13.10. Errai Cordova
15.13.11. Errai Security
16. Troubleshooting & FAQ
16.1. Why does it seem that Errai can’t see my class at compile time?
16.2. Why am I getting "java.lang.ClassFormatError: Illegal method name "<init>$" in class org/xyz/package/MyClass"?
16.3. I’m getting "java.lang.RuntimeException: There are no proxy providers registered yet." in my @PostConstruct method!
16.4. Why do I get a "404 - Not Found" page if I try to navigate to my web page by typing in the URL or refreshing the page?
17. Upgrade Guide
17.1. Upgrading from 1.* to 2.0
17.2. Upgrading from 2.0.Beta to 2.0.*.Final
17.3. Upgrading from Errai 2.2.x to 2.4 or 3.0
17.4. Upgrading to Errai 3.0
17.5. Upgrading to Errai 3.1 from 3.0
17.6. Upgrading to Errai 3.2 from 3.1
18. Downloads
19. Sources
20. Reporting problems
21. Errai License

Errai is a framework which combines a constellation of web and server-side technologies to assist you in developing large, scaleable rich web applications using a consistent, standardized programming model for client and server development.

Since Errai is an end-to-end framework, in that, parts of the framework run and operate within the client and parts run and operate within the server, there is a set of various technologies upon which Errai relies. This section will detail the basic core technologies which you’ll need to be familiar with.

CDI is a standard part of the Java EE 6.0 stack, and is defined in the JSR-299 specification. CDI is the main programming model explored in this guide. As such, the basic concepts of CDI will be introduced in this guide, so pre-existing knowledge is not strictly necessary.

Errai’s support for CDI is two-fold. For the server-side, Errai has integration with Weld, which is the reference implementation (RI) of the JSR-299 specification. The client-side integration for CDI is provided by the Errai CDI extension. Errai CDI implements a subset of the JSR-299 specification to provide the CDI programming model within client code.

Maven Required

The first thing you’ll need to do if you have not already, is install Maven. If you have not already installed Maven, do so now.

Warning: If you use maven2, you will run into this problem: https://community.jboss.org/thread/177645

You have two options to set up an Errai application. You can start by copying an existing example application (i.e. the errai tutorial demo) or by building an app with the Errai Forge Addon:

Simply download and unzip this demo. Check out the README file and continue with running the app in GWT’s development mode and importing the project into Eclipse.

Another way to start a new project with Errai is to use Forge and the Errai Forge Addon. To use this method, follow the instructions here to install the Errai Forge Addon and create a new project.

In the upcomming sections, we will demonstrate how to run your app in GWT Development Mode through the command line and eclipse, so it would be nice to have something to run so that you are able to verify that everything is working. Here is a sample class you can use that displays an alert when the app loads:

// Add the package declaration here


import javax.annotation.PostConstruct;
import org.jboss.errai.ioc.client.api.EntryPoint;
import com.google.gwt.user.client.Window;
@EntryPoint
public class App {
  @PostConstruct
  public void onLoad() {
    Window.alert("Hello World!");
  }
}

For this code to run properly, you must use the Errai Forge Addon Add Errai Features command to install Errai IOC.

Create new subfolder, client/local, under the folder containing your GWT module file. Then create a file, App.java, in this new package and copy the above sample code (making sure to replace the top comment with the package declaration).

Tip

Plugin Tips

Keep an eye out for tips in the proceeding sections on how you can use the Errai Forge plugin to configure other Errai features for your new project.

There are two ways to configure your project in your IDE. One option is to use the built-in Maven tooling to set up Maven run and debug configurations within your IDE. The other option is to download and use GWT tooling that is available for your IDE, and create custom run/debug configurations with that. Note that for Intellij IDEA, the GWT tooling is only available for users of the Ultimate Edition.

Errai’s EmbeddedWildFlyLauncher provides an embedded WildFly instance within Dev Mode to allow users to debug server- and client-side code simultaneously in a single JVM. Here are the instructions for using it in Eclipse and Intellij IDEA Ultimate Edition:

This method requires the Google Plugin for Eclipse (GPE). You can find the instructions to download and install it here.

Here are the steps to setup a run/debug configuration using the embedded WildFly launcher:

  1. Ensure that your app is using the Google Web Toolkit. Right-click on your project in Eclipse, and select Google → Web Toolkit Settings, and make sure that the "Use Google Web Toolkit" box is checked and the appropriate GWT SDK is selected.


  2. Set up a Web Application run/debug configuration as follows:

    Create a new Web Application run/debug configuration, select your Errai app in the Project field and set com.google.gwt.dev.DevMode as the main class:


  3. In the Server tab, check the Run built-in server checkbox, and enter the port number 8888.


  4. Select Super Development Mode in the GWT tab, and add your GWT module under Available Modules.


  5. Under the Arguments tab, there are two fields, Program arguments and VM arguments. In the Program arguments field, amend the server flag as follows:

    Program Arguments

    -server org.jboss.errai.cdi.server.gwt.EmbeddedWildFlyLauncher

    Make sure the following VM arguments are set:

    VM arguments

    -Xmx2048m -XX:MaxPermSize=512M -Derrai.jboss.home=/home/ddadlani/errai-tutorial/target/wildfly-8.2.0.Final/

    where errai.jboss.home points to your own WildFly installation. This can either be your local WildFly installation directory, or in the target/ directory of your app. For the Errai Tutorial app, errai.jboss.home points to the WildFly installation within the target/ directory, which is redownloaded and installed as part of the build. See below for information on how to automatically download WildFly into the target/ directory prior to running Super Dev Mode.


That’s it! To debug your application within Eclipse, simply select your debug configuration and hit Debug. This will start GWT’s dev mode as well as the debugger within Eclipse.

The Ultimate Edition for Intellij IDEA comes with a built-in GWT plugin that allows you to run and debug GWT apps specifically. We can configure the plugin to use the embedded WildFly launcher for debugging ease, in order to debug both server and client-side code in one debug session. This section describes how to set up a GWT run/debug configuration within Intellij IDEA:

  1. If you have not already done so, add a GWT facet to your main module. Instructions to add a GWT facet to an existing module can be found here.
  2. On the top right hand corner of your Intellij IDEA session, select the dropdown box labeled Edit Configurations to create a new run/debug configuration.


  3. Press the + button under GWT Configurations to create a new GWT configuration. Check the Super Dev Mode checkbox and select the name of your module. Fill out the following parameters in the corresponding boxes:

    VM Options

    -Xmx2048m -XX:MaxPermSize=512M -Derrai.jboss.home=/home/ddadlani/errai-tutorial/target/wildfly-8.2.0.Final/

    where errai.jboss.home points to your WildFly installation directory. This can either be your local WildFly installation directory, or in the target/ directory of your app. For the Errai Tutorial app, errai.jboss.home points to the WildFly installation within the target/ directory, which is redownloaded and installed as part of the build. See below for information on how to automatically download WildFly into the target/ directory prior to running Super Dev Mode.

    Dev Mode Parameters

    -server org.jboss.errai.cdi.server.gwt.EmbeddedWildFlyLauncher


  4. Select the Default server and make sure the start page is index.html. Select your browser and check the with JavaScript debugger box to take advantage of Intellij IDEA’s built-in JavaScript tooling.
  5. Click on the + button under Before Launch and select the Make option. This will tell Intellij to compile your project before launching Dev Mode.

To run or debug your app, select this configuration in the top right corner of Intellij IDEA and click the Run or Debug buttons next to it. Your app should start up in Dev Mode within Intellij automatically and you should be able to use Intellij’s own debugger to debug your code.

Now that you have everything set up, it’s time to move on to coding!

Plugin Tip

Use the Errai Forge Addon Add Errai Features command and select Errai CDI to follow along with this section.

Errai CDI as its namesake implies is based on, and is in fact, a partial implementation of the CDI (Contexts and Dependency Injection) specification. Errai CDI covers most of the programming model but omits the CDI SPI, instead replacing it with it a custom set of APIs which are more appropriate for the client programming model of Errai.

These differences aside, using Errai CDI in conjunction with CDI on the server will provide you with a uniform programming model across the client and server code of your application.

This guide does not assume any past experience with CDI. However, you may wish to consider reading the Weld Documentation in addition to this guide.

Scopes, put simply, are the context within which beans live. Some scopes are short-lived and some are long-lived. For instance, there are beans which you may only want to create during a request, and beans which you want to live for as long as the application is running.

It turns out that CDI includes a set of default scopes which represent these very things.

We’ll start by taking a look at the application scope, which is lovingly represented by the annotation @ApplicationScoped. An application-scoped bean is a bean which will live for the entire duration of the application. In this sense, it is essentially like a singleton. And it’s generally okay to think of it in that way.

So let’s declare an application-scoped bean:

@ApplicationScoped

public class Bar {
  public String getName() {
    return "Mr. Bar";
  }
}

That was almost as easy as making the last bean. The difference between this bean and the last, is Bar will actually be instantiated by the container automatically, and Foo will not.

So what can we do with Foo? Well, let’s go ahead and get familiar with dependency injection, shall we?

@ApplicationScoped

public class Bar {
  @Inject Foo foo;
  public String getName() {
    return "Mr. Bar";
  }
}

We have added a field of the type Foo which we declared earlier, and we have annotated it with javax.inject.Inject. This tells the container to inject an instance of Foo into our bean. Since our Foo bean is of the dependent scope, the bean manager will actually create a new instance of Foo and pass it in.

This scope of the newly instantiated Foo is dependent on the scope that it was injected into. In this case, the application scope. On the other hand, if we were to turn around an inject Bar into Foo, the behaviour is quite different.

public class Foo {

  @Inject Bar bar;
  public String getName() {
    return "Mr. Foo";
  }
}

Here, every time a new instance of Foo is created, the same instance of Bar will be injected. That is to say: this pseudo-code assertion is now always true:

assert fooInstance.bar.foo == fooInstance

In the case of an Errai application, there are a bunch of application scoped beans which come built-in for common services like ErraiBus. Thus, in an Errai application which uses the message bus, we can inject a handle to the MessageBus service into any of our beans. Let’s go ahead and do that in our Bar class:

@ApplicationScoped

public class Bar {
  @Inject Foo foo;
  @Inject MessageBus bus;
  public String getName() {
    return "Mr. Bar";
  }
}

If working with dependency injection is new to you, then this is where you’ll start seeing some practical benefit. When you need a common service in your client code, you ask the container for it by injecting it. This frees you from worrying about the proper APIs to use in order to access a service; we need to use the message bus in our Bar bean, and so we inject it.

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

ErraiBus 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 such as building instant messaging clients, stock tickers, to monitoring instruments. There’s no more messing with RPC APIs, or unwieldy AJAX or COMET frameworks. We’ve built it all in to one concise 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’s look at some use cases.

In 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.

public class HelloWorld implements EntryPoint {


  // Get an instance of the RequestDispatcher
  private RequestDispatcher dispatcher = ErraiBus.getDispatcher();
  public void onModuleLoad() {
    Button button = new Button("Send message");
    button.addClickHandler(new ClickHandler() {
      public void onClick(ClickEvent event) {
        // Send a message to the 'HelloWorldService'.
        MessageBuilder.createMessage()
          .toSubject("HelloWorldService") // (1)
          .signalling() // (2)
          .noErrorHandling() // (3)
          .sendNowWith(dispatcher); // (4)
        });
        [...]
      }
   }
}

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:

Important

An astute observer will note that access to the RequestDispatcher differs within client code and server code. Because this client code does not run within a container, access to the RequestDispatcher and MessageBus is provided statically using the ErraiBus.get() and ErraiBus.getDispatcher() methods. See the section on Errai IOC and Errai CDI for using ErraiBus from a client-side container.

When using Errai IOC or CDI, you can also use the Sender<T> interface to send messages.

In 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 ':

@Service

public class HelloWorldService implements MessageCallback {
  private RequestDispatcher dispatcher;
  @Inject
  public HelloWorldService(RequestDispatcher dispatcher) {
    dispatcher = dispatcher;
  }
  public void callback(CommandMessage message) {
    // Send a message to the 'HelloWorldClient'.
    MessageBuilder.createMessage()
      .toSubject("HelloWorldClient") // (1)
      .signalling()                  // (2)
      .with("text", "Hi There")      // (3)
      .noErrorHandling()             // (4)
      .sendNowWith(dispatcher);      // (5)
    });
  }
}

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

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.

You can obtain the SessionID directly from a Message by getting the QueueSession resource:

   QueueSession sess = message.getResource(QueueSession.class, Resources.Session.name());

   String sessionId = sess.getSessionId();

You can extract the SessionID from a message so that you may use it for routing by obtaining the QueueSession resource from the Message. For example:

...

  public void callback(Message message) {
   QueueSession sess = message.getResource(QueueSession.class, Resources.Session.name());
   String sessionId = sess.getSessionId();
    // Record this sessionId somewhere.
    ...
  }

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.

  MessageBuilder.createMessage()

    .toSubject("ClientMessageListener")
    .signalling()
    .with(MessageParts.SessionID, sessionId)
    .with("Message", "We're relaying a message!")
    .noErrorHandling().sendNowWith(dispatcher);

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

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.

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.

MessageBuilder.createMessage()

    .toSubject("HelloWorldService")
    .signalling()
    .with("msg", "Hi there!")
    .errorsHandledBy(new ErrorCallback() {
      public boolean error(Message message, Throwable throwable) {
        throwable.printStackTrace();
          return true;
      }
    })
    .sendNowWith(dispatcher);

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.

ErrorCallback error = new ErrorCallback() {

  public boolean error(Message message, Throwable throwable) {
    throwable.printStackTrace();
    return true;
  }
}
MessageBuilder.createMessage()
  .toSubject("HelloWorldService")
  .signalling()
  .with("msg", "Hi there!")
  .errorsHandledBy(error)
  .sendNowWith(dispatcher);

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.

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

  MessageBuilder.createMessage()

    .toSubject("FunSubject")
    .signalling()
    .withProvided("time", new ResourceProvider<String>() {
       SimpleDateFormat fmt = new SimpleDateFormat("hh:mm:ss");
       public String get() {
         return fmt.format(new Date(System.currentTimeMillis());
       }
     }
     .noErrorHandling()
     .sendRepeatingWith(requestDispatcher, TimeUnit.SECONDS, 1); //sends a message every 1 second

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.

AsyncTask task = MessageBuilder.createConversation(message)

  .toSubject("TimeChannel").signalling()
  .withProvided(TimeServerParts.TimeString, new ResourceProvider<String>() {
     public String get() {
       return String.valueOf(System.currentTimeMillis());
     }
   }).defaultErrorHandling().replyRepeating(TimeUnit.MILLISECONDS, 100);
    ...
  // cancel the task and interrupt it's thread if necessary.
  task.cancel(true);

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 implements a JSON-based wire protocol which is used for the federated communication between different buses. The protocol specification encompasses a standard JSON payload structure, a set of verbs, and an object marshalling protocol. The protocol is named J.REP. Which stands for JSON Rich Event Protocol.

All wire messages sent across are assumed to be JSON arrays at the outermost element, contained in which, there are 0..n messages. An empty array is considered a no-operation, but should be counted as activity against any idle timeout limit between federated buses.


Here we see an example of a J.REP payload containing two messages. One bound for an endpoint named "SomeEndpoint" and the other bound for the endpoint "SomeOtherEndpoint". They both include a payload element "Value" which contain strings. Let’s take a look at the anatomy of an individual message.


The message shows a very vanilla J.REP message. The keys of the JSON Object represent individual message parts, with the values representing their corresponding values. The standard J.REP protocol encompasses a set of standard message parts and values, which for the purposes of this specification we’ll collectively refer to as the protocol verbs.

The following table describes all of the message parts that a J.REP capable client is expected to understand:

PartRequiredJSON TypeDescription

ToSubject

Yes

String

Specifies the subject within the bus, and its federation, which the message should be routed to.

CommandType

No

String

Specifies a command verb to be transmitted to the receiving subject. This is an optional part of a message contract, but is required for using management services

ReplyTo

No

String

Specifies to the receiver what subject it should reply to in response to this message.

Value

No

Any

A recommended but not required standard payload part for sending data to services

PriorityProcessing

No

Number

A processing order salience attribute. Messages which specify priority processing will be processed first if they are competing for resources with other messages in flight. Note: the current version of ErraiBus only supports two salience levels (0 and >1). Any non-zero salience in ErraiBus will be given the same priority relative to 0 salience messages

ErrorMessage

No

String

An accompanying error message with any serialized exception

Throwable

No

Object

If applicable, an encoded object representing any remote exception that was thrown while dispatching the specified service

Federation between buses requires management traffic to negotiate connections and manage visibility of services between buses. This is accomplished through services named ClientBus and ServerBus which both implement the same protocol contracts which are defined in this section.

Both bus services share the same management protocols, by implementing verbs (or commands) that perform different actions. These are specified in the protocol with the CommandType message part. The following table describes these commands:


PartRequiredJSON TypeDescription

CapabilitiesFlags

Yes

String

A comma delimited string of capabilities the bus is capable of us

Subject

Yes

String

The subject to subscribe or unsubscribe from

SubjectsList

Yes

Array

An array of strings representing a list of subjects to subscribe to

ErraiBus has support for WebSocket-based communication. When WebSockets are enabled, capable web browsers will attempt to upgrade their COMET-based communication with the server-side bus to use a WebSocket channel.

There are three different ways the bus can enable WebSockets. The first uses a sideband server, which is a small, lightweight server which runs on a different port from the application server. The second is native JBoss AS 7-based integration and the third is to rely in JSR-356 support in WildFly. Of course, you only need to configure one of these three options!

This is an alternative approach to the sideband server described in the previous chapter. Make sure to NOT configure both! It is currently necessary to use the native connector in JBoss AS for WebSockets to work. So the first step is to configure your JBoss AS instance(s) to use the native connector by changing the domain/configuration/standalone.xml or domain/configuration/domain.xml file as follows:


<subsystem xmlns="urn:jboss:domain:web:1.1" default-virtual-server="default-host" native="false">

to:


<subsystem xmlns="urn:jboss:domain:web:1.1" default-virtual-server="default-host" native="true">

You will then need to configure the servlet in your application’s web.xml which will provide WebSocket upgrade support within AS7.

Add the following to the web.xml:


<context-param>
  <param-name>websockets-enabled</param-name>
  <param-value>true</param-value>
</context-param>

<context-param>
  <param-name>websocket-path-element</param-name>
  <param-value>in.erraiBusWS</param-value>
</context-param>

This will tell the bus to enable web sockets support. The websocket-path-element specified the path element within a URL which the client bus should request in order to negotiate a websocket connection. For instance, specifying in.erraiBusWS as we have in the snippit above, will result in attempted negotiation at http://<your_server>:<your_port>/<context_path>/in.erraiBusWS. For this to have any meaningful result, we must add a servlet mapping that will match this pattern:


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

<servlet-mapping>
  <servlet-name>ErraiWSServlet</servlet-name>
  <url-pattern>*.erraiBusWS</url-pattern>
</servlet-mapping>

Do not remove the regular ErraiBus servlet mappings!

When configuring ErraiBus to use WebSockets on JBoss AS, you do not remove the existing servlet mappings for the bus. The WebSocket servlet is in addition to your current bus servlet. This is because ErraiBus always negotiates WebSocket sessions over the COMET channel.

Important dependency

Also make sure to deploy the required errai-bus-jboss7-websocket.jar to your server. If you’re using Maven simply add the following dependency to your pom.xml file:


    <dependency>
        <groupId>org.jboss.errai</groupId>
        <artifactId>errai-bus-jboss7-websocket</artifactId>
        <version>${errai.version}</version>
    </dependency>

Errai provides two implementations for this:

Make sure to add the following project dependency:


<!-- For JSR-356 without depending on Weld -->
<dependency>
    <groupId>org.jboss.errai</groupId>
    <artifactId>errai-bus-jsr356-websocket</artifactId>
    <version>${errai.version}</version>
</dependency>

<!-- For JEE environment with Weld-->
<dependency>
    <groupId>org.jboss.errai</groupId>
    <artifactId>errai-bus-jsr356-websocket-weld</artifactId>
    <version>${errai.version}</version>
</dependency>

To configure ErraiBus that WebSocket communication should be used, define the following in your web.xml


<context-param>
    <param-name>websockets-enabled</param-name>
    <param-value>true</param-value>
</context-param>

You can also define filters when using the JSR-356 WebSocket implementation. These filters will be executed for each received ErraiBus message on the server. Your filters need to implement org.jboss.errai.bus.server.websocket.jsr356.filter.WebSocketFilter and must be configured in your appliations’s web.xml as an ordered comma separated list:


<context-param>
    <param-name>errai-jsr-356-websocket-filter</param-name>
    <param-value>foo.bar.FooFilter,foo.bar.BarFilter</param-value>
</context-param>

Because one of the filter method parameters is the actual WebSocket session, you also have to add the following dependency to your pom.xml:


<dependency>
    <groupId>org.jboss.spec.javax.websocket</groupId>
    <artifactId>jboss-websocket-api_1.0_spec</artifactId>
    <scope>provided</scope>
    <version>1.0.0.Final</version>
</dependency>

Please take a look at the JavaDoc of the filter interface for more information about the method parameters.

Errai supports Websocket security (wss) for two deployment scenarios.

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.

Plugin Tip

Use the Errai Forge Addon Add Errai Features command and select Errai IOC to follow along with this section.

Manual Setup

Checkout the Manual Setup Section for instructions on how to manually add Errai IOC to your project.

The core Errai IOC module implements 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.

Classpath Scanning and ErraiApp.properties

Errai only scans the contents of classpath locations (JARs and directories) that have a file called ErraiApp.properties at their root. If dependency injection is not working for you, double-check that you have an ErraiApp.properties in every JAR and directory that contains classes Errai should know about.

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

In order to inject TimeService, you must annotate it with @ApplicationScoped or the Errai DI container will not acknowledge the type as a bean.

@ApplicationScoped

public class TimeService {
}

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 and auto-discovered by the container.

A Provider is essentially a factory which produces type instances within in the container, and 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 these default top-level providers, all defined in the org.jboss.errai.ioc.client.api.builtin package:

  • CallerProvider: Makes RPC Caller<T> objects available for injection.
  • DisposerProvider: Makes Errai IoC Disposer<T> objects available for injection.
  • InitBallotProvider: Makes instances of InitBallot available for injection.
  • IOCBeanManagerProvider: Makes Errai’s client-side bean manager, ClientBeanManager, available for injection.
  • MessageBusProvider: Makes Errai’s client-side MessageBus singleton available for injection.
  • RequestDispatcherProvider: Makes an instance of the RequestDispatcher available for injection.
  • RootPanelProvider: Makes GWT’s RootPanel singleton injectable.
  • SenderProvider: Makes MessageBus Sender<T> 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 regular beans, so they can inject dependencies particularly from other top-level providers as necessary.

As Errai IOC provides a container-based approach to client development, support for Errai services are exposed to the container so they may be injected and used throughout your application where appropriate. This section covers those services.

The IOC container, by default, provides a set of default injectable bean types. They range from basic services, to injectable proxies for RPC. This section covers the facilities available out-of-the-box.

The org.jboss.errai.ioc.support.bus.client.Sender<?> interface is the lower-level counterpart to the Caller<?> interface described above. You can inject a Sender to send low-level ErraiBus messages directly to subscribers on any subject.

For example:

  @Inject

  @ToSubject("ListCapitializationService")
  Sender<List<String>> listSender;
  // ... ///
  @EventHandler("button")
  public void onButtonClick(ClickHandler handler) {
    List<String> myListOfStrings = getSelectedCitiesFromForm();
    listSender.send(myListOfStrings, new MessageCallback() {
      public void callback(Message reply) {
        // do stuff with reply
      }
    );
  }

The Sender.send() method is overloaded. The variant demonstrated above takes a value and a MessageCallback to reply receive a reply (assuming the subscriber sends a conversational reply). The following variants are available:

The reply-to service can also be specified declaratively using the @ReplyTo annotation. This allows the app to receive conversational replies even when using the send() variants that do not take a MessageCallback:

  @Inject

  @ToSubject("ListCapitializationService")
  @ReplyTo("ClientListService")
  Sender<List<String>> listSender;
  // ... ///
  @EventHandler("button")
  public void onButtonClick(ClickHandler handler) {
    List<String> myListOfStrings = getSelectedCitiesFromForm();
    listSender.send(myListOfStrings);
  }
  @Singleton
  @Service
  public static class ClientListService implements MessageCallback {
    @Override
    public void callback(Message message) {
      // do stuff with message
    }
  }

These Sender<?> features are just convenient wrappers around the full-featured programmatic ErraiBus API. See Messaging API Basics and Conversations for full information about low-level ErraiBus communication.

A problem commonly associated with building large applications in the browser is ensuring that things happen in the proper order when code starts executing. Errai IOC provides you tools which permit you to ensure things happen before initialization, and forcing things to happen after initialization of all of the Errai services.

The @Timed annotation allows scheduling method executions on managed client-side beans. Timers are automatically scoped to the scope of the corresponding managed bean and participate in the same lifecycle (see Bean Lifecycle for details).

In the following example the updateTime method is invoked repeatedly every second.

@Timed(type = TimerType.REPEATING, interval = 1, timeUnit = TimeUnit.SECONDS)

private void updateTime() {
  timeWidget.setTime(System.currentTimeMillis);
}

For delayed one-time execution of methods type = TimerType.DELAYED can be used instead.

It may be necessary at times to manually obtain instances of beans managed by Errai IOC from outside the container managed scope or creating a hard dependency from your bean. Errai IOC provides a simple client-side bean manager for handling these scenarios: org.jboss.errai.ioc.client.container.ClientBeanManager.

As you might expect, you can inject a bean manager instance into any of your managed beans. If you use Errai IOC in its default mode you will need to inject the synchronous bean manager (org.jboss.errai.ioc.client.container.SyncBeanManager).

If you have asynchronous IOC mode enabled simply inject the asynchronous bean manager (org.jboss.errai.ioc.client.container.async.AsyncBeanManager) instead. Asynchronous IOC brings support for code splitting. That means that any bean annotated with @LoadAsync can be compiled into a separate JavaScript file that’s downloaded when the bean is first needed on the client. @LoadAsync also allows to specify a fragment name using a class literal. Using GWT 2.6.0 or higher, all types with the same fragment name will be part of the same JavaScript file.


If you need to access the bean manager outside a managed bean, such as in a unit test, you can access it by calling org.jboss.errai.ioc.client.container.IOC.getBeanManager()

It may be desirable to have multiple matching dependencies for a given injection point with the ability to specify which implementation to use at runtime. For instance, you may have different versions of your application which target different browsers or capabilities of the browser. Using alternatives allows you to share common interfaces among your beans, while still using dependency injection, by exporting consideration of what implementation to use to the container’s configuration.

Consider the following example:

@Singleton @Alternative

public class MobileView implements View {
  // ... //
}

and

@Singleton @Alternative

public class DesktopView implements View {
  // ... //

In our controller logic we in turn inject the View interface:

@EntryPoint

public class MyApp {
  @Inject
  View view;
  // ... //
}

This code is unaware of the implementation of View, which maintains good separation of concerns. However, this of course creates an ambiguous dependency on the View interface as it has two matching subtypes in this case. Thus, we must configure the container to specify which alternative to use. Also note, that the beans in both cases have been annotated with javax.enterprise.inject.Alternative.

In your ErraiApp.properties for the module, you can simply specify which active alternative should be used:

errai.ioc.enabled.alternatives=org.foo.MobileView

You can specify multiple alternative classes by white space separating them:

errai.ioc.enabled.alternatives=org.foo.MobileView \
                               org.foo.HTML5Orientation \
                               org.foo.MobileStorage

You can only have one enabled alternative for a matching set of alternatives, otherwise you will get ambiguous resolution errors from the container.

Similar to alternatives, but specifically designed for testing scenarios, you can replace beans with mocks at runtime for the purposes of running unit tests. This is accomplished simply by annotating a bean with the org.jboss.errai.ioc.client.api.TestMock annotation. Doing so will prioritize consideration of the bean over any other matching beans while running unit tests.

Consider the following:

@ApplicationScoped

public class UserManagementImpl implements UserManagement {
  public List<User> listUsers() {
     // do user listy things!
  }
}

You can specify a mock implementation of this class by implementing its common parent type (UserManagement) and annotating that class with the @TestMock annotation inside your test package like so:

@TestMock @ApplicationScoped

public class MockUserManagementImpl implements UserManagement {
  public List<User> listUsers() {
     // return only a test user.
     return Collections.singletonList(TestUser.INSTANCE);
  }
}

In this case, the container will replace the UserManagementImpl with the MockUserManagementImpl automatically when running the unit tests.

The @TestMock annotation can also be used to specify alternative providers during test execution. For example, it can be used to mock a Caller<T>. Callers are used to invoke RPC or JAX-RS endpoints. During tests you might want to replace theses callers with mock implementations. For details on providers see Container Wiring.

@TestMock @IOCProvider

public class MockedHappyServiceCallerProvider implements ContextualTypeProvider<Caller<HappyService>> {
  @Override
  public Caller<HappyService> provide(Class<?>[] typeargs, Annotation[] qualifiers) {
    return new Caller<HappyService>() {
      ...
    }
}

All beans managed by the Errai IOC container support the @PostConstruct and @PreDestroy annotations.

Beans which have methods annotated with @PostConstruct are guaranteed to have those methods called before the bean is put into service, and only after all dependencies within its graph has been satisfied.

Beans are also guaranteed to have their @PreDestroy annotated methods called before they are destroyed by the bean manager.

Beans under management of Errai IOC, of any scope, can be explicitly destroyed through the client bean manager. Destruction of a managed bean is accomplished by passing a reference to the destroyBean() method of the bean manager.


When the bean manager "destroys" the bean, any pre-destroy methods the bean declares are called, it is taken out of service and no longer tracked by the bean manager. If there are references on the bean by other objects, the bean will continue to be accessible to those objects.

Important

Container managed resources that are dependent on the bean such as bus service endpoints or CDI event observers will also be automatically destroyed when the bean is destroyed.

Another important consideration is the rule, "all beans created together are destroyed together." Consider the following example:



In this example we pass the instance of AnotherBean, created as a dependency of SimpleBean, to the bean manager for destruction. Because this bean was created at the same time as its parent, its destruction will also result in the destruction of SimpleBean; thus, this action will result in the @PreDestroy cleanUp() method of SimpleBean being invoked.

Plugin Tip

Use the Errai Forge Addon Add Errai Features command and select Errai CDI to follow along with this section.

Manual Setup

Checkout the Manual Setup Section for instructions on how to manually add Errai CDI to your project.

CDI (Contexts and Dependency Injection) is the Jave EE standard (JSR-299) for handling dependency injection. In addition to dependency injection, the standard encompasses component lifecycle, application configuration, call-interception and a decoupled, type-safe eventing specification.

The Errai CDI extension implements a subset of the specification for use inside of client-side applications within Errai, as well as additional capabilities such as distributed eventing.

Errai CDI does not currently implement all life cycles specified in JSR-299 or interceptors. These deficiencies may be addressed in future versions.

Important

Errai CDI is implemented as an extension on top of the Errai IOC Framework (see Dependency Injection), which itself implements JSR-330. Inclusion of the CDI module your GWT project will result in the extensions automatically being loaded and made available to your application.

Classpath Scanning and ErraiApp.properties

Errai CDI only scans the contents of classpath locations (JARs and directories) that have a file called ErraiApp.properties at their root. If CDI features such as dependency injection, event observation, and @PostConstruct are not working for your classes, double-check that you have an ErraiApp.properties at the root of every JAR and directory tree that contains classes Errai should know about.

Any CDI managed component may produce and consume events. This allows beans to interact in a completely decoupled fashion. Beans consume events by registering for a particular event type and optional qualifiers. The Errai CDI extension simply extends this concept into the client tier. A GWT client application can simply register an Observer for a particular event type and thus receive events that are produced on the server-side. Likewise and using the same API, GWT clients can produce events that are consumed by a server-side observer.

Let’s take a look at an example.


Two things are noteworthy in this example:

  1. Injection of an Event dispatcher proxy
  2. Creation of an Observer method for a particular event type

The event dispatcher is responsible for sending events created on the client-side to the server-side event subsystem (CDI container). This means any event that is fired through a dispatcher will eventually be consumed by a CDI managed bean, if there is an corresponding Observer registered for it on the server side.

In order to consume events that are created on the server-side you need to declare an client-side observer method for a particular event type. In case an event is fired on the server this method will be invoked with an event instance of type you declared.

To complete the example, let’s look at the corresponding server-side CDI bean:


A key feature of the Errai CDI framework is the ability to federate the CDI eventing bus between the client and the server. This permits the observation of server produced events on the client, and vice-versa.

Example server code:


Domain-model:



Client application logic:


The CDI integration is a plugin to the Errai core framework and represents a CDI portable extension. Which means it is discovered automatically by both Errai and the CDI container. In order to use it, you first need to understand the different runtime models involved when working GWT, Errai, and CDI.

Typically a GWT application lifecycle begins in Development Mode and finally a web application containing the GWT client code will be deployed to a target container (Servlet Engine, Application Server). This is no way different when working with CDI components to back your application.

What’s different however is availability of the CDI container across the different runtimes. In GWT development mode and in a pure servlet environment you need to provide and bootstrap the CDI environment on your own. While any Java EE 6 Application Server already provides a preconfigured CDI container. To accomodate these differences, we need to do a little trickery when executing the GWT Development Mode and packaging our application for deployment.

Plugin Tip

Use the Errai Forge Addon Add Errai in Project command to setup development mode, usable for any Errai application, including one with Errai CDI.

Manual Setup

Checkout the Manual Setup Section for instructions on how to manually setup Errai CDI in Development Mode.

Errai includes a comprehensive marshalling framework which permits the serialization of domain objects between the browser and the server. From the perspective of GWT, this is a complete replacement for the provided GWT serialization facilities and offers a great deal more flexibility. You can use it with your own application-specific domain models as well as preexisting models, including classes from third-party libraries using configuration files or the custom definitions API.

Plugin Tip

If you used the Errai Forge Addon Add Errai Features command to add Errai Messaging or Errai CDI then Marshalling is already available to you.

All classes that you intend to be marshalled between the client and the server must be exposed to the marshalling framework explicitly. There are several ways to do that, and this section will take you through the different approaches.

The easiest way to make a Java class eligible for serialization with Errai Marshalling is to mark it with the org.jboss.errai.common.client.api.annotations.Portable annotation. This tells the marshalling system to generate marshalling and demarshalling code for the annotated class and all of its nested classes.

The mapping strategy that will be used depends on how much information you provide about your model up-front. If you simply annotate a domain type with @Portable and do nothing else, the marshalling system will use an exhaustive strategy to determine how to serialize and deserialize instances of that type and its nested types.

The Errai marshalling system works by enumerating all of the Portable types it can find (by any of the three methods discussed in this section of the reference guide), eliminating all the non-portable types it can find (via @NonPortable annotations and entries in ErraiApp.properties), then enumerating the marshallable properties that make up each remaining portable entity type. The rules that Errai uses for enumerating the properties of a portable entity type are as follows:

Note that the existence of methods called getFoo(), setFoo(), or both, does not mean that the entity has a property called foo. Errai Marshalling always works from fields when discovering properties.

When reading a field foo, Errai Marshalling will call the method getFoo() in preference to direct field access if the getFoo() method exists.

When writing a field foo, Errai Marshalling gives first preference to a parameter of the mapping constructor (defined below) annotated with @MapsTo("foo"). Failing this, Errai Marshalling will the method setFoo() if it exists. As a last resort, Errai Marshalling will use direct field access to write the value of foo.

Each field is mapped independently according to the above priority rules. Portable classes can rely on a mix of constructor, setter/getter, and field access.

For de-marshalling a @Portable type, Errai must know how to obtain a new instance of that type. To do this, it selects a mapping constructor (which could literally be a constructor, but could also be a static factory method) using the following rules:

If no suitable mapping constructor can be found on a type marked @Portable, it is a compile-time error.

Now let’s take a look at some common examples of how this works.

For types with a large number of optional attributes, a builder is often the best approach.

@Portable

public class Person {
  private final String name;
  private final int age;
  private Person(@MapsTo("name") String name, @MapsTo("age") int age) {
    this.name = name;
    this.age = age;
  }
  public String getName() {
    return name;
  }
  public int getAge() {
    return age;
  }
  @NonPortable
  public static class Builder {
    private String name;
    private int age;
    public Builder name(String name) {
      this.name = name;
      return this;
    }
    public Builder age(int age) {
      this.age = age;
      return this;
    }
    public Person build() {
      return new Person(name, age);
    }
  }
}

In this example, we have a nested Builder class that implements the Builder Pattern and calls the private Person constructor. Hand-written code will always use the builder to create Person instances, but the @MapsTo annotations on the private Person constructor tell Errai Marshalling to bypass the builder and construct instances of Person directly.

One final note: as a nested type of Person (which is marked @Portable), the builder itself would normally be portable. However, we do not intend to move instances of Person.Builder across the network, so we mark Person.Builder as @NonPortable.

Some classes may be out of your control, making it impossible to annotate them for auto-discovery by the marshalling framework. For cases such as this, there are two approaches to include these classes in your application.

The first approach is the easiest, but is contingent on whether or not the class is directly exposed to the GWT compiler. That means, the classes must be part of a GWT module and within the GWT client packages. See the GWT documentation on Client-Side Code for information on this.

The marshalling framework supports and promotes the concept of marshalling by interface contract, where possible. For instance, the framework ships with a marshaller which can marshall data to and from the java.util.List interface. Instead of having custom marshallers for classes such as ArrayList and LinkedList, by default, these implementations are merely aliased to the java.util.List marshaller.

There are two distinct ways to go about doing this. The most straightforward is to specify which marshaller to alias when declaring your class is @Portable.

package org.foo.client;


@Portable(aliasOf = java.util.List.class)
public MyListImpl extends ArrayList {
  // .. //
}

In the case of this example, the marshaller will not attempt to comprehend your class. Instead, it will merely rely on the java.util.List marshaller to dematerialize and serialize instances of this type onto the wire.

If for some reason it is not feasible to annotate the class, directly, you may specify the mapping in the ErraiApp.properties file using the errai.marshalling.mappingAliases attribute.

errai.marshalling.mappingAliases=org.foo.client.MyListImpl->java.util.List \
                                 org.foo.client.MyMapImpl->java.util.Map

The list of classes is whitespace-separated so that it may be split across lines.

The example above shows the equivalent mapping for the MyListImpl class from the previous example, as well as a mapping of a class to the java.util.Map marshaller.

The syntax of the mapping is as follows: <class_to_map><contract_to_map_to>.

Although the default marshalling strategies in Errai Marshalling will suit the vast majority of use cases, there may be situations where it is necessary to manually map your classes into the marshalling framework to teach it how to construct and deconstruct your objects.

This is accomplished by specifying MappingDefinition classes which inform the framework exactly how to read and write state in the process of constructing and deconstructing objects.

All manual mappings should extend the org.jboss.errai.marshalling.rebind.api.model.MappingDefinition class. This is base metadata class which contains data on exactly how the marshaller can deconstruct and construct objects.

Consider the following class:

public class MySuperCustomEntity {

   private final String mySuperName;
   private String mySuperNickname;
   public MySuperCustomEntity(String mySuperName) {
     this.mySuperName = mySuperName;;
   }
   public String getMySuperName() {
     return this.mySuperName;
   }
   public void setMySuperNickname(String mySuperNickname) {
     this.mySuperNickname = mySuperNickname;
   }
   public String getMySuperNickname() {
     return this.mySuperNickname;
   }
}

Let us construct this object like so:

  MySuperCustomEntity entity = new MySuperCustomEntity("Coolio");

  entity.setSuperNickname("coo");

It is clear that we may rely on this object’s two getter methods to extract the totality of its state. But due to the fact that the mySuperName field is final, the only way to properly construct this object is to call its only public constructor and pass in the desired value of mySuperName.

Let us consider how we could go about telling the marshalling framework to pull this off:

@CustomMapping

public MySuperCustomEntityMapping extends MappingDefinition {
  public MySuperCustomEntityMapping() {
    super(MySuperCustomEntity.class);                                                          // (1)
    SimpleConstructorMapping cnsMapping = new SimpleConstructorMapping();
    cnsMapping.mapParmToIndex("mySuperName", 0, String.class);                                 // (2)
    setInstantiationMapping(cnsMapping);
    addMemberMapping(new WriteMapping("mySuperNickname", String.class, "setMySuperNickname")); // (3)
    addMemberMapping(new ReadMapping("mySuperName", String.class, "getMySuperName"));          // (4)
    addMemberMapping(new ReadMapping("mySuperNickname", String.class, "getMySuperNickname"));  // (5)
  }
}

And that’s it. This describes to the marshalling framework how it should go about constructing and deconstructing MySuperCustomEntity.

Paying attention to our annotating comments, let’s describe what we’ve done here.

There is another approach to extending the marshalling functionality that doesn’t involve mapping rules, and that is to implement your own Marshaller class. This gives you complete control over the parsing and emission of the JSON structure.

The implementation of marshallers is made relatively straight forward by the fact that both the server and the client share the same JSON parsing API.

Consider the included java.util.Date marshaller that comes built-in to the marshalling framework:

Example 5.3. DataMarshaller.java from the built-in marshallers

@ClientMarshaller(Date.class)

@ServerMarshaller(Date.class)
public class DateMarshaller extends AbstractNullableMarshaller<Date> {
  @Override
  public Date[] getEmptyArray() {
    return new Date[0];
  }
  @Override
  public Date doNotNullDemarshall(final EJValue o, final MarshallingSession ctx) {
    if (o.isObject() != null) {
      EJValue qualifiedValue = o.isObject().get(SerializationParts.QUALIFIED_VALUE);
      if (!qualifiedValue.isNull() && qualifiedValue.isString() != null) {
        return new Date(Long.parseLong(qualifiedValue.isString().stringValue()));
      }
      EJValue numericValue = o.isObject().get(SerializationParts.NUMERIC_VALUE);
      if (!numericValue.isNull() && numericValue.isNumber() != null) {
        return new Date(new Double(numericValue.isNumber().doubleValue()).longValue());
      }
      if (!numericValue.isNull() && numericValue.isString() != null) {
        return new Date(Long.parseLong(numericValue.isString().stringValue()));
      }
    }
    return null;
  }
  @Override
  public String doNotNullMarshall(final Date o, final MarshallingSession ctx) {
    return "{\"" + SerializationParts.ENCODED_TYPE + "\":\"" + Date.class.getName() + "\"," +
            "\"" + SerializationParts.OBJECT_ID + "\":\"" + o.hashCode() + "\"," +
            "\"" + SerializationParts.QUALIFIED_VALUE + "\":\"" + o.getTime() + "\"}";
  }
}

The class is annotated with both @ClientMarshaller and @ServerMarshaller indicating that this class should be used for both marshalling on the client and on the server.

The doNotNullDemarshall() method is responsible for converting the given JSON object (which has already been parsed and verified non-null) into a Java object.

The doNotNullMarshall() method does roughly the inverse: it converts the given Java object into a String (which must be parseable as a JSON object) for transmission on the wire.

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 for 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.

Plugin Tip

Using the Errai Forge Addon Add Errai Features command, Errai RPC can be used if Errai Messaging or Errai CDI have been installed.

Manual Setup

Checkout the Manual Setup Section for instructions on how to manually add Errai Messaging or Errai CDI to a project.

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.


<servlet>
  <servlet-name>ErraiServlet</servlet-name>
  <servlet-class>org.jboss.errai.bus.server.servlet.DefaultBlockingServlet</servlet-class>
  <init-param>
    <param-name>auto-discover-services</param-name>
    <param-value>true</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

Calling a remote service involves use of the MessageBuilder API. Since all messages are asynchronous, the actual code for calling the remote service involves the use of a callback, which we use to receive the response from the remote method. Let’s see how it works:

MessageBuilder.createCall(new RemoteCallback<Boolean>() {

  public void callback(Boolean isHappy) {
    if (isHappy) Window.alert("Everyone is happy!");
  }
 }, MyRemoteService.class).isEveryoneHappy();

In the above example, we declare a remote callback that receives a Boolean, to correspond to the return value of the method on the server. We also reference the remote interface we are calling, and directly call the method. However, don’t be tempted to write code like this:

 boolean bool = MessageBuilder.createCall(..., MyRemoteService.class).isEveryoneHappy();

The above code will never return a valid result. In fact, it will always return null, false, or 0 depending on the type. This is due to the fact that the method is dispatched asynchronously, as in, it does not wait for a server response before returning control. The reason we chose to do this, as opposed to emulate the native GWT-approach, which requires the implementation of remote and async interfaces, was purely a function of a tradeoff for simplicity.

Handling remote exceptions can be done by providing an ErrorCallback on the client:

MessageBuilder.createCall(

  new RemoteCallback<Boolean>() {
    public void callback(Boolean isHappy) {
      if (isHappy) Window.alert("Everyone is happy!");
    }
  },
  new ErrorCallback() {
    public boolean error(Message message, Throwable caught) {
      try {
        throw caught;
      }
      catch (NobodyIsHappyException e) {
        Window.alert("OK, that's sad!");
      }
      catch (Throwable t) {
        GWT.log("An unexpected error has occurred", t);
      }
      return false;
    }
  },
  MyRemoteService.class).isEveryoneHappy();

As remote exceptions need to be serialized to be sent to the client, the @Portable annotation needs to be present on the corresponding exception class (see Marshalling). Further the exception class needs to be part of the client-side code. For more details on ErrorCallbacks see Handling Errors.

Client-side remote call interceptors provide the ability to manipulate or bypass the remote call before it’s being sent. This is useful for implementing crosscutting concerns like caching, for example when the remote call should be avoided if the data is already cached locally.

If computing the result of an RPC call takes a significant amount of time (i.e. because a third party service needs to be contacted or a long running query needs to be executed) it might be preferable to release the request-processing thread so it can perform other work and provide the result in a different execution context farther in the future. So, the RPC endpoint method can return immediately and the thread handling the incoming request doesn’t need to stay active until the result is available. Computing and setting the result can be done in a different thread (i.e. from a smaller thread pool provided by a library).

Errai provides a special return type CallableFuture to indicate to the RPC system that the result of the remote method call will be provided asynchronously (after the remote method call has returned).

Here’s an example returning a result of type String:

@Remote

public interface LongRunningService {
  public CallableFuture<String> someLongRunningTask();
}
@Service

public class LongRunningServiceImpl implements LongRunningService {
  @Override
  public CallableFuture<String> someLongRunningTask() {
    final CallableFuture<String> future = CallableFutureFactory.get().createFuture(String.class);
    final ExecutorService executorService = Executors.newSingleThreadExecutor();
    executorService.submit(new Runnable() {
      @Override
      public void run() {
        try {
          Thread.sleep(5000);
          future.setValue("result");
        }
        catch (Throwable t) {
          t.printStackTrace();
        }
      }
    });
    executorService.shutdown();
    return future;
  }
}

Note that the client-side code does not change when using this feature and will work exactly as described in Section 6.2, “Making calls” i.e.:

MessageBuilder.createCall(new RemoteCallback<String>() {

  @Override
  public void callback(String response) {
    assertEquals("foobar", response);
    finishTest();
  }
}, LongRunningService.class).someLongRunningTask();

JAX-RS (Java API for RESTful Web Services) is a Java EE standard (JSR-311) for implementing REST-based Web services in Java. Errai JAX-RS brings this standard to the browser and simplifies the integration of REST-based services in GWT client applications. Errai can generate proxies based on JAX-RS interfaces which will handle all the underlying communication and serialization logic. All that’s left to do is to invoke a Java method.

Errai’s JAX-RS support consists of the following:

  • A client-side API to communicate with JAX-RS endpoints
  • A code generator that runs at your project’s build time, providing proxy implementations for each JAX-RS resource interfaces visible within the GWT module
  • Errai IoC and CDI providers that allow you to @Inject instances of Caller<T> (the same API used in Errai RPC)
  • Integration with either Errai Marshalling or Jackson to translate request and response data between Java object and a string-based wire format

Plugin Tip

Use the Errai Forge Addon Add Errai Features command and select Errai JAXRS to follow along with this section.

Manual Setup

Checkout the Manual Setup Section for instructions on how to manually add JAX-RS to your project. You can also go to the Errai tutorial project or the demo collection for an example of JAX-RS.

Errai JAX-RS works by leveraging standard Java interfaces that bear JAX-RS annotations. You will also want these interfaces visible to server-side code so that your JAX-RS resource classes can implement them (and inherit the annotations). This keeps the whole setup typesafe, and reduces duplication to the bare minimum. The natural solution, then is to put the JAX-RS interfaces under the client.shared package within your GWT module:

The contents of the server-side files would be as follows:


The above interface is visible both to server-side code and to client-side code. It is used by client-side code to describe the available operations, their parameter types, and their return types. If you use your IDE’s refactoring tools to modify this interface, both the server-side and client-side code will be updated automatically.


The above class implements the shared interface. Since it performs database and/or filesystem operations to manipulate the persistent data store, it is not GWT translatable, and it’s therefore kept in a package that is not part of the GWT module.

Save typing and reduce duplication

Note that all JAX-RS annotations (@Path, @GET, @Consumes, and so on) can be inherited from the interface. You do not need to repeat these annotations in your resource implementation classes.

An instance of Errai’s RemoteCallback<T> has to be passed to the RestClient.create() call, which will provide access to the JAX-RS resource method’s result. T is the return type of the JAX-RS resource method. In the example below it’s just a Long representing a customer ID, but it can be any serializable type (see Marshalling).

RemoteCallback<Long> callback = new RemoteCallback<Long>() {

  public void callback(Long id) {
    Window.alert("Customer created with ID: " + id);
  }
};

A special case of this RemoteCallback is the ResponseCallback which can be used as an alternative. It provides access to the Response object representing the underlying HTTP response. This is useful when more details of the HTTP response are needed, such as headers and the status code. The ResponseCallback can also be used for JAX-RS interface methods that return a javax.ws.rs.core.Response type. In this case, the MarshallingWrapper class can be used to manually demarshall the response body to an entity of the desired type.

ResponseCallback callback = new ResponseCallback() {

  public void callback(Response response) {
    Window.alert("HTTP status code: " + response.getStatusCode());
    Window.alert("HTTP response body: " + response.getText());
  }
};

For handling errors, Errai’s error callback mechanism can be reused and an instance of ErrorCallback can optionally be passed to the RestClient.create() call. In case of an HTTP error, the ResponseException provides access to the Response object. All other Throwables indicate a communication problem.

ErrorCallback errorCallback = new RestErrorCallback() {

  public boolean error(Request request, Throwable throwable) {
    try {
      throw throwable;
    }
    catch (ResponseException e) {
      Response response = e.getResponse();
      // process unexpected response
      response.getStatusCode();
    }
    catch (Throwable t) {
      // process unexpected error (e.g. a network problem)
    }
    return false;
  }
};

To provide more customized error handling, Errai also defines client side exception handling via the ClientExceptionMapper interface. The client exception mapper allows developers to process a REST Response into a Throwable prior to the error being delivered to the ErrorCallback described above. The exception mapper class must be annotated with javax.ws.rs.ext.Provider as well as implement the ClientExceptionMapper interface.

@Provider

public class MyAppExceptionMapper implements ClientExceptionMapper {
  /**
   * @see org.jboss.errai.enterprise.client.jaxrs.ClientExceptionMapper#fromResponse(com.google.gwt.http.client.Response)
   */
  @Override
  public Throwable fromResponse(Response response) {
    if (response.getStatusCode() == 404)
      return new MyAppNotFoundException();
    else
      return new MyAppServerError(response.getStatusText());
  }
}

The ClientExceptionMapper will, by default, be invoked for every error response. However, Errai also provides the org.jboss.errai.enterprise.shared.api.annotations.MapsFrom annotation which provides for additional granularity. An exception mapper can be annotated so that it is only invoked for methods on specific REST interfaces.

@Provider

@MapsFrom({ SomeRestInterface.class })
public class SpecificClientExceptionMapper implements ClientExceptionMapper {
  /**
   * @see org.jboss.errai.enterprise.client.jaxrs.ClientExceptionMapper#fromResponse(com.google.gwt.http.client.Response)
   */
  @Override
  public Throwable fromResponse(Response response) {
     ... // Do something specific here
  }
}

Client-side remote call interceptors provide the ability to manipulate or bypass the request before it’s being sent. This is useful for implementing crosscutting concerns like caching or security features e.g:

Errai’s JSON format will be used to serialize/deserialize your custom types. See Marshalling for details.

Alternatively, a Jackson compatible JSON format can be used on the wire. See Configuration for details on how to enable Jackson marshalling.

Starting with Errai 2.1, Errai implements a subset of JPA 2.0. With Errai JPA, you can store and retrieve entity objects on the client side, in the browser’s local storage. This allows the reuse of JPA-related code (both entity class definitions and procedural logic that uses the EntityManager) between client and server.

Errai JPA implements the following subset of JPA 2.0:

  • Annotation-based configuration
  • Entity Types with
  • Identifiers of any numeric type (int, long, short, etc.)
  • Generated identifiers
  • Regular attributes of any JPA Basic type (Java primitive types, boxed primitives, enums, BigInteger, BigDecimal, String, Date, Time, and Timestamp)
  • Singular and Plural (collection-valued) attributes of other entity types
  • All association types (one-to-one, one-to-many, many-to-one, many-to-many)
  • All association cascade rules (ALL, PERSIST, MERGE, REMOVE, REFRESH, DETACH)
  • Circular and self references work properly
  • Polymorphic queries and collections (queries for a base entity type can result in instances of its subtypes)
  • Property access by field or get/set methods
  • Named, typed JPQL queries that select exactly one entity type
  • With cascading fetch of related entities
  • With or without WHERE clause
  • All boolean, arithmetic, and string operators supported
  • All String manipulation functions supported
  • With or without ORDER BY clause
  • Lifecycle events and entity lifecycle listeners
  • Much of the Metamodel API (Metamodel, EntityType, SingularAttribute, PluralAttribute, etc.)

It’s all client-side

Errai JPA is a declarative, typesafe interface to the web browser’s localStorage object. As such it is a client-side implementation of JPA. Objects are stored and fetched from the browser’s local storage, not from the JPA provider on the server side.

Plugin Tip

Use the Errai Forge Addon Add Errai Features command and select Errai JPA to follow along with this section.

Manual Setup

Checkout the Manual Setup Section for instructions on how to manually add Errai JPA to your project.

Classes whose instances can be stored and retrieved by JPA are called entities. To declare a class as a JPA entity, annotate it with @Entity.

JPA requires that entity classes conform to a set of rules. These are:

Here is an example of a valid entity class with an ID attribute (id) and a String-valued persistent attribute (name):

@Entity

public class Genre {
  @Id @GeneratedValue
  private int id;
  private String name;
  // This constructor is used by JPA
  public Genre() {}
  // This constructor is not used by JPA
  public Genre(String name) {
    this();
    this.name = name;
  }
  // These getter and Setter methods are optional:
  public int getId() { return id; }
  public void setId(int id) { this.id = id; }
  public String getName() { return name; }
  public void setName(String name) { this.name = name; }
}

When an entity changes state (more on this later), that state change can be cascaded automatically to related entity instances. By default, no state changes are cascaded to related entities. To request cascading of entity state changes, use the cascade attribute on any of the relationship quantifiers @OneToOne, @ManyToOne, @OneToMany, and @ManyToMany.

CascadeType valueDescription

PERSIST

Persist the related entity object(s) when this entity is persisted

MERGE

Merge the attributes of the related entity object(s) when this entity is merged

REMOVE

Remove the related entity object(s) from persistent storage when this one is removed

REFRESH

Not applicable in Errai JPA

DETACH

Detach the related entity object(s) from the entity manager when this object is detached

ALL

Equivalent to specifying all of the above

For an example of specifying cascade rules, refer to the Artist example above. In that example, the cascade type on albums is ALL. When a particular Artist is persisted or removed, detached, etc., all of that artist’s albums will also be persisted or removed, or detached correspondingly. However, the cascade rules for genres are different: we only specify PERSIST and MERGE. Because a Genre instance is reusable and potentially shared between many artists, we do not want to remove or detach these when one artist that references them is removed or detached. However, we still want the convenience of automatic cascading persistence in case we persist an Artist which references a new, unmanaged Genre.

The entity manager provides the means for storing, retrieving, removing, and otherwise affecting the lifecycle state of entity instances.

To obtain an instance of EntityManager on the client side, use Errai IoC (or CDI) to inject it into any client-side bean:

@EntryPoint

public class Main {
  @Inject EntityManager em;
}

To retrieve one or more entities that match a set of criteria, Errai JPA allows the use of JPA named queries. Named queries are declared in annotations on entity classes.

To receive a notification when an entity instance transitions from one lifecycle state to another, use an entity lifecycle listener.

These annotations can be applied to methods in order to receive notifications at certain points in an entity’s lifecycle. These events are delivered for direct operations initiated on the EntityManager as well as operations that happen due to cascade rules.

AnnotationMeaning

@PrePersist

The entity is about to be persisted or merged into the entity manager.

@PostPersist

The entity has just been persisted or merged into the entity manager.

@PreUpdate

The entity’s state is about to be captured into the browser’s localStorage.

@PostUpdate

The entity’s state has just been captured into the browser’s localStorage.

@PreRemove

The entity is about to be removed from persistent storage.

@PostRemove

The entity has just been removed from persistent storage.

@PostLoad

The entity’s state has just been retrieved from the browser’s localStorage.

JPA lifecycle event annotations can be placed on methods in the entity type itself, or on a method of any type with a public no-args constructor.

To receive lifecycle event notifications directly on the affected entity instance, create a no-args method on the entity class and annotate it with one or more of the lifecycle annotations in the above table.

For example, here is a variant of the Album class where instances receive notification right after they are loaded from persistent storage:

@Entity

public class Album {
  ... same as before ...
  @PostLoad
  public void postLoad() {
    System.out.println("Album " + getName() + " was just loaded into the entity manager");
  }
}

To receive lifecycle methods in a different class, declare a method that takes one parameter of the entity type and annotate it with the desired lifecycle annotations. Then name that class in the @EntityListeners annotation on the entity type.

The following example produces the same results as the previous example:

@Entity

@EntityListeners(StandaloneLifecycleListener.class)
public class Album {
  ... same as always ...
}
public class StandaloneLifecycleListener {
  @PostLoad
  public void albumLoaded(Album a) {
  public void postLoad() {
    System.out.println("Album " + a.getName() + " was just loaded into the entity manager");
  }
}

Traditional JPA implementations allow you to store and retrieve entity objects on the server side. Errai’s JPA implementation allows you to store and retrieve entity objects in the web browser using the same APIs. All that’s missing is the ability to synchronize the stored data between the server side and the client side.

This is where Errai JPA Data Sync comes in: it provides an easy mechanism for two-way synchronization of data sets between the client and the server.

Plugin Tip

Use the Errai Forge Addon Add Errai Features command and select Errai JPA Datasync to follow along with this section.

Manual Setup

Checkout the Manual Setup Section for instructions on how to manually add Errai JPA Datasync to your project.

For the rest of this chapter, we will refer to the following Entity classes, which are defined in a shared package that’s visible to client and server code:

@Portable

@Entity
@NamedQuery(name = "allUsers", query = "SELECT u FROM User u")
public class User {
  @Id
  @GeneratedValue
  private long id;
  private String name;
  // getters and setters omitted
}
@Portable

@Entity
@NamedQuery(name = "groceryListsForUser", query = "SELECT gl FROM GroceryList gl WHERE gl.owner=:user")
public class GroceryList {
  @Id
  @GeneratedValue
  private long id;
  @ManyToOne
  private User owner;
  @OneToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH })
  private List<Item> items = new ArrayList<Item>();
  // getters and setters omitted
}
@Portable

@Entity
@NamedQuery(name = "allItems", query = "SELECT i FROM Item i")
public class Item {
  @Id
  @GeneratedValue
  private long id;
  private String name;
  private String department;
  private String comment;
  private Date addedOn;
  @ManyToOne(cascade = { CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH })
  private User addedBy;
  // getters and setters omitted
}

To summarize: there are three entity types: User, GroceryList, and Item. Each GroceryList belongs to a User and has a list of Item objects.

Now let’s say we want to synchronize the data for all of a user’s grocery lists. This will make them available for offline use through Errai JPA, and at the same time it will update the server with the latest changes made on the client. Ultimately, the sync operation is accomplished via an annotated method or an asynchronous call into ClientSyncManager, but first we have to prepare a few things on the client and the server.

A data sync operation begins when the client-side sync manager sends an Errai RPC request to the server. Although a server-side implementation of the remote interface is provided, you are responsible for implementing a thin wrapper around it. This wrapper serves two purposes:

  1. It allows you to determine how to obtain a reference to the JPA EntityManager (and to choose which persistence context the server-side data sync will operate on)
  2. It allows you to inspect the contents of each sync request and make security decisions about access to particular entities

If you are deploying to a container that supports CDI and EJB 3, you can use this DataSyncServiceImpl as a template for your own:

@Stateless @org.jboss.errai.bus.server.annotations.Service

public class DataSyncServiceImpl implements DataSyncService {
  @PersistenceContext
  private EntityManager em;
  private final JpaAttributeAccessor attributeAccessor = new JavaReflectionAttributeAccessor();
  @Inject private LoginService loginService;
  @Override
  public <X> List<SyncResponse<X>> coldSync(SyncableDataSet<X> dataSet, List<SyncRequestOperation<X>> remoteResults) {
    // Ensure a user is logged in
    User currentUser = loginService.whoAmI();
    if (currentUser == null) {
      throw new IllegalStateException("Nobody is logged in!");
    }
    // Ensure user is accessing their own data!
    if (dataSet.getQueryName().equals("groceryListsForUser")) {
      User requestedUser = (User) dataSet.getParameters().get("user");
      if (!currentUser.getId().equals(requestedUser.getId())) {
        throw new AccessDeniedException("You don't have permission to sync user " + requestedUser.getId());
      }
    }
    else {
      throw new IllegalArgumentException("You don't have permission to sync dataset " + dataSet.getQueryName());
    }
    DataSyncService dss = new org.jboss.errai.jpa.sync.server.DataSyncServiceImpl(em, attributeAccessor);
    return dss.coldSync(dataSet, remoteResults);
  }
}

If you are not using EJB 3, you will not be able to use the @PersistenceContext annotation. In this case, obtain a reference to your EntityManager the same way you would anywhere else in your application.

Like many Errai features, Errai JPA DataSync provides an annotation-driven programming model and a programmatic API. You can choose which to use based on your needs and preferences.

The declarative data sync API is driven by the @Sync annotation. Consider the following example client-side class:

  // This injected User object could have been set up in a @PostConstruct method instead of being injected.

  @Inject
  private User syncThisUser;
  @Sync(query = "groceryListsForUser", params = { @SyncParam(name = "user", val = "{syncThisUser}") })
  private void onDataSyncComplete(SyncResponses<GroceryList> responses) {
    Window.alert("Data Sync Complete!");
  }

By placing the above code snippet in a client-side bean, you tell Errai JPA Data Sync that, as long as a managed instance of the bean containing the @Sync method exists, the Data Sync system should keep all grocery lists belonging to the syncThisUser user in sync between the client-side JPA EntityManager and the server-side EntityManager. Right now, the data sets are kept in sync using a sync request every 5 seconds. In the future, this may be optimised to an incremental approach that pushes changes as they occur.

The annotated method needs to have exactly one parameter of type SyncResponses and will be called each time a data sync operation has completed. All sync operations passed to the method will have already been applied to the local EntityManager, with conflicts resolved in favour of the server’s version of the data. The original client values are available in the SyncResponses object, which gives you a chance to implement a different conflict resolution policy.

The query attribute on the @Sync annotation must refer to an existing JPA Named Query that is defined on a shared JPA entity class.

The params attribute is an array of @SyncParam annotations. There must be exactly one @SyncParam for each named parameter in the JPA query (positional parameters are not supported). If the val argument is surrounded with brace brackets (as it is in the example aboce) then it is interpreted as a reference to a declared or inherited field in the containing class. Otherwise, it is interpreted as a literal String value.

Transport (network) errors are logged to the slf4j logger channel org.jboss.errai.jpa.sync.client.local.ClientSyncWorker. As of Errai 3.0.0.M4, it is not possible to specify a custom error handler using the declarative API. See the next section for information about the programmatic API.

When the client sends the sync request to the server, it includes information about the state it expects each entity to be in. If an entity’s state on the server does not match this expected state on the client, the server ignores the client’s change request and includes a ConflictResponse object in the sync reply.

When the client processes the sync responses from the server, it applies the new state from the server to the local data store. This overwrites the change that was initially requested from the client. In short, you could call this the "server wins" conflict resolution policy.

In some cases, your application may be able to do something smarter: apply domain-specific knowledge to merge the conflict automatically, or prompt the user to perform a manual merge. In order to do this, you will have to examine the server response from inside the onCompletion callback you provided to the coldSync() method:

    RemoteCallback<List<SyncResponse<GroceryList>>> onCompletion = new RemoteCallback<List<SyncResponse<GroceryList>>>() {

      @Override
      public void callback(List<SyncResponse<GroceryList>> responses) {
        for (SyncResponse<GroceryList> response : responses) {
          if (response instanceof ConflictResponse) {
            ConflictResponse<GroceryList> cr = (ConflictResponse<GroceryList>) response;
            List<Item> expectedItems = cr.getExpected().getItems();
            List<Item> serverItems = cr.getActualNew().getItems();
            List<Item> clientItems = cr.getRequestedNew().getItems();
            // merge the list of items by comparing each to expectedItems
            List<Item> merged = ...;
            // update local storage with the merged list
            em.find(GroceryList.class, cr.getActualNew().getId()).setItems(merged);
            em.flush();
          }
        }
      }
    };

Remember, because of Errai’s default "server wins" resolution policy, the call to em.find(GroceryList.class, cr.getActualNew().getId()) will return a GroceryList object that has already been updated to match the state present in serverItems.

Errai’s data binding module provides the ability to bind model objects to UI fields/widgets. The bound properties of the model and the UI components will automatically be kept in sync for as long as they are bound. So, there is no need to write code for UI updates in response to model changes and no need to register listeners to update the model in response to UI changes.

The data binding module is directly integrated with Errai UI and Errai JPA but can also be used as a standalone project in any GWT client application:

Plugin Tip

Use the Errai Forge Addon Add Errai Features command and select Errai Data Binding to follow along with this section.

Manual Setup

Checkout the Manual Setup Section for instructions on how to manually add Errai Data Binding to your project.

Bindings can be created by calling the bind method on a DataBinder instance, thereby specifying which widgets should be bound to which properties of the model. It is possible to use property chains for bindings, given that all nested properties are of bindable types. When binding to customer.address.streetName, for example, both customer and address have to be of a type annotated with @Bindable.

public class CustomerView {

  @Inject
  private DataBinder<Customer> dataBinder;
  private Customer customer;
  private TextBox nameTextBox = new TextBox();
  // more UI widgets...
  @PostConstruct
  private void init() {
    customer = dataBinder
        .bind(nameTextBox, "name")
        .bind(idLabel, "id")
        .getModel();
  }
}

After the call to dataBinder.bind() in the example above, the customer object’s name property and the nameTextBox are kept in sync until either the dataBinder.unbind() method is called or the CustomerView bean is destroyed.

That means that a call to customer.setName() will automatically update the value of the TextBox and any change to the TextBox’s value in the browser will update the customer object’s name property. So, customer.getName() will always reflect the currently displayed value of the TextBox.

Tip

Errai also provides a declarative binding API that can be used to create bindings automatically based on matching field and model property names.

Errai has built-in conversion support for all Number types as well as Boolean and Date to java.lang.String and vice versa. However, in some cases it will be necessary to provide custom converters (e.g. if a custom date format is desired). This can be done on two levels.

Programmatic binding as described above (see Creating Bindings) can be tedious when working with UI components that contain a large number of input fields. Errai provides an annotation-driven binding API that can be used to create bindings automatically which cuts a lot of boilerplate code. The declarative API will work in any Errai IOC managed bean (including Errai UI templates). Simply inject a data binder or model object and declare the bindings using @Bound.

Here is a simple example using an injected model object provided by the @Model annotation (field injection is used here, but constructor and method injection are supported as well):

@Dependent

public class CustomerView {
  @Inject @Model
  private Customer customer;
  @Inject @Bound
  private TextBox name;
  @Bound
  private Label id = new Label();
  ....
}

Here is the same example injecting a DataBinder instead of the model object. This is useful when more control is needed (e.g. the ability to register property change handlers). The @AutoBound annotation specifies that this DataBinder should be used to bind the model to all enclosing widgets annotated with @Bound. This example uses field injection again but constructor and method injection are supported as well.

@Dependent

public class CustomerView {
  @Inject @AutoBound
  private DataBinder<Customer> customerBinder;
  @Inject @Bound
  private TextBox name;
  @Bound
  private Label id = new Label();
  ...
}

In both examples above an instance of the Customer model is automatically bound to the corresponding UI widgets based on matching field names. The model object and the UI fields will automatically be kept in sync. The widgets are inferred from all enclosing fields and methods annotated with @Bound of the class that defines the @AutoBound DataBinder or @Model and all its super classes.

By default, bindings are determined by matching field names to property names on the model object. In the examples above, the field name was automatically bound to the JavaBeans property name of the model (user object). If the field name does not match the model property name, you can use the property attribute of the @Bound annotation to specify the name of the property. The property can be a simple name (for example, "name") or a property chain (for example, user.address.streetName). When binding to a property chain, all properties but the last in the chain must refer to @Bindable values.

The following example illustrates all three scenarios:

@Bindable

public class Address {
  private String line1;
  private String line2;
  private String city;
  private String stateProv;
  private String country;
  // getters and setters
}
@Bindable
public class User {
  private String name;
  private String password;
  private Date dob;
  private Address address;
  private List<Role> roles;
  // getters and setters
}
@Templated
public class UserWidget {
  @Inject @AutoBound DataBinder<User> user;
  @Inject @Bound TextBox name;
  @Inject @Bound(property="dob") DatePicker dateOfBirth;
  @Inject @Bound(property="address.city") TextBox city;
}

In UserWidget above, the name text box is bound to user.name using the default name matching; the dateOfBirth date picker is bound to user.dob using a simple property name mapping; finally, the city text box is bound to user.address.city using a property chain. Note that the Address class is required to be @Bindable in this case.

The @Bound annotation further allows to specify a converter to use for the binding (see Specifying Converters for details). This is how a binding specific converter can be specified on a data field:

@Inject

@Bound(converter=MyDateConverter.class)
@DataField
private TextBox date;

By default, Errai DataBinding updates model values when the corresponding Widget fires a ValueChangeEvent. For text-based widgets, this means that the model values are updated only once the widget loses focus. However in some cases, you may also need to update a model’s value as soon as the text changes in the Widget.

Errai allows you to do this by setting the onKeyUp flag in the @Bound annotation. Note that this parameter can only be used on Widgets that extend GWT’s ValueBoxBase widget. Setting this parameter to true will cause the model value to update on a KeyUpEvent as well as the default ValueChangeEvent. This will result in the model object being updated as soon as any text is entered/removed from the Widget. You can specify this as follows:

@Inject

@Bound(onKeyUp = true)
private TextBox name;

You can also achieve the same effect using programmatic bindings. To do this, you can use the method DataBinder.bind(Widget widget, String property, Converter converter, boolean bindOnKeyUp). As an example, take a look at the following code snippet:

@Inject

DataBinder<Model> binder;
@Inject
private TextBox nameTextBox;
...
@PostConstruct
public void onLoad() {
  binder.bind(nameTextBox, "name", converter, true);
}

Java bean validation (JSR 303) provides a declarative programming model for validating entities. More details and examples can be found here. Errai provides a bean validation module that makes Validator instances injectable and work well with Errai’s data binding module. The following line needs to be added to the GWT module descriptor to inherit Errai’s bean validation module:


To use Errai’s bean validation module, you must add the module, the javax.validation API and an implementation such as hibernate validator to your classpath. If you are using Maven for your build, add these dependencies:


    <dependency>
      <groupId>org.jboss.errai</groupId>
      <artifactId>errai-validation</artifactId>
      <version>${errai.version}</version>
    </dependency>

    <dependency>
      <groupId>javax.validation</groupId>
      <artifactId>validation-api</artifactId>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>javax.validation</groupId>
      <artifactId>validation-api</artifactId>
      <classifier>sources</classifier>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>4.2.0.Final</version>
      <scope>provided</scope>
    </dependency>

    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-validator</artifactId>
      <version>4.2.0.Final</version>
      <scope>provided</scope>
      <classifier>sources</classifier>
    </dependency>

Now it is as simple as injecting a Validator instance into an Errai IOC managed bean and calling the validate method.

@Inject

private Validator validator;
Set<ConstraintViolation<Customer>> violations  = validator.validate(customer);

// display violations

One of the primary complaints of GWT to date has been that it is difficult to use "pure HTML" when building and skinning widgets. Inevitably one must turn to Java-based configuration in order to finish the job. Errai, however, strives to remove the need for Java styling. HTML template files are placed in the project source tree, and referenced from custom "Composite components" (Errai UI Widgets) in Java. Since Errai UI depends on Errai IOC and Errai CDI, dependency injection is supported in all custom components. Errai UI provides rapid prototyping and HTML5 templating for GWT.

The Errai UI module is directly integrated with Data Binding and Errai JPA but can also be used as a standalone project in any GWT client application by simply inheriting the Errai UI GWT module, and ensuring that you have properly using Errai CDI’s @Inject to instantiate your widgets:

Plugin Tip

Use the Errai Forge Addon Add Errai Features command and select Errai UI to follow along with this section.

Manual Setup

Checkout the Manual Setup Section for instructions on how to manually add Errai UI to your project. If you work better by playing with a finished product, you can see a simple client-server project implemented using Errai UI here.

Custom components in Errai UI are single classes extending from com.google.gwt.user.client.ui.Composite, and must be annotated with @Templated.

Templates in Errai UI may be designed either as an HTML snippet or as a full HTML document. You can even take an existing HTML page and use it as a template. With either approach, the id, class, and data-field attributes in the template identify elements by name. These elements and their children are used in the Composite component to add behavior, and use additional components to add functionality to the template. There is no limit to how many component classes may share a given HTML template.

We will begin by creating a simple HTML login form to accompany our @Templated LoginForm composite component.


<form>
  <legend>Log in to your account</legend>

  <label for="username">Username</label>
  <input id="username" type="text" placeholder="Username">

  <label for="password">Password</label>
  <input id="password" type="password" placeholder="Password">

  <button>Log in</button>
  <button>Cancel</button>
</form>

Or as a full HTML document which may be more easily previewed during design without running the application; however, in this case we must also specify the location of our component’s root DOM Element using a "data-field", id, or class attribute matching the value of the @Templated annotation. There is no limit to how many component classes may share a given HTML template.

@Templated("my-template.html#login-form")

public class LoginForm extends Composite {
   /* Specifies that <... id="login-form"> be used as the root Element of this Widget */
}

Notice the corresponding HTML id attribute in the form Element below (we could have used data-field or class instead). Note that multiple components may use the same template provided that they specify a corresponding data-field, id, or class attribute. Also note that two or more components may share the same DOM elements; there is no conflict since components each receive a unique copy of the template DOM rooted at the designated element at runtime (or from the root element if a fragment is not specified.)


<!DOCTYPE html>
<html lang="en">
<head>
    <title>A full HTML snippet</title>
</head>
<body>
    <div>
        <form id="login-form">
          <legend>Log in to your account</legend>

          <label for="username">Username</label>
          <input id="username" type="text" placeholder="Username">

          <label for="username">Password</label>
          <input id="password" type="password" placeholder="Password">

          <button>Log in</button>
          <button>Cancel</button>
        </form>
    </div>

    <hr>
    <footer id="theme-footer">
        <p>(c) Company 2012</p>
    </footer>
</body>
</html>

For example’s sake, the component below could also use the same template. All it needs to do is reference the template name, and specify a fragment.

@Templated("my-template.html#theme-footer")

public class Footer extends Composite {
   /* Specifies that <... id="theme-footer"> be used as the root Element of this Widget */
}

Now that we have created the @Templated Composite component and an HTML template, we can start wiring in functionality and behavior; this is done by annotating fields and methods to replace specific sub-elements of the template DOM with other Widgets. We can even replace portions of the template with other Errai UI Widgets!

Each @DataField reference in the Java class must match an element in the HTML template. The matching of Java references to HTML elements is performed as follows:

If more than one Java reference matches the same HTML element in the template, it is an error. For example, given a template containing the element <div class="eat drink be-merry">, the following Java code is in error:

@Templated

public class ErroneousTemplate extends Composite {
   @Inject @DataField
   private Label eat;
   @Inject @DataField
   private Label drink;
}

because both fields eat and drink refer to the same HTML div element.

So now we must ensure there are data-field, id, or class attributes in the right places in our template HTML file. This, combined with the @DataField annotation in our Composite component allow Errai UI to determine where and what should be composited when creating component instances.


<form id="form">
  <legend>Log in to your account</legend>

  <label for="username">Username</label>
  <input id="username" type="text" placeholder="Username">

  <label for="password">Password</label>
  <input data-field="pass" id="password" type="password" placeholder="Password">

  <button id="submit">Log in</button>
  <button>Cancel</button>
</form>

Now, when we run our application, we will be able to interact with these fields in our Widget.

Three things are merged or modified when Errai UI creates a new Composite component instance:

Dealing with User and DOM Events is a reality in rich web development, and Errai UI provides several approaches for dealing with all types of browser events using its "quick handler" functionality. It is possible to handle:

The last approach is handles the case where native DOM events must be handled, but no such GWT event handler exists for the given event type. Alternatively, it can also be used for situations where Elements in the template should receive events, but no handle to the Element the component class is necessary (aside from the event handling itself.) Native DOM events do not require a corresponding @DataField be configured in the class; only the HTML data-field, id, or class template attribute is required.


<div>
   <a id="link" href="/page">this is a hyperlink</a>
   <div data-field="div"> Some content </div>
</div>

The @SinkNative annotation specifies (as a bit mask) which native events the method should handle; this sink behaves the same in Errai UI as it would with DOM.sinkEvents(Element e, int bits). Note that a @DataField reference in the component class is optional.

@Templated

public class QuickHandlerComponent extends Composite {
  @DataField
  private AnchorElement link = DOM.createAnchor().cast();
  @EventHandler("link")
  @SinkNative(Event.ONCLICK | Event.ONMOUSEOVER)
  public void doSomething(Event e) {
    // do something
  }
  @EventHandler("div")
  @SinkNative(Event.ONMOUSEOVER)
  public void doSomethingElse(Event e) {
    // do something else
  }
}

Using asynchronous Javascript calls often make realizing the benefits of modern browsers difficult when it comes to form submission. But there is now a base class in Errai UI for creating @Templated form widgets that are perfect for tasks such as creating a login form.

Here is a sample @Templated login form class. This form has:

@Dependent

@Templated
public class LoginForm extends AbstractForm { 
1
  @Inject
  private Caller<AuthenticationService> authenticationServiceCaller;
  @Inject
  @DataField
  private TextBox username;
  @Inject
  @DataField
  private PasswordTextBox password;
  @DataField
  private final FormElement form = DOM.createForm(); 
2
  @Inject
  @DataField
  private Button login; 
3
  @Override
  protected FormElement getFormElement() {
    return form; 
4
  }
  @EventHandler("login")
  private void loginClicked(ClickEvent event) {
    authenticationServiceCaller.call(new RemoteCallback<User>() {
      @Override
      public void callback(User response) {
        // Now that we're logged in, submit the form
        submit(); 
5
      }
    }).login(username.getText(), password.getText());
  }
}

The key things that you should take from this example:

1

The class extends org.jboss.errai.ui.client.widget.AbstractForm.

2

The form field is a @DataField but it is not injected.

3

The login button is a regular button widget, with a click handling method below.

4

The getFormElement method inherited from AbstractForm must return the FormElement that will be submitted.

5

After the user has successfully logged in asynchronously we call submit(). This causes form submission to happen in a way that will not cause the page to refresh, but will still properly notify the browser of a form submission.

When a user successfully logs in via this example, the web browser should prompt them to remember the username and password (assuming this is a feature of the browser being used).

A recurring implementation task in rich web development is writing event handler code for updating model objects to reflect input field changes in the user interface. The requirement to update user interface fields in response to changed model values is just as common. These tasks require a significant amount of boilerplate code which can be alleviated by Errai. Errai’s data binding module provides the ability to bind model objects to user interface fields, so they will automatically be kept in sync. While the module can be used on its own, it can cut even more boilerplate when used together with Errai UI.

In the following example, all @DataFields annotated with @Bound have their contents bound to properties of the data model (a User object). The model object is injected and annotated with @Model, which indicates automatic binding should be carried out. Alternatively, the model object could be provided by an injected DataBinder instance annotated with @AutoBound, see Declarative Binding for details.

@Templated

public class LoginForm extends Composite {
   @Inject
   @Model
   private User user;
   @Inject
   @Bound
   @DataField
   private TextBox name;
   @Inject
   @Bound
   @DataField
   private PasswordTextBox password;
   @DataField
   private Button submit = new Button();
}

Now the user object and the username and password fields in the UI are automatically kept in sync. No event handling code needs to be written to update the user object in response to input field changes and no code needs to be written to update the UI fields when the model object changes. So, with the above annotations in place, it will always be true that user.getUsername().equals(username.getText()) and user.getPassword().equals(password.getText()).

By default, bindings are determined by matching field names to property names on the model object. In the example above, the field name was automatically bound to the JavaBeans property name of the model (user object). If the field name does not match the model property name, you can use the property attribute of the @Bound annotation to specify the name of the property. The property can be a simple name (for example, "name") or a property chain (for example, user.address.streetName). When binding to a property chain, all properties but the last in the chain must refer to @Bindable values.

The following example illustrates all three scenarios:

@Bindable

public class Address {
  private String line1;
  private String line2;
  private String city;
  private String stateProv;
  private String country;
  // getters and setters
}
@Bindable
public class User {
  private String name;
  private String password;
  private Date dob;
  private Address address;
  private List<Role> roles;
  // getters and setters
}
@Templated
public class UserWidget extends Composite {
  @Inject @AutoBound DataBinder<User> user;
  @Inject @Bound TextBox name;
  @Inject @Bound(property="dob") DatePicker dateOfBirth;
  @Inject @Bound(property="address.city") TextBox city;
}

In UserWidget above, the name text box is bound to user.name using the default name matching; the dateOfBirth date picker is bound to user.dob using a simple property name mapping; finally, the city text box is bound to user.address.city using a property chain. Note that the Address class is required to be @Bindable in this case.

Often you will need to bind a list of model objects so that every object in the list is bound to a corresponding widget. This task can be accomplished using Errai UI’s ListWidget class. Here’s an example of binding a list of users using the UserWidget class from the previous example. First, we need to enhance UserWidget to implement HasModel.

@Templated

public class UserWidget extends Composite implements HasModel<User> {
  @Inject @AutoBound DataBinder<User> userBinder;
  @Inject @Bound TextBox name;
  @Inject @Bound(property="dob") DatePicker dateOfBirth;
  @Inject @Bound(property="address.city") TextBox city;
  public User getModel() {
    userBinder.getModel();
  }
  public void setModel(User user) {
    userBinder.setModel(user);
  }
}

Now we can use UserWidget to display items in a list.

@Templated

public class MyComposite extends Composite {
  @Inject @DataField ListWidget<User, UserWidget> userListWidget;
  @PostConstruct
  public void init() {
    List<User> users = .....
    userListWidget.setItems(users);
  }
}

Calling setItems on the userListWidget causes an instance of UserWidget to be displayed for each user in the list. The UserWidget is then bound to the corresponding user object. By default, the widgets are arranged in a vertical panel. However, ListWidget can also be subclassed to provide alternative behaviour. In the following example, we use a horizontal panel to display the widgets.

public class UserListWidget extends ListWidget<User, UserWidget> {


  public UserList() {
    super(new HorizontalPanel());
  }
  @PostConstruct
  public void init() {
    List<User> users = .....
    setItems(users);
  }
  @Override
  public Class<UserWidget> getItemWidgetType() {
    return UserWidget.class;
  }
}

The @Bound annotation further allows to specify a converter to use for the binding (see Specifying Converters for details). This is how a binding specific converter can be specified on a data field:

@Inject

@Bound(converter=MyDateConverter.class)
@DataField
private TextBox date;

Errai’s DataBinder also allows to register PropertyChangeHandlers for the cases where keeping the model and UI in sync is not enough and additional logic needs to be executed (see Property Change Handlers for details).

Templating would not be complete without the ability to inherit from parent templates, and Errai UI also makes this possible using simple Java inheritance. The only additional requirement is that Composite components extending from a parent Composite component must also be annotated with @Templated, and the path to the template file must also be specified in the child component’s annotation. Child components may specify @DataField references that were omitted in the parent class, and they may also override @DataField references (by using the same data-field name) that were already specified in the parent component.

When developing moderately-complex web applications with Errai, you may find yourself needing to do quite a bit of programmatic style changes. One common case is showing or enabling controls only if a user has the necessary permissions to use them. One part of the problem is securing those features from being used, and the other part which is an important usability consideration is communicating that state to the user.

Let’s start with the example case I just described. We have a control that we only want to be visible if the user is an admin. So the first thing we do is create a style binding annotation.

@StyleBinding

@Retention(RetentionPolicy.RUNTIME)
public @interface Admin {
}

This defines Admin as a stylebinding now we can use it like this:

@EntryPoint

@Templated
public class HelloWorldForm extends Composite {
  @Inject @Admin @DataField Button deleteButton;
  @Inject SessionManager sessionManager;
  @EventHandler("deleteButton")
  private void handleSendClick(ClickEvent event) {
    // do some deleting!
  }
  @Admin
  private void applyAdminStyling(Style style) {
    if (!sessionManager.isAdmin()) {
      style.setVisibility(Style.Visibility.HIDDEN);
    }
  }
}

Now before the form is shown to the user the applyAdminStyling method will be executed where the sessionManager is queried to see if the user is an admin if not the delete button that is also annotated with @Admin will be hidden from the view.

The above example took at Style object as a parameter, but it is also possible to use an Element. So the applyAdminStyling method above could have also been written like this:

  @Admin

  private void applyAdminStyling(Element element) {
    if (!sessionManager.isAdmin()) {
      element.addClassName("disabled");
    }
  }

The CSS class "disabled" could apply the same style as before ("visibility: hidden") or it could have more complex behaviour that is dependent on the element type.

User interfaces often need to be available in different languages. Errai’s i18n support makes it easier for you to publish your web app in multiple languages. This section explains how to use this feature in your application.

To get started with Errai’s internationalization support, simply put @Bundle("bundle.json") or @Bundle("bundle.properties") annotation on your entry point and add an empty bundle.json or bundle.properties file to your classpath (e.g. to src/main/java or src/main/resources). Of course, you can name it differently provided the file extension is .json or .properties.

Errai will scan your HTML templates and process all text elements to generate key/value pairs for translation. It will generate a file called errai-bundle-all.json and put it in your .errai directory. If you used a JSON file in you @Bundle annotation, you can copy this generated file and use it as a starting point for your custom translation bundles. If the text value is longer than 128 characters the key will get cut off and a hash appended at the end.

The translation bundle files use the same naming scheme as Java (e.g. bundle_nl_BE.json or bundel_nl_BE.properties for Belgian Dutch, and bundle_nl.json or bundle_nl.properties for plain Dutch). Errai will also generate a file called errai-bundle-missing.json in the .errai folder containing all template values for which no translations have been defined. You can copy the key/value pairs out of this file to create our own translations when you use a JSON file:

{
"StoresPage.Stores!" : "Stores!",
"WelcomePage.As_you_move_toward_a_more_and_more_declarative_style,_you_allow_the_compiler_and_the_framework_to_catch_more_mistakes_up_front._-734987445" : "As you move toward a more and more declarative style, you allow the compiler and the framework to catch more mistakes up front. Broken links? A thing of the past!"
}

Here are the same translations as specified by a properties file:

StoresPage.Stores! = Stores!
WelcomePage.As_you_move_toward_a_more_and_more_declarative_style,_you_allow_the_compiler_and_the_framework_to_catch_more_mistakes_up_front._-734987445 = As you move toward a more and more declarative style, you allow the compiler and the framework to catch more mistakes up front. Broken links? A thing of the past!

If you want to use your own keys instead of these generated ones you can specify them in your templates using the data-i18n-key attribute:


<html>
<body>
  <div id="content">
  <p data-i18n-key="welcome">Welcome to errai-ui i18n.</p>
<div>
...

By adding this attribute in the template you can translate it with the following:

{
    "Widget.welcome": "Willkommen bei Errai-ui i18n."
}

or

Widget.welcome=Willkommen bei Errai-ui i18n.

Because your templates are designer templates and can contain some mock data that doesn’t need to be translated, Errai has the ability to indicate that with an attribute data-role=dummy:


<div id=navbar data-role=dummy>
  <div class="navbar navbar-fixed-top">
    <div class=navbar-inner>
      <div class=container>
        <span class=brand>Example Navbar</span>
        <ul class=nav>
          <li><a>Item</a>
          <li><a>Item</a>
        </ul>
      </div>
    </div>
  </div>
</div>

Here the template fills out a navbar with dummy elements, useful for creating a design, adding data-role=dummy will not only exclude it form being translated it will also strip the children nodes from the template that will be used by the application.

When you have setup a translation of your application Errai will look at the browser locale and select the locale, if it’s available, if not it will use the default (bundle.json). If the users of your application need to be able to switch the language manually, Errai offers a pre build component you can easily add to your page: LocaleListBox will render a Listbox with all available languages. If you want more control of what this language selector looks like there is also a LocaleSelector that you can use to query and select the locale for example:

@Templated

public class NavBar extends Composite {
  @Inject
  private LocaleSelector selector;
  @Inject @DataField @OrderedList
  ListWidget<Locale, LanguageItem> language;
  @AfterInitialization
  public void buildLanguageList() {
    language.setItems(new ArrayList<Locale>(selector.getSupportedLocales()));
  }
...
// in LanguageItem we add a click handler on a link
  @Inject
  Navigation navigation;
  @Inject
  private LocaleSelector selector;
  link.addClickHandler(new ClickHandler() {
      @Override
      public void onClick(ClickEvent event) {
        selector.select(model.getLocale());
        navigation.goTo(navigation.getCurrentPage().name());
      }
    });

The @TranslationKey annotation and TranslationService class extend Errai’s i18n support to Java code. They provide a mechanism for developers to declare translation strings from within their GWT application code (as opposed to the HTML templates).

To do this, developers must annotate a field which represents the translation key with @TranslationKey annotation. This key will then map to a value in the translation bundle file. Once the field is annotated appropriately, the developer must directly invoke the TranslationService’s format() method. This method call will perform a lookup in the translation service of the value mapped to the provided key. Note that value substitution using the {N} format is supported.

As an example, consider the following code:

package org.example.ui.client.local;


public class AppMessages {
   @TranslationKey(defaultValue = "I guess something happened!")
   public static final String CUSTOM_MESSAGE = "app.custom-message";
   @TranslationKey(defaultValue = "Hey {0}, I just told you something happened!")
   public static final String CUSTOM_MESSAGE_WITH_NAME = "app.custom-message-with-name";
}
package org.example.ui.client.local;


@Dependent
@Templated
public class CustomComponent extends Composite {
   @Inject
   private TranslationService translationService;
   @Inject
   @DataField
   private Button someAction;
   @EventHandler("someAction")
   private void doLogin(ClickEvent event) {
      // do some action that may require a notification sent to the user
      String messageToUser = translationService.format(AppMessages.CUSTOM_MESSAGE);
      Window.alert(messageToUser);
      String username = getCurrentUserName();
      String messageToUserWithName = translationService.format(AppMessages.CUSTOM_MESSAGE_WITH_NAME, username);
      Window.alert(messageToUserWithName);
   }
}

Errai also supports LESS stylesheets. To get started using these you’ll have to create a LESS stylesheet and place it on the classpath of your project and declare their ordering with the StyleDescriptor annotation. Every application should have 0 or 1 classes annotated with StyleDescriptor like the following example:

package org.jboss.errai.example;


@StyleDescriptor({ "/main.less", "other.css" })
public class MyStyleDescriptor {
}

The two files listed above, main.less and other.css, will be compiled into a single stylesheet by Errai. The relative path for other.css will be loaded relative to the package org.jboss.errai.example.

Do Not Declare Imported Stylesheets

It is only necessary to declare top-level stylesheets with the StyleDescriptor. If a CSS or LESS resource is only meant to be imported by another LESS stylesheet, then it need only be on the classpath.

Errai will convert the LESS stylesheet to css, perform optimisations on it, and ensure that is get injected into the pages of your application. It will also obfuscate the class selectors and replace the use of those in your templates. To be able to use the selectors in your code you can use:

public class MyComponent extends Component {

  @Inject
  private LessStyle lessStyle;
  ...
  @PostConstruct
  private void init() {
    textBox.setStyleName(lessStyle.get("input"));
  }
}

Finally it will also add any deferred binding properties to the top of your LESS stylesheet, so for example you could use the user.agent in LESS like this:

.mixin (@a) when (@a = "safari") {

  background-color: black;
}
.mixin (@a) when (@a = "gecko1_8") {
  background-color: white;
}
.class1 { .mixin(@user_agent) }

Because a dot is not allowed in LESS variables it’s replaced with an underscore, so in the example above class1 will have a black background on Safari and Chrome and white on Firefox. On the top of this LESS stylesheet @user_agent: "safari" will get generated.

Starting in version 2.1, Errai offers a system for creating applications that have multiple bookmarkable pages. This navigation system has the following features:

  • Declarative, statically-analyzable configuration of pages and links
  • Compile time referential safety (i.e. “no broken links”)
  • Generates a storyboard of the application’s navigation flow at compile time
  • Decentralized configuration
  • Create a new page by creating a new annotated class. No need to edit a second file.
  • Make navigational changes in the natural place in the code
  • Integrates cleanly with Errai UI templates, but also works well with other view technologies
  • Builds on Errai IoC & CDI
  • Provides support for HTML5 pushState and path-parameter based URLs

Plugin Tip

Use the Errai Forge Addon Add Errai Features command and select Errai Navigation to follow along with this section.

Manual Setup

Checkout the Manual Setup Section for instructions on how to manually add Errai Navigation to your project.

Errai Navigation has these main parts:

The Navigation singleton owns a GWT Panel called the navigation panel. This panel always contains a widget corresponding to the fragment ID (the part after the # symbol) in the browser’s location bar. Whenever the fragment ID changes for any reason (for example, because the user pressed the back button, navigated to a bookmarked URL, or simply typed a fragment ID by hand), the widget in the navigation panel is replaced by the widget associated with that fragment ID. Likewise, when the application asks the navigation system to follow a link, the fragment ID in the browser’s location bar is updated to reflect the new current page.

To declare a page, annotate any subclass of Widget with the @Page annotation:

@Page

public class ItemListPage extends Composite {
  // Anything goes...
}

By default, the name of a page is the simple name of the class that declares it. In the above example, the ItemListPage will fill the navigation panel whenever the browser’s location bar ends with #ItemListPage. If you prefer a different page name, use the @Page annotation’s path attribute:

@Page(path="items")

public class ItemListPage extends Composite {
  // Anything goes...
}

There are four annotations related to page lifecycle events: @PageShowing, @PageShown, @PageHiding, and @PageHidden. These annotations designate methods so a page widget can be notified when it is displayed or hidden:

@Page

public class ItemPage extends VerticalPanel {
  @PageShowing
  private void preparePage() {
  }
  @PageHiding
  private void unpreparePage() {
  }
  // Anything goes...
}

A page widget will often represent a view on on instance of a class of things. For example, there might be an ItemPage that displays a particular item available at a store. In cases like this, it’s important that the bookmarkable navigation URL includes not only the name of the page but also an identifier for the particular item being displayed.

This is where page state parameters come in. Consider the following page widget:

@Page

public class ItemPage extends VerticalPanel {
  @PageState
  private int itemId;
  // Anything goes...
}

This page would be reachable at a URL like http://www.company.com/store/#ItemPage;itemId=4, assuming www.company.com was the host address and store was the application context. Before the page was displayed, the Errai UI Navigation framework would write the int value 4 into the itemId field.

Page state parameters can also be accessed using URLs with path parameters. In this case, you have to declare the template of the page’s path in the path field of the @Page annotation. As an example, consider the following code:

@Page(path="item/{itemID}/{customerID}")

public class ItemPage extends VerticalPanel {
  @PageState
  private int itemID;
  @PageState
  private String customerID;
  // Anything goes...
}

There are three ways to pass state information to a page: by passing a Multimap to TransitionTo.go(); by passing a Multimap to Navigation.goTo(), or by including the state information in the path parameter or fragment identifier of a hyperlink as illustrated in the previous paragraph (use the HistoryToken class to construct such a URL properly.)

A page widget can have any number of @PageState fields. The fields can be of any primitive or boxed primitive type (except char or Character), String, or a Collection, List, or Set of the allowable scalar types. Nested collections are not supported.

@PageState fields can be private, protected, default access, or public. They are always updated by direct field access; never via a setter method. The updates occur just before the @PageShowing method is invoked.

In addition to receiving page state information via direct writes to @PageState fields, you can also receive the whole Multimap in the @PageShowing and @PageShown methods through a parameter of type HistoryToken. Whether or not a lifecycle method has such a parameter, the @PageState fields will still be written as usual.

Page state values are represented in the URL in place of the corresponding parameter variables declared in the URL template (the path field of the @Page annotation. See Declaring a Page). If a parameter variable is declared in the URL template and is missing from the actual typed URL, it will cause a navigation error as Errai will not be able to match the typed URL to any template.

Any additional path parameters not found in the URL template are appended as key=value pairs separated by the ampersand (&) character. Multi-valued page state fields are represented by repeated occurrences of the same key. If a key corresponding to a @PageState field is absent from the state information passed to the page, the framework writes a default value: null for scalar Object fields, the JVM default (0 or false) for primitives, and an empty collection for collection-valued fields. To construct and parse state tokens programmatically, use the HistoryToken class.

To illustrate this further, consider the following example:

@Page(path="item/{itemID}/{customerID}")

public class ItemPage extends VerticalPanel {
  @PageState
  private int itemID;
  @PageState
  private String customerID;
  @PageState
  private int storeID;
  // Anything goes...
}

Given the host "www.company.com", the context store, and a state map with the values itemID=4231, customerID=9364, and storeID=0032, the following URL will be generated: www.company.com/store/#item/4231/9364;storeID=0032

If the value for storeID is undefined, the URL will be www.company.com/store/#item/4231/9364;storeID=0.

If the URL typed into the browser is www.company.com/store/#item/4231;storeID=0032, it will cause a navigation error (assuming there is no other page by this url) because there is a missing path parameter.

Errai now comes with support for pushState and path-parameter-based URLs. If HTML5 pushState is enabled Errai Navigation urls will not use the fragment-identifier (#). Thus the non-pushState url from the previous section, www.company.com/store/#item/4231/9364, would become www.company.com/store/item/4231/9364.

HTML5 pushState can be enabled by adding the following lines to your GWT host page:


<script type="text/javascript">
    var erraiPushStateEnabled = true;
</script>

The application context must be the same as the application’s servlet web context deployed on the server. Errai attempts to infer the application context upon the first page load, but it can also be set manually. To explicitly declare the application context, you can use the setApplicationContext method in the Navigation class, or set the erraiApplicationWebContext variable in your GWT host page as follows:


<script type="text/javascript">
    var erraiApplicationWebContext = "store";
</script>

In the event that the browser does not support HTML5, Errai automatically disables pushState functionality and reverts to a #-based URL format. That is, Errai uses fragment identifiers to refer to particular resources.

If the page that the user is trying to navigate to cannot be found, a 404 - Not Found page is displayed. You can override this functionality and display a custom page in the case of a page not found error. For example, to navigate to the GWT host page by default, add the following lines to your web.xml file:


<error-page>
    <error-code>404</error-code>
    <location>/</location>
</error-page>

Beginning in version 2.4, Errai will automatically attach the Navigation Panel to the Root Panel, but it is possible to override this behaviour by simply adding the Navigation Panel to another component manually. The best time to do this is during application startup, for example in the @PostConstruct method of your @EntryPoint class. By using the default behaviour you can allow Errai Navigation to control the full contents of the page, or you can opt to keep some parts of the page (headers, footers, and sidebars, for example) away from Errai Navigation by choosing an alternate location for the Navigation Panel.

The following example reserves space for header and footer content that is not affected by the navigation system:

@EntryPoint

public class Bootstrap {
  @Inject
  private Navigation navigation;
  @PostConstruct
  public void clientMain() {
    VerticalPanel vp = new VerticalPanel();
    vp.add(new HeaderWidget());
    vp.add(navigation.getContentPanel());
    vp.add(new FooterWidget());
    RootPanel.get().add(vp);
  }
}

This last example demonstrates a simple approach to defining the page structure with an Errai UI template. The final product is identical to the above example, but in this case the overall page structure is declared in an HTML template rather than being defined programmatically in procedural logic:

@Templated

@EntryPoint
public class OverallPageStructure extends Composite {
  @Inject
  private Navigation navigation;
  @Inject @DataField
  private HeaderWidget header;
  @Inject @DataField
  private SimplePanel content;
  @Inject @DataField
  private FooterWidget footer;
  @PostConstruct
  public void clientMain() {
    // give over the contents of this.content to the navigation panel
    content.add(navigation.getContentPanel());
    // add this whole templated widget to the root panel
    RootPanel.get().add(this);
  }
}

Starting with version 2.4.0, Errai now supports mobile development. One of the modules that makes this feasible is the Cordova module. It offers a way to integrate with native hardware in an Errai way.

Plugin Tip

Use the Errai Forge Addon Add Errai Features command and select Errai Cordova to follow along with this section.

Manual Setup

Checkout the Manual Setup Section for instructions on how to manually add Errai Cordova to your project.

When the Cordova module is included you can integrate with native hardware by injecting the native components into your code:

@Templated("#main")

public class KitchenSinkClient extends Composite {
  @Inject
  Camera camera;
  @Inject
  @DataField
  Button takePicture;
  @EventHandler("takePicture")
  public void onTakePicktureClicked(ClickEvent event) {
    PictureOptions options = new PictureOptions(25);
    options.setDestinationType(PictureOptions.DESTINATION_TYPE_DATA_URL);
    options.setSourceType(PictureOptions.PICTURE_SOURCE_TYPE_CAMERA);
    camera.getPicture(options, new PictureCallback() {
      @Override
      public void onSuccess(String data) {
        image.setUrl(UriUtils.fromSafeConstant("data:image/jpeg;base64," + data));
      }
      @Override
      public void onFailure(String error) {
        setGeneralErrorMessage("Could not take picture: " + error);
      }
    });
  }

The components that are supported come from the gwt-phonegap project have a look there form more documentation.

Here are the native hardware components you can inject:

  • Camera
  • Accelerometer
  • Contacts
  • Capture (Provides access to the audio, image, and video capture capabilities of the device).
  • Compass
  • Notification (see documentation on phonegap site)
  • File create a native file
  • Device Get general information about the device.

So to integrate with these things all we have to do is @Inject these classes. There are also a couple of CDI events one can observe to be informed about hardware state:

  • BackButtonEvent
  • BatteryCriticalEvent
  • BatteryEvent
  • BatteryLowEvent
  • BatteryStatusEvent
  • EndCallButtonEvent
  • MenuButtonEvent
  • OffLineEvent
  • OnlineEvent
  • PauseEvent
  • ResumeEvent
  • SearchButtonEvent
  • StartCallButtonEvent
  • VolumeDownButtonEvent
  • VolumeUpButtonEvent

Example of how to use these events:

  private void batteryIsLow(@Observes BatteryLowEvent event) {

    //mission accomplished. we can stop the infinite loop now.
  }

Errai Security provides a lightweight security API for declaring RPC services and client-side UI elements which require authentication or authorization.

Plugin Tip

Use the Errai Forge Addon Add Errai Features command and select Errai Security to follow along with this section.

Manual Setup

Checkout the Manual Setup Section for instructions on how to manually add Errai Security to your project.

The simplest way to begin experimenting with Errai Security is to add Users and Roles to PicketLink programmatically. Here is some sample server-side code from the Errai Security Demo.

@Singleton

@Startup
public class PicketLinkDefaultUsers {
  @Inject
  private PartitionManager partitionManager; 1
  /**
   * <p>Loads some users during the first construction.</p>
   */
  @PostConstruct
  public void create() {
    final IdentityManager identityManager = partitionManager.createIdentityManager();
    final RelationshipManager relationshipManager = partitionManager.createRelationshipManager();
    User john = new User("john");
    john.setEmail("john@doe.com");
    john.setFirstName("John");
    john.setLastName("Doe");
    User hacker = new User("hacker");
    hacker.setEmail("hacker@illegal.ru");
    hacker.setFirstName("Hacker");
    hacker.setLastName("anonymous");
    identityManager.add(john); 
2
    identityManager.add(hacker);
    final Password defaultPassword = new Password("123");
    identityManager.updateCredential(john, defaultPassword);
    identityManager.updateCredential(hacker, defaultPassword);
    Role roleDeveloper = new Role("simple");
    Role roleAdmin = new Role("admin");
    identityManager.add(roleDeveloper);
    identityManager.add(roleAdmin);
    relationshipManager.add(new Grant(john, roleDeveloper)); 
3
    relationshipManager.add(new Grant(john, roleAdmin));
  }
}

Here are the important things that are happening here:

1

PicketLink uses the concept of partitions, which are sections that can contain different users and roles. What we really need to make users and roles are the IdentityManager and RelationshipManager, but these objects are @RequestScoped so in order to access them when the application starts we must @Inject the PartitionManager.

2

Here we add are new users to the IdentityManager. It is also used below to give passwords to the new users, and to add the simple and admin roles.

3

The RelationshipManager defines relationships between entities. In this case, it is used to specify that a user belongs to a role.

Once you’ve created some users and roles, you’re ready to write some client-side code. Authentication is performed with the org.jboss.errai.security.shared.service.AuthenticationService via Errai RPC.

Here is some sample code involving the user john from the previous Security Demo excerpt.

The annotation @RestrictedAccess is the only annotation necessary to secure a resource or UI element. In general, @RestrictedAccess blocks a resource from users who are either not logged in or who lack required roles. Roles are defined through the @RestrictedAccess annotation in one of the following two ways.

To secure an Errai RPC service, simply annotate the RPC interface (either the entire type or just a method) with one of the security annotations.

For example:

When access to a secured RPC service is denied an UnauthenticatedException or UnauthorizedException is thrown. This error is then transmitted back to the client, where it can be caught with an ErrorCallback (provided when the RPC is invoked).

Here is how we would invoke the previous MixedService example with error handling:

MessageBuilder.createCall(new RemoteCallback<Void>() {


    @Override
    public void callback(Void response) {
      // ...
    }
  }, new ErrorCallback<Message>() { 
1
    @Override
    public boolean error(Message message, Throwable t) {
      if (instanceof UnauthenticatedException) {
        // User is not logged in.
        return false;
      }
      else if (instanceof UnauthorizedException) {
        // User is logged in but lacked sufficient roles.
        return false;
      }
      else {
        // Some other error has happened. Let it propogate.
        return true;
      }
    }
  }, MixedService.class).adminService();

1

This ErrorCallback is parameterized with the type Message because it is an Errai Bus RPC. In the next section we will demonstrate the use of a JAX-RS RPC.

JAX-RS RPCs are secured exactly as bus RPCs. Here is the first example from the previous section, but converted to use JAX-RS instead of the Errai Bus.

@Path("/rest-endpoint")

@RestrictedAccess
public interface UserOnlyStuff {
  @Path("/some-method")
  @GET
  public void someMethod();
  @Path("/other-method")
  @GET
  public void otherMethod();
}

There are two important differences when calling a secured JAX-RS RPC (in contrast to an Errai Bus RPC):

Because there is no global error-handling, you should always pass a RestErrorCallback when using a JAX-RS RPC. Errai provides the DefaultRestSecurityErrorCallback that provides the same default behaviour as the DefaultBusSecurityErrorCallback mentioned above. It can also optionally wrap a provided callback as demonstrated below:

Any class annotated with @Page can also be marked with @RestrictedAccess. By doing so, users will be prevented from navigating to the given page if they are not logged in or lack authorization.

Here are two simple examples:

Security checks performed before page navigation do not use any RPC calls, but are instead performed from a cached (in-memory) instance of the org.jboss.errai.security.shared.api.identity.User. This prevents the possibility of lengthy delays between page navigation while waiting for RPC return values.

But the drawback is that any attempts to navigate to a secured @Page before the cache is populated will result in redirection to the LoginPage — even if the user is in fact logged in.

In practice, this is only likely to happen if a user starts an Errai app with a URL to a secure page while still logged in on the server from a previous session.

One option offered by Errai is to persist the org.jboss.errai.security.shared.api.identity.User object in a cookie. This can be done by adding the following to ErraiApp.properties:

errai.security.user_cookie_enabled=true

With this option enabled the User will be persisted in a browser cookie, which is loaded quickly enough to avoid the described navigation issue. This feature can also be used to allow an application to work offline, or allow the server to log in a user on an initial page request.

If you do not wish to use this feature you will likely want to handle this case in the @PageShowing method of your LoginPage. Here is an outline of what you might want to do:

@Page(role = LoginPage.class)

@Templated
public class ExampleLoginPage extends Composite {
  @Inject
  private SecurityContext securityContext;
  @Inject
  private Caller<AuthenticationService> authService;
  @Inject
  @DataField
  private Label status;
  @PageShowing
  public void checkForPendingCache() {
    // Check if cache is invalid.
    if (!securityContext.isUserCacheValid()) {
      // Update the status.
      status.setText("loading...");
      // Force cache to update by calling getUser
      authService.call(new RemoteCallback<User> {
        @Override
        public void callback(User user) {
          /* An interceptor will have updated the cache by now.
             So check if we are logged in and redirect if necessary.
          */
          if (!user.equals(User.ANONYMOUS)) {
            /* This is a special transition that takes us back to
               a secure page from which we were redirected. */
            securityContext.navigateBackOrHome();
          }
          else {
            status.setText("You are not logged in.");
          }
        }
      }).getUser();
    }
  }
}

If you do enable the Errai Security cookie, it is possible to use a form-based login from outside your GWT/Errai app. The errai-security-server jar contains a servlet filter for encoding the currently authenticated user as a cookie in the http response. Here are the steps for setting this up:

  1. Create a login page using an html form that posts to a servlet-filter. If you are using Errai Security with PicketLink you will want to use the org.picketlink.authentication.web.AuthenticationFilter servlet-filter. Otherwise, you will need to implement one yourself that authenticates the user by calling AuthenticationService.login(String, String) method.
  2. Add this filter-mapping for setting the Errai Security user cookie:

    
      <filter-mapping>
        <filter-name>ErraiUserCookieFilter</filter-name>
        <url-mapping>/gwt-host-page.html</url-mapping>
      </filter-mapping>

    The mapped URL should be that of your GWT Host Page.

    This mapping must come after the filter that authenticates the user

    If this filter maps to the same URL as the filter for authentication, this filter must come after the authentication filter or else it will set the cookie before the user has logged in.

  3. Make sure this is in your ErraiApp.properties file: errai.security.user_cookie_enabled=true

Keycloak is is a new project that provides integrated SSO and IDM for browser apps and RESTful web services. By using Keycloak it is possible to outsource the responsibility of authentication and account management from your application entirely. Errai Security provides an optional errai-security-keycloak jar that provides an implementation of the AuthenticationService that works with Keycloak.

To start from scratch and add Keycloak integration to your application:

  • Setup a Keycloak server. Please consult the Keycloak documentation for details on how this is achieved.
  • Start the Keycloak server.
  • Go to the Keycloak Administrative Console (i.e. http://localhost:8080/auth/admin/) (the username and password are both admin on first use).
  • Click Add Realm and create a custom realm for your application.
  • Select the Clients tab and click Create, then fill in the following to add the client application to this realm:

    • Client ID: the name of your client application (i.e. errai-security-demo)
    • Access Type: public
    • Redirect URI: the url of your application (i.e. http://localhost:8080/[your-application]/*)
  • After saving your application, choose the new application in the menu and make sure the following are set:

    • In the Roles tab add your custom roles.
    • In the Installation tab choose the format option keycloak.json and copy the contents in your WEB-INF/keycloak.json file.
  • Click on Users on the side-panel to add a user:

    • Fill out the Username, Email, First Name, and Last Name with any values.
    • After saving go to the Credentials tab and set a password.
    • Go to the Role Mappings tab. Add at least one role to the Assigned Roles for your application (scroll down to Application Roles and select your application to do this).
  • Add the errai-security-keycloak jar to your project and make sure it’s being deployed to the server. In maven, the dependency is org.jboss.errai:errai-security-keycloak.
  • Configure the ErraiUserCookieFilter in your web.xml. All that is necessary is adding a filter-mapping for your GWT host page like so:

    
      <filter-mapping>
        <filter-name>ErraiUserCookieFilter</filter-name>
        <url-pattern>/index.html</url-pattern>
      </filter-mapping>
  • Configure the ErraiLoginRedirectFilter in your web.xml.

    • Create a filter-mapping of this filter onto a path that will act as a url to the Keycloak login page. For example, if your deployed app is called my-app and you wanted <server-uri>/my-app/app-login as your login url then you would add the following:

      
        <filter-mapping>
          <filter-name>ErraiLoginRedirectFilter</filter-name>
          <url-pattern>/app-login</url-pattern>
        </filter-mapping>
    • Add a security-constraint to login url. This is what actually causes the redirection to Keycloak. All the filter does is redirect back to your app (which happens after the login completes). For the previous example, the constraint would look like this:

      
        <security-constraint>
          <web-resource-collection>
            <web-resource-name>Login</web-resource-name>
            <url-pattern>/app-login</url-pattern>
          </web-resource-collection>
          <auth-constraint>
            <role-name>*</role-name>
          </auth-constraint>
        </security-constraint>
    • Optionally configure the URL that the ErraiLoginRedirectFilter redirects to. You can do this with the redirectLocation param, which takes a path relative to the app context:

      
        <filter>
          <filter-name>ErraiLoginRedirectFilter</filter-name>
          <init-param>
            <param-name>redirectLocation</param-name>
            <param-value>/index.jsp</param-value>
          </init-param>
        </filter>
  • Set the login method to use Keycloak in you web.xml:

    
      <login-config>
        <auth-method>KEYCLOAK</auth-method>
        <realm-name>[your-realm-name]</realm-name>
      </login-config>
  • Add roles available to users in your application to the web.xml. Here is an example declaration of a "user" role:

    
      <security-role>
        <role-name>user</role-name>
      </security-role>

All users must have at least one role

With this configuration all users must have at least a single role, or else they will not be redirected propertly. Unfortunately, there is no way to define a security-constraint that only requires authentication. The simplest solution is to add a default role to your realm.

Errai now supports using the slf4j logging api on the server and client. This gives you the flexibility of choosing your own logging back-end for your server-side code, while still allowing a uniform logging interface that can be used in shared packages.

The client-side slf4j code uses the GWT Logging as the back-end. Using slf4j in client-side code has three steps:

  • Add the errai-common artifact as a maven dependency to your project
  • Inherit the GWT module org.jboss.errai.common.ErraiCommon

    
      <inherits name="org.jboss.errai.common.ErraiCommon" />
  • Enable logging and configure the log level in your gwt.xml module descriptor:

    
      <set-property name="gwt.logging.enabled" value="TRUE"/>
      <set-property name="gwt.logging.logLevel" value="ALL"/>

Log handler levels can be changed at run-time through Java or Javascript. To do so through Java, use the LoggingHandlerConfigurator in Errai Common. Here’s an example:


Each handler has a native Javascript variable associated with its log level:

HandlerVariable Name

ErraiSystemLogHandler

erraiSystemLogHandlerLevel

ErraiConsoleLogHandler

erraiConsoleLogHandlerLevel

ErraiDevelopmentModeLogHandler

erraiDevelopmentModeLogHandlerLevel

ErraiFirebugLogHandler

erraiFirebugLogHandlerLevel

Since these are native Javascript variables, they can easily be set in a script tag on your host page:


<script type="text/javascript">
  erraiSystemLoghandlerLevel = "INFO";
</script>

The possible log levels correspond to those in java.util.logging.Level.

Logging Levels

If you are increasing the logging level of an Errai log handler, you will also need to increase the gwt.logging.logLevel (set in your *.gwt.xml). Handlers will not receive log records that are lower than the GWT log level, which is set to INFO in ErraiCommon.gwt.xml.

15.1. Errai Development Mode Configuration
15.1.1. Deployment in Development Mode (JBossLauncher)
15.1.2. Additional JBossLauncher Arguments
15.1.3. Deployment to an Application Server
15.2. Errai Offline Mode Configuration
15.3. ErraiApp.properties
15.3.1. As a Marker File
15.3.2. As a Configuration File
15.4. Messaging (Errai Bus) Configuration
15.4.1. Compile-time Dependencies
15.4.2. Disabling remote communication
15.4.3. Configuring an alternative remote remote bus endpoint
15.4.4. ErraiService.properties
15.4.5. Servlet Configuration
15.5. Errai JAX-RS Setup
15.5.1. Compile-time dependency
15.5.2. GWT Module
15.5.3. Configuration
15.6. Errai JPA
15.6.1. Compile-time Dependencies
15.6.2. GWT Module Descriptor
15.7. Errai JPA Data Sync
15.7.1. Compile-time Dependencies
15.7.2. GWT Module Descriptor
15.8. Errai Data Binding
15.8.1. Compile-time Dependencies
15.8.2. GWT module descriptor
15.8.3. Bootstrapping Data Binding without Errai IOC
15.9. Errai UI
15.9.1. Compile-time dependency
15.9.2. GWT Module Descriptor
15.10. Errai UI Navigation
15.10.1. Compile-time Dependencies
15.10.2. GWT Module Descriptor
15.11. Errai Cordova (Mobile Support)
15.11.1. Compile-time Dependencies
15.11.2. Cordova Maven Plugin
15.11.3. GWT Module Descriptor
15.11.4. Building with Errai Cordova
15.12. Errai Security
15.12.1. Compile-time dependency
15.12.2. GWT Module Descriptor
15.12.3. CDI and Interceptor Bindings
15.13. Errai Project Dependencies
15.13.1. Errai Messaging
15.13.2. Errai CDI
15.13.3. Errai IOC
15.13.4. Errai UI
15.13.5. Errai Navigation
15.13.6. Errai DataBinding
15.13.7. Errai JPA Client
15.13.8. Errai JPA Datasync
15.13.9. Errai JAXRS
15.13.10. Errai Cordova
15.13.11. Errai Security

This section contains information on manually setting up Errai and describes additional configurations and settings which may be adjusted.

In development mode we need to bootstrap the CDI environment on our own and make both Errai and CDI available through JNDI (common denominator across all runtimes). GWT by default uses Jetty, that only supports read only JNDI. The current solution for this is to use a custom launcher to control a JBoss AS 7 or Wildfly 8 instance instead of GWT’s built-in Jetty.

To do this, requires the following configurations in the gwt-maven-plugin configuration:


<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>gwt-maven-plugin</artifactId>
  <version>${gwt.version}</version>

  <configuration>
  ...
    <extraJvmArgs>-Derrai.jboss.home=$JBOSS_HOME -Derrai.jboss.javaagent.path=${settings.localRepository}/org/jboss/errai/errai-client-local-class-hider/$ERRAI_VERSION/errai-client-local-class-hider-$ERRAI_VERSION.jar</extraJvmArgs>
    <noServer>false</noServer>
    <server>org.jboss.errai.cdi.server.gwt.JBossLauncher</server>
  </configuration>
  <executions>
  ...
  </executions>
</plugin>

What does all this mean?

We provide integration with the JBoss Application Server, but the requirements are basically the same for other vendors. When running a GWT client app that leverages CDI beans on a Java EE 6 application server, CDI is already part of the container and accessible through JNDI (java:/BeanManager).

Errai provides special support for HTML5’s application caching mechanism that enables applications to work offline. If you’re not familiar with the HTML5 application cache you can find all the details here.

As GWT compiles separate browser-specific JavaScript permutations for your application, it is not enough to manually create a cache manifest file and simply list all generated JavaScript files. This would cause every browser to download and cache JavaScript files that it doesn’t need in the first place (i.e. Safari would download and cache JavaScript files that were generated for Internet Explorer only). Errai solves this problem by using a custom linker to generate user-agent specific cache manifest files.

The following steps are necessary to activate this linker:

  • Define the linker in your gwt.xml module descriptor:

<define-linker name="offline" class="org.jboss.errai.offline.linker.DefaultCacheManifestLinker" />
<add-linker name="offline" />
  • Add the manifest (your_module_name/errai.appcache) to the html tag in your host page:

<html manifest="your_module_name/errai.appcache">
  • Add a mime-mapping to your web.xml file (you can skip this step if you deploy the errai-javaee-all.jar as part of your application):

<mime-mapping>
  <extension>manifest</extension>
  <mime-type>text/cache-manifest</mime-type>
</mime-mapping>
  • Make sure the errai-common.jar file is deployed as part of your application. It contains a servlet that will provide the correct user-agent specific manifest file in response to requests to your_module_name/errai.appcache
  • To obtain manifests that contain other files in addition to those generated by the DefaultCacheManifestLinker, create a subclass that overrides otherCachedFiles(), and use this subclass as a linker instead:
@Shardable

@LinkerOrder(Order.POST)
public class MyCacheManifestLinker extends DefaultCacheManifestLinker {
  @Override
  protected String[] otherCachedFiles() {
    return new String[] {"/my-app/index.html","/my-app/css/application.css"};
  }
}

ErraiApp.properties acts both as a marker file for JARs that contain Errai-enabled GWT modules, and as a place to put configuration settings for those modules in the rare case that non-default configuration is necessary.

ErraiApp.properties is usually left empty, but it can contain configuration settings for both the core of Errai and any of its extensions. Configuration properties defined and used by Errai components have keys that start with " errai. ". Third party extensions should each choose their own prefix for keys in ErraiApp.properties.

The ErraiService.properties file contains basic configuration for the bus itself. Unlike ErraiApp.properties, there should be at most one ErraiService.properties file on the classpath of a deployed application. If you do not need to set any properties to their non-default values, this file can be omitted from the deployment entirely.

Dispatchers encapsulate the strategy for taking messages that need to be delivered somewhere and seeing that they are delivered to where they need to go. There are two primary implementations that are provided with Errai, depending on your needs.

SimpleDispatcher:

SimpleDispatcher is basic implementation that provides no asychronous delivery mechanism. Rather, when you configure the Errai to use this implementation, messages are delivered to their endpoints synchronously. The incoming HTTP thread will be held open until the messages are delivered.

While this sounds like it has almost no advantages, especially in terms of scalablity. Using the SimpleDispatcher can be far preferable when you’re developing your application, as any errors and stack traces will be far more easily traced and some cloud services may not permit the use of threads in any case.

AsyncDispatcher:

The AsyncDispatcher provides full asynchronous delivery of messages. When this dispatcher is used, HTTP threads will have control immediately returned upon dispatch of the message. This dispatcher provides far more efficient use of resources in high-load applications, and will significantly decrease memory and thread usage overall.

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 Cordova allows you build an Errai app to natively run on a device. In order to make this as easy as possible we have a maven plugin that will create a native binary that you can install on a device. It will put the html and javascript of you application in a cordova application.


<build>
 ...
    <plugins>
      <plugin>
        <groupId>org.jboss.errai</groupId>
        <artifactId>cordova-maven-plugin</artifactId>
        <version>${errai.version}</version>
      </plugin>

For those not using maven, here is the dependency tree of Errai project jars.

This section explains the cause of and solution to some common problems that people encounter when building applications with Errai.

Of course, when lots of people trip over the same problem, it’s probably because there is a deficiency in the framework! A FAQ list like this is just a band-aid solution. If you have suggestions for permanent fixes to these problems, please get in touch with us: file an issue in our issue tracker, chat with us on IRC, or post a suggestion on our forum.

But for now, on to the FAQ:

Possible symptoms:

Answer: Make sure the ErraiApp.properties file is actually making it into your runtime classpath.

One common cause of this problem is a <resources> section in pom.xml that includes src/main/java (to expose .java sources to the GWT compiler) that does not also include src/main/resources as a resource path. You must include both explicitly:


<resources>
  <resource>
    <directory>src/main/java</directory>
  </resource>
  <resource>
    <directory>src/main/resources</directory>
  </resource>
</resources>

This chapter contains important information for migrating to newer versions of Errai. If you experience any problems, don’t hesitate to get in touch with us. See Reporting problems.

The first issues that will arise after replacing the jars or after changing the version numbers in the pom.xml are unresolved package imports. This is due to refactorings that became necessary when the project grew. Most of these import problems can be resolved automatically by modern IDEs (Organize Imports). So, this should replace org.jboss.errai.bus.client.protocols.* with org.jboss.errai.common.client.protocols.* for example.

The following is a list of manual steps that have to be carried out when upgrading:

  • @ExposedEntity became @Portable (org.jboss.errai.common.client.api.annotations.Portable). See Marshalling for details.
  • The @Conversational annotation must now target the event objects themselves, not the observer methods of the events. So an event type is either conversational or not; you no longer specify that listeners receive arbitrary events in a conversational context. See the Conversational Events section of the CDI chapter for details.
  • Errai CDI projects must now use the SimpleDispatcher instead of the AsynDispatcher. This has to be configured in Messaging (Errai Bus) Configuration.
  • The bootstrap listener (configured in WEB-INF/web.xml) for Errai CDI has changed (org.jboss.errai.container.DevModeCDIBootstrap is now org.jboss.errai.container.CDIServletStateListener).
  • gwt 2.3.0 or newer must be used and replace older versions.
  • mvel2 2.1.Beta8 or newer must be used and replace older versions.
  • weld 1.1.5.Final or newer must be used and replace older versions.
  • slf4j 1.6.1 or newer must be used and replace older versions.
  • This step can be skipped if Maven is used to build the project. If the project is NOT built using Maven, the following jar files have to be added manually to project’s build/class path: errai-common-2.x.jar, errai-marshalling-2.x.jar, errai-codegen-2.x.jar, netty-4.0.0.Alpha1.errai.r1.jar.
  • If the project was built using an early version of an Errai archetype the configuration of the maven-gwt-plugin has to be modified to contain the <hostedWebapp>path-to-your-standard-webapp-folder</hostedWebapp>. This is usually either war or src/main/webapp.

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.