Integrating GWT into AppFuse

I've been interested in integrating GWT into AppFuse ever since I blogged about it 4 years ago. A few months after that post, I wrote about Enhancing Evite.com with GWT and Grails. After Evite, I had a gig near Boston where I developed with GXT for the remainder of the year. When all was said and done, I ended up spending a year with GWT and really enjoyed my experience. I haven't used it much since.

GWT is scheduled to be integrated into AppFuse in version 4.0. That's quite a ways off. The good news is you might not have to wait that long, thanks to Iván García Sainz-Aja. Iván let us know about his work a couple weeks ago in an email to the appfuse-dev mailing list.

It's still work in progress but it has already most of AppFuse functionality..

If you want to give it a try

https://github.com/ivangsa/appfuse.git

the quickest way to have a go would be

web/gwt> mvn -P gwtDebug -Dgwt.inplace=true gwt:compile jetty:run  

at the moment it still requires this fork of gwt-bootstrap to be compiled first

https://github.com/ivangsa/gwt-bootstrap.git

It needs a lot of testing yet but it's getting quite there

As you can imagine, I was very excited to hear about Iván's work. So I cloned his repo, built gwt-bootstrap locally and checked it out. Functionality wise, it was great! However, when I dug into the source code, I found a whole lotta code.

To see how the GWT flavor compared to the other implementations in AppFuse, I created a cloc report on the various web frameworks in AppFuse. I'm sure these reports could be adjusted to be more accurate, but I believe they give a good general overview. I posted some graphs that displays my findings in visual form.

Lines of Java Number of Files

When I sent this to the mailing list, Ivan responded that it was a lot of code and estimated 12 new files would be needed to CRUD an entity. This sure seems like a lot to me, but he defended this yesterday and noted that his implementation follows many of GWT's latest best practices: MVP pattern, Activities and Places, EventBus, Gin and Guice. He also shared a wiki page with explanations and diagrams of how things work.

The reason I'm writing this post is to get more feedback on this implementation. First of all, does GWT really require this much code? Secondly, are there other GWT implementations that reduce a lot of the boilerplate? SmartGWT, Vaadin* and Errai come to mind.

If you were starting a new GWT project and using AppFuse, how would you want it implemented?

* Vaadin 7 claims it can be used as a drop-in replacement for GWT. I tried replacing the gwt-servlet and gwt-user dependencies with Vaadin's, but it didn't work.

Posted in Java at Mar 07 2013, 06:49:28 PM MST 7 Comments
Comments:

Well, there's several ways of looking at GWT. The way I like to look at GWT is something more akin to the JDK. It's ultimately a set of tools for compiling Java to JavaScript. The manner in which you go about that is up to you, the developer.

Some patterns in GWT are boilerplate heavy. Frameworks like Errai make GWT boilerplate light. There are arguments by some that the boilerplate of MVP is worth it in the end, because it leads to more maintainable code.

Errai straddles that line, in that, it doesn't prevent you from using the MVP approach (http://errai-blog.blogspot.com/2012/03/large-scale-application-development.html). But we think there is also a lot of value in the more agile approach that you can achieve with Errai UI, while still retaining most of the benefits of type safety and modularity.

A CRUD Errai app would most certainly require 12 new files. It would require the definition of an Entity, which could also server as the DTO if made @Portable (so that's one class that kills two birds) a Errai RPC or JAX-RS service to talk to (2 classes -- one interface, one implementation) and 1 application class on the client. So from zero to 1 CRUD scenario would be 4 classes. But a second CRUD entity, if it was a member of the same RPC or JAX-RS service would only bear the tax of defining an additional @Entity and any UI code to do something with it. So the second entity could be added with only one more class in Errai.

So these facts about GWT are sort of manifestly wrong in the sense they pigeonhole it by making the assumption that GWT is defined by the specific architectural approach you cite. It's clearly not.

Posted by Mike Brock on March 08, 2013 at 11:03 AM MST #

Correction to the above sentence.

Where I said: "A CRUD Errai app would most certainly require 12 new files." I meant to say: "A CRUD Errai app would most certainly NOT require 12 new files."

Posted by Mike Brock on March 08, 2013 at 01:00 PM MST #

I haven't done any more than look at the docs for SmartGWT and Vaadin so can't comment on them but if you're working on a project that is already using CDI or JSF perhaps with some JEE6 EJB components then you'll definitely want to take a close look at Errai since it brings a lot of CDI injection functionality into GWT. In fact, even if you're not using CDI you may want to use Errai if you're using any kind of Java code server side because their RPC functionality requires much less boilerplate than GWT RPC does...

My 2 cents.

Posted by Yeroc on March 08, 2013 at 01:57 PM MST #

I'm sure there is some plumbing code that can be reduced using something like GWTP, maybe Mvp4g, I don't know about Errai, but it may fit as well, I will look into it..

and for a large or medium size application I would certainly use one of those frameworks

and for sure there is also a lot of code that I would love to get generated from models (entity proxies, remote requests, view scaffold..), Spring Roo does that but I found it really hard to work with it if you move away just a little bit from its way

I may be wrong but if I choose raw GWT for the infraestructure code was because I tought that in this way GWT was at plain sight, I don't want to build a meta-framework on top of it hiding it from users

anyway if you are building a medium/large application there is a lot of infraestructure work you will be doing on top of appfuse, so you may also choose to add your favorite framework, that will be easier than remove it in the other case..

When I said that to CRUD on a new entity it would take about 12 new files I was talking about some remote interfaces and proxies + 4 files for each screen, master/detail: activity, view interface, view, uibinder template...

you can not certainly do CRUD on a new entity following the MVP pattern with just one file.

@Mike if you think I'm wrong please ilustrate how you can do CRUD on an entity with just one file

cheers all

Posted by ivangsa on March 08, 2013 at 03:15 PM MST #

Matt, I'm glad you actually noticed and questioned the amount of code required with the so called GWT MVP best practices. This blog on GWT MVP best practices comes to mind : http://blog.hivedevelopment.co.uk/2009/08/google-web-toolkit-gwt-mvp-example.html

Building a simple hello world like dialog that interacts with the server takes over a dozen classes and interfaces, and I see comments from readers impressed by the "clear explanation" while I have my head spinning wondering why it's even acceptable for simple functionality to blow up into so many classes and lines of code. I would never advocate use of such "pattern" overloaded practices that make simple things overly complex to accomplish.

As you know, I am a SmartGWT committer but can I confidently tell you that with SmartGWT, you can literally toss our 80% or more of the MVP code to accomplish the same functionality. Have a look at the source of this sample : http://www.smartclient.com/smartgwtee/showcase/#dmi

You would literally need two classes with minimal code - one for the client side (around 50 - 60 lines of "real" code), and a handler / DMI class on the server side that can delegate the CRUD class to your service API.

Posted by Sanjiv Jivan on March 08, 2013 at 06:54 PM MST #

12 files is a lot, but could be acceptable if it was really laying down a framework that made further CRUD screens easier to set up. The problem is, you get just as much scaffolding with every CRUD entity.

Consider the following scenario: you want to build a reusable component that represents a particular type of recurring screen in your application. You want to make this screen a component that can bind to bind to any entity.

In MVP this is, in essence, not achievable. At least not without adding extensions to the GWT compiler to do code generation, to try to manage the combinatoric explosion of code that would result. And I can't imagine using an architecture that doesn't easily handle this - after all it's not a problem in lots of other frameworks.

I'd love to see AppFuse support GWT, but I don't think using MVP is a good idea - it needs a ground-up redesign to be useful, so embracing it in its current form is just going to lead to rework later..

Posted by Aaron Asbery on March 12, 2013 at 11:42 AM MDT #

Hello.
In case of I am not too late: I use command pattern for GWT RPC:

http://gkislin.ru/sw/command.html

It considerably decrease number of files for client-server communication. It could be adopted for CRUD operation as well.

Posted by Grigory Kislin on December 02, 2013 at 12:55 PM MST #

Post a Comment:
  • HTML Syntax: Allowed