For someone who already has extensive experience in JSP/JEE and HTML/Javascript, GWT would take only half a day to understand. But it will take you two months to master.
Here is a recommendation of the combination of technologies with GWT that I believe would make your enterprise level apps successful. I think you should use GWT because of its debuggability. But debuggability comes at a price. GWT debugging requires at least a quad core 8GB machine. If you don't find this to be true, it's probably because you have found a way to make your GWT UI small and simple.
Eclipse is getting Hang while debugging GWT application
RequiresResize, ProvidesResize and Layouts
The first thing you need to master in GWT is the simple concept of layouts that are dictated by the interfaces RequiresResize, ProvidesResize. You need to ensure the chain of RequiresResize/ProvidesResize from the RootLayoutPanel down to the resizable widgets must be unbroken. And you need to master architectecting the flow of RequiresResize/ProvidesResize in your UI. Otherwise, when the browser is resized, you would see one or two odd hanging fruits that stick out unresizable.
I think writing scheduled resizers for every widget rather than depending on Google's RequiresResize/ProvidesResize should be avoided at all cost. Otherwise, remember to debounce the resize over a few iterations. Too much trial/error for me to perfect the resizing.
Async Async Async
The next concept you need to accept ... I did not say "you need to learn", but "you need to accept" is async behaviour of Javascript and hence of GWT Java. It does not matter if you used GWT or not. You have to get used to inversion of control given to the callee to control the success response of the caller.
You cannot write
List<Persons> persons = server.getData(personId);
You have to succumb to doing
server.getData(personId, new Callback<Persons>(){
@override public void onSuccess(Person person){ ..... }
@override public void onFailure(Exception ex){ ..... }
});
You cannot write
boolean doOrNot = ConfirmDialogBox();
You have to write
ConfirmDialogBox(new CloseHandler(){
public void onAccept(Person person){ ...}
public void onCancel(){ ... }
});
GWT is Java but not Java
I am amused by the constant existence of people who keep trying to use apache bytecode jars to compile with the GWT client, GWT client is Javascript written in Java.
Binary Data and GWT
GWT visual client
The best combination that I find is GWT 2.4.0 with Sencha gxt 2.2.5.
I avoid using the GXT-Uibinder project because I find that it places inconvenient restrictions on other combinations of 3rd party GWT frameworks. Particularly those frameworks that depend heavily on GWT.create() generator. GXT-Uibinder is a project outside of Sencha.
GXT 2.2 and below requires me to write wrappers to make it usable with uibinder, because of my refusal to use the kludgy GXT-uibinder project. Wrappers are necessary because of one silly misalignment. Any class used as a parent widget node in uibinder must implement GWT HasWidgets, which requires implementing a method returning iterator<Widget>
. Unfortunately, GXT 2.2-- already implements the iterator() method that returns the wrong genericized iterator.
GXT 3 solves that problem. I think GXT 3 incorporates GXT-uibinder but you don't have to use it. You do not have to write much wrapping with GXT 3 (without using GXT-uibinder) to use it with uibinder. But I find that GXT 3 still has some quirky misbehaviour and trying to solve those quirks is just not worth my time. So I stick with GXT 2.2.5 until GXT 3 stabilises.
I founded the google code project for wrapping SmartGWT (uibinding-smartgwt). SmartGWT is a very selfish fraemwork. My efforts often result in disaster if I try to mix it with GWT vanilla. It is due to some kinda of Z-indexing between the widgets of SmartClient and GWT.
If you decide to use SmartGWT due to licensing concerns, you have to makes sure you use only SmartGWT and not with any other Widget provider. Not even GWT vanilla. And you highly probably would need to use my uibinding-smartgwt project. I am trying to enhance it to use some newer uibinder features and redefine the non-visual elements not to be widgets, but my current use of GXT is simply too involved and thinking about the two frameworks at the same time confuses me. Because they behave differently.
Whereas GXT 3 seems to have made itself in complete alignment with GWT, SmartGWT has not demonstrated any effort to do so. Complete alignment between a 3rd party widget provider with GWT so that it implements GWT's interfaces smoothly is absolutely necessary to avoid wasting lots of time having to write kludges after kludges to solve some minor visual issues. Yes, especially the ProvidesResize/RequiresResize architecture.
Don't ever use GWT incubation. Try them and then try to make your project maintainable, sustainable and enhanceable. Let's not even go there.
Client-server communications
Do not use GWT-RPC. DO NOT. Except for the convenience of learning GWT.
RPC is good for simple apps whose role you have no intention of extending beyond the demo stage and barely usable stage. Programers who do not write distributed/sprawled out enterprise level apps probably would not agree with me.
Unit testing is very helpful in developing your app. Forget about all those unit testing framework first. Just being able to write a simple routine to test each little feature without involving the huge gigantic picture of the app is very crucial. I just want to test that camelization loop to make it work, for example. GWT-RPC is an extreme inconvenience towards making your formal/informal unit testing.
I am very attracted to using JAX-RS REST-RPC thro RestGWT on the GWT client side and RestEasy on the server side. I use JAX-B in conjunction with RestEasy's implementation of Jackson JSON processing. Instead of Resteasy, you could try using Jersey.
In this way, I could use FireFox REST client to test the server independent of GWT. In fact, after starting your project using GWT on the client-side, you could extend your app to use non-GWT clients like JQuery as clients to the REST services.
REST also makes it easy for you to write proxy/tunneling servers to let you overcome the SLD-SO-P ("2nd level domain, same origin" policy) security restrictions of browsers. Whereas, the data format of GWT-RPC is deliberately undecipherable and unstable (I don't understand the Google engineer's mentality behind how this increases security, since you could still see bits and pieces of human readable text), I have not attempted to write a proxy to tunnel GWT-RPC services. I don't know how viable it is.
http://h2g2java.blessedgeek.com/2011/11/gwt-with-jax-rs-aka-rpcrest-part-0.html.
BTW, script-include to overcome sld-sop is very bad idea. Don't even think about it.
Persistence
Hibernate JPA for non-GAE.
Eclipselink JPA for GAE with Google's MySQL
DataNucleus JPA for GAE with Google data store.
Initially, I bought into the idea of JDO. I tried so hard, and JDO keeps giving me conflicts. I gave up. Initially Google appeared to have been trying hard to persuade us that JDO is superior JPA. Whether it is true or not, I have failed to acquire skills to using JDO persistence so far. And since I have to program for non-GAE too, I don't want to contaminate my mind with the complexity of JDO.
The reason I mentioned this is because I tend to use the same JPA POJO with the JAX-RS POJO. Which means, I've found that JPA, JAX-RS, JAXB and Jackson annotation mix into the same POJO-DTO with no conflicts. I often have one set of POJOs (with some exceptions) shared between GWT client, JAX_RS server and JPA persistence. To achieve that, you have to have one restriction - all DTOs must be GWT-serializable. Not just serializable. Avoid writing dto converters as much as possible. Waste of time having three different sets of POJO-DTOs and then having converters between them.
MVP
I find that MVP4G a very easy to manage MVP framework. The following discussion demonstrates how I use MVP4G:
https://groups.google.com/forum/?fromgroups#!searchin/mvp4g/blessedgeek/mvp4g/T6r7egk-3Kk/Jz-dTqZDeMIJ
MVP is a very helpful pattern. Because it helps me separate "concerns". When you are able to separate concerns, you are able to test and solve issues individually. It also helps you enhance/extend your project with as little interference/entanglement as possible from other concerns/modules of your labyrinth of applications.
MVP4G also makes it easy to unit test, because you could simply mock a view or a presenter, or use a simplified eventbus/state-machine to debug only those parts you need to debug. And because of its modularity, you can easily avoid contamination of your non-test classes so that you could remove your test source trees without breaking your production classes. IOW, you don't have to modify your non-test classes to test them.