JBoss.orgCommunity Documentation
Errai is a GWT-based framework for building rich web applications using next-generation web technologies. Built on-top of ErraiBus, the framework provides a unified federation and RPC infrastructure with true, uniform, asynchronous messaging across the client and server.
Errai requires a JDK version 6 or higher and depends on Apache Maven to build and run the examples, and for leveraging the quickstart utilities.
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.
GWT is a toolkit built around a Java-to-JavaScript compiler. It provides a JRE emulation library, abstraction of browser quirks, a development mode runtime, and tools for native JavaScript integration.
Errai uses GWT to accomplish the translation of concepts such as CDI into the browser, which enables a consistent client and server programming experience.
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.
JAX-RS is an API which provides a standardized programming model for specifying web services based around the concept of the Representational State Transfer (REST) architecture. REST has by and far become the preferred way of developing web services, and is used pervasively in modern web applications. Errai provides a set of tools to make working with JAX-RS easier.
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).
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.
GWT’s development mode allows for code-refresh development cycles. Simply change a client-side class and refresh the browser to see your changes. You can also debug client and server side code in your IDE of choice.
Change into the newly created project directory and type the following:
mvn clean gwt:run
This will begin the download of all the dependencies required to develop with and run Errai. It may take a few minutes to complete the download.
When it is finished, you should see the GWT Development Mode runtime window appear as shown in Figure 1 running on Windows.
Next, click the Launch Default Browser button. If you have have never used GWT before on your computer, you may get an error when your browser loads as shown in Figure 2 .
Click the blue button that says Download the GWT Developer Plugin to download the plugin. Run the installer to install the plugin for your browser.
If you get a 404 Error for Internet Explorer when clicking the link, you can download the latest plugin for your browser directly from these links:
Once you have configured your browser for development with GWT, and after loading the app with the Launch Default Browser button, you should see the application load.
If you are using errai-tutorial, you should see a page with a complaint form.
If you followed the instructions for using the Errai Forge plugin, there should be a blank page with an alert saying "Hello World!".
That’s it! You’ve got your first Errai Application up and running. In the next section we’ll learn how to run super devmode. Otherwise, skip to the section afterwards to setup your IDE.
Regular Devmode requires a special browser plugin to run client-side code in a as Java. Super Devmode is an alternative method that compiles code to javascript to be run natively in any browser. With browsers that support source-mapping, it is possible to debug with lines from your original source code within the browser.
To run super devmode you will need to open two terminals in your project. In the first enter:
mvn clean gwt:run
This will launch a classic devmode server for hosting server-side resources. In the second enter:
mvn gwt:run-codeserver
This will launch the super devmode codeserver that hosts compiled GWT code. When the super devmode codeserver is finished compiling your GWT module, it will display a message like this:
The code server is ready. Next, visit: http://localhost:9876
Go to the displayed link and copy the two bookmarks Dev Mode On and Dev Mode Off.
After completing the above, you may run your application as follows:
?gwt.codesvr=...
).This next section assumes you have followed the instructions in the previous section. As such, we assume you have created an Errai project using the Errai Forge plugin or a copy of the errai-tutorial project, which we’ll be importing into your IDE.
The project that was made in the last section is a Maven project. Thus, we will be relying on Maven to manage our project model throughout this guide. As such, we will want to install Maven tooling in the IDE. If you have not already installed m2e in Eclipse, you will want to do so now.
To install the Maven tooling, use the following steps:
Go to the Eclipse Marketplace under the Help menu in Eclipse.
In the Find dialog enter the phrase Maven and hit enter.
Find the Maven Integration for Eclipse plugin and click the Install button for that entry.
Once you have completed the installation of the prerequisites from the previous section, you will now be able to go ahead and import the Maven project you created in the first section of this guide. We will use the errai-tutorial project as an example.
Follow these steps to get the project setup:
From the File menu, select Import…
You will be presented with the Import dialog box. From here you want to select Maven → Existing Maven Projects
From the Import Maven Projects dialog, you will need to select the directory location of the project you created in the first section of this guide. In the Root Directory field of the dialog, enter the path to the project, or click Browse… to select it from the file chooser dialog.
When the import process has finished, you should see your project imported within the Eclipse Project Explorer . If you are using errai-tutorial, the App
class should be visible within the client
package.
Next you will need to setup a Maven Run Profile for Development Mode. To do so select Run As… > Run Configurations… from the toolbar.
Select Maven Build from the sidebar and create a new launch configuration by pressing the New button in the top left corner.
Give the configuration a name, then click Browse Workspace and select the root directory of your new project.
In the Goals text box, type "clean gwt:run". Click Apply to save the configuration and then Close.
You can add this new configuration under the Run As button in your toolbar by selecting Run As > Organize Favorites, then clicking Add and selecting the run configuration.
At this point, you should try running your new configuration to make sure everything is in working order. To run your app, find the run configuration under the Run As menu in the toolbar.
This will start the GWT Development Mode exactly as running mvn clean gwt:run
from the command line.
To setup a debug run configuration for GWT Development Mode, repeate steps (2) and (3) from the section above, but this time use the Goals "clean gwt:debug".
Next we will need to setup our remote debugger configurations in Eclipse. Because the client and server code run on separate JVMs, we will need to setup two such configurations. To create a debug configuration, select Debug As… > Debug Configurations… from the toolbar.
In the sidebar, select Remote Java Application and click the New button in the top right corner.
This new configuration will be for remote debugging your client-side code, so give it an appropriate name. If the name of your project is not already in the Project field, click Browse and select it. The Host and Port values should be localhost and 8000 respectively, such that your configuration looks like this:
If everything is correct, click Apply.
Create another Remote Java Application run configuration with the steps just described for remote debugging server code. The only differences from the client configuration should be the name and the port, which is 8001. Thus the server remote debug configuration should look like this:
The project you created and setup in the previous two sections (ERRAI:Create your Project and ERRAI:Configuring your project for Eclipse) will be used as the basis for this section. So if you have not read them, do so now.
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.
A bean in CDI is merely a POJO (Plain Old Java Object), for the most part. In the context of CDI, any plain, default constructable class is a member of the dependent scope . Don’t worry too much about what that means for now. Let’s just go ahead and make one:
public class Foo {
public String getName() {
return "Mr. Foo";
}
}
That was an easy, if uninteresting, exercise. But despite this class' worthy distinction as a dependent-scoped bean, it’s actually quite a useless dependent scope beaned. Well, maybe not so much useless as it is unused.
Well, how would we use this bean? To answer that question we’re going to need to introduce the concept of scopes in more detail.
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
This identity check will not actually be true at runtime due to the need to proxy the class in this scenario. But it is true, that fooInstance
and fooInstance.bar.foo
both point to the same underlying bean instance.
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.
Now that we’re getting the gist of how dependency injection works, let’s go back to our sample project.
In the App
class that was created you may have noticed that the bean’s scope is @EntryPoint
.
The @EntryPoint
annotation is an annotation which provides a an analogue to the GWT EntryPoint concept within the context of CDI in Errai. Basically you want to think of @EntryPoint
beans as the Errai CDI-equalivalent of main()
methods. But as of Errai 2.2., that might actually be going a little far. In fact, you might be asking what is the real difference between @ApplicationScoped
and @EntryPoint
in practice. The short answer is: nothing.
When Errai IOC, the technology which powers Errai’s client-side CDI, was first built, it lacked the concept of scopes. To create entry point objects into the application which would automatically run, this annotation was added.
If you’re not convinced, try running this example with the mvn clean gwt:run
command (described above).
Please note, that when launching maven the first time on your machine, it will fetch all dependencies from a central repository. This may take a while, because it includes downloading large binaries like GWT SDK. However, subsequent builds are not required to go through this step and will be much faster.