Errai: The browser as a platform

Tuesday, October 19, 2010

Community Asylum Podcast

This time we got Heiko and Pete talking with us about JUDCon Berlin and Heiko's work on the Errai project.

As usual we also cover short news from the JBoss Community, but if you've wondered what Errai actually is and what it brings to the table then take a listen from about 30 minutes in, Heiko outlines it all in this episode.

Get it here

Saturday, October 16, 2010

Slides from JUDCon Berlin

"Errai offers a set of components for building rich web applications using The Google Web Toolkit. The framework provides a unified federation and RPC infrastructure with true, uniform, asynchronous messaging across the client and server.

It extends the Google Web Toolkit in two distinct areas:

- True asynchronous bi-directional communication between GWT clients and backend systems
- Integration with enterprise component models and technologies.


In this session we'll look at CDI integration module. It offers seamless integration of CDI backend components with GWT client applications. Build as an extension to the Errai core framework, it allows you to transparently access CDI beans while harnessing the power of the core framework.

Beans that are deployed to a CDI container (i.e. JBoss 6) will automatically be registered with Errai and exposed to your GWT client application. Communication between GWT client components and CDI beans can be done in several ways:

- RPC style invocations on beans through a typed interface
- Access beans in a publish/subscribe manner
- Wiring up your GWT application with the CDI event subsystem


After this session you should have a good idea about the core framework capabilities and CDI integration in particular."


Thursday, September 23, 2010

Errai at JUDCon Berlin, October 2010

We'll be presenting Errai at the JBoss Developer Conference in Berlin next month.
Besides the core framework features we'll take a particular look at the CDI integration capabilities.
Bring your laptops, because we'll wait for you at the hackfest Thursday night.

More information here

Thursday, August 19, 2010

Enjoy the benefits of the Java EE 6 component model using GWT as an alternative view layer technology.


 

The CDI integration module offers seamless integration of CDI backend components with GWT client applications. Build as an extension to the Errai core framework, it allows you to transparently access CDI beans while harnessing the power of the core framework.

Beans that are deployed to a CDI container (i.e. JBoss 6) will automatically be registered with Errai and exposed to your GWT client application. Communication between GWT client components and CDI beans can be done in several ways:
  • RPC style invocations on beans through a typed interface
  • Access beans in a publish/subscribe manner
  • Wiring up your GWT application with the CDI event subsystem
RPC Style Invocations
When chosing RPC style invocations on beans, you basically rely on a typed java interface the CDI managed bean needs to expose. A GWT client component can then create an invocation proxy based on this interface. For more information see chapter on RPC mechanism.

Publish/Subscribe with CDI managed components
If you chose publish/subscribe then your CDI bean needs to implement the MessageCallback interface, as described in chapter 'Messaging'. Any bean exposed in this way can be accessed through the MessageBuilder API.

Integration with the CDI event subsystem
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 qualifier. 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 GWT clients can produce events that are consumed by a server side component.

Let's take a look at an example GWT component:

public class FraudClient extends LayoutPanel {

@Inject
public Event event; (1)

private HTML responsePanel;

public FraudClient() {
super(new BoxLayout(BoxLayout.Orientation.VERTICAL));

Button button = new Button("Create activity", new ClickHandler() {
public void onClick(ClickEvent clickEvent) {
event.fire(new AccountActivity());
}
});

responsePanel = new HTML();

add(button);
add(responsePanel);
}


public void processFraud(@Observes Fraud fraudEvent) { (2)
responsePanel.setText("Fraud detected: " + fraudEvent.getTimestamp());
}
}
Two things are notable in this example:
  1. Injection of an event dispatcher proxy
  2. Creation of an Oberserver method for a particular event type
Event dispatcher proxy
The event dispatcher is responsible to send 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 Observer registered for it on the server side.

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

To complete this exercise, let's look at the corresponding CDI managed bean as well:

@ApplicationScoped
public class AccountService {
@Inject @Any
Event event;

public void watchActivity(@Observes @Inbound AccountActivity activity) {
Fraud payload = new Fraud(System.currentTimeMillis());
event.fire(new Outbound(payload));
}
}

Whetting your appetite? Here are some links to get you going:

"Fueling the rocket" - Approaching 1.1-Final







Ready for lift-off? The 1.1 Candidate Release has been released today. We got plenty of goodies baked into this one:

  • Serialization
    Plenty of bugfixes and performance improvements.
    Up to 40% performance gain and a much better memory footprint.

  • Deployment
    Complete replacement for the meta data facilities and deployment hooks. This a fixes a lot of problems with nested deployment artifacts (i.e. WAR inside EAR)

  • Monitoring
    Improvement activity monitoring tools. Added capabilities to query for certain message types/payload patterns.

  • CDI Integration
    Seamless integration of CDI backend components with GWT client applications.

  • And much more ...
    Check the Userguide for a complete reference of new features.


Download it now.
Browse the Userguide.
Get the sources.

Have fun,
the Errai Team





Image from "Fortress on a Skyhook" written and illustrated by Frank Tinsley, Mechanix Illustrated April, 1949

Monday, July 19, 2010

Dependency Injection in the Browser!

One of the things that will be coming in Errai 1.1 is our new IOC module which provides a dependency injection framework, based on JSR-330 in the browser. Now, this is not just Gin packaged with Errai. Rather, it's an implementation which has been built specifically to intermix with Errai's code generation infrastructure and provide a boiler-plate free experience.

When we release 1.1, gone will be the days of having to access the bus or the dispatchers through static factories. Rather, your client-side code will look even more like your server-side code.

Check out our new HelloWorld example built atop our new DIfoundations.

@EntryPoint @Service
public class HelloWorld extends VerticalPanel implements MessageCallback
{
    private Button sayHello;
    private Label label;

    private MessageBus bus;

    @Inject
    public HelloWorld(MessageBus bus) {
        this.bus = bus;
    }

    public void callback(Message message) {
        label.setText(SimpleMessage.get(message));
    }

    @PostConstruct
    public void init() {
        sayHello = new Button("Say Hello!");

        /**
         * Register click handler.
         */

        sayHello.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                MessageBuilder.createMessage()
                        .toSubject("HelloWorldService")
                        .with(MessageParts.ReplyTo, "HelloWorld")
                        .done().sendNowWith(bus);
            }
        });

        label = new Label();

        add(sayHello);
        add(label);

        RootPanel.get().add(this);
    }
}


Notice use of the @EntryPoint annotation. When you use @EntryPoint you don't need to implement your own GWT EntryPoint class, we build that for you.

You're probably already wondering if you can provide your own arbitrary providers to inject custom services, widgets and other components. And the answer is yes. We've provided a simple Provider interface that you can annotate to be discovered by the container at compile time to provide an injectable dependency. In fact both MessageBus and RequestDispatcher plug-in using this mechanism. Here's the provider for MessageBus:

@Provider
@Singleton
public class MessageBusProvider implements TypeProvider<MessageBus> {
    public MessageBus provide() {
        return ErraiBus.get();
    }
}


Pretty cool, huh? Doing more sophisticated things requires tying into the code generator which is used to generate the wiring code, and there will be documentation on how to do that. But the code generation interfaces will be surprisingly easy to use if you want to do anything particularly advanced, such as provide custom annotations for the container to process during the bootstrap process.

This is just one of the many cool features coming to Errai 1.1. Stay tuned for more!

Sunday, May 30, 2010

GWT, CDI and Errai at Jazoon

If you happen to be at Jazoon this year and you are interested in GWT, CDI and Errai then these sessions may be interesting to you:

Patterns and Best Practices for building large GWT applications
Tuesday, 1 June 2010, 14:00-14:50, Arena 3

In this presentation we’ll see how to organize a nontrivial GWT application. We’ll go through the lessons learned in a real world project and take a look the complete development lifecycle and best practices that go beyond what GWT has to offer out-of-the-box. This talk does focus on modularity of GWT applications and how to overcome the burdens of compile-time linking. We’ll talk about client side patterns and server side implementation options and explore different approaches that allow for quick turn around times without sacrificing maintainability.

GWT, CDI and JAX-RS: A match made in heaven
Tuesday, 1 June 2010, 15:00-15:50, Arena 3

Every non-trivial GWT application requires integration with the server side. While GWT itself ships with the integration capabilities (i.e GWT RPC) it doesn't go beyond that. Developers have to decide how to build the backend to their GWT applications. While freedom of choice is a good thing, it doesn’t always lead to a good decision. In this session we’ll look at two options, JSR-299 [1] and JSR-311 [2], both part of the EE6 specification and see how they interplay with GWT. We'll discuss the use cases and justifications for each technology see how they are applied in practice by looking at some code examples.

[1] JSR-299: Java Contexts and Dependency Injection for the Java EE platform (CDI) is the new Java standard for dependency injection and contextual lifecycle management.

[2] JSR-311: A that specification defines a set of Java APIs for the development of Web services built according to the Representational State Transfer[1] (REST) architectural style.



The complete schedule can be found here.

Wednesday, May 12, 2010

Hello, 1.1 Milestone 1!

Today, we’re pleased to announce our first step towards version 1.1, which sets us solidly on a course with 1.1 destiny.

This milestone release is a big step towards honing the concepts that we introduced in 1.0, driving someone them towards their logical conclusions, and smoothing out the rough edges. Community feedback was important to us, and we’ve worked diligently to respond to it.

This release brings a range of new features, including (but not limited to):

* Support for more servlet containers.
* New Async Task API
* A new bus monitor to make troubleshooting easier
* A new RPC API, that leverages the bus architecture, and provides an alternative to GWT-RPC.
* Better error handling.
* Better documentation.
* Bug fixes galore!

We think you should take a look. And we hope you have as much fun using it as we did building it.

Remember, Errai is always looking for community contributions. So if you’re interested in becoming a contributor, drop us a line. Download it before it gets cold.

Wednesday, May 5, 2010

Best Practices

Fellow JBoss core developer, and lead engineer for JBoss's security initiatives, Anil Saldhana took a deep dive into Errai in recent weeks, and he's documented some best practices here.

He offers some valuable advice worth checking out.

Sunday, April 25, 2010

Introducing new asynchronous task APIs

One of the things that we've come to realize while developing Errai is that when you work with a framework such as Errai, where push messaging is basically free, easy and awesome -- you end up wanting to do things like stream live data across the wire. Stuff like stock quotes, news feeds, twitter feeds, clocks, weather patterns, and the migration activity of pigeons.

A lot of our demos have involved creating threads and pushing data across completely asynchronously. And it's always messy code. You need to worry about managing those threads, making sure they die when the session dies, or when the subject is unsubscribed, etc. Having to worry about all this creates security problems, resource management issues, and it makes your code messy.

Well, worry no longer! The latest commit into trunk introduces a new comprehensive (and simple) way of creating asynchronously running tasks -- as part of the the standard MessageBuilder API.

Take our TimeDisplay demo, where we stream a bunch of updates from the server to the client containing System.currentTimeMillis() results.

Up until now, the demo consisted of a thread that looped around and around and built new messages to send. Through the addition of a new API extensions, this demo is greatly simplified.

The first addition is some helper classes that help you create managed contexts to store stuff in the session. One is called SessionContext, and the other is called LocalContext. SessionContext allows you to create session scoped attributes, and LocalContext lets you create locally-scoped, as in, page-scoped. So if a user has multiple browser windows open, or multiple tabs, each window or tab is it's own LocalContext. This is a pretty powerful little tool.

The second addition is the implementation of what I'm calling provided message parts. Unlike regular message parts, these parts are resolved via providers at the time of transmission. This is a key aspect of what we're about to show below, as it creates message re-usability.

The third addition is the implementation of a repeating and delayed message transmission calls as part of the standard messaging API.

Let's take a look at the example:


AsyncTask task = MessageBuilder.createConversation(message)
    .toSubject("TimeChannel").signalling()
    .withProvided(TimeServerParts.TimeString, new <>ResourceProvider() {
        public String get() {
            return String.valueOf(System.currentTimeMillis());
        }
    }).noErrorHandling().replyRepeating(TimeUnit.MILLISECONDS, 100);



In this example, we create a conversational message which replies not just once, but replies continuously. Once every 100 milliseconds as it would turn out. The replyRepeating() and replyDelayed(), sendRepeating() and sendDelayed() methods all return an instance of AsyncTask, which is a handle on the task being performed. You can use this object to cancel the task.

Doing so is pretty easy.

    task.cancel(true)

Knowing all this, which isn't very much -- and that's the cool part -- let's put it all together:


@Service("TimeServer")
@RequireAuthentication
public class TimeDisplay implements MessageCallback {
    private MessageBus bus;

    @Inject
    public TimeDisplay(MessageBus bus) {
        this.bus = bus;
    }

    public void callback(final Message message) {
        if (message.getCommandType() == null) return;

        /**
         * Create a local context to store state that is unique to this client instance. (not session wide).
         */

        final LocalContext context = LocalContext.get(message);

        /**
         * Switch on the TimeServerCommand type provided
         */

        switch (TimeServerCommands.valueOf(message.getCommandType())) {
            case Start:
                /**
                 * We want to start streaming.
                 */

                AsyncTask task = MessageBuilder.createConversation(message)
                        .toSubject("TimeChannel").signalling()
                        .withProvided(TimeServerParts.TimeString, new <>ResourceProvider() {
                            public String get() {
                                return String.valueOf(System.currentTimeMillis());
                            }
                        }).noErrorHandling().replyRepeating(TimeUnit.MILLISECONDS, 100);

                /**
                 * Store the task as an attribute uniquely identified by it's class type.
                 */

                context.setAttribute(AsyncTask.class, task);

                /**
                 * Create a listener that will kill the task gracefully if the subject is unsubscribed.  This
                 * isn't 100% necessary, as the task will be auto-killed ungracefully.  But this provides
                 * and opportunity to clean up after ourselves.
                 */

                bus.addUnsubscribeListener(new UnsubscribeListener() {
                    public void onUnsubscribe(SubscriptionEvent event) {
                        if ("TimeChannel".equals(event.getSubject())) {
                            /**
                             * Delete this listener after this execution.
                             */

                            event.setDisposeListener(true);

                            /**
                             * Stop the task from running.
                             */

                            context.getAttribute(AsyncTask.class).cancel(true);

                            /**
                             * Destroy the local context.  Sort of unnecessary, but helps reduce memory usage.
                             */

                            context.destroy();
                        }
                    }
                });
                break;

            case Stop:
                /**
                 * Access our stored AsyncTask from this instance and cancel it.
                 */

                context.getAttribute(AsyncTask.class).cancel(true);

                /**
                 * Destroy the local context.  Sort of unnecessary, but helps reduce memory usage.
                 */

                context.destroy();
                break;
        }
    }
}



That's all there is to it. It's pretty sweet. This API works on both the client and the server side. All the thread scheduling is all transparently managed by an executor service on the server, and by a simple Timer based implementation in the client. I'm hoping people will find this a welcome addition to Errai-land.

There will be more details coming as I iron out the bugs. This code is all new, so proceed at your own risk and all that stuff.

Tuesday, April 20, 2010

Monday, March 29, 2010

Visual Bus Monitor


For the past few weeks, I've been focusing on seeing how we can improve the development / debugging experience with ErraiBus. The biggest component of this, is our new Swing-based ErraiBus Monitor application.

It's really straight-forward to get up and running.

You simply add it as a runtime dependency, and bootstrap GWT Development Mode with the -Derrai.tools.bus_monitor_attach=true VM flag, and this magical UI should automatically appear as ErraiBus bootstraps.

When the monitor is activated, it attaches probes in into the bus and records all activity accordingly. You can drill down into individual services and examine individual messages that have been received to debug any mysterious problems that arise.

There will be more details to come as I firm up the tool, but I thought I'd share my progress with the community since Heiko says I don't blog enough :)

Friday, March 5, 2010

Errai-Seam integration: Student projects

The seam team is offering a range of student projects related that aim at improving the integration with Errai. I.e:

"Errai is a new project from JBoss.org, aiming to ease building GWT applications. Errai provides a bus which is used to communicate either from client to client or client to server. To build an Errai based application, you are likely to want to communicate with services on the server. CDI's services (and the integrations it offers with Java EE technologies as well as it's extension ecosystem) should be available for use here. A particular challenge here is to provide a mapping between the type safe injection facilities of CDI in pure Java code, and the compiled Java to Javascript that GWT produces."

More information can be found here

Tuesday, March 2, 2010

Errai 1.0!

I am pleased to announce our 1.0 Release of the Errai Framework. It rounds out the first stepping stone in our journey towards building a truly innovative way to build next-generation web applications.

I would like to thank the entire team for their hard work on this: Heiko Braun, Lillian Angel, Rodney Russ, and myself for contributing to getting us to this goal.

We'd especially like to thank our early adopters who helped us work out the kinks, report bugs, and make us aware of what the community needs.

Some of the important highlights and milestone of this release include:

- Async IO support in ErraiBus for Apache Tomcat, JBoss AS, and Jetty. As well as standard synchronous IO support for all servlet containers.
- Easy to use homogeneous programming model that permeates both the server and client.
- Initial public release of our Workspaces RAD console/app framework.

Version 1.1, which will be released in the coming weeks will add support for Glassfish, WebLogic and WebSphere.

We encourage anybody interested in contributing to contact us on our mailing lists. For more information on Errai, check our main project website here: http://www.jboss.org/errai

Friday, February 19, 2010

Mission Control: Prepare for landing

I am glad to announce that we've begun preparing the 1.0 release of Errai:
http://anonsvn.jboss.org/repos/errai/branches/errai-1.0.x/


(Image courtesey of
CBSNEWS)

We will add another round of QA during the next week and polish our documentation. If you are an early adopter, this would be a good time to tell us what problems you experience. So make sure to file your bugs and let us now through the mailing list.

Wednesday, February 17, 2010

Errai at the JUG Toronto @ 18.0.2010

Mike Brock will be presenting Errai at the Toronto Java User's Group on Thursday, February 18th at the Free Time Cafe (320 College St, Toronto). Details here.

Errai at the Java User Group Zurich, Switzerland

Heiko will be talking about Errai in Zurich at the 2.3.2010:

Patterns and Best Practices for building large GWT applications

In this presentation weʼll see how to organize a nontrivial GWT application. Weʼll go through the lessons learned in a real world project and take a look the complete development lifecycle and best practices that go beyond what GWT has to offer out-of-the-box. This talk does focus on modularity of GWT applications and how to overcome the burdens of compile-time linking. Weʼll talk about client side patterns and server side implementation options and explore different approaches that allow for quick turn around times without sacrificing maintainability.

Travel details can be found here:
http://www.jugs.ch/html/events.html