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.
As of GWT 2.7, we use Super Dev Mode to run your app in hosted mode during development. GWT’s Super Dev 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. These sections will describe how to use Super Dev Mode to develop and debug your web app.
Change into your web app’s 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.
Next, click the Launch Default Browser button. You should now 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. The next sections will describe how to set up your app with your IDE.
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.
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.
This section will walk you through using Maven tooling for running and debugging your app within Eclipse. 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:
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:
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.
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:
In the Server tab, check the Run built-in server checkbox, and enter the port number 8888
.
Select Super Development Mode in the GWT tab, and add your GWT module under Available Modules.
Under the Arguments tab, there are two fields, Program arguments and VM arguments. In the Program arguments field, amend the server
flag as follows:
-server org.jboss.errai.cdi.server.gwt.EmbeddedWildFlyLauncher
Make sure the following VM arguments are set:
-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.
If you wish to automatically download and install WildFly as part of your build into the target/ directory of your web app, you will need to run mvn process-resources
prior to running or debugging your app. To do this, you can set up a Maven build configuration in Eclipse and specify Goals: "process-resources". You can then run the Maven configuration prior to running GWT’s 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.
If you wish to debug your client-side JavaScript as Java code from within Eclipse, you will need to use the SDBG plugin for GWT Super Dev Mode. More information can be found here.
The inbuilt GWT tooling for Intellij IDEA is only available in the Ultimate Edition. If you are using the Community Edition, you will not have access to the GWT plugin.
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:
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.
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:
-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.
-server org.jboss.errai.cdi.server.gwt.EmbeddedWildFlyLauncher
+
button under Before Launch and select the Make option. This will tell Intellij to compile your project before launching Dev Mode.If you wish to automatically download and install WildFly as part of your build into the target/ directory of your web app, you will need to run mvn process-resources
prior to running or debugging your app. To do this, you can add a Maven goal to the Before Launch task list. Click the +
button as before, select Run Maven Goal and in the Command Line field, enter "process-resources". Ensure that the working directory is the same as your project directory before clicking "OK". Intellij IDEA will then run the Maven goal prior to starting Super 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!
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.