21
I Use This!
Activity Not Available

News

Posted about 13 years ago by [email protected] (Jonathan Fuerth)
There are already dozens of well-known serialization frameworks for Java, but Errai needs one that works with code that's been translated to JavaScript via the GWT compiler. For serialization frameworks, GWT presents special challenges: reflection ... [More] only goes as deep as class literals and Object.getClass(). No dynamic method calls; no dynamic field reads and writes; no dynamic creation of arbitrary types of objects.So we decided the best way forward for Errai was to build our own annotation-driven marshalling framework based on code generation. My favourite part about this is that we got to design it from the ground up to support immutable types.First, here's a basic mutable Bean that can be serialized and deserialized by Errai Marshalling:import java.util.Date;import org.jboss.errai.common.client.api.annotations.Portable;@Portablepublic class OrientationSensorReading {  private Date observationTime;  private double x;  private double y;  private double z;  public Date getObservationTime() { return observationTime; }  public void setObservationTime(Date observationTime) {    this.observationTime = observationTime;  }    public double getX() { return x; }  public void setX(double x) { this.x = x; }  public double getY() { return y; }  public void setY(double y) { this.y = y; }    public double getZ() { return z; }  public void setZ(double z) { this.z = z; }}Pretty easy, right? Just annotate it with @Portable, and OrientationSensorReading objects will be marshallable on both the client and the server. Notice that the java.util.Date instance didn't require any special treatment. In fact, all GWT-translatable types in the standard Java library (including Exceptions) are handled by Errai Marshalling out-of-the-box. Likewise, you can nest instances and collections of any Portable entity types you have declared in your project's codebase.But wait! This type is a natural candidate for immutability. Once we've taken a sample from an accelerometer, this reading should never change. Here's an immutable variant of the above that works with Errai Marshalling:import java.util.Date;import org.jboss.errai.common.client.api.annotations.Portable;import org.jboss.errai.marshalling.client.api.annotations.MapsTo;@Portablepublic final class OrientationSensorReading {  private final Date observationTime;  private final double x;  private final double y;  private final double z;  public OrientationSensorReading(      @MapsTo("observationTime") Date observationTime,      @MapsTo("x") double x,      @MapsTo("x") double y,      @MapsTo("x") double z) {    this.observationTime = new Date(observationTime.getTime());    this.x = x;    this.y = y;    this.z = z;  }  public Date getObservationTime() { return new Date(observationTime.getTime()); }  public double getX() { return x; }  public double getY() { return y; }  public double getZ() { return z; }}Note the @MapsTo annotations on the constructor arguments. These specify the names of the Bean properties the arguments map to. This is necessary because–unfortunately–the names of method and constructor parameters are not preserved in Java class files. I believe the advantage of having truly immutable objects where they make sense in your code will more than make up for this inconvenience.Errai marshalling also understands the factory method pattern recommended by Josh Bloch in Effective Java. This is also an Errai Marshalling compatible type:import java.util.Date;import org.jboss.errai.common.client.api.annotations.Portable;import org.jboss.errai.marshalling.client.api.annotations.MapsTo;@Portablepublic class OrientationSensorReading {  private final Date observationTime;  private final double x;  private final double y;  private final double z;  private OrientationSensorReading(      Date observationTime, double x, double y, double z) {    this.observationTime = new Date(observationTime.getTime());    this.x = x;    this.y = y;    this.z = z;  }  public static OrientationSensorReading newInstance(      @MapsTo("observationTime") Date observationTime,      @MapsTo("x") double x,      @MapsTo("x") double y,      @MapsTo("x") double z) {    return new OrientationSensorReading(observationTime, x, y, z);  }  public Date getObservationTime() { return new Date(observationTime.getTime()); }  public double getX() { return x; }  public double getY() { return y; }  public double getZ() { return z; }}In this case, because Errai Marshalling simply calls your static method when it needs a particular instance of a type, you can return whatever you want. For example, you can build in an instance cache and guarantee there are no duplicates floating around with the same values. Or you could obtain instances via GWT.create() and take advantage of code splitting in your marshallable types. This kind of flexibility is wonderful.But what about JAXB? Errai brings Java EE 6 to the browser, and JAXB is part of Java EE 6, right? Well, we would like to implement JAXB on the client eventually, but Errai Marshalling was much quicker to implement and it offers a more compact API that's well-suited to the immediate needs of Errai:JAXB is a much larger API than Errai Marshalling needs. Much of the complexity of JAXB lies in the ability to control the XML representation of the object graph. This is essential if you are mapping Java objects to a predefined XML schema, but a lot of dead weight if you aren't.JAXB does not support marshalling instances of immutable types; Errai Marshalling does.JAXB is primarily intended for XML; Errai Marshalling is primarily intended for JSON.Note also that Errai Marshalling and JAXB annotations can happily coexist. It's not an either/or choice. In most cases, it suffices to stick "@Portable" on an existing JAXB entity class, and you get the best of both worlds. [Less]
Posted about 13 years ago by [email protected] (Mike Brock)
Another new feature in Errai 2.0 is the addition of WebSockets support for the ErraiBus. It provides a transparent COMET-to-WebSockets session upgrade mechanism within the bus itself. This means, that no changes are required to your existing Errai ... [More] code to take advantage of WebSockets. When enabled, all bus traffic (CDI events, RPC, Bus Messages) will all be routed over the WebSocket channel.WebSocket support is still not very up-to-snuff in the world of Java Servlet containers and even web browsers. Therefore, our existing WebSocket support is technically considered experimental.But when it comes to the open source community, there's never any shortage of people willing to play. And we'd love it for you to give the feature a spin.The WebSocket server is a built-in feature of ErraiBus 2.0. Therefore all you really need to do, metaphorically speaking, is flip the switch to turn it on. You do this by adding the following line to your ErraiService.properties file:errai.bus.enable_web_socket_server=true Now startup your app, and use a compatible browser (like Chrome or Firefox) and connect to your app. Then, open up your JavaScript console and check to see that it actually worked:Hey, check it out! Errai opened a web socket. You can actually see more information about the connection state itself by executing the JavaScript function errai_status() from the console:You may notice something curious here, however: the WebSocket server is running on port 8085 not port 8080 with the rest of the appserver. This is simply because currently, due to lack of standardized support in Java Servlet containers (although there is an effort afoot to remedy this), we currently run the WebSocket server as a sideband server.This, of course, is not ideal and it's something that we at JBoss are working to address in an internal cross-project effort. I hope to be making some interesting announcements about that over the next year. But that's not the end of the world, of course. There are front-end proxy solutions which can be used to remedy this problem and munge the servicing of the WebSocket onto the same public-facing port -- the facilities of which are usually good practice for any application server environment in any case.Anyways, I'd love to hear back from the community on this.Mike, out. [Less]
Posted about 13 years ago by [email protected] (Mike Brock)
A serious problem that we've faced internally in making a framework like Errai work nicely is the sometimes unpredictability of the order in which client-side services initialize. Non-GWT client-side developers working with jQuery often run into a ... [More] similar problem. For a long time, we've had various mechanisms to manage this problem. Well, it's really the same mechanism spread across many components -- "post-init" callback events. It's a good pattern, works good and it's intuitive enough to work with. But with Errai 2.0, we've added a set of new features when working inside Errai IOC/CDI. We lovingly call them "Lifecycle Tools" in our new documentation for them, which you can find here.It's easy enough to register callbacks and wait to be called back to. But since Errai has heavy emphasis on dependency injection, this problem seemed ripe for a nice, clean, don't-call-us-we'll-call-you approach.So, when you have a client side bean -- and I use @Singleton here for maximum compatibility if you're not using CDI -- you can merely declare a startup dependency on your component by, well, injecting a startup dependency!@Singletonpublic class MyClientBean {  @Inject InitBallot<MyClientBean> ballot;  @PostConstruct  public void doVote() {    // do lots of initializy stuff.        ballot.voteForInit();  }} This code ensures that initialization of framework services will need to be delayed until it can do whatever work needs to be done. The parameterizing of the InitBallot is the way in which we categorize the dependency. You don't actually have to use the declaring classname. But the dependency must be unique. For instance InitBallot<Foo> will create a dependency on the class Foo. This is purely symbolic. But if the service fails to dial home with a voteForInit() call, in the bootstrap error message, it will be Foo that will be reported as the failed dependency. So keep that in mind.Doing Stuff After...There's of course the other obvious side to this coin. Which is wanting to do things only after you know all the framework services are initialized, happy, and doing their best Elvis dance. This job calls for our latest annotation, lovingly inspired by @PostConstruct, the wonderfully new and shiny @AfterInitialization annotation.This is about as straight-forward as it gets. You create a method in your bean, and you... annotate it! When all the crazy things Errai does to bootstrap are done (bus federation, rpc proxies loaded, marshallers ready), your method will get called! It works like, and basically has all the same restrictions as @PostConstruct and so you use it like so:@Singletonpublic class MyClientBean {  @AfterInitialization  public void doStuffAfterInit() {    // do lots of after-initialzy stuff!  }}... And there's all there is to it!The only downside is this feature is not in our 2.0.Beta1 release (Boo!). But it is in our latest 2.0-SNAPSHOT release, and will be in the 2.0.Beta2 release. So if you're daring you can use it now, or you can wait for Beta2 which is right around the corner.Mike, out. [Less]
Posted about 13 years ago by [email protected] (Jonathan Fuerth)
A Quick Tour of Errai 2.0The first beta of Errai 2.0, 2.0.Beta1, is now available! You can download the release in a zipfile, or–even simpler–use one of our archetypes to get started right away.In this post, I will walk you through all the bits and ... [More] pieces of the framework as it stands today, and I will wrap up with a peek at the future. But first, let's look at where and why we started this project, and what motivated us to take it where it is today.The PastErrai started with the vision that, as browsers become more and more capable computing platforms, the complexity of codebases we write for the browser will grow. Although the ECMAScript language has matured significantly over the years in terms of features, uniform behaviour across browsers, and speed of execution, it still remains true to its roots as a scripting language: loosely typed, little support for encapsulation, poor support for immutable types, and no direct linguistic support for namespaces. Perhaps most importantly, ECMAScript is a slippery target for refactoring and navigation tools.The idea behind the Errai Framework is that we (Java developers) have already learned how to develop large code bases, managing their complexity with an array of tools and practices that are simply not available to us in other environments:Completely safe refactorings such as rename, move, extract to method, and moreTypesafe code completion with popup API documentationThe ability to create truly immutable objectsTest-driven development using JUnitIDEs that highlight dead code, unused methods, and unsafe castsStatic analysis with FindBugs, CheckStyle, and PMDAdvanced step-by-step debugging toolsErrai's vision is that we can and should apply these advantages to the increasingly intricate codebases we write for the client side of today's modern web applications.The PresentWith Errai 2.0, we're taking a big step toward the realization of Errai's vision: to provide a uniform, familiar, and well-tooled programming model across client and server. Yes, Errai 1.x provided a uniform programming model across client and server, providing its own publish/subscribe bus API and its own RPC API. Those APIs remain in place, but we now think of them as lower-level enablers. With Errai 2.0, we've begun implementing Java EE 6 APIs on top of the base APIs in Errai 2.0. So far, we support CDI in the client, as well as a JAX-RS client API.High-level APIs in Errai 2.0CDI in the BrowserWith CDI in the browser, not only can you @Inject dependencies into your beans, but you can also @Observe events that occur both locally (on the client) as well as remotely (on the server.) Naturally, the inverse is true: events fired on the client are observable on the server. To be clear, all of the following are possible:Client-local communication (fire and observe events within the browser)Server-local communication (this is just traditional CDI eventing)Server-to-client communication (Errai pushes server events to the client)Client-to-server communication (Errai pushes events from the client to the server)Underlying this feature is the good old Errai Bus, which will ensure that events are only routed across the wire if there are actually observers interested in that event on the other end of the connection. No HTTP traffic for local events.Here's what it looks like:Server Side@ApplicationScopedpublic class TickerService {  @Inject  private Event<Tick> tickEvent;  private void sendTick() {    tickEvent.fire(new Tick());  }} Client Side@EntryPointpublic class TickerClient {  public void tickHappened(@Observes Tick tick) {    // update the UI with the new data  }}To dig in further, use the Errai-CDI quickstart archetype to generate a project you can play with.JAX-RS ClientNew in Errai 2.0 is the JAX-RS client. This is a true JAX-RS client framework. It does not route messages over the Errai Bus; it makes direct AJAX (XMLHTTPRequest) calls to the JAX-RS resource methods on the server side. Of course, all the object marshalling is taken care of on both sides, just like with bus messaging.Sticking with the theme of "familiar," you simply implement your server-side resources with standard JAX-RS annotations, and on the client, you use exactly the same code as you would use for Errai RPC calls. A great new feature with no new APIs!Here's a taste:Server Side@Path("customers")public interface CustomerService {  @GET  @Produces("application/json")  public List<Customer> listAllCustomers();}public class CustomerServiceImpl implements CustomerService {  @Override  public List<Customer> listAllCustomers() {    List<Customer> customers = CustomerDAO.getAll();    Collections.sort(customers);    return customers;  }}Client Side@EntryPointpublic class CustomerClient {  @Inject  private Caller<CustomerService> customerService;  private void populateCustomersTable() {    RemoteCallback<List<Customer>> listCallback =          new RemoteCallback<List<Customer>>() {      public void callback(List<Customer> customers) {        addCustomersToTable(customers);      }    };    customerService.call(listCallback).listAllCustomers();  }}To dig in further, use the Errai JAX-RS archetype to generate a project.Errai RPCErrai RPC remains an important high-level API in Errai 2.0. And since it's identical to the JAX-RS client API at the call site, you are free to switch between Errai Bus and RESTful communication simply be re-annotating your server-side code. The client remains untouched. Here's how it looks (notice that the client code is identical to the JAX-RS example):Server Side@Remotepublic interface CustomerService {  public List<Customer> listAllCustomers();}@ApplicationScoped@Servicepublic class CustomerServiceImpl implements CustomerService {  @Override  public List<Customer> listAllCustomers() {    List<Customer> customers = CustomerDAO.getAll();    Collections.sort(customers);    return customers;  }}Client Side@EntryPointpublic class CustomerClient {  @Inject  private Caller<CustomerService> customerService;  private void populateCustomersTable() {    RemoteCallback<List<Customer>> listCallback =          new RemoteCallback<List<Customer>>() {      public void callback(List<Customer> customers) {        addCustomersToTable(customers);      }    };    customerService.call(listCallback).listAllCustomers();  }}And like Errai CDI, client and server code are interchangeable. You could swap these client and server code snippets, or put both on the client, or both on the server, and they would sill be able to communicate with each other.To try Errai RPC yourself, clone our Errai Kitchen Sink quickstart (note this quickstart also uses JPA, JAX-RS, CDI, and Bean Validation, and it's only set up to work in JBoss AS 7 at the moment.)Lower-level APIs in Errai 2.0Errai Bus and MessageBuilderIf you're familiar with Errai from the 1.x days, you'll already be familiar with the Errai Bus. The bus remains central to the workings of  most Errai high-level features, including CDI remote eventing and Errai RPC (JAX-RS is the exception; it's independent of the bus.)Using the low-level Errai Bus API, you can send messages on a particular subject and register/deregister callbacks that receive messages on a particular subject. Naturally, the API for doing this on the client or the server is the same.MessageBuilder is a fluent API for constructing (and optionally transmitting) Errai Bus messages. Although we're now leading with the higher-level APIs, MessageBuilder remains available as a convenient way to construct Errai Bus messages "by hand." Of course, the above-mentioned high-level communication features are actually using the MessageBuilder API on your behalf.Server Side@Servicepublic class HelloWorldService implements MessageCallback {  public void callback(Message message) {    MessageBuilder.createConversation(message)      .subjectProvided()      .withValue("Hello, World! The server's time is now " + new Date() + ".")      .done().reply();  }}Client Side@EntryPointpublic class HelloWorldClient extends VerticalPanel {  @Inject  private MessageBus bus;  void sendMessage() {    MessageBuilder.createMessage()        .toSubject("HelloWorldService")        .withValue("Hello, There!")        .done()        .repliesTo(new MessageCallback() {          public void callback(Message message) {            responseLabel.setText(                message.get(String.class, MessageParts.Value));          }        })        .sendNowWith(bus);  }}To play with a working project that uses MessageBuilder, just use the Errai Bus quickstart archetype.Enabling TechnologiesErrai-codegenBecause we use the GWT compiler to bring all this great stuff to the browser, and because GWT eschews runtime reflection in favour of up-front code generation, most Errai features are centred around generating Java source code to feed into GWT at compile time. Because we're such believers in the value of static type checking, we felt compelled to do something a little more structured than just spitting strings into a file and hoping that the result was a well-formed Java source file. Enter Errai's code generator.Errai-codegen is a fluent API for generating Java source code. It provides static type checking and variable scope checking as it goes, and its promise to you is that it will not allow the creation of a class that can't compile. It also does a really nice job of formatting its output.Do you generate Java code in any of your projects? Feel free to try out our code generator and let us know what you think. We'd love to hear from you!Server Side (typically runs at compile time)Context ctx = Context.create();String s = StatementBuilder            .create()            .declareVariable("n", Integer.class, "10")            .generate(ctx);assertEquals("Integer n = 10;", s);VariableReference n = ctx.getVariable("n");assertEquals("n", n.getName());assertEquals(MetaClassFactory.get(Integer.class), n.getType());assertEquals(LiteralFactory.getLiteral(10), n.getValue());Errai MarshallingEvery object sent across the Errai Bus, as well as the JSON representations sent and received by your JAX-RS resources, is represented as a JSON object. Errai provides a robust marshalling framework that aims to provide maximum flexibility while imposing minimum markup on your code.Errai's Marshalling framework includes all of the following techniques, which you can mix and match as you like, based on where you place your annotations:Private/default/protected/public field read & writeSetter and Getter property accessProvide all properties to the constructor - my favourite because it allows for marshalling properly immutable typesOut-of-the-box support for marshalling all JDK classes that are GWT translatableCustom marshallers for those really hard-to-reach classes :)Errai IoCAlthough Errai supports dependency injection via CDI, CDI remains an optional module for now. If you choose not to use it, you can still use @Inject annotations to obtain references to Errai-provided dependencies such as Sender<?> and Caller<?>. And of course, this works the same in client code and server code.The FutureOf course, we have our eyes on the horizon beyond Errai 2.0. The theme of our longer-term plans is to continue providing Java EE 6 functionality within the client, while providing a practical framework to keep your app running offline, when the server is unavailable.JPA with SyncFor starters, you probably already have JPA annotations on your model objects. We plan to breathe life into them on the client side. Errai's JPA module will allow you to store and query your model objects locally on the client for speedy access and for storage and retrieval when the web server can't be contacted. We also plan to add features that will make data synchronization as painless as possible when the server does come back.Shadow ServicesSpeaking of offline, I've already mentioned a couple of times that Errai Bus can deliver messages locally as well as remotely. When the server goes away, the local bus remains fully operational in the webpage. This means you can already create services within the client, and the calling code doesn't look any different: the bus itself makes the routing decisions.We plan to take full advantage of this behaviour by having the client-side bus automatically deliver messages to local "shadow" services when the remote ones are unavailable. Combined with client-side JPA, we hope this will make for a really slick programming model for webapps that keep on tickin' when the server is unreachable.JBoss ForgeWe love Forge, and we can't wait to start using it to build Errai projects. Forge's existing JPA scaffolding will already help you quite a bit with an Errai app, but we can extend that further to make the necessary objects marshallable, and maybe even generate some UiBinder templates. Exciting times ahead!And maybe you have some ideas! What other parts of the EE 6 suite of APIs do you wish you could use in client-side code? What tooling would make this even better? Come to our discussion forum and let's talk! [Less]
Posted about 13 years ago by [email protected] (Mike Brock)
If you're in Bangalore in India or Brno in Czech Republic over the next few weeks, you have an opportunity to see Errai getting talked up by myself (Mike Brock) and Christian Sadilek.I'll be giving two talks at JUDCon India on January 24th. And if ... [More] you come out for that, we've got a full schedule of other cool things for you to check out while you're there. See the JUDCon website for details and schedules.On February 17th, Christian Sadilek will be giving a talk at the Fedora Developer Conference in Brno. Check out the details here. [Less]
Posted about 13 years ago by [email protected] (Mike Brock)
Over the past few months the Errai team has been busy at work preparing the next version of the Errai Framework, Errai 2.0.It is a significant update that leverages all the best ideas that Errai 1.x had, while retiring some ideas and approaches that ... [More] didn’t quite work out the way we’d planned. Errai has developed a philosophy about rich application development in the browser. That philosophy might be summed up as: Your Application. Everywhere. Literally. However, there’s been some people who’ve criticized this methodology. I’d like to respond to some of this now.We have eschewed much of the conventional wisdom about how you should architect a web application by focusing on not just rich user experience, but rich developer experience. We believe that the latter ultimately leads to a better former. We reject the need for polyglot applications as necessary -- the idea that the best way to build an application is to arrange a constellation of disparate languages and frameworks into a coherent single application is simply the “best approach” is something we don’t agree with.You’re building your application in Java on the server. Why do you build the other part of it in JavaScript? The common response to this is, well, “that’s just the best way to do it”. But is it? We don’t think it is. At the end of the day, the whole HTML5 group of technologies is just a specification that tells us how to make a browser do things.Whether we write HTML and JavaScript directly or not, whether it’s translated from CoffeeScript, Dart, or in the case of Errai -- Java -- is immaterial. And it’s wrong to even suggest that Errai, with its use of the GWT compiler, sandboxes you into a world that proscribes any of these things. It doesn’t. With Errai, your application can contain no JavaScript, or be almost all JavaScript. The important part is how Errai helps you share not just model between the client and the server, but functionality. Without the need to write it twice, or write marshalling code, or worry about setting up your own comet or websockets. The communication model is central to the application development model.Being able to share functionality, using the same code, with the same functionality is a good thing. You get all the benefits of type checking, code reuse, and productivity.The implication that some make that, this sort of thing “hides the true nature of the web” is always one that puzzled me among those who advocate for a pure JavaScript approach. I’ve always been of the opinion that such essentialist notions of pretty much anything are probably notions you should be suspicious of. I mean, the Java compiler hides bytecode. The C++ and C that the JVM is written in hides machine code. It goes without saying that JavaScript itself is hiding all of this. Moreover, JavaScript isn’t a terribly good language for large applications. And it surprises me that some of the very same people who trumpet the advantages of Java over other languages, will so willingly jettison their arguments in favor Java when it comes to JavaScript. There’s no immutability, side effects are hard to control, the object model is a mess, there’s nothing resembling a threading model, etc. To which, counterarguments often include techniques about how JavaScript prototypes can be used in ways that simulate classes and inheritance, unit testing can guard against unintended side effects in large codebase, concurrency concerns do not apply in the world of the future, etc -- as if any of this somehow redeems JavaScript in any way in the eyes of someone who buys into these notions as being intrinsically good parts of a language. JavaScript isn’t a bad language. Don’t get me wrong. It is mature and well understood. It does what its supposed to do. But the problem is, it was never designed with large application development in mind. Its designers did not envision a world where there’d be codebases of 100,000 lines of JavaScript code. Yet, this is the world we’re quickly moving into. And the reality is, that technologies like GWT are extremely good solutions to manage these sorts of projects. Over the next few weeks we’re going to show you why. Watch this space. [Less]
Posted over 13 years ago by [email protected] (Jonathan Fuerth)
Since joining the Errai team, I've been telling lots of people about our project. Every time I do this, I find myself dispelling some common misconceptions about what GWT is and how it can be used. I also find people are surprised that GWT code has ... [More] easy access to the browser's native environment: although GWT smooths out implementation details between browsers, it is not a firewall that cuts you off from the underlying environment.So what is GWT?GWT, the Google Web Toolkit, is a project with many independent parts. Here's a partial list:A Java-to-JavaScript compilerA class library providing:a subset of the Java SE 5 standard library (most notably java.lang and java.util)A programmatic UI framework (somewhat like Swing)Java wrappers for native browser functionality such as JSON and XML manipulation, XMLHttpRequest (AJAX and Comet), and HTML 5 features like Canvas, Local storage, Audio and Video.An RPC mechanism you can use if your application's backend happens to be written in Java (GWT RPC can't easily be retrofitted on an existing object model, but you can use it to build a server-side RPC layer)GWT Designer, a visual UI layout tool that generates code for the Swing-like UI frameworkUiBinder, a system for declarative UI (you define layout in files that are essentially XHTML interspersed with GWT widgets, with named elements automatically bound to fields in a companion Java class)Plugins for Eclipse, Maven, and Ant that help with creating, building, testing, and debugging GWT applicationsThe compiler itself is fundamental to any usage of GWT. Everything that follows is optional: you can take it or leave it, mix and match, use third-party alternatives, or invent your own replacements.And what isn't GWT?Now that we've listed off the highlights of what is included in GWT, it's important to address what it's not:GWT doesn't mandate a single, prescribed way of creating user interfaces. In particular, you don't have to create UIs in a "Swing for the browser" mindset unless you want to.GWT is not a server-centric system like JSF. Your GWT application compiles down to a collection of static files: HTML, CSS, images, and JavaScript. The application runs autonomously in the browser, communicating with the server only when it wants to. If you're not using GWT RPC, your apps need not be hosted on a Java web server.GWT does not require any browser plugins. Your compiled app is just one or more standards-based web pages.GWT does not prevent you from writing JavaScript directly. You can write inline JavaScript in your Java classes using JSNI, you can expose your Java APIs to JavaScript, and you can call JavaScript APIs from Java.GWT is not a dead project. Rumours of its demise are greatly exaggerated. If my GWT app just boils down to JavaScript and HTML, why bother with all this?That's a great question. Thanks for asking. There are many compelling reasons to use GWT over raw HTML and JavaScript. I will address my favourite reasons in a future post, along with another question that I hope is burning in your mind: if GWT does all this, what does Errai add to the mix? [Less]
Posted over 13 years ago by [email protected] (Christian Sadilek)
The Errai team is proud to announce the release of 1.3.0.GA. This is the final 1.3.0 release and includes improvements and fixes based on community feedback. We would like to thank the Errai community for raising questions, suggesting improvements ... [More] and reporting problems. Please stay tuned, there's a lot more to come in the near future.Furthermore, Mike Brock's hard work and epic late-night battle with the Maven Release Plugin (which he demonstrably won) deserves a big thank you from the rest of the Errai team (Jonathan Fuerth and myself). [Less]
Posted over 13 years ago by [email protected] (Christian Sadilek)
The JAX-RS integration module is our latest extension to the Errai Framework. It brings another enterprise standard to the browser and simplifies the integration of REST-based services in GWT client applications.How does it work?To jump right in ... [More] , let's assume we have the following JAX-RS interface which we want our clients to send requests to:@Path("customers")public interface CustomerService {  @GET  @Produces("application/json")  public List<Customer> listAllCustomers();  @POST  @Consumes("application/json")  @Produces("text/plain")  public long createCustomer(Customer customer);  @PUT  @Path("/{id}")  @Consumes("application/json")  @Produces("application/json")  public Customer updateCustomer(@PathParam("id") long id, Customer customer);  @DELETE  @Path("/{id}")  public void deleteCustomer(@PathParam("id") long id);  @GET  @Path("/{id}")  @Produces("application/json")  public Customer retrieveCustomerById(@PathParam("id") long id);}We simply put this interface somewhere in our client packages (e.g. client.shared) where the GWT compiler can find it. To create a request all that needs to be done is to invoke RestClient.create(), thereby providing the JAX-RS interface, a response callback and to invoke the corresponding interface method.@EntryPointpublic class App {...  final RemoteCallback<Long> callback = new RemoteCallback<Long>() {    public void callback(Long id) {      Window.alert("Customer created with ID: " + id);    }  };  @PostConstruct  public void init() {    final Button create = new Button("Create", new ClickHandler() {      public void onClick(ClickEvent clickEvent) {        Customer customer = new Customer(firstName, lastName, postalCode);        RestClient.create(CustomerService.class, callback).createCustomer(customer);      }    });...  }}Error HandlingFor handling errors, the existing error callback mechanism can be reused and the error callback can be passed to the RestClient.create() call. The ResponseException provides access to the Response object containing all details of the underlying HTTP response.final ErrorCallback errorCallback = new ErrorCallback() {  public boolean error(Message message, 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;  }};What does this buy you?Errai will take care of generating the HTTP request logic for you and will automatically serialize/deserialize your method parameters. This helps alleviating boilerplate code for creating the URL, setting the HTTP headers, parsing the response, etc. By default, Errai's wire format will be used, but don't be dissuaded by that fact. Errai's wire format really is just simple JSON.Future workWe are currently improving Errai's marshalling capabilities. One outcome of this will be a mechanism for pluggable custom serializers. So in the near future you will have the flexibility to choose your serialization format.Interested and want to give it a try?We have prepared a maven archetype, which generates a working JAX-RS CRUD application: https://docs.jboss.org/author/display/ERRAI/JAX-RS+Quickstart+GuideThis should help getting you started quickly.As always, feedback is welcome and appreciated! [Less]
Posted over 13 years ago by [email protected] (Mike Brock)
On behalf of the Errai team and the rest of Red Hat, and JBoss, I would like to extend my warm welcome to Jonathan Fuerth who joins the team, right here in Toronto.Jonathan has an extensive background in software engineering, and has been actively ... [More] involved in open source Java development for years, as well as being a community builder here in the Toronto area as a co-organizer of the Toronto Java User's Group.Expect to here more from Jonathan in the coming weeks and months, right here in this space. [Less]