Matt RaibleMatt Raible is a Java Champion and Developer Advocate at Okta. developer.okta.com

The JHipster Mini-Book The JHipster Mini-Book is a guide to getting started with hip technologies today: Angular, Bootstrap, and Spring Boot. All of these frameworks are wrapped up in an easy-to-use project called JHipster.

This book shows you how to build an app with JHipster, and guides you through the plethora of tools, techniques and options you can use. Furthermore, it explains the UI and API building blocks so you understand the underpinnings of your great application.

For book updates, follow @jhipster-book on Twitter.

10+ YEARS


Over 10 years ago, I wrote my first blog post. Since then, I've authored books, had kids, traveled the world, found Trish and blogged about it all.

Comparing Web Frameworks: Presentation Outline

My Comparing Web Frameworks outline is due to the ApacheCon Planners today. I spent a couple of hours putting it together this morning and I'm mostly done. In reality, I know that I won't cover the things that everyone wants to know. In an ideal world, I could simply target the presentation towards people like me: they know Struts but want to learn more about the other frameworks. Before diving in, they want to know some things to watch out for.

The problem with doing that is writing for people like me sometimes backfires. I'd like to make it an advanced presentation, but I'm not an authority on all 5 frameworks - so that seems a bit far fetched. However, if I could add Tapestry and JSF support to AppFuse in the next two weeks - I'd have a lot more experience to refer to. But that ain't gonna happen - the first update chapter for Spring Live is due next week. OK, enough rambling - here's the slide titles I've come up with. So far, it's 22 slides and shouldn't grow any since it's supposed to be finalized when I submit it.

  • Who is Matt Raible? My background, open source involvement, etc. Trying to give myself some credibility. ;-)
  • Framework Experience: Long time Struts user, used Spring since end of last year, developed apps with other three this summer. AppFuse supports Struts, Spring MVC and WebWork; Tapestry and JSF coming before end of year.
  • Meet the Candidates
    • Struts: Pros and Cons. Pretty much a standard, lots of examples, HTML tag library kicks ass. ActionForms kinda suck, can't unit test (only StrutsTestCase integration tests), Mailing list is swamped.
    • Spring MVC: Nice lifecyle (for overriding binding, validation, etc.) integrates with many view options seamlessly, IoC for easy testability. Not widely used, requires lots of code in JSPs, almost too flexible (no parent controller for SimpleFormController and Controller).
    • WebWork: Simple architecture, tag library easy to customize, interceptors are pretty slick. Documentation only recently written, few examples, client-side validation needs work.
    • Tapestry: Very productive once you learn it, templates are HTML (great for designers), healthy project. Documentation very conceptual, rather than pragmatic (lots of "read the book"). Steep learning curve, few examples. Impossible to test - page classes are abstract.
    • JSF: J2EE standard (lots of demand and jobs), fast and easy to develop with, rich navigation framework. Tag soup for JSPs, a bit immature (doesn't come with everything), no single source for implementation.
  • Controllers and Views: Show controllers for all 5 frameworks and template page (JSP/HTML) for forms. Give URL to download sample apps.
  • List Screens: How easy is it to integrate a sortable/pageable list of data? Struts, Spring and WebWork can use tag libraries like the display tag, value list or data grid. Tapesty has contrib:Table. JSF has dataTable component that requires custom logic for sorting (let me know if this has changed).
  • Bookmarking and URLs: Struts, Spring and WebWork give you full URL control. Tapestry has ugly URLs. JSF does a POST for everything. Conclusion: first 3 play nicely with container-managed authentication. Tapestry doesn't (although there's a patch for pretty URLs). JSF is not friendly to bookmarking.
  • Validation: Struts and Spring MVC can use Commons Validation - a mature solution. I've heard it's architecture is ugly, but who cares - it works! WebWork uses OGNL which allows powerful expressions. Client-side support is new and maturing. Tapestry has robust validation w/ good messages out-of-the-box. JSF has ugly default error messages, but is the easiest to configure.
  • Testability: Struts you can use StrutsTestCase, which requires web.xml and struts-config.xml. WebWork and Spring allow easy testing with Mocks. Spring has a spring-mock.jar that can be used for mocking the Servlet API with any framework (it's not Spring-specific). Tapestry is impossible to test because page classes are abstract. The argument I've hard is "you don't need to test them b/c they're so simple." JSF page classes can be easily tested and actually look a lot like WebWork Actions (except they don't extend anything).
  • Success Messages: The easiest way to solve the duplicate-post problem is to redirect after doing a POST. Struts is the only framework that allows for success messages to live through a redirect. It's fairly easy to get i18n messages in a Struts Action. Spring has nothing "built-in" for success messages. Long classnames / method arguments make it kinda clunky to get messages. WebWork has the cleanest way to get messages using a simple "getText()" method. Both require a custom solution to make your messages live through a redirect. Tapestry requires you to throw an exception to redirect and it still doesn't redirect (I haven't solved the duplicate post problem with Tapestry). JSF requires lots of code to get a ResourceBundle, but you could use Spring's IoC to inject a "messageSource" bean, making it a lot easier. JSF requires a custom solution for messages to live past a redirect.
  • Spring Integration: Supported by all, sample apps have examples (quick slide).
  • Internationalization: JSTL's <fmt:message> tag makes it easy in all JSP-supporting frameworks. Too bad there's not a standard for getting bundles in controllers and setting messages. Struts, Spring and JSF encourage you to use one ResourceBundle for all messages while WebWork and Tapestry encourage separate files for each page/action. This strategy is probably better for large teams.
  • Page Decoration: I used to be a huge advocate of Tiles (using it since August 2001). SiteMesh is much easier to setup and use. Tiles can be used in Struts, Spring MVC and JSF. SiteMesh can be used with all 5 frameworks. In fact, the sample app uses the same SiteMesh setup for all w/o changing a thing. SiteMesh requires no maintenance, Tiles requires you add entries to tiles-config.xml whenever you add a new page.
  • Tools: Struts has lots of tools available for it and even frameworks built on top of it (i.e. Beehive's NetUI/PageFlow). Spring has Spring IDE which is really just an XML tool for validating your bean and their relationships. WebWork has none (that've been released), but it is on the roadmap. Tapestry has Spindle, which is great for code-level programmers. It doesn't do drag-n-drop, but it does validate relationships between files. JSF has lots - but all of them cost money and tend to hook into proprietary app servers.
  • Business/Marketing: Struts has lots of jobs and is well-known in the industry. A lot of enterprise applications are based on it. Spring is getting more press, but mostly because of the framework's other features. Knowing the rest of Spring is more valuable than Spring MVC. WebWork is gaining ground, but it's still virtually unheard of on job boards. If you do get gigs using WebWork, it's likely word-of-mouth and you'll probably be working with some pretty smart people. Often used with Spring and Hibernate. Tapestry needs more marketing - no one has heard of it, hence no jobs exist for it. JSF is quickly becoming the most popular. Want to stay employed? Learn JSF. The best reason: so you can back up your arguments on why you do/don't like it.

    Dice Job Count: Struts (1006), Spring (15 - not a very good name for searching, used "spring framework"), WebWork (14), Tapestry (9), JSF (147).

  • My Opinion: You have to come to the conference for that ;-). Slides should be posted following my presentation.
  • Resources: Link and such for downloads, frameworks and tools mentioned.

Comments, suggestions, like it/hate it? Let me know. I expect to send this in in a few hours - so you'd better be quick!

Posted in Java at Oct 15 2004, 12:02:03 PM MDT 22 Comments

I don't hate JSF

I'm still amazed by all the traffic and comments received by my experience with JSF. In some cases it feels like I insulted some of these guys wives or something. Here's some good quotes from the comments:

The less than positive experience is because Matt wants to write an app while asking a million questions all over mailing lists and not investing the time to learn.

I think you're too in love with struts to have a clear sight on what's going on.

Pick your poison and stop bad-mouthing others because you don't get.

I admit that I was a bit harsh on JSF in my post. Here's why. I developed 5 simple apps this summer, all doing the same thing with different frameworks: Struts, Spring MVC, WebWork, Tapestry and JSF. All of them hooked into the same backend, which was Spring+Hibernate. I had a learning curve to overcome with WebWork, Tapestry and JSF. I already knew Struts and Spring MVC, so those versions where easy to develop with. Of the three (WebWork, Tapestry and JSF), I was able to complete the JSF version the fastest. It took me a 1 1/2 days for WebWork, 3 days for Tapestry and 1 day for JSF. Or so I thought.

The JSF app was pretty close to being finished, but I was missing one thing - a sortable/pageable table. And I hadn't written the test for my page classes yet. This was Wednesday. I made a post late that night on how much I liked the JSF-Spring integration library. If you'll notice in this post, I mentioned that I got the displaytag to work too (almost). I found that I had to use an empty tag to pull the list of users from my page bean into the request, and then the displaytag could render the list. This was almost perfect, but the <h:commandLink> didn't work, so I had no way of editing a record from the table.

At this point, it all started to break down - and my frustration began. I was sooo close to completing this application and so far (even with the minor snags I'd hit) it was the easiest one to develop. Juergen left a comment stating that Spring's core now had a DelegatingVariableResolver in its core. So I figured I'd make my application more "pure" and use that instead of the JSF-Spring integration library. This was my first mistake. The DelegatingVariableResolver from Spring didn't work with Sun's RI and only worked with MyFaces. I figured it wouldn't be hard to switch (JSF is a standard, right?) - so I went to it the next day. I'd also heard that MyFaces had a sortable/pageable dataGrid - so the switch seemed like a good idea.

The first bump in the road was that while the DelegateVariableResolver worked, MyFaces reported an error. The Spring guys blamed MyFaces and MyFaces blamed Spring. Result: it's a bug that no one will fix. I spent a couple hours being a good open-source citizen by 1) trying to fix it and 2) reporting it. The second bumb in the road was that I had to change a few things that worked in the RI but didn't work in MyFaces (I forget what now). However, this wasn't so bad since it also fixed a couple of issues.

Next I tried to use MyFace's <x:dataTable> to replace the display tag. Since it had a sortHeader component, I figured this would be easy. It turns out this component requires you to implement custom logic in your page bean. Things might've changed since July, but I doubt it. Lastly, aftering getting everything to work, I went to work on writing a jWebUnit test to test it all. While doing so, I found that it was almost impossible to test my edit screen. With other frameworks, I could specify a URL with a record id and then proceed to change form fields and push buttons. With JSF, there was no easy way to determine the URL. The rendered UI used heavy JavaScript and when you clicked on a link in the dataTable, this called a JavaScript function. I have no problems with JavaScript and I think it's a great technology. However, the current UI testing frameworks I use (jWebUnit and Canoo WebTest) use the Rhino JavaScript library (js.jar) and it sucks at JavaScript. It reports errors where there are no errors - and hence, I tend to exclude the JAR and disable JavaScript support in my tests. If there was better JavaScript support in these testing frameworks - I'd likely have to problems with JSF's "I post for every link" mantra.

In most of my development life, I've most often been a framework user rather than a developer. This means that if I find problems, I don't extend the framework - I look for other solutions. Call me whatever you like, but I'm just trying to get my job done and the project completed. I don't want to mess with the internals of a framework to make that happen. With JSF (and Tapestry too), you have to be more of a framework developer. You have to be willing to create your own components. These frameworks are designed as component frameworks and they want you to extend them. That's one of the major points of their architecture.

So here I am again, posting about JSF - which will undoubtably get an incredible amount of hits just because it has "JSF" in the title. Why? Because you can't ignore JSF. Even if you don't want to develop with it - there's going to be tons of jobs that require JSF in the near future. In fact, there are already quite a few. Surprisingly enough, in my job search last month, I has a more opportunities for JSF (and WebWork suprisingly enough) than Struts. Finding a Tapestry gig - good luck. Of course, I'm a consultant, not an employee - so I don't often don't get to choose frameworks for companies.

I think JSF is an immature technology that will rapidly mature. I hope it does b/c it was fairly easy to develop with - there were merely some minor bugs in the two implementations. These can be fixed. In reality, I think we should all quit bashing on JSF and jump in to try and make it better. Rather than complaining, let's try to help.

I've done my part and applied to be on the JSF Expert Group. They probably won't let me in though - everyone seems to link I hate JSF. If I had my way, I'd scrap the sucker and make Tapestry the JSF standard. ;-)

Posted in Java at Oct 15 2004, 09:04:03 AM MDT 12 Comments