I've only glanced at the GWT docs, so can't compare the technologies. I know next to nothing about Flex. I'll spill what I know about JSF, though, so hopefully you can make up your own mind. I know there was an effort to integrate GWT and JSF (G4JSF), but don't think it went anywhere.
JSF2 is on the cusp of release. David Geary is writing a series of devWorks articles on the new features.
- Layout: is it declarative, programmatic or a mix of both?
Generally declarative. There are two common view technologies: JSP and Facelets. The JSF component tree approach to UI can be at odds with the inherent nature of JSPs, so prefer Facelets. Facelets are standardised in JSF2 and thus will become part of JEE6.
It is possible, but non-trivial, to use a purely programmatic view.
Most JSF tags provide a binding attribute which can be used to provide an alternative component at view creation time, but I wouldn't recommend using it without a detailed understanding of the JSF framework. Programmatic composite example on the MyFaces wiki.
- Control library: how rich is the available control library? How easy is it to extend or write custom controls that "play nice" with the built-ins?
The standard library is very basic. This is what you get with a JSF implementation (e.g. Mojarra; MyFaces).
Beyond this, you can drop in libraries onto your classpath to provide new or alternative controls. As of JSF 1.2, this is the primary method by which you gain AJAX-enabled controls. There are a number of open source/commercial libraries out there and proprietary IDEs generally provide more. I believe many of these libraries take their own approach to AJAX implementation, so would be surprised if they mixed well. jsfmatrix.net tries to maintain a list of libraries and their features.
Writing a JSF control is a fiddly process with many manual steps. Writing a sophisticated control that supports children (like a datagrid) can get quite complex and requires a detailed knowledge of the JSF framework.
It is possible to create composite controls from existing controls and this is considerably easier than writing a control from scratch.
Trying to integrate existing JavaScript libraries can be difficult. A particular sticking point can be in how JSF handles HTML ids. Adding your own AJAX support can be non-trivial due to the way the JSF lifecycle works and how controls decode their own input values from the request.
In JSF2, AJAX support is standardised in the framework. Jim Driscoll wrote a blog post last November about how to write an in-place editable text field (the API might have changed since, though). There are a few other tweaks that should help with AJAX integration.
- Javascript: how much of it do I need to write in order to be successful with the framework?
None, so long as the set of controls you use does everything you want. See above.
- Cross-browser: assuming I'm not writing a lot of my own HTML and JS, do the frameworks function equally well in all modern browsers?
This will depend on the widget libraries you choose. There is some JS in the base implementations - expect it to be browser agnostic.
- Tooling: is a rapid edit/refresh cycle available? How easy is it to debug the client and server code?
I debug on a web server, so performance depends on how heavyweight the container is. The Eclipse tools tend to autodeploy-on-save to a running container; NetBeans uses a run button to do the same (these may not be the only options - I haven't had cause to go looking). The experience is adequate but not exceptional.
I've seen JSP WYSIWYG editors in both Eclipse and NetBeans (though I think the latter is for the Visual JSF/Project Rave/Woodstock library). I don't know about Facelet editors - I haven't gone looking. I did notice this: Jim Driscoll's comments on the state of JSF2 tooling.
- Bookmarking / Browser Navigation: this is a common problem in Flex; does the framework play nicely with these?
There is nothing inherent in JSF that stops you from bookmarking a page, though it does tend to be a HTTP POST-based framework. It relies on (usually *.faces or /faces/*) servlet mappings to serve the views, so URLs tend not to be friendly (though there are things you can do about that).