Errai: The browser as a platform

Wednesday, December 19, 2012

Errai 2.2.0.CR2

Thanks for all the feedback on Errai 2.2.0.CR1. Over the past few weeks, we fixed all the reported issues, and now Errai 2.2.0.CR2 is ready for your consideration.

Please try this latest release candidate as soon as possible, and let us know what you think through any of the usual channels! We expect to make the final release of 2.2.0 in January.

For an overview of the major changes since Errai 2.1, see the earlier post about 2.2.0.CR1.

Friday, November 30, 2012

Get ready for Errai 2.2

Today marks the first candidate release for Errai 2.2.0. With this release, we're delivering dozens of fixes and enhancements. If we had to choose the three most important changes, they would be: the new client-side Bus Lifecycle API, addition of state parameters to the Page Navigation framework, and the ability to nest bindable properties.

While you're reading this, why not kick off a compile of your existing Errai project against the new release?

Do it now! It only takes a couple of minutes to switch the version number in your pom.xml to 2.2.0.CR1. If you're not using Maven, grab the release bits from our download page.

Seriously! We'll wait right here for you!

Client-side Bus Lifecycle

We've had questions over the years about how to find out exactly what the client-side message bus is up to: is it connected to the server? Is it attempting to reconnect? Has it given up and gone offline? Although there were ways to infer some of this information in the past, we decided it was time to make all of this information available in one place, and to make some guarantees about the order that these state transitions will happen in.

The best way to dive into the new bus lifecycle API would be to check out the BusStatusWidget that we added to the bus-stress-test demo, but here's a quick teaser:

class BusStatusLogger implements BusLifecycleListener {

  @Override
  public void busAssociating(BusLifecycleEvent e) {
    GWT.log("Errai Bus trying to connect...");
  }

  @Override
  public void busOnline(BusLifecycleEvent e) {
    GWT.log("Errai Bus connected!");
  }

  @Override
  public void busOffline(BusLifecycleEvent e) {
    GWT.log("Errai Bus trying to connect...");
  }

  @Override
  public void busDisassociating(BusLifecycleEvent e) {
    GWT.log("Errai Bus going into local-only mode.");
  }
}

To attach such a listener to the bus, just do the following in client-side code:

ClientMessageBus bus = (ClientMessageBus) ErraiBus.get();
bus.addLifecycleListener(new BusStatusLogger());


Nested Bindable Properties

We got good feedback about the data binding module that we added in Errai 2.1, which lets you bind properties from your model objects to GWT widgets (actually, to anything that implements HasValue). As a refresher, imagine you have an Item class with name and department properties, and a Department class with a name property of its own:

@Bindable
public class Item {

  private String name;
  private Department department;

  public String getName() { return name; }
  public void setName(String name) { this.name = name; }

  public Department getDepartment() { return department}
  public void setDepartment(Department department) { this.department = department; }
}

@Bindable
public class Department {

  private String name;

  public String getName() { return name; }
  public void setName(String name) { this.name = name; }
}

Then you can link the value of item.name to a TextBox like this (this annotation-driven approach is provided by Errai UI):

@Templated("#main")
public class ItemWidget extends Composite {
  @Inject private @AutoBound DataBinder<Item> itemBinder;
  @Inject private @Bound @DataField TextBox name;
}

This is great, but what about the department name? We want a TextBox for that too! It became apparent pretty quickly that this feature would be way better if you could dig into the object graph and bind to nested properties, the data binding feature would cover a lot more use cases. Now you can:

@Templated
public class ItemWidget extends Composite {
  @Inject private @AutoBound DataBinder<Item> itemBinder;
  @Inject private @Bound @DataField TextBox name;
  @Inject private @Bound(property="department.name") @DataField TextBox department;
}

That's it! The name of the Department object nested inside item will be kept in sync with the contents of the department textbox.

State Parameters in Page Navigation

The last big enhancement we want to call out is the addition of extra parameters to the page navigation framework. Following from the previous example, say your ItemWidget is also a @Page:

@Templated @Page("item")
public class ItemWidget extends Composite {

  @Inject private @AutoBound DataBinder<Item> itemBinder;
  @Inject private @Bound @DataField TextBox name;
  @Inject private @Bound(property="department.name"@DataField TextBox department;

}


That's great: you can bookmark that you were at http://myapp.mycompany.com/#item. But which item were you looking at? That's important!

Now you can do this:

@Templated @Page("item")
public class ItemWidget extends Composite {

  @Inject private @AutoBound DataBinder<Item> itemBinder;
  @Inject private @Bound @DataField TextBox name;
  @Inject private @Bound(property="department.name"@DataField TextBox department;

  @PageState private int itemId;

  @PageShowing
  private void setupItem() {
    itemBinder.setModel(findItem(itemId));
  }

}

And presto! Your bookmarkable URL is now http://myapp.mycompany.com/#item;itemId=42.

We hope to enhance the navigation framework even more in Errai 3.0. Your input has been invaluable so far. Keep it coming!



On top of the three headliners, 2.2.0 CR1 includes 17 bug fixes and 10 enhancements/features across virtually every part of the framework. See the release notes for full details.

Once again, I urge you to try your project against Errai 2.2.0.CR1 today! We truly believe this is the best and most stable release to date, so you have nothing to lose. And in the unlikely event that you do find a new issue, you'll be able to tell us before 2.2.0 goes final.

Happy coding,
The Errai Team

Friday, November 16, 2012

The Future is Asynchronous!

For the last month or so, I've been hiding in a cave working on a big, upcoming feature in Errai 3.0. Which may sound crazy considering that we have yet to release 2.2 yet. But that's how I roll.

Well, it's more that this is a big feature, and we've feature-frozen Errai 2.2 on its path to productization as part of JBoss's WFK product, of which Errai will be a featured framework next year. So, big new features are bound for 3.0.

So what is this new feature? It is nothing other than the new asynchronous bean manager for Errai IOC/CDI! If you follow me on Twitter (@JBossMike) or on Google+, then you might have stumbled upon the highs and lows of my gargantuan effort to implement this.

First the big questions: what is asynchronous bean management, and why do we need it?

Asynchronous bean management may be an unfortunate term. Perhaps a more accurate name would be asynchronously-loading bean management. But I don't like how that sounds, so... the former it is!

The basic idea behind asynchronous bean management is the idea that the loading, construction and dependency-injectimification (yes, I made that word up) are done asynchronously. Obviously. But what does that mean?

It means that bean loading happens in parallel to your application logic -- the reason why this is desirable will be answered in the 'why' part.

In practice, you make a request to the bean manager for the instance of a bean, it goes and gets the bean (if it's already in existence) or it makes a new instance and gives it to you. But the way it gives the bean to you is through a callback mechanism.

Let's take a look at this in practice:
That's a bit different than what one might be use to if you've used the old bean manager API, where you would instead do this:

The asynchronous version is quite a bit more code!

The difference is, with the asynchronous lookup, the anonymous class we defined -- CreationalCallback  -- is used to receive the bean once its been created by the bean manager. When this happens, the callback() method is called, passing an instance of the bean. You then do something with that bean. In this case, we call it's show() method which, displays the popup widget.

You could imagine this sort of thing getting really out of hand. But really, most direct calls to the bean manager in your app are probably quite rare, and probably something you may already be abstracting away behind say, an Activity and Places pattern -- in which case, this extra code overhead is negligible.

But here's the real question: why?

The answer is: code-splitting!

One of the really cool features of GWT is its ability to partition your code behind runAsync() calls. This means, that as your app grows, you may find that the upfront loading time becomes undesirably long; wouldn't it be nice if the actual code needed was downloaded on-demand, based on the parts of the application which the user is actually using? Well, that's what GWT's code-splitting does!

The problem with synchronous bean loading, is it short-circuits your ability to use GWT's code-splitting effectively if your app is built completely around CDI. This is because Errai emits synchronously executing bootstrapping code to wire you application.

The asynchronous bean manager instead makes all the mechanics of the bean manager internally and externally (as shown above) based completely on a callback pattern. Meaning, quite simply, any aspect of bean management can now be contained in a GWT runAsync() callback. Yay!

Taking our example above as a scenario to contemplate: it may be that we have indicated that the class Popup is a bean we'd like to code-split. Errai 3.0 will allow you to do this by annotating that bean with the @LoadAsync annotation. This means, that all of the code of Popup -- assuming it does not have code paths to and from parts of your app that are needed in the initial application download --  can be segmented into a separate JavaScript payload. So, when we make our asynchronous lookup of this bean for the first time, we are able to download the JavaScript code, create the bean, and pass the loaded bean to you when it's ready!

You might decide, for the size of you app, that you don't need this functionality. Which is fine. We will be retaining both implementations of the bean manager -- the old one is not being deprecated. The caveat is only this: your app will be required to use one or the other. You cannot mix synchronous and asynchronous bean management within a single Errai app. Trust me: it's not possible or practical.

In closing, this is just one of the new amazing features coming in 3.0 which will allow you to take maximum advantage of GWT's performance-optimizing capabilities when using Errai.

I'm hoping to have something people can play with in the coming days. Stay tuned!

Friday, September 28, 2012

Errai 2.1.0.Final

After a flurry of great feedback on our CR2 release, the Errai Team is proud to announce the release of Errai 2.1.0.Final.

Errai 2.1 includes better Dev Mode reload support along with lots of stability enhancements over 2.0.x. Also we've introduced a number of exciting new features, all of which are explored with code examples in our recent post announcing CR2.

We'll be at JavaOne next week. If you're there too, drop us a note and we can meet up and chat about Errai!

Until next time,
The Errai Team

Wednesday, September 19, 2012

The future of GWT: What say you?

Are you looking to have your voice heard on the future direction of GWT as it moves beyond the 2.5 release?

The guys over at Vaadin have collaborated with other members of the GWT Steering Committee to build a survey in order to poll the GWT community, how they use GWT, what they use with GWT, and most importantly, what do they want from future GWT releases?

We think this is a very useful exercise to help us determine priorities moving forward. 

If you have a few minutes of time, please go check out this post over at the Vaadin blog and fill out the survey. 

Tuesday, September 18, 2012

Errai 2.1 is On The Way

Throughout our summertime communications blackout (sorry about that), the Errai team has been working overtime to further polish and stabilize all the great features in Errai 2.0 while also introducing a bunch of brand new features. This article outlines all the major changes between Errai 2.0 and Errai 2.1.

If you are new to Errai, the quickest way to get started is via the archetypes described in our Getting Started guide.


New in 2.1

We're calling these new features in 2.1 "preview" because we want a chance to incorporate your feedback before we lock down the APIs in 3.0. We crave your input: share your use cases, feature requests, and of course pull requests.


Client-Side JPA


Errai 2.1 adds JPA2 to our Java-EE-6-in-the-client lineup. Errai JPA implements a subset of JPA 2.0, allowing familiar JPA code to do double-duty on the client and the server. For example, the following familiar-looking JPA entity can be persisted the in the browser's local storage:


@NamedQueries ({
  @NamedQuery(name="allAlbums",
              query="SELECT a FROM Album a ORDER BY a.releaseDate, a.artist"),
  @NamedQuery(name="albumByName",
              query="SELECT a FROM Album a WHERE a.name LIKE :name")
})
@Entity
public class Album {

  @GeneratedValue
  @Id
  private Long id;

  private String name;

  @ManyToOne(cascade={CascadeType.PERSIST, CascadeType.MERGE})
  private Artist artist;

  private Date releaseDate;

  private Format format;

  public Long getId() { return id; }
  public void setId(Long id) { this.id = id; }

  ...

  @Override
  public String toString() {
    return "Album [id=" + id + ", name=" + name
            + ", artist=" + (artist == null ? "null" : artist.getName())
            + ", format=" + format
            + ", releaseDate=" + releaseDate + "]";
  }
}

Of course, this code does the same thing on the client as it would on the server:

@Inject EntityManager em;

public void createExampleAlbum() {
  Artist samNDave = new Artist();
  samNDave.setName("Sam & Dave");
  samNDave.addGenre(new Genre("Rock"));
  samNDave.addGenre(new Genre("Soul"));
  samNDave.addGenre(new Genre("R&B"));

  Album album = new Album();
  album.setArtist(samNDave);
  album.setFormat(Format.LP);
  album.setName("Hold On, I'm Comin'");
  album.setReleaseDate(new Date(-121114800000L));
  em.persist(album);
  em.flush();
}

public List<Album> fetchAlbums(String nameContains) {
  TypedQuery<Album> query = em.createNamedQuery("albumByName", Album.class);
  query.setParameter("name", "%" + nameContains + "%");
  return query.getResultList();
}

Get your hands dirty by playing with the demo, which you can find on GitHub.


ErraiUI Templates


As we clarified previously, GWT offers a wide array of choices when it comes to implementing your user interface. You can opt for declarative XML-based layout with UIBinder, programmatic layout with GWT panels and widgets, or even mash up GWT with something else like jQuery.

In Errai 2.1, we're adding a new option to the mix: Errai UI. Errai UI gives you declarative layout through templates that are valid HTML 5 documents, paired with Java classes that imbue behaviour into them. Of course, you get compile-time checks to make sure everything lines up properly. We want to help you avoid unpleasant surprises at runtime!

Here's an Errai UI template:


<!DOCTYPE html>
<div>
  <label for=itemName>Name:</label>
  <input id=itemName type=text data-field=name>
  <br>
  <label for=itemDept>Department:</label>
  <input id=itemDept type=text data-field=department>
  <br>
  <label for=itemComments>Notes:</label>
  <input id=itemComments type=text data-field=comment>
  <br>
  <button class=btn data-field=saveButton>Save</button>
</div>

The only special bits are the data-field attributes. These line up with field names in the companion Java class, like this:

@Templated
public class ItemForm extends Composite {

  @Inject @DataField private TextBox name;
  @Inject @DataField private TextBox comment;
  @Inject @DataField private TextBox department;
  @Inject @DataField private Button saveButton;

  public void grabKeyboardFocus() {
    name.setFocus(true);
  }

  @EventHandler("saveButton")
  public void onSaveButtonClicked(ClickEvent event) {
    // this method will be called for each click event on saveButton
  }
}

Each @DataField field is matched up with the corresponding element in the template, and a reference to it is injected. If you prefer, you can also declare fields as raw DOM element types rather than GWT widgets (for example, the name field could have been an InputElement rather than a TextBox). And you're not limited to just the standard DOM elements plus the widgets that come with GWT. You can inject your own widget types, even (especially?) other ErraiUI @Templated ones.

To handle events, simply annotate a method with @EventHandler("DataFieldName"). The method should take an argument of the event type you want to receive. Errai UI will ensure the source node sinks the appropriate events, and it will deliver them to your method each time they happen.

To learn more, check out the ErraiUI demo, and also read through Errai UI's reference guide.

But wait! There's more!

There are two more new Errai modules that go great with Errai UI: data binding and navigation.


Model-View Data Binding


Errai Data Binding is a great complement to Errai UI, but it's also just as handy in conjunction with other approaches to UI that you may already be using in your GWT and Errai apps.

Errai Data Binding lets you bind property values in your model objects to widgets in your UI.

To make a model object amenable to having its properties bound, annotate it with @Bindable:

@Bindable
public class Employee {

  private int id;
  private String name;
  private Integer age;
  private boolean active;

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

  public Integer getAge() { return age; }
  public void setAge(Integer age) { this.age = age; }

  public boolean isActive() { return active; }
  public void setActive(boolean active) { this.active = active; }
}

Then to establish data bindings to UI widgets, use the fluent configuration API:

public class EmployeeForm {
  private final TextBox nameTextBox = new TextBox();
  private final TextBox ageTextBox = new TextBox();
  private final CheckBox activeCheckBox = new CheckBox();

  private Employee employee;

  @PostConstruct
  public void init() {
    employee = DataBinder.forType(Employee.class)
      .bind(nameTextBox, "name")
      .bind(ageTextBox, "age")
      .bind(activeCheckBox, "active")
      .getModel();
  }
}

The model instance that comes back from the getModel() call is now automatically kept in sync with the bound UI fields.

Declarative Data Binding

When Errai Data Binding is used together with Errai UI templates, you can skip the fluent API and simply declare "auto-bindings." Going back to the ItemForm example:

  ...
  @Inject @AutoBound private DataBinder<Item> itemBinder;

  @Inject @Bound @DataField private TextBox name;
  @Inject @Bound @DataField private TextBox comment;
  ...

By injecting an @AutoBound DataBinder and adding the @Bound annotations on the widgets, we get a declarative approach to data binding. With the above code snippet in place, it will always be true that itemBinder.getModel().getName().equals(name.getText()).

Errai data binding also allows custom converters, wrapping existing model objects, and more. See the reference guide for all the juicy details!


"Multi-Page" Navigation


The third new UI-related feature in 2.1 is Errai Navigation. Errai Navigation adds a decentralized, declarative configuration mechanism to GWT's built-in History facility. This allows back-button and forward-button navigation, plus bookmarkable locations within your app. And since the configuration is declarative, it even produces navigation flow graphs like this at compile time:


The navigation system simply manages the contents of a panel (a div element in the DOM): based on what comes after the # in the location bar, the contents of that div change. Typically, in your app's entry point, you would add that panel to a large, central region of the document. Headers, footers, and sidebars can remain outside of this div, which allows them to stay in place when the user navigates between pages.

As an example, if you want the URL http://example/my-app/host-page.html#FunPage to cause the page body to contain an instance of your FunPage widget, you would do the following:

@Page
public class FunPage extends Widget {
  // whatever Widgety things you want to do
}

Pages are CDI beans, and the navigation obtains instances from the client-side bean manager when needed. So the above implicit-scoped bean would be newly instantiated each time the browser's URL bar changes to http://example/my-app/host-page.html#FunPage. If you'd prefer one instance of FunPage to hang around for the life of the app (simply appearing and disappearing based on the current URL fragment,) just annotate it with @ApplicationScoped.

But what good are pages without links between them? To make links between pages, inject TransitionTo instances like so:

@Page
public class FunPage extends Widget {

  @Inject TransitionTo<UltraFunPage> upgradeLink;
  @Inject TransitionTo<WelcomePage> quitLink;
  @Inject TransitionTo<SillyPage> sillinessEnsues;

  public void onQuitButtonClick(ClickEvent e) {
    quitLink.go();
  }

  // whatever Widgety things you want to do
}

To follow a link, simply call go() on the link in question.

These links make up the arrows in the navigation graph that's produced at compile time. The type parameter controls the widget (CDI bean) type that provides the page contents, and the field names are the label text on the arrows.

Of course it goes without saying that Errai Navigation goes great with Errai UI templates: a @Templated widget can also be a @Page.


Improved Since 2.0


That was a lot of new API, but we didn't stop there. We've also made a bunch of incremental improvements to the existing APIs from 2.0 and earlier.


Client-side Remote Call Interceptors (JAX-RS and RPC)


Sometimes you need a chance to tweak a request just before it's sent to the server. For example, maybe you need to add special authentication headers to certain REST requests. Or maybe you want to short-circuit requests when you already have locally-cached data. Previously, you would have had to give up on the typesafe Errai JAX-RS Caller<T> interface for those requests, and fall back to RequestBuilder.

Well, starting in Errai 2.1, you can intercept, inspect, modify, and even cancel any Errai JAX-RS and Errai RPC request. See the documentation for the details and example code.


GWT 2.5 Compatibility


Errai 2.1 still defaults to GWT 2.4, but we've tested it with the release candidates of GWT 2.5, and we're committed to compatibility. You're free to choose whichever you're most comfortable with.

In Errai 3.0, we do plan to bump up the minimum requirement to GWT 2.5, so get testing!


Code-and-Refresh: Better Than Ever


Code-and-refresh support (Dev Mode) is crucial to a pleasant GWT development experience. We're pleased to say that Errai's code-and-refresh support for CDI is now better than ever. You can make almost any change–even structural changes–to your client-side code, refresh in the browser, and see the results right away.

Additionally, the dynamic (server-side) marshalling system in Errai 2.1 is now run through the same set of tests as the statically-compiled marshallers. This means you can stick to dynamic marshalling at development time, with two big advantages: firstly, it makes dev mode setup simpler (especially when using an external web server); secondly, it behaves well in conjunction with server-side hot reload products such as JRebel.


Errai Marshalling: Now Compatible with Jackson


Speaking of Marshalling enhancements, Errai 2.1 now offers compatibility with the popular Jackson Java-JSON marshalling package. Via the use of a converter, Errai JAX-RS clients can produce requests in a Jackson-compatible format, and can also understand and properly demarshal Jackson payloads in the response. The major use case is that you can now call many pre-existing JAX-RS resource methods from an Errai JAX-RS client. Another possibility is to use Jackson compatibility mode in a new Errai JAX-RS app in order to provide simpler JSON payloads to non-Errai clients. There are a few weaknesses compared with Errai's fully-typed native JSON format, but you can do pretty much everything in Errai's Jackson compatibility mode that you can do with plain Jackson.

The user guide has a section that details how to enable Jackson compatibility mode in the REST client.


Try it

Now that 2.1.0.RC2 is out in the wild, I hope you will take the time to test your Errai app with it. We hope to go final soon, so get those bug reports and pull requests in before it's too late!

And if you're new to Errai, the quickest way from-zero-to-Errai is our Getting Started guide.

Happy hacking!

Thursday, September 13, 2012

Team Errai on Tour

After an intense summer of coding on Errai 2.1, the whole Errai team will be on tour this fall presenting the latest and greatest in rich web development. We'll be covering our greatest hits and some exciting new material: Errai JPA, Errai UI, data binding, page navigation and more!

Here are the tour dates:

Toronto: Sep. 18 at 7pm 
Mike Brock, Christian Sadilek and Jonathan Fuerth will be at the Toronto Google Developer Group meetup. Find all details here.

Montreal: Sep. 25 at 5:30pm
Jonathan and Christian will present Errai at the Montreal Java User Group.

San Francisco: JavaOne (Sep. 30 - Oct. 4)
  • Oct. 2 at 11am: Christian and Jonathan will present "CDI in the browser. Wait? What!" at the JBoss mini theatre on the trade show floor.
  • Oct. 3 at 11am: Lincoln Baxter will make all your wildest dreams come true with HTML5 and Errai UI at the JBoss mini theatre.
  • Oct. 3 at 2pm: Jonathan and Christian will present "In-Browser Storage and JAX-RS Clients: Typesafe Edition" at the JBoss mini theatre.
  • Oct. 4 at 12:30pm: Christian and Jonathan will present Errai in this full JavaOne conference session.

Nice: Oct. 12 at 6pm
Mike Brock at the Riviera JUG! Yes, he will come all the way across the pond for just one day! Make sure to meet him there. More details here.

We hope to meet many of you at these events!