Geertjan is a DZone Zone Leader and has posted 468 posts at DZone. You can read more from them at their website. View Full User Profile

Web Frameworks: Comfort vs. Expediency?

05.08.2008
| 7812 views |
  • submit to reddit
Two nights ago I had a conversation with Craig McLanahan, among others, in a slightly dubious sports bar near the JavaOne conference site. When the subject of web frameworks came up, an interesting, and probably obvious, angle emerged.

For those who don't know (which, in this case, suggests you're not actually a web framework developer), Craig is the creator and thinker behind several frameworks, such as Struts and Shale. The discussion turned to "web frameworks out there", where Craig's argument turned on the usefulness of pre-packaged components in the real world. JSF components, together with the various extensions to JSF, would on this basis be much preferred to anything where the developer needs to do any kind of coding. To really drive this point home, let's look at integrating Google map into a web application. Google map, which is really the ultimate AJAX widget, can be introduced as simply as follows, via the RichFaces framework, which extends JSF:

<rich:panel header="Google Demo">
<rich:gmap />
</rich:panel>

That's all. We can then add a slider that will zoom in/out, by adding another component, as shown below:

<rich:panel header="Google Demo">
<rich:gmap />
<rich:inputNumberSlider width="400"
id="zoom" showInput="false" minValue="1"
maxValue="18" onchange="map.setZoom(this.value)"/>
</rich:panel>

Simpler is hard to imagine. On the other hand, you have little control over the component, while simultaneously not feeling very comfortable as a Java developer. Tag libraries and JSPs are poison to many programmers. Both GWT and Wicket offer a much more comfortable environment, since you're coding directly in Java. Here, for example, is how one might go about it in Wicket:

final GMap gMap = new GMap(new GLatLng(0d, 0d), 1);
gMap.setTypeControl(true);
gMap.setOverviewMapControl(true);
gMap.setLargeMapControl(true);
GLatLngBounds bounds = new GLatLngBounds(new GLatLng(-90, -180),
new GLatLng(90, 180));
gMap.setBounds(bounds);
// Create panel to hold the GMap:
gMapPanel = new GMapPanel("gmap", gMap, 440, 450, "yourSiteKey"));
GMapListener listener = new GMapListener() {
public void onClick(AjaxRequestTarget target, GMap arg1) {
// User has ended a map move, need to update map,
// but clear all the markers first:
gMap.getOverlays().clear();
gMap.addOverlay(new GMarker(new GLatLng(0,0),
new Label("info","heey thats my marker")));
}};
gMapPanel.setDragEndListener(listener);
}

The above code is from this document, which may be slightly aged. Whatever the case, the above would be more or less how a GMap panel would be defined in Wicket. Next, you would add that GMap definition to a component, such as a Wicket panel, via code such as the below...

add(gMapPanel);

...and then add a Wicket tag to the matching HTML file:

<div wicket:id="gmap"></div>

Wonderful, if you're a Java developer. However, isn't the simple RichFaces component far more attractive, when you're thinking about "time to market" and similar terms? Does this not doom GWT and Wicket, and projects that attempt similar approaches, to being adopted by only a very small subset of companies in the real world? Perhaps, therefore, the buzz around GWT and Wicket only exists because those creating that buzz are very vocal and very visible people who are online a lot, far more than the corporate developer quickly composing their web apps via predefined JSF components? Maybe one also hears less from them because they have less problems, since their components simply work, meaning that there's nothing to cheer or complain about online. What do you think? Are Java programming models on top of technologies such as AJAX a waste of time? Isn't the user community better served with prepackaged components that they can simply plop on their page?

Published at DZone with permission of its author, Geertjan Wielenga.

Comments

Berry Crawford replied on Thu, 2008/05/08 - 11:11pm

Its pretty easy to use google maps with just regular javascript.  Im not sure why would would need a taglib to help.

Vinodh Lakshmin... replied on Fri, 2008/05/09 - 4:17am

Isn't the user community better served with prepackaged components that they can simply plop on their page?

 

Far too many times I have seen what amounts to this. The team decides to use a per packaged component. Everything is hunky dory and looks rosy. Then the team decides that the compoent needs to be modified / customised. The reason: We are having a pre packaged component and there is no effort for developing it. Let's use the same effort to modify it.

If the product allows for modification, well and good. Even then, time would not have been factored to stidy the compoenent and then modify it. The end result?? Blame the product or the team.

If the product doesn't allow for modification? Chaos and blame game all over again.

Chris Kent replied on Fri, 2008/05/09 - 4:21am

The two examples aren't really comparing apples to apples are they?  The RichFaces example creates a map at the default location and adds a slider to zoom it.  The Wicket example creates a map, explicitly sets its location and adds a listener to add a marker when the user drags the map.  To create the same map as the RichFaces example would've taken about 5 lines of Wicket code.

Having created Google Maps applications both with plain JavaScript and with Wicket I can say that I'm extremely happy with the way Wicket works.  Coding in nothing but Java and creating pages in pure HTML is a real pleasure.  And I'm not sure I understand why you think pre-packaged components and extensions in something like Wicket are any different to components in JSF and require any more code.

Johan Compagner replied on Fri, 2008/05/09 - 4:28am

Hmm this is not a really far example because what do you think the RichFaces component does it is pre packages component???

Exactly the same kind of thing wicket does.

So if i create that code you displayed here for wicket.. And give it to you then the only thing you have to do is:

 

html:

 <div wicket:id="gmap"></div> 

 java:

 add(new MyPredefinedGMapComponent());

 

done.

I just looked the other day to some JSF faces implementation.. Its really horrible many many things based on strings.. Strings!! why do people want that? Why do people want to program in xml? And then use attributes that have a string value that is a java expression.. 

 I personally never got that, always hated that xml declaration of stuff (for example flow) even back in 2000.. But happily more and more people see the light.. :)

 

Thomas Mäder replied on Fri, 2008/05/09 - 7:27am

To quote from "What is wicket":
(you remember Java right? It's like OGNL, but with even more cool features)"
I guess someone should take a shufti at the wicketstuff site. Loads of useful components, and you can even easily create new ones without even sacrificing a goat and guessing your way to the right xml incantation. Yes, I sound bitter, but JSF has stolen 6 months of my life. In my experience, Wicket is an order of magnitude more productive for anything non-trivial. Geertjans example is actually pretty good: look, you can configure the widget from here to San Francisco and WOW! the compiler is going to check that you're passing in the right parameters ( anyone?) Anyhoo, until someone builds a good XML debugger, I'm sticking with Wicket!

Geertjan Wielenga replied on Fri, 2008/05/09 - 9:27am in response to: Johan Compagner

[quote=joco]

Hmm this is not a really far example because what do you think the RichFaces component does it is pre packages component???

Exactly the same kind of thing wicket does.

So if i create that code you displayed here for wicket.. And give it to you then the only thing you have to do is:

html:

<div wicket:id="gmap"></div>

java:

add(new MyPredefinedGMapComponent());

 

done.

[/quote]

 

Good point. But does the Wicket team [or someone else] make Wicket components available for AJAX in the way that RichFaces et al do? If I can simply put a JAR on my classpath containing a long list of Wicket AJAX components, such as GMap, and then reuse them as above, that would be very cool. And I wonder what Craig McLanahan would say, if this was true, because then the AJAX components would be accessible in the same way for both Wicket and JSF, except that one would be using them in completely different ways.

PS: I guess all I'm asking for is for as many AJAX-related components as possible to be added to the standard Wicket JARs, i.e., including Google map.

Jose Maria Arranz replied on Fri, 2008/05/09 - 12:17pm

 

My AJAX version from scratch with ItsNat following a Java centric approach generating DOM from server:

Java code:

public class GMapLoadListener implements ItsNatServletRequestListener
{
    public void processRequest(ItsNatServletRequest request, ItsNatServletResponse response)
    {
        double x = 40.416741, y = -3.70325; // Madrid
        
ItsNatDocument itsNatDoc = request.getItsNatDocument();
        gmap(itsNatDoc,"map","zoomIn","zoomOut",400,300,x,y);
    }

public static void gmap(final ItsNatDocument itsNatDoc,String mapId,String zoomInId,String zoomOutId,
            int width,int height,double x,double y)
    {
        HTMLDocument doc = (HTMLDocument)itsNatDoc.getDocument();        
        HTMLScriptElement script = (HTMLScriptElement)doc.createElement("script");
        script.setSrc("http://maps.google.com/maps?file=api&v=2;key=ADD_YOUR_KEY_HERE");
        script.setType("text/javascript");        
        Element head = ItsNatTreeWalker.getFirstChildElement(doc.getDocumentElement());
        head.appendChild(script);        
        Element map = doc.getElementById("map");
        map.setAttribute("style","width:"+width+"px;height:"+height+"px");

ScriptUtil scriptUtil = itsNatDoc.getScriptUtil();
        String mapRef = scriptUtil.getNodeReference(map);
        String initMap = "";
        initMap += "window.map = new GMap2(" + mapRef + ");";
        initMap += "window.map.setCenter(new GLatLng(" + x + "," + y + "),13);";           
        itsNatDoc.addCodeToSend(initMap);   
 
        final Element zoomIn = doc.getElementById(zoomInId);        
        final Element zoomOut = doc.getElementById(zoomOutId);         
        EventListener listener = new EventListener()
        {
            public void handleEvent(Event evt)
            {
                String op = (evt.getCurrentTarget() == zoomIn) ? "+" : "-";
                itsNatDoc.addCodeToSend("window.map.setZoom(window.map.getZoom()"+op+"1);");
            }            
        };
        itsNatDoc.addEventListener((EventTarget)zoomIn,"click", listener, false);
        itsNatDoc.addEventListener((EventTarget)zoomOut,"click", listener, false);        
    }
} 

 

HTML:

<body xmlns:itsnat="http://itsnat.org/itsnat" itsnat:nocache="true" >

<div id="map"></div>
<div>Zoom: &nbsp; <button id="zoomIn"> + </button> &nbsp; <button id="zoomOut"> - </button> </div>

 

Johan Compagner replied on Sat, 2008/05/10 - 7:04am in response to: Geertjan Wielenga

[quote=geertjan]

Good point. But does the Wicket team [or someone else] make Wicket components available for AJAX in the way that RichFaces et al do? If I can simply put a JAR on my classpath containing a long list of Wicket AJAX components, such as GMap, and then reuse them as above, that would be very cool. And I wonder what Craig McLanahan would say, if this was true, because then the AJAX components would be accessible in the same way for both Wicket and JSF, except that one would be using them in completely different ways.

PS: I guess all I'm asking for is for as many AJAX-related components as possible to be added to the standard Wicket JARs, i.e., including Google map.

[/quote]

 

Things like google map dont belong in the core wicket. I am against that. Core is the basic building block for all the basic stuff wicket-extentions are more specialized component

GMap is already a seperate component that is created by the wicket-stuff people where many projects and components are hosted. Thats the whole point that components are made and supported from many places. 

Wicket components can be packages in jars and dropped into the classpath of you webapplication and they are ready to go. Without any other (xml) configuration issues. They are just there, ready to use in your prefered IDE.

Such a component can have java/html/css/js files or any other resource files (images) they want. They are completely stand alone an self sufficient. 

Mittal Bhiogade replied on Fri, 2008/05/09 - 2:24pm

There were some interesting comments around coporate developers, which would definitely prefer pre-packaged components to be readily use in thier business apps to improve productivity and schedule of projects. I do believe most of JSF open source projects do offer customization via skins or so. In terms of extending existing components, question would be how extendable a component should be, to represent universe of use-cases.

 

Thanks Mittal

Jose Maria Arranz replied on Fri, 2008/05/09 - 3:51pm

 The reasoning is simple:

 If you want drag-drop components to quick development, the pre-made/full blown/black box component approach may be sucessful. One problem: if you need to modify the behavior of those components... you are in a serious problem.

 For instance: mobile browsers, your amazing component probably is not supported... 

 In summary: components... yes, non-customizable components... NO 

 

Tim Boudreau replied on Sat, 2008/05/10 - 1:43am

I don't know that the source comparison above is really fair - you set a bucket-load of properties on the wicket component, but can you set all of those with RichFaces, and if so, is the markup that simple if you do?

Figure that some of the context (what the map is showing, etc.) is going to come from the server-side (even if the actual code extracts it from somewhere else on the page via javascript as the RichFaces example does).  I don't really see that the fact that RichFaces lets you embed a map with a single tag really helps, since somewhere there has to be enough code to inject contextual information.  That code is explicit in the Wicket example and missing in the RichFaces example.  How easy or hard is it to get all the properties the Wicket example sets into the RichFaces example, and what does the code look like to do it?

 -Tim 

Tim Boudreau replied on Sun, 2008/05/11 - 12:13am

"Does this not doom GWT and Wicket, and projects that attempt similar approaches, to being adopted by only a very small subset of companies in the real world?"

I suspect the economics of software development cause a general gravitation toward toolsets that make the problem as simple as it is and no simpler (in the java world, certainly making the problem more complex than it is has its own history, but that's pathological).  Make a problem simpler than it is and you end up with something people adopt and then it breaks down in real world use cases.

The biggest problem Wicket has is that there is not some big company out there flogging it (its fatal flaw may be that it doesn't overcomplicate things, so it ever feeding armies of consultants is unlikely - if I wanted to teach a 14-year-old web development I would teach them Wicket, unquestionably).  That being the case, the level of adoption it has gotten is remarkable and quite a testament to how well it solves the problem it sets out to solve.

 So I don't think there's much difference in the examples - the RichFaces example uses some javascript to feed in "map.setZoom(this.value)" but there's a lot of code somewhere driving what "this.value" is, and at some point it involves some coding.  Also, the GMap component doesn't appear to follow typical Wicket design patterns - the listener pattern is absent from Wicket for a good reason.  It is certainly possible to design a gmap component that requires less verbose initialization.

-Tim 

Jonathan Locke replied on Sat, 2008/05/10 - 1:39pm

"Yes, I sound bitter, but JSF has stolen 6 months of my life. In my experience, Wicket is an order of magnitude more productive for anything non-trivial."

What makes me feel a bit bitter is that I had to strike out on my own with no resources to create Wicket while the people with the resources took a decade to build the mediocrity that is JSF. I do not blame this on the people, btw, but on the process and in particular on the organization.  There are absolutely some great coders in JSF land and I used to work with some of them, so I should know.  I just think it's tragic that they could not be working on something more inspiring.

Looking back at these past 10 years (I had the initial impulse for Wicket in 1997 when JSF was being conceived), I'm convinced we could have all done SO much better than we did.  It really ought to be amazing to anyone paying attention that JSF has a serious competitor in a framework created by a handful of volunteer programmers working nights and weekends whose "marketing campaign" is merely some "very vocal and visible people who are online a lot". It really brings us back to Scott McNeally's quote from the late 90's: innovation happens elsewhere.

Working for Sun was absolutely the best and the worst job I ever had and this thread really brings back both the brilliance and excitement of the Java early days as well as the abject frustration and anger I felt watching Sun repeatedly snatch defeat from the jaws of victory.

I'd like to make another suggestion to Sun (if anyone there is tracking this), although this time more publicly.  I think that one very small change to JavaFX could help it to take over the universe: the Java platform really MUST include a complete set of fonts.  In my opinion, what DEFINES a platform IS: the consistent availability of resources. Without a universe of portable fonts that designers and coders can rely on, JavaFX users will always be forced to deal with some variant of layout managers. And in spite of the fact that some very smart people at Sun want to prove they can make layout managers usable, they are not a good idea for users no matter what the tool set might be. This one issue is nearly 100% responsible for the failure of Swing to explode in growth and it will also be responsible for the lackluster growth of JavaFX. Provide a full platform which seamlessly installs pixel-reliable fonts and the rest will just happen. You can thank me later.

 

Geertjan Wielenga replied on Sat, 2008/05/10 - 2:52pm

Wow, my admittedly rather poor post (in retrospect) has really thrown up a lot of interesting contributions. (FWIW, I'm personally a pretty big Wicket fan, even demoing the Wicket plugin on NetBeans day, receiving several good responses afterwards.) However, I clearly (judging from my post here) did not understand a number of key things yet. Now I do and am even more interested in Wicket than I was before. By the way, it sucks that the bookshop at JavaOne did not have any books on Wicket, because I, for one, would certainly have bought it. (Ended up buying one on Google Guice instead.)

Tim Boudreau replied on Sun, 2008/05/11 - 12:09am in response to: Geertjan Wielenga

It also rather sucked that as far as I could tell from the content catalogue, there were no talks on Wicket whatsoever at JavaOne (no doubt some were submitted - and a lot of people have worked hard to open up the selection committee process - I know at least for the tools track, the majority of the people on the committee were non-Sun people, so I'm not saying anything nefarious is going on).

Henk De Boer replied on Sun, 2008/05/11 - 11:26am

What always strikes me in these JSF vs Wicket comparisons, is that most people seem to forget that JSF components are also perfectly usuably from plain Java code. In fact, in JSF a tag handler is just an extra interface for a component that basically does little more than set it's properties and (optionally) associates a renderer with the component.

All of this can be done in pure Java code too:

UIViewRoot root = FacesContext.getCurrentInstance().getViewRoot();
UIOutput output = new UIOutput();
output.setValue("hello");
root.getChildren().add(output);

Of course this is a simple example, but by definition everything you can do with tags in JSF can be done in code too. You can iterate over children, add or remove them, set event listeners, set or change CSS styling etc.

All of this can be done from a backing bean, where you could for example bind a panel grid to it and provide its properties and child components programmatically. Taking it one step further you can very easily decorate the view handler in JSF in order to build the whole component tree programmatically.

 

 

 

 

 

Jose Maria Arranz replied on Mon, 2008/05/12 - 6:57am in response to: Henk De Boer

  Ok, but the main difference between JSF and pure HTML template web frameworks is the HTML layout control.

  With JSF you loses almost absolutely the HTML layout control (no, CSS is not enough). This is fine if you are confortable with the layout and DHTML behavior of your components, otherwise building custom components with non-HTML based templating technologies is a pain.

 

Henk De Boer replied on Mon, 2008/05/12 - 12:01pm in response to: Jose Maria Arranz

[quote=jmarranz]
Ok, but the main difference between JSF and pure HTML template web frameworks is the HTML layout control.With JSF you loses almost absolutely the HTML layout control[/quote]

Are you sure? I mean what about the jsfc attribute and TagDecorators?

E.g.

<input type="text" jsfc="h:inputText" value="#{somebean.someValue}" />

In this case <input> is regular HTML markup. I used <input> here, but it can really be anything. This is identical to the jwcid attribute in Tapestry. But I take it this is not exactly what you mean?

 

 

 

Jose Maria Arranz replied on Mon, 2008/05/12 - 3:11pm in response to: Henk De Boer

Nice try henk :) but if you are going to build an HTML <table> with data, <h:dataTable> is far far away from <table>.

JSF adds a layer on top of HTML, if this layer works for you, fine, but if you have a special need... this is the reason of some frustration around JSF, vendors have to cope with *any* user need because JSF defines a high level approach to web development (developer perspective of course).

=> More productivity but riskier (when the tool doesn't fit with my need).

ItsNat follows a radically different approach:  the view is almost totally controlled by the developer (in fact is pure DHTML on the server), components are simpler but highly controlled by developer.

=> Lower productivity but lower risk because almost any layout and behavior can be achieved.

 

Henk De Boer replied on Mon, 2008/05/12 - 4:08pm in response to: Jose Maria Arranz

[quote]JSF adds a layer on top of HTML, if this layer works for you, fine, but if you have a special need...[/quote]

I hear you. Sure, if you have a some special need JSF may not be suitable for you. The right tool for the right job, right ;)

Nevertheless, at least for me JSF has been working very nicely. I mainly prefer to build user interfaces the default way using tags representing components in an xhtml file. To go along with that I've build myself a small set of custom components and helper classes.

For some highly dynamic user interfaces, where a static layout in an xhtml file wouldn't make much sense, I've been using the programmatic approach I outlined above with great success. This has the additional benifit that I can customize existing components simply by inheriting from them. In a few occasions I've mixed both approaches, i.e. I mainly layout the components statically and insert a simple empty panelgroup where I insert dynamic components programmically.

In a few occasions, I've mixed in a more traditional approach in JSF pages. Simply some markup with basically some conditionals and loops around them, e.g. something like this:

<select name="somenamefor#{bean.id}" >
   <t:dataList value="#{bean.options}" var="option" >
      <option value="#{option.id}" #{option.selected} >
         <h:outputText value="#{option.text}" />
      </option>
   </t:dataList>
</select>

The above is again just an example and not what I actually used, but just to give you some idea. Like I said, this has been working great for me, but I understand it may not work for everyone.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.