Arjan Tijms and Bauke Scholtz (BalusC) explain their motivation for creating the open source JSF utility library OmniFaces and discuss their latest project zeef.com.

Kito: Hello Arjan and Bauke. So first, tell me about yourselves -- your background, and how you got into JSF development.

Arjan: Well, I got into computers at a relatively young age, around 7 or so. I started with a Commodore 64, which had the nice feature of presenting a programming environment right when you turn it on.

Kito: Nice! I started with a TRS-80 :-).

Arjan: I naturally got interested in how programs worked and started in Basic, and a little later Simon's Basic, then some assembler TRS-80. Nice.

Bauke: I started computers when I got a Commodore 64 with Simon's Basic. It has always been a hobby. I've not studied ICT, but I've studied Laboratory Technology. After all, I decided to jump into ICT when it attracted me during the peak of the dotcom bubble around 2001. At IBM, I became familiar with Java / J2EE. Later, around 2006, after moving to another employer I got started with a JSF 1.1 project. Since then, I've been working with JSF almost daily.

Arjan: After the Commodore 64 I got an Amiga and a Mac+. Especially the Amiga was great from a system's point of view. Getting to know how the custom chips and CPU etc worked together was great. I knew then that I wanted to become a programmer later. I learned C and C++ on a SGI Indy -- programmed a long time in C++.

Kito: Yeah, everyone thought the Amiga was great. I never had one, but a friend of mine did.

Arjan: In Europe they were really popular. A friend from the US told me they were less popular over there.

Arjan: After learning C++ I studied computer science at the University. It's a different approach to programming than what I had already learned on my own.

Kito: Bauke, you got attracted to IT during the peak of the bubble, but you skipped startups and worked for IBM?

Bauke: Yes, I didn't have an ICT degree, only a B.Sc Medical Biology which also covers -- among others -- algebra and physics, IBM was the only challenging company for which this was sufficient.

Kito: Ah.

Bauke: I privately already had moderate HTML and PHP experiences and I passed all knowledge/"smartness" tests they offered with great scores.

Kito: Hehe. Good deal. So, you guys both work at Kizitos now?

Bauke: That's correct.

Arjan: Indeed, it's a new startup.

Bauke: Kizitos is formed from nearly the entire old development team of M4N.nl.

Arjan: We were already working together at M4N, our previous company.

Kito: Ah, okay. Was M4N using JSF, or is it just Kizitos?

Bauke: M4N was taken over by Zanox mid 2011. Yes, M4N was using JSF.

Arjan: M4N was completely in JSF, but it was migrated from a JSP based version.

Bauke: Which in turn was migrated from a PHP version.

Arjan: Yes, a kind of PHP version.

Bauke: When I started, M4N was about to migrate JSF 1.2 to 2.0. I've helped that part to a great extent.

Arjan: In the beginning when M4N was a startup we were all pretty inexperienced. When I joined in late 2003, I had just graduated from University and still had a lot to learn. Our code was only partially in version control and we didn't had a real development process yet. At some point we realized we needed a web framework, but couldn't decide on one. JSF 1.0 wasn't very good back then, but we dipped our toes in it just before 1.2 came out. We gradually migrated the JSP based pages to JSF 1.2, but needed a lot of custom utility code and it took a while before we learned about the best practices. Things got better when we discovered Bauke's blog.

Kito: So, is that how Bauke joined the team?

Bauke: Nope, I just solicited them directly, when my job contract at another employer was about to expire and I needed a new job for which I could work from home. My wife stumbled upon jdevelopment.nl and I applied over there.

Arjan: One thing we specialized in at M4N was working from home.

Bauke: http://jdevelopment.nl/working/. Currently it's referencing Kizitos, but previously it was referencing M4N.

Arjan: I personally worked from home two days per week then, and we had a friend of mine working remotely from China.

Kito: Sounds like a great place to work! So, tell us about the Kizitos product -- I see there is a prototype up already.

Bauke: It is. I was over there in the Netherlands for 2-3 weeks in 2011. Yes, zeef.com is already online, you can explore http://jsf.zeef.com. The live version is currently very much in beta -- a lot of things have been polished in the meantime.

Arjan: I just created a page as well, it's on http://javaee7.zeef.com. Indeed, the live version is currently a "silent" beta.

Kito: Should I leave out the links when we post this?

Bauke: No, just keep it in, if Arjan agrees.

Arjan: I was thinking about that too; it's not secret in any way, but it runs on a very moderate server and the current version hasn't been optimized yet for performance or anything. But I think the links can stay in... We're about to release a more optimized version in the next two weeks (after our current 2 week Sprint ends).

Kito: Ok. The site is very snappy -- clean look. Tell us about the site.

Bauke: You can learn about the background at the blog at http://zeef.org.

Arjan: It's built on Java EE 6, using PrimeFaces and of course OmniFaces.

Bauke: I've also blogged about it at http://balusc.blogspot.com/2013/04/zeef-get-links-sieved-zeefed-for-you-by.html.

Arjan: We use a lot of the Java EE technologies: JSF of course, with CDI, Bean Validation, JPA, EJB, JASPIC.

Bauke: To the point, the site is to offer experts a chance to provide a filtered overview of sites they think are very helpful on the particular subject. I've also got another one: http://curacao.zeef.com.

Arjan: EJB has been controversial in the past, but starting with EJB 3.0 and JPA 1.0 we found it to be a great technology.

Kito: Agreed.

Arjan: At M4N we had custom JDBC and Services/DAOs before that. Things looked simple at first, but manual transaction handling and propagation became incredibly tedious.

Bauke: Yes, currently Zeef is on Java EE 6 + Java SE 7 + JSF 2.1 + PrimeFaces 3.5 and OmniFaces 1.6 / snapshot. Right, with EJBs it's really a breeze now.

Arjan: When we switched to EJB and JPA, our Services afterwards were only maybe 10, 20% of their original size, and much easier to understand.

Kito: What's the revenue model behind Zeef?

Arjan: As a former affiliate marketing team, the model will be affiliate marketing again, but both Bauke and I are not the ones driving the commercial side of things of course.

Kito: Makes sense. Very cool stuff!

Bauke: Was trying to say it like that, but Arjan expresses it better.

Arjan: We have tons of things planned. The social aspect is going to be important as well.

Arjan: We didn't like the fact for instance that people could "claim" a subject. With Zeef nobody can exclusively claim a subject. I made a Java EE 7 page, but maybe someone in Japan can make a better version. He or she can claim the same subject, and create a new version of the page. The best one will eventually become the default. Maybe because of more clicks, maybe because of more page views, incoming links, whatever. But people can always switch to the alternative versions.

Bauke: Yes, one can create their own page on the same subject, check the "Compete" button in the "Experts" section. If there are multiple experts on the same subject, other experts will be listed there.

Kito: Fascinating. So experts sort of compete? Did you consider letting multiple experts manage the same page?

Arjan: Yes, that's definitely a scenario we have talked about. But it's not yet implemented. We do have a simpler version of this up now where people can suggest links for a given page.

Bauke: Yes, they can be approved or rejected by experts.

Kito: I think we may have to do a separate "In the Trenches" interview just about zeef.com!

Arjan: That would be cool indeed!

Kito: Yeah, I just find it pretty interesting stuff :-)

Bauke: In fact, the current beta is the first release, just in time for our colleagues to enter the Dutch camp in San Francisco.

Kito: Dutch camp?

Arjan: There's a startup event there called Holland in the Valley.

Kito: Oh, nice!

Arjan: Our commercial people have been attending that.

Kito: Cool. Well, I suppose we should move on. Before we get to OmniFaces, I did want to ask Bauke what it's like being a Stack Overflow superstar :-).

Bauke: Well, it was not my primary goal, I merely want to help people out with their JSF trouble and explain to people in simple terms why JSF works like that. And so, generally my aim is to remove the ignorance around JSF and to make it simple to understand and use. I'd been a contributor of the JSF forum at forums.sun.com until Sun was taken over by Oracle and the forums became somewhat a mess, then I moved to Stack Overflow which is a perfect platform for Questions and Answers. As I kept answering questions for years, I eventually ended up in the top users.

Kito: How do you find the time to answer so many questions in such detail?

Arjan: Sometimes I wonder that too!

Bauke: Well, I spend on average 2-3 hours a day and the fact that I can answer/explain many things just off the top of my head also helps a lot.

Arjan: Bauke finishes a lot of JIRA issues, but somehow still finds the time to answer those questions. For a while I answered some question on SO too, got 17K reputation or so…not that much compared to Bauke.

Bauke: I use Stack Overflow mainly as "pause"/"exercise" during my job.

Kito: Nice. It's your Pomodoro break, eh?

Bauke: Even more, in the weekends I'm rarely on Stack Overflow, I spend more often quality time with my family and kids, BBQ on the beach, for example. Sorry I'm not native English, I don't understand "Pomodoro break".

Kito: Well, that's good to hear. I was starting to wonder if you had any free time! The community is definitely grateful for your contribution.

Bauke: Oh right. http://en.wikipedia.org/wiki/Pomodoro_Technique

Kito: Yep ;-).

Bauke: Yes, my contributions have also resulted in OmniFaces (along with the trigger of Arjan as in "Hey why not create an open source library based on all those answers?")

Arjan: Exactly.

Bauke: Without Arjan, I'd probably never have started OmniFaces.

Arjan: We saw the same questions and the same example and utility code posted over and over again.

Kito: I see exactly the same thing, but for some reason I never started a library myself. Perhaps I needed an Arjan :-). So, tell us about OmniFaces.

Arjan: At the same time, we had built our own separate utility libs. I had one at home for personal projects, we had one at work. Bauke, I believe, had several as well for playground projects etc.

Bauke: Yes, they had pretty much common things, from my previous job projects, we also had similar utility libraries. Everything was reinvented over and over based on information found in forums and Q&A sites. Why not just create one standard library so that nobody needs to reinvent the wheel?

Arjan: One particular artifact that we were just discussing is the Ajax reset handler. I've seen so many versions of this before we included it in OmniFaces.

Arjan: If people were having this particular JSF issue, I always had to point them to this and that forum, and then they had to copy/paste code from within the middle of some page etc.

Kito: Have you seen the version included with JSF 2.2? It's based on your work, plus PrimeFaces-Extensions. But for those who don't know, perhaps it's useful to explain the problem it's trying to solve.

Bauke: Just to note that PrimeFaces Extensions is unrelated to OmniFaces and essentially a separate project.

Arjan: Yes, I've seen the JSF 2.2 version. I've been tracking JSF 2.2 pretty closely on http://jdevelopment.nl/jsf-22. It's really good that it's in the standard spec now. Eventually we hope that more than a few things that are in OmniFaces end up in the spec, so it will be even easier for people to have access to it. The spec reset version is really nice, but it's maybe missing a few small things.

Kito: Like what?

Arjan: Like a setting to have it be the default for the entire app.

Bauke: In OmniFaces it's also offered as an application wide phase listener. It just makes sense that when you explicitly specify components in <f:ajax render> but not in <f:ajax execute>, then it means that you actually just would like to "reset" them -- why else would you explicitly exclude them from Ajax execute?

Arjan: I really like the idea of also having an <f:resetValues> for non-AJAX requests. You have to think about that for a moment perhaps, but it's quite clever.

Kito: Yeah, that's a case I didn't think of either. I can't remember if it was Ed or Cagatay who brought that up.

Arjan: It would also be nice if the standard version had support for things like @form and @all, but this can, of course, be added in JSF 2.3 or later.

Kito: Yeah, that would definitely be nice. So, what other features does OmniFaces provide? There's a lot of stuff in there...

Bauke: Well, as a recent example, <o:outputFormat> and <o:param>.

Bauke: You can't do <h:outputLink title="<h:outputFormat .../>" />, but you can do <o:outputFormat .. var="title"/><h:outputLink title="#{title}" />.

Arjan: Okay, really nice and as I said, clever thinking.

Bauke: It is mainly those little things.

Arjan: We cover quite a wide range of functionality. I think the FullAjaxExceptionHandler is particularly popular.

Bauke: Then the Faces and Messages utility classes, which should reduce API boilerplate to single method calls or even introduce some sane defaults…Faces.getLocale(), Faces.sendFile(), Faces.redirect(), etc.

Kito: I'm definitely fond of FullAjaxExceptionHandler myself -- great way to display a proper error page for Ajax requests.

Bauke: Yes, that's also a popular thing, and the combined resource handler (currently also in use by ZEEF).

Arjan: Indeed, there was an issue about having some of those "chain flattening" utility methods for JSF 2.2, but it wasn't picked up it seems. Adding a Faces message without OmniFaces, especially if you need i18n, is rather verbose.

Kito: Agreed.

Arjan: Matt Raible complained about this years ago. In fact, I think it was one of the first complaints he had against JSF.

Kito: Matt complains about everything :-). Tell us about the combined resource handler.

Arjan: He does sort of, doesn't he? But he has some good points as well and his complaints about the way messages are added are, IMHO, quite valid.

Bauke: The CombinedResourceHandler locates all <h:outputStylesheet> and <h:outputScript> components with target="head" in the component tree, removes them all, and inserts a single one for CSS and another single one for JS.

Bauke: Thereby reducing the HTTP connections on CSS/JS resources. It streams just all CSS and JS resources each into a single response. Among others, YSlow and Google Pagespeed will give you + points on that.

Kito: Yes, he does have _some_ good points :-). Ah, nice feature. What are some other highlights?

Bauke: The select items converter, the <o:viewParam> and <o:form>.

Arjan: I personally like those ones a lot as well.

Bauke: The select items converter allows you to have a <h:selectOneMenu> referencing entities without the need to create a custom converter.

Arjan: The viewParam is a really great addition to JSF, but its stateful nature is not always needed. The <o:viewParam> component essentially came out of this blog article I wrote: http://jdevelopment.nl/stateless-stateful-jsf-view-parameters.

Bauke: In view scoped beans the viewParam is set again after the initial request, which is unnecessary and potentially expensive when a converter is involved, which acts with a DB again on every postback, I mean.

Arjan: Indeed, that holds for the select items converter as well. Just having to write a converter is perhaps just tedious. But how do you normally go from an entity ID to an entity instance? A lot of times this is done via some Service, which does a DB call. This is needlessly expensive if you still have the data in your backing bean.

Bauke: By default JSF submits to an URL without any request parameters, the <o:form> allows you to submit against an URL with view parameters or request parameters, on synchronous postbacks -- this improves the bookmarkability (no disappearing query string anymore) and on Ajax postbacks this retains the view parameters on request scoped beans.

Arjan: Yes, I think there are no less than 3 issues about this on the JSF spec JIRA.

Bauke: All in all, OmniFaces just tries to fix all those little annoying JSF things :).

Arjan: We heard this complaint a lot, people submit a form in JSF, then for some reason or other want to copy the URL from the address bar or just want to refresh the page by hitting enter in that address bar. If the request parameter is gone, this won't work correctly or at all.

Bauke: If you check the menu on http://showcase.omnifaces.org, there are after all quite a lot of features.

Arjan: A very simple thing that our boss/manager Klaas always complained about was that JSF messages didn't have links in them. The message said: "Please go to your profile to do this and that". But the profile wasn't a link.

Bauke: Ah right, that was fixed with <o:messages> which now supports escape="false".

Arjan: And the user had to lookup manually where to find "profile". Making "profile" a link is just so much user friendlier.

Kito: That's a really good point :-). They should use expressions, shouldn't they?

Bauke: Not exactly that, it's that HTML in Faces messages is by default escaped, e.g. <a href ="foo"> would appear as plain text instead of as a link and there is no way to disable it, like as <h:outputText escape="false">.

Arjan: So of course you need to be careful with this, if you use the same message for "Value <user input something> is not valid!", then you'll run into a XSS risk. But that's the same with <h:outputText escape="false">. You need to use this feature with care.

Bauke: Indeed, but the same is true for <h:outputText escape="false">, although the showcase warns that somewhat explicitly: http://showcase.omnifaces.org/components/messages -- press the "show HTML message" button.

Arjan: Indeed.

Kito: Ah, right. These sound like some excellent features. I was very glad when I found this library last year -- you definitely have systematically tackled all of those little things we deal with on a daily basis. I've used some portion of the library on a couple of projects now. We need to start pushing some of these into the next version of JSF, too.

Bauke: That's great to hear.

Kito: Well, thanks a lot for the details, guys. We're over our allotted time, but I wanted to ask a couple of general questions.

Arjan: Sure.

Kito: What is your favorite thing about JSF, and what is your least favorite thing?

Arjan: Favorite thing is the elegance of having those bi-directional bindings between components and data.

Bauke: Well, I think I most like its component based approach.

Arjan: This really makes for a nice and intuitive programming model.

Bauke: jQuery's "Do more with less code" holds true for JSF as well, if used and done the right way.

Arjan: It's also nice that JSF in general has an association between what's being rendered and what's being posted back.

Bauke: OmniFaces helps a lot in this, we're also seeing this back in ZEEF.

Arjan: This makes things like Rails' mass assignment vulnerability less likely in JSF. I personally like the way Facelets works a lot as well, with its templates and such. As an experiment I once coded a VDL that uses pure Java to author pages, but I'm not a big fan of that.

Kito: Hmmm... how far did your experiment get, Arjan? Ed Burns has an experiment with that as well. I think it has promise, perhaps with a different VM language.

Arjan: I didn't get really far with it, but far enough that it did actually work. The code was committed at https://code.google.com/p/javavdl and I wrote two articles at JDevelopment about it: http://jdevelopment.nl/authoring-jsf-pages-pure-java and http://jdevelopment.nl/single-class-pure-java-jsf-application.

A particular unresolved issue was that it used some Mojarra specific code. The ViewDeclarationLanguage type in JSF appeared to be not entirely reusable. Particularly Mojarra uses the proprietary type com.sun.faces.context.StateContext to track modifications to the view. In an ideal world the code that's just building a component tree would not have to care about this (see https://code.google.com/p/javavdl/source/browse/src/javavdl/impl/JavaViewDeclarationLanguage.java).

Bauke: It's hard to tell what I like the least in JSF. I think its stateful nature and the expired views, but that can be "fixed" to some extent -- Arjan is currently looking into Stateless JSF and view state pooling.

Arjan: Scopes, mainly the view scope, are very nice as well. The scoping for CDI beans is, if I'm not mistaken, largely inspired by the scopes of JSF managed beans, isn't it?

Arjan: Yeah, so view scope is great, but it's not always clear why components need to be stateful. I did some investigation; what exactly do components store in the view state?

Kito: You're right about the CDI scopes.

Arjan: Sometimes it's just cache...like if bean validation is available globally I'm not sure that needs to be in a per-component view state, seems more like application wide state really. I think in general we should not blame state, state can be very useful, but we need more options for tweaking it. Like the ability to set per view, or perhaps per component if you want state on a server or a client.

Kito: I think the component state dates back to the original desire to have the components live separate from the model, more like older desktop component frameworks like Delphi or VB. Yeah, that would be nice. I think we're getting there.

Arjan: And the ability to distinguish between *real* state, e.g. where you are in a stateful dialog, or simply a cache that can be restored if lost.

Bauke: Yes, definitely the state management needs more options for tweaking; the new <f:view transient="true"> is already a step in the right direction.

Arjan: In JSF, everything in view state is now just state... there's no distinction.

Bauke: The <f:view transient="true"> tag now allows you to disable state on a per-view basis. It would be great if this same tag would let you control server/client side state saving on a per-view basis as well.

Kito: Yes, definitely a step in the right direction.

Bauke: State saving can currently only be set application wide, not on a per view or even per form basis.

Arjan: Indeed, I created an issue on the JSF spec JIRA. It's currently one of the more popular issues to have more fine control about state.

Bauke: It's hard to get OmniFaces to "just" fix it as it's implementation dependent and rather complicated.

Arjan: Indeed, I spend a lot of time on thinking about how to let OmniFaces implement a per view choice for client/server state.

Kito: You should talk to Leonardo Uribe @ MyFaces. He's been thinking a lot about this, too.

Arjan: But although JSF has a great plug-in structure, this aspect is not as pluggable. You can't re-use just the client state save algorithm. Patching the Mojarra source code is relatively easy, but for OmniFaces this is really hard. Leonardo Uribe has some very good ideas about view pooling. In late 2011, I was busy with that as well, but then Rudi from Industrie IT came with an implementation that was more advanced so I dropped this work. But I haven't heard much about it lately. I think it never came to a final version.

Kito: I haven't seen anything else from him either... I think this should definitely be on the table for JSF 2.3. Alright have one final question.

What do you think about the server-side component approach (JSF, Tapestry, Wicket) vs. coding the UI completely on the client-side and contacting the server via REST?

Arjan: That's a big topic, we had an intern investigating this approach a while back. Completely client side may have some merits, but I still don't really like the options that are available.

Bauke: Let's say, you can use JSF to produce exactly that client side code with JSF components to keep the client side code DRY.

Arjan: Maybe with a much better protocol and a better platform than JavaScript, things would be different. We did some experiments, but found that if you send data to the client, there's still an amount of time the client needs to render it. Ready-to-render HTML definitely has performance advantages too. I think Twitter a while back went partially back to the model of having this ready to render HTML.

Kito: Excellent. Well, it's been a real pleasure chatting with you guys.

Arjan: Thanks, thanks for talking to us.

Bauke: Thank you and you're welcome.