Skip to main content

Using JSF in a project? Where does the time go?

Posted by edburns on August 2, 2010 at 1:59 PM PDT

I'm organizing my thoughts for my JavaOne talk HyperproductiveJSF 2.0 and I want to build the talk around the most common waysthat time is wasted when using JSF in a project. I've talked to lots ofusers, in many different kinds of organizations over the years but it'shard to organize the stories. So, I'm coming, cap in hand, to theblogosphere asking people to share the things that have caused them towaste development time when using JSF in production.

Here's a list to get you started. Please share things that havesimply taken too long to do when developing with JSF. You don't need tosay why it took too long, or how you worked around it.

  • Deployment step is slow

  • Server startup/shutdown slow

  • Have to restart the server too frequently

  • Complex server environment

  • Build is compiling/packaging things that haven't changed

  • Runtime library version mismatches

  • I have to get resources from all over the place in order to just build the war.

  • Getting all the necessary elements of the distributed system up and running takes too long.

  • I'm not getting the most out of my tools. They should be providing me shortcuts, but they are not.

  • Because there are so many different ways to do the same thing in JSF, we waste a lot of time trying to reconcile the different ways in different parts of the project.

  • We don't make use of continuous integration tools, so the builds are occasionally corrupt.

Anything else?

Technorati Tags:

Comments

Using JSF in a project? Where

Hello Mr Burns,
I´d like to known if there is on the web a vid or the slides of your javaone's presentation "HyperproductiveJSF 2.0".
thank you.

AJAX Question Not Answered in Your Book

Hi Ed, Love the JSF 2.0 Complete Reference. I cannot figure out how to intercept and manipulate the ajax response from the server. You talk about how to customize the jsf.ajax.request from the client. Straight forward. I want to add a tag in the response XML from the server so the response receiver on the client triggers the onerror handler. I can't find an answer anywhere! I want to use the f:ajax in 2.0 but I just need a little help on this one. Maybe I missed it in your book. I'd be equally happy if you sent me the location from the book (if it exists). Thanks!

My experiences with JSF

I'll list the things that have taken a lot of time for me. I was new to JSF at the commencement of my project and my comments should be taken in that context, but some of the problems I've experienced are not uncommon to other new JSF developers from what I've seen on various forums. These are mostly not development environment related scenarios, just anything I've encountered that was not straightforward along the way. Apologies if many of these observations are not very "big picture".

1. Inter-page communication with request scope & post-redirect get

I've never been able to get flash working consistently, either getting inconsistent results or the JSF1095 error, so I've had to switch to using view parameters. A search for JSF1095 on Google is returning 106 results so I'm not alone in having these problems. With flash you can pass an object reference from page to page, with view parameters you need a converter to convert the object reference to a unique id and back again. Then you've got a big security problem with hackable ids in the url that need obfuscation and additional security security checks required in a preRenderView event.

I've found it best to use a backing bean per page, and struggled initially to figure out how to pass a reference to (for example) a department from the deptList to the deptEdit page, given that I've got a deptList bean and a deptEdit bean. Only after finding the BalusC blog "Communication in JSF" did I find that using f:setPropertyActionListener on the h:commandButton in the source page and view parameters in the target page could I achieve what I wanted.

This is simple master/detail navigation but took me ages to get it working.

2. Intra-page communication when using AJAX

Here I was trying to have three selectOneMenu components on the same page, the value of the 1st affecting the possible values of the 2nd, the 2nd affecting the 3rd. I'd use a value change listener on the first component to alter the values displayed by the 2nd etc. The problem was that with request scope this worked ok with just two components, but when I added the 3rd component the value change listener on the 2nd component wouldn't fire to alter the list of values displayed by the 3rd component.

Following a suggestion on the primefaces forum I switched to using view scope and got it working, but a bit of a drastic change for something that should be so simple. So this essence of this problem seemed to be that I was using AJAX and request scope.

3. Dynamic f:selectItems - a minor but non obvious complexity

Related to the above item I recollect that f:selectItems value= has to return the same result set during render response of the display form as during apply request values for the form submit. In the case of the co-operating combo boxes scenario (3 selectOneMenus) described above you have to ensure that the value change listener of the 1st selectOneMenu reloads the data to be displayed by the f:selectItems value="{}" of the 2nd selectOneMenu. It's not as obvious as it seems retrospectively.

4. dataTable getters called multiple times

It wasn't immediately obvious to me that the getter on the dataTable value= property would be called multiple times and that database access should be handled by a different mechanism (and that getters should just do what getters are supposed to do - fair enough). It wasn't until an early debugging session that I realised this.

5. Stricter parsing of facelets pages

For example, for some time I was nesting f:event type=preRenderView tags within f:metadata, but then realised that the preRenderView listener was being called twice (I also use templates which may or may not have something to do with this). I now know that the spec says that only f:viewParam tags should nest within f:metadata, but an error would have resolved this immediately. Basically if something isn't where it ought to be, I'd love to see an error rather than dubious side effects.

6. AJAX

Bearing in mind that it's now 5 years since Google maps hit the streets I'd have thought that all the example programs, tutorials and JSF books would have shifted more strongly towards being AJAXified. Chapter 10 in a very recent JSF book is entitled "AJAX". I'd have thought it would be better as "Before AJAX", with the rest of the book using ajax examples.

I don't know if it's just that it's not seen as being difficult to ajaxify an application, but how many people really appreciate that you shouldn't mix ajax and regular http requests on the same page because of lack of certainty over ordering of request completion? I'm not entirely convinced that it's well understood.

7. JavaScript - Clearing error messages/setting input focus

- If I have a validator throw up an error on an ajax component I typically have to use javascript onfocus and onmouseover event to clear the error text, it'd be nice to build this in if possible. There's quite a lot of fiddling on each page to clear displayed errors when you're going back into a component to address the problem already reported.

- When using templates it can get a bit messy trying to set input focus using h:body onload= because you may only have one h:body tag (in the template) on which to attach the onload attribute. PrimeFaces has the p:focus tag which solves the problem if you use primefaces, but it'd be useful to build this into Mojarra.

- It took me quite a while to figure out that if you add onkeydown="if (event.keyCode == 13) event.keyCode = 9;" to h:inputText it stops hitting enter submitting the form.

8. More components needed

- Without even the ability to select a row in a datatable or a basic calendar component, assuming these are things you need, you've got to go out and select a component library unless you're knowledgeable enough to develop your own.

Following the demise of woodstock I wasn't keen on ICEFaces because I understood it to be incompatible with other libraries. When GlassFish v3 was released on 9th Dec 2009 I didn't really expect RichFaces to be at milestone 2 by september the following year, so PrimeFaces has really helped me out. I was particularly pleased to see that PrimeFaces 2.2 is using an industrial strength testing/release process.

- A registration/login component is a lot of work despite there being some well documented examples.

- File upload is a massive headache. I couldn't get the primefaces file upload component to work and got a BalusC version working. The problem there was that you have to use a multipart form and any non file upload components on the form became incredibly slow. I ended up using two forms on one page, but really I need to be able to embed buttons in cells in a datatable to facilitate file upload and I've not managed to get this working.

- Some sort of page counter infrastructure would be nice. Ideally it'd be able to take the IP address from the incoming request, call a user specified routine to lookup the country and score the hit against the page/country. One point worth noting is that in an application scoped managed bean the @PreDestroy routine can't make EJB calls because the EJB container is closing down - problematic when attempting to persist in-memory counters.

9. https - http downgrade

I'd like to be able to choose if my servers have to handle the additional load of using https just because the login page needs to use ssl and there's no way back. I have managed to write a filter that does revert from https to http although it throws up some error or other in the server log and I get all kinds of browser certificate errors.

10. Exception handling

I had quite a lot of trouble getting the error-page in web.xml working because, I think, it doesn't work if PROJECT_STAGE is set to Development, which it is. I ended up writing a custom exception handler to handle ViewExpiredExceptions and navigate to my serious-error-page. But with a custom exception handler I was not able to use the nice default JSF error page with a stack trace (nav.handleNavigation(fc, null, "javax.faces.error.xhtml") didn't work for me). So I've got differences in error processing between my development and production environments when I don't want them and I've not got them when I do.

Then there's the problem with wrapping errors from within the bowels of the container into ServletException or EvaluationException. I recall that you can run through the exception chain to find your application exception, but the net impact is that you pretty much have to handle each potential error scenario on an individual basis rather than having an overall policy.

11. Better form support

Is there anything that could be done out of the box to make is really easy to reuse all the same facelets and java code for creating and then editing forms? it's do-able but there's enough fiddly stuff to make it easier to just separate it out.

12. Validators

- Closely related to the create/edit form scenario above, imagine a f:validator tag attached to a h:inputText component which checks the uniqueness a team name. You want to use the same page for both creating the team and editing the details, but the validator is attached to the component. You've got 2 h:commandButtons, one for create and one for edit.

Although you can use f:attribute to pass additonal parameters to the validator I've not found a way to also let the validator know if I'm creating or editing. This is important because in the case of "create" the team name must be unique, but in the edit case (and you're not changing the team name, some other associated data) it won't be unique, the name of team being edited already exists.

- It would be nice to be able to use @EJB in validators rather than doing JNDI lookups to inject resources.

- If you're using f:validateRegex you probably want to override the default validator message with validatorMessage, but if you additionally want to use f:validator on the same component (i.e. for a uniqueness check) then validatorMessage overrides any message thrown by the custom validator. So you have to incorporate the pattern matching from f:validateRegex into the custom validator and eliminate the use of f:validateRegex. Not the biggest problem in the world but it took a little time to get right.

13. f:viewParam - pass object references

Would it not be possible to pass object references via view parameters, instead of: reguser.xhtml?firstname=John&lastname=Doe have reguser.xhtml?user=%XAAFF00EE or something, preferably with an obfuscation option? This would also help reduce the vast numbers of converters that I have to use.

14. Passing context information between JSF & EJB layers

It would be nice to be able to pass a context block, typically containing login/security information between JSF beans and the EJB layer without having to include specific parameters in the EJB method calls. I experimented with the "context holder" design pattern as described in Adam Bien's book which describes using @AroundInvoke interceptors and TransactionSynchronizationRegistry but I couldn't get it working to my satisfaction.

Thanks for your thoughtful feedback

You obviously took a lot of time to prepare it, so thank you.  I've added it to my input for next week's presentation.

Sincerely,

 

Ed Burns

Server Startup and shutdown

Most of my time is spent around deploying the application in server. I have my own build script that packages the war file (runs pretty faster). After few deployments in WASCE, we get OutOfMemoryError although I set the JAVA_OPTS. I guess it reloads not only the context but also the dependent modules (by that time, the previous footprint should have been completely removed). I have tried integrating it with Eclipse IDE and publishing the app (the app server -plugin is quite effective that it detects the changes as soon as you modify the files); publishing it through.. Now, I still need to restart server but not that often.

Tooling support for the UI designer

Converting a UI mockup in to a JSF application sure does take a lot of time. Especially if your JSF framework tags paint their own DIVs & SPAN tags!! I know it's not straight forward, but having tools which speak JSF for the UI designer is definitely a big plus point.

A few points to add to your

A few points to add to your list: (1) Unit testing (2) Lack of an "app framework"--basic functionality such as authentication or menuing has to be rewritten each time (3) Painful I18n (programmatic access to resources, managing app messages vs. component messages vs. bean validation, resources other than strings) (4) Dealing with the Stack Trace from Hell

Cheers,

Cay

Lots of place to waste time on

Hi,

we loose lots of time on the following points:

  • Lack of proper error reporting. Many times things just don't work and you don't get any notification why things are not happening, even will full error logging turned on + <h:messages/>
  • Many components require too much boilerplate code to do something useful when compared with other frameworks
  • Lack of documentation for some common scenarios. It already happened more than once that I need to google around to understand how some APIs are used, because they are not documented in any JSF book.
  • Tools are still lacking when compared with other frameworks
  • JSF flexibility can be good in some scenarios, but it leads to a complex framework for simple day to day development. After 3 years doing JSF development, I still have to go read about JSF on regular basis!

Even if JSF 2.0 tackles some of the issues that I mention, please remember that for most of us outside Sun/Oracle, JSF work still means JSF 1.2 and sometimes JSF 1.1!

Best Practice

Because there are so many different ways to do the same thing in JSF, we waste a lot of time trying to reconcile the different ways in different parts of the project. It took me ages to figure out the best/right way to use JSF. The net is flooded with tutorials on doing basic stuff with JSF, but few of them address concerns on how to build production-ready JSF applications. Another major annoyance in the beginner was the lack of proper support for HTML tables. Not being able to span across columns use to drive me crazy.

Setup and project environment

Hello Ed,

I think some of the items are not really issue with JavaEE/JSF. When a project does not have a CI environment (or no source-code-control) it's not the problem of the used technology if bad things happen. It's up the project. Even for a simple RAILs project, I'd always use GIT/SVN...


Regarding tools, the issue with the vanilla Eclipse WTP and JSF is that you have to get the stuff from somewhere else: Your servlet-container (like Tomcat) or the JSF implementation, like Mojarra 2.x or 1.2.. Better integrated tools, like JDEV and/or Netbeans do offer a way better integration; You can simply start by creating a project and a JSPX. Click run and it deploys to the *integrated* container. In JDEV/WLS case, just click "make" on Java file and it should be reloaded.


Using a maven-based build does help to get things working in a commonly established way: No custom/crazy setup. More knowledge available if you follow a standard.


On JSF itself sometimes: I hear that the generated/rendered HTML by components (like h:dataTAble) does not always play nice with extern CSS/designs, like from those fancy agencies.


Generally providing some tips and hints on being more productive does sound like a great session! Too bad I do arrive on Monday evening...

CU there! Matthias

open a web page via windows forms

Subject: How to open a web page via windows forms with minimal browser options? Issue Description: I tried to open a web page via windows forms with the following code C#: process.start("iexlorer.exe","url"); This code opens IE with menu bar & toolbar options. I want to know is there any way to show the browser with url and content only and no other browser options. Thanks, Sreeram

Errors

The last time we tried JSF (1.2), we wasted too much time trying to understand errors. The error messages, when they weren't swallowed, didn't help at all. For example, a "invalid value" was printed on the page, and nothing on the console. It turned out that what was causing this was a dropdown that expected SelectItem's and was receiving a list of strings. This kind of thing, mixed with Seam errors, turned our experience into a real nightmare.