GWT or not for enterprise apps

2019-03-11 13:18发布

问题:

I am working on an tool to create enterprise level applications on app-engine. This needs to be cross browser (also including IE8), works on mobile, and at a later point of time also supports desktop clients through (Qt4/GTK/etc)

The problem that I consistently face is this: For my web-application - should I use GWT(GoogleWebToolkit) or not?

I am pretty good at using "EXT-JS", but its not a choice due to its open-source policy. There is another framework "SmartClient" which has a better opensource license- Its pretty mature and better than EXT-JS (based on some POCs), but its documentation sucks! It takes me a lot of time to get something done in a right way. SmartClient and EXT-JS are pretty good for enterprise level applications (when used correctly) - I have experienced this with Ext-JS and very much sure on SmartClient too.

Then there is this combination "JQuery and addons and HTML5". I love the faster, cleaner and smaller JS compared to the above libs. I am skeptical about HTML5 since thats an evolving standard

What I really like about GWT is its performance benefits. Atleast the examples seem to work great. What I dislike about it is Java and I am pretty good at javascript For my server-side-application at app-engine I am not using Java -but Python. so rpc would be based on json only. We do not have a mobile-version on the plate yet, but thats again a very much needed version later and we may use Sencha-touch for that later.

I have done POCs for all of these and GWT deployments feel fast and smooth compared to extjs or smartclient. And there is a lot of stuff that GWT does for me automatically. Also I love the "clean-html" rendered by gwt. I am pretty good at using javascript too and very well aware of the "mistakes" that happen there that lead to the javascript hell.

(I am not looking forward to ExtGWT or SmartGWT)

Any suggestions on whether I should switch to GWT or is it a good thing for enterprise level applications?

Or if somebody has experienced building large apps using GWT, what were the cons (and pros)?

回答1:

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.



回答2:

Questions like should I use X or Y depends always on your experience with these tools and the requirements. The best tool/framework is worth nothing if you do not know how to use it and if you have no other requirements than "I want to build an app", I would suggest to use the tool you feel best with.

The pros and cons of GWT are explaind quite often. I think its not neccessary to be repetitive.

Greetings, Peter



回答3:

I use mostly pure GWT for my projects.
However you have to invest some time in creating custom widgets and style them for your needs.

In addition to the suggestions you already got, you could also check out Vaadin and Jboss Errai.

I really like Errai's UI templates which you can view in this screencast.

Vaading provides an appealing widget set and also is going to use GWT as a core in version 7.
Both (JBoss and Vaadin) are in the steering committee for future GWT developments.