A few drawbacks that pop to mind:
- JSF is a component-based framework.
This has inherent restrictions that
have to do with obeying the
component-model.
- AFAIK JSF supports only POST, so if you want a GET somewhere you have
to do a plain servlet/JSP.
- Most components try to provide abstractions over domains like
relational databases and front-end
JavaScript, and many time these
abstractions are "leaky" and very hard to debug.
- These abstractions might be a good starting point for a junior developer or someone not comfortable with a particular domain (e.g. front-end JavaScript), but are very hard to optimise for performance, since there are several layers involved, and most people that use them have little understanding of what is going on under the hood.
- The templating mechanisms that are usually used with JSF have nothing to do with how web desigers work. The WYSIWYG editors for JSF are primitive and in any case, your designer will give you HTML/CSS that you'll have to spend ages converting.
- Things like EL expressions are not statically checked and both the compiler and IDEs are not doing a good job at finding errors, so you'll end up with errors that you'll have to catch at run-time. This might be fine for dynamically typed language like Ruby or PHP, but if I have to withstand the sheer bloat of the Java ecosystem, I demand typing for my templates.
To sum up: The time you will save with JSF, from avoiding to write the JSP/servlet/bean boilerplate code, you'll spent it x10 to make it scale and do exactly what you want it to do.