Matt RaibleMatt Raible is a writer with a passion for software. Connect with him on LinkedIn.

The Angular Mini-Book The Angular Mini-Book is a guide to getting started with Angular. You'll learn how to develop a bare-bones application, test it, and deploy it. Then you'll move on to adding Bootstrap, Angular Material, continuous integration, and authentication.

Spring Boot is a popular framework for building REST APIs. You'll learn how to integrate Angular with Spring Boot and use security best practices like HTTPS and a content security policy.

For book updates, follow @angular_book on Twitter.

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.
You searched this site for "framework". 558 entries found.

You can also try this same search on Google.

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

Comparing the Big 5 Web Frameworks

My session at ApacheCon is titled Comparing Web Frameworks: Struts, Spring MVC, WebWork, Tapestry & JSF. I have to turn in my presentation by Friday. The purpose of this post is to get your feedback and see what you'd like to see in such a talk. Here's the abstract:

This session is designed to explore the popular Java web frameworks. It will briefly explain how each one works and the strengths and weaknesses of each. Tips, tricks and gotcha's will be plentiful. A simple web application will be dissected and the different options will be compared. Lastly, it will provide attendees with a sample app they can download that has options to use any of the frameworks described.

The simple webapp is MyUsers from Spring Live. As part of my gig with Open Logic this summer, I wrote a number of sample apps using Equinox. Among these where 1) a Mavenized version, 2) a Tapestry version, 3) a JSF version, and 4) WebWork version. The Struts and Spring MVC versions were already done as part of the book. They agreed to let me use the code and knowledge from that experience. This is all to say it shouldn't be too hard to create the sample app for this talk.

The hard part is going to be talking about things that developers care about. In my post on JSF a while back, I noted the things I typically want in my webapps. The following topics might make good points of discussion.

  • A sortable/pageable list of data. It's possible, but you have to add special sorting logic for each class. JSP already has this with the display tag - I'd simply like to be able to use it in JSF.
  • Bookmarkability. Container managed authentication gives us a great way to offer users the ability to bookmark pages. If everything is a POST with JSF, we lose this ability. Sure there's the HTMLOutputLink, but if we can't invoke actions, what good is it?
  • Clean and easy to read validation messages. The validation messages in both MyFaces and Sun's RI are not something you'd deliver to customers. What's wrong with making clean messages out-of-the-box? Tapestry seems to have no problems doing this. All the other MVC frameworks make you specify your own - which is fine with me.
  • Easy cancelling and multi-button form handling. JSF does this well - better than the rest I'd say.
  • Easy testability. Because of the plethora of JavaScript, JSF apps are difficult to test with tools like jWebUnit and Canoo's WebTest. Don't get me wrong, I love JavaScript - but an application should be able to be tested w/o it.
  • Success Messages. JSF does success messages OK - it's a pity it's not easier to get a resource bundle and it's a shame that you can't escape HTML in the <h:messages> tag. This seems like an oversight to me.

I could do a number of slides and show how each framework handles the above situations. Other topics that would be worthwhile would be:

  • Model in View - can you use your model objects to back forms or do you have to use something like ActionForms?
  • Spring Integration - all of them have this. This would merely be a discussion on how its handled.
  • Validation - how robust and/or extensible is it? How hard is it to do chained validation? What about client-side validation? Is the client-side stuff immature like WebWork's?
  • Internationalization - how is it done and how hard is it to get messages in your classes? JSF sucks at this.
  • The Duplicate Post Problem - how does it handle duplicate posts. Not the "push the submit button twice" but the "hit refresh after saving" kind. Tapestry fails this test.
  • Page Decoration - SiteMesh can be used for all frameworks, Tiles for some. Discuss how much easier it is to use SiteMesh.
  • Tools - since some frameworks have tools to help ease there development and others don't.
  • Business/Marketing - how well known is the framework and will your skills be marketable if you learn it? JSF and Struts are in high demand. Tapestry is virtually unheard of. WebWork is for the evil few (heh!) and Spring MVC is the new kid on the block.

Whaddya think - what is so special about your framework that'll make it look better in my talk? What are the things that suck that I can bash on? If you're a committer on one of these frameworks - are you going to be at ApacheCon? I'd love to have some folks defend their projects after I'm done ripping on them. ;-) If I don't rip on yours, then you can bask in all its glory.

If you live in Denver, I'll be delivering this presentation at DJUG's Architecture SIG on November 3rd.

Posted in Java at Oct 12 2004, 11:59:16 PM MDT 28 Comments

The New Gig

I started a new gig on Monday. For the next 6 weeks or so I'll be helping Oak Grove Systems enhance their Reactor products. I'm excited about the opportunity. I was going to use Equinox to build the prototype (due Monday), but since the final product requires security and user management - AppFuse is a more logical choice. I'd like to use WebWork or Spring, but since Oak Grove's reference implementation of their portal framework uses Struts, it's probably wise that I do the same so they can maintain it easier.

I almost went to work full-time and in an office - but now that I've chosen to take a gig with 100% work-from-home, I'm pretty glad I did. It would be tough to give up the musing-blaring, 23" monitor environment I've grown to know and love. The new office later this month will make it even nicer. BTW, the house is coming along and we should move in in a couple of weeks. Here's some pics: view from front, view from back and inside view.

Posted in Java at Oct 07 2004, 10:02:11 AM MDT 4 Comments

Aren't out-of-container tests supposed to be faster?

Earlier this week, I converted my StrutsTestCase tests from using CactusStrutsTestCase to MockStrutsTestCase. At first, this seemed like a great thing - on my Windows XP box. To run all the tests in AppFuse, it takes around 2:20. I know, this is quite a bit of time for unit tests - but it was 3:15 in version 1.5. At least it's faster than it was. 1:20 of this is for starting Tomcat and running Canoo WebTests.

This all seemed great until I ran "ant test-all" on my PowerBook tonight. It averages around 7:00 minutes. WFT?! I know PowerBooks are slow - but they're not that slow. I'm guessing the reason is because Spring's ApplicationContext is loaded by each test - whereas the Cactus versions would always grab it out of the ServletContext. Sounds like I need a TestSuite.

What if I isolate and compare times for just the "test-web" target? This target runs all the Action, Filter and Listener tests. Time to execute on Windows: 33 seconds, PowerBook: 2 minutes 21 seconds. What about just testing the JSPs (with Cargo)? Windows: 1:24, PowerBook: 3:32. My Windows desktop has 1.5 GB RAM and a 2.6 GHz processor. My PowerBook has 1 GB RAM and 1.5 GHz. I agree that it seems like an unfair comparison - but AppFuse tests ran in around 4 minutes on the PowerBook in the last release. I guess it's back to the drawing board.

Update: Nevermind. I just downloaded and checked out AppFuse 1.5 - almost 8 minutes for running all the tests. If I were going to work on my PowerBook for my next project, I'd refactor AppFuse Managers and Actions to use jMock. Luckily I'm using my Windows machine. ;-)

Update 2: I found a solution! Using Ant 1.6.2's forkmode="once", I was able to reduce the time of the test-web target from 2:21 to 24 seconds on my PowerBook!! Windows: :33 -> :18. Running "ant test-all" on the Mac is now 2:15 - while the Windows version is 2:20.

WTF!? My PowerBook is actually faster than my Windows box? I never thought I'd see the day - Yeeee haaawwww!!

Now I just have to figure out how to detect 1.6.2 and warn users if they aren't using it.

Posted in Java at Oct 05 2004, 09:26:56 PM MDT 8 Comments

Integrating WebWork into AppFuse

Last week was a busy one as I was trying to finish up AppFuse 1.6 before starting my new gig (more on that later). Most of this involved 1) integrating WebWork and 2) writing the Ant-based installer for replacing Struts with WebWork. I've worked with WebWork before, so this post is mostly an extension of that - as well as documentation on what I did so others can understand AppFuse+WebWork better. Below is a list of things I found.

  • WebWork's concept of "results" are very similar to Struts "action-forwards". However, they also allow you to chain to other actions and use expressions.
  • Implementing the ModelDriven interface in your Actions is a good idea, but it's not that great. I found that by simply using get/setUser(), I got the same functionality - except that I had to add "user." to all my form elements in my JSP. The advantage to doing things this way (over ModelDriven) is you can have an Action that services many objects. The main reason I'm not using ModelDriven is because the following tag doesn't render the label (it's just blank). Strangely enough, it renders just fine after validation fails.
    <ww:textfield label="getText('user.firstName')" name="'user.firstName'"
        value="user.firstName" required="true"/>
  • WebWork is similar to Tapestry in that they encourage you to specify i18n messages (properties files) on a per-action basis (Tapestry is per page). Some might think this is a good idea, but after using Struts and Spring, I'm used to using one ResourceBundle for everything. To migrate AppFuse from using 1 bundle to many bundles just for WebWork would've been a pain. Luckily, in WebWork 2.1, they added the ability to specify a custom bundle using "webwork.custom.i18n.resources=ApplicationResources" in webwork.properties. I believe my issue with ModelDriven and labels is caused by this new feature.
  • The Spring-integration provided by SpringObjectFactory is quite nice. Unfortunately, client-side visitor validation doesn't work with it.
  • Unit-testing WebWork actions is easy, though it's kinda wierd to not send request parameters and such to set values (instead, you just set values directly on the Action).
  • I experimented with putting stuff on the stack and pulling it off in JSPs, but never got it to work quite right. After failing the 10 minute test, I decided to just put stuff in the request and get it working. Looking through the code now, there's only 3 places where I'm stuffing attributes into the request: 2 in FileUploadAction and 1 in ExceptionHandlerInterceptor.
  • With most frameworks I've used in the past, I rarely jumped into the source to try and see how things worked. Because of this, I rarely extended framework classes for my own use. However, with WebWork/XWork, I found it quite easy to dig in and extend the framework. Especially with Interceptors - which I dig.
  • Following up on Interceptors, I was able to easily create my own ValidationInterceptor that cancels validation on GET requests, and when cancel or delete is clicked.
  • Other interceptors that came in handy are a UserRoleAuthorizationInterceptor (which I borrowed from Spring) and an ExceptionHandlerInterceptor (which is modeled after Spring's SimpleMappingExceptionResolver). The 1st interceptor made it easy to mimic Struts' ability to declare a "roles" attribute on an action-mapping. The 2nd one allows you to map exceptions to results. This is something I was looking for when I first started using WebWork.
  • The "required" attribute in WebWork's JSP tags have nothing to do with validation, except that they add an asterisk to the field label. I'd rather this be integrated with validation - where an asterisk shows up when a field is "required" in its Action/POJO-validation.xml file.
  • I had a few other issues with validation: client-side validation shows one error at a time, client-side validation doesn't allow cancelling and field errors are displayed in a random order. If I were to start a project tomorrow that wanted WebWork with client-side validation, I'd probably try to integrate Commons Validator.
  • Testing Actions is easy, as it should be. Using Spring's Servlet API mocks made it easy to test Actions that used ServletActionContext to set cookies and other such request-related stuff.
  • I dig the rich set of form tags and it's great that these can be easily customized. I customized a few for AppFuse to make the syntax a bit more XHTML-compliant.
  • I'm a stickler for formatting and good-looking XHTML in JSPs. I try to keep lines less than 80 characters. Here's a comparison of the LOC required by the different frameworks for userForm.jsp:
    • Struts: 298
    • Spring: 319
    • WebWork: 186

All in all, I enjoyed working with WebWork and if given a choice of an AppFuse combination to use on my next project - it would probably be WebWork+Hibernate. If the client wanted client-side validation, I'd either integrate Commons Validator (which shouldn't be too hard) or use Spring+Hibernate. After using Spring and WebWork, which allow you to use your model objects directly in the view, it would be tough to go back to Struts. However, I still do know Struts better than the other two - so if I had a really tight deadline, that might be the smart way to go.

Posted in Java at Oct 04 2004, 08:17:37 AM MDT 2 Comments

AppFuse 1.6 almost done

I spent many hours and quite a few late nights this week working on AppFuse. It's funny how little sleep you can live on when you're working on something you're passionate about. There's only a few items left on the 1.6 roadmap, so I hope to do a release in the next week or so.

The major new feature in 1.6 is WebWork as a web framework choice. If you'd like to dig in and take AppFuse+WebWork for a test-drive, checkout AppFuse from CVS and execute "ant install-webwork". From there, the tutorials are a good place to start. The QuickStart Guide has more detailed instructions.

If you don't want to do the DAO and Manager stuff, and you'd rather just dig into WebWork, you can download the files from the first two tutorials and extract them into your project.

For a complete list of changes (so far) in 1.6, see the README.txt in CVS. You can also checkout the following demos:

I'll try to write up a detailed post about my WebWork experience in the next couple of days. In the meantime, let's just say I dig it.

Posted in Java at Oct 02 2004, 03:45:49 PM MDT 5 Comments

WebWork's Validation and SpringObjectFactory

For the last couple of nights, I've been wresting with WebWork's validation framework and trying to get it's client-side stuff to work with AppFuse. After much frustration, I finally figured it was caused by the SpringObjectFactory class. By using this patch, I was able to get regular client-side validation to work, but not the VisitorFieldValidator - which is what I'm using for almost all validations.

Since I've been done with the WebWork integration into AppFuse for a few days now, I think it's time to cut my losses and start working on other stuff for the 1.6 release. Hopefully someone will figure this out someday, but in the meantime, the server-side validation should satisfy most requirements.

In other words: there will be no client-side validation for WebWork in AppFuse 1.6.

Update: After playing a bit more tonight, I almost added client-side validation by specifying the validation rules per-action rather than per-POJO. Then I discovered that the client-side validation has no way to cancel its invocation. With Commons Validation, you can add an onclick handler to a submit button (onclick="bCancel=true") to cancel client-side validation.

Posted in Java at Sep 27 2004, 06:09:31 PM MDT 2 Comments

[DJUG] JMX and JDO 2.0

Last night I attended the local Denver JUG meeting. Chris Huston gave a presentation on JMX and Dion gave a presentation on JDO 2.0. Below are my notes from the event.
-----------------------------

Java Management Extensions one of the first JSRs and now included in to JDK 5. Monitors health of the system. Alter sys-admin of error conditions. Provides capability of to view and modify runtime parameters.

MBeans are deployed in an MBeanServer and their capabilities are exposed through Connectors. Then tools talk to these connectors to get their information.

JMX is covered by two separate specifications: JSR-3 (MBeans) and JSR-160 (Connectors). BTW, Chris has some good slide-making capabilities - I'll have to get some tips from him for my next preso. For example, he shows an entire class and its methods, then he fades it and zooms in on certain methods and highlights them to explain what they do.

Four types of MBeans: Standard MBeans, Dynamic MBeans, Model MBeans and Open MBeans. More info on these Mbeans can be found at http://docs.sun.com.

Standard MBean: All you need to do create an interface for your class your class name with "MBean" appended to it.

In order to deploy, you need to create and configure an MBeanServer. You can create an MBeanServer using javax.management.MBeanServerFactory.createMBeanServer(). MBeanServers keep track of MBeans using a javax.management.ObjectName. After creating and configuring an MBeanServer, you simply need to register your MBean using an Agent. All pretty simple so far, right? Now you have to use a Connector to expose your MBean to the outside world.

"Connectors are the fly in the ointment." MX4J is an open source project that has good Connectors: i.e. RMIAdaptor and HTTPAdaptor. There's also SNMP Adapters from a number of commercial vendors. In order to solve the current lack of good Connectors we have JSR-160: Distributed Services Specification. This JSR defines one connector: JMXConnector (part of JDK 5).

Chris is now showing us a counter widget deployed as a Swing app and managed using MX4J's web interfaces. Very cool stuff - the ability manipulate runtime parameters. As Chris stated - the real power of JMX will come from the tools. I wonder if there's MBeans available for monitoring webapps - seems like there'd be quite a market for management beans you could just drop in and deploy.

Notifications are another feature of MBeans and can be sent by an MBean. Two important interfaces: NotificationEmitter and NotificationListener.

Chris gave a good introduction to JMX, but I don't see myself using it anytime soon. It seems to be something that framework and container developers might use, but not many application developers. Maybe I'm wrong - are you deploying MBeans as part of your web applications? Chris mentioned that Hibernate and Spring have MBeans as part of their distribution - anyone using these? If nothing else, it's great to know that JMX is available if I ever do need to monitor and control applications.

-----------------------------
Now Dion's up after a 1/2 hour break with announcements. Dion is talking about JDO 2.0. I think JDO would be a lot more popular if it wasn't for Hibernate. Hibernate seems to have done JDO better and faster.

What is JDO?

  • Allows for object persistence
  • "I have objects, some need to be persisted"
  • "Keep state and behavior together. That is the OO way."

JDO Main Objectives:

  • To enable pluggable implemenentations of data stores into application servers
  • To provide applicaiton programmers a Java-centric view of persistent information, including enterprise data and locally stored data.

Other Objectives:

  • Transparent Persistence
  • Persistence-by-Reachability
  • OO framework on top of potentially non-OO stores.
    • RDBMS (98% of the time)
    • Files
    • TP Monitors
    • Legacy
    • Properietary
  • Integrate with existing technologies
  • Java compatible - no need to learn new language
  • Usable in managed and non-managed environments
  • Define easy semantics for caching objects
  • Ability to run in all Java platforms (J2SE, J2EE, J2ME)

When JDO first started, a bad thing happened - the object database guys were heavily involved. JDO 1.0 had 80% of its Expert Group from object database vendors. JDO 2.0 got object guys off the committee and real-world (relational) folks onto it.

JDO 1.0: Most of it is not very new - just a standard way of implementing persistence. Other proprietary tools already accomplish most of what JDO is.

JDO 2.0 Strategic Goals:

  • Easy to Use
    • natural programming model
    • configuration and deployment
  • In a Wide Variety of Environments
    • J2SE (rich clients)
    • application, web servers

JDO 2 Status: First Early Draft Review is out there. Soon there's going to be a Community Review - then things will start rolling after that.

JDO 2.0 Goals:

  • Maintain JDO 1.0 Compatibility (big thing with Sun)
  • Standardize Mapping to Relational DB (was vendor extension in 1.0)
  • Multi-tier Development Improvements
  • Usability Improvement
  • Better Object Modelling
  • Richer Queries - JDOQL, SQL and Named Queries
  • More Vendor Support - try to get Hibernate and Oracle on the bandwagon for political reasons

Dion's take on politics between EJB 3 and JDO 2

  • Let's get a standard around transpanent persistence first
  • Let's have a standard that can be shared between various groups: J2EE, J2SE, J2ME
  • Why have more than one O/R mapping specification?
  • Specifications such as EJB could be an umbrella spec for the cross cutting concerns

Why are people even arguing about it? Money. Because companies have invested a lot of time and money into X technology and therefore they bash the other. This problem might be solved by an O/R Mapping JSR that both EJB and JDO have to adhere to.

JDBC vs. JDO

JDBC JDO
SQL-oriented Object-oriented
Explicit intrusive code Fully transparent
Manual mapping Automatic mapping (automatic == create XML file)
RDBMS-centric Universal

JDO will use all J2EE services inside a container.

Deployment time scalability - database becomes bottleneck as number of users increases. JDO middle tier can relieve this load on the databse. JDO's configuration can be altered at deploy time to handle better scalability through caching.

JDO 2.0 Multi-tier Development - big thing is disconnected objects through attach/detach. Very simple API for detaching and re-attaching objects. Internally there's a version that's used to determine if the object is the same one.

JDO and EJB
As opposed to Entity bean, JDO instances...

  • May have subclasses
  • May exist outside a container
  • Has 1 optional interface to implement
  • Accessible as transient objects

And as of JDO 2 (new and improved object modeling!)

  • Persistent Abstract Class Support
    • map abstract classes to tables
    • map properties, fields to columns
    • create new implementation instances
  • Persistence Interface Support
    • map interfaces to tables
    • map properties to columns
    • more, but I missed them

Some argue that JDO is what Entity Beans should have been!

  • JDO is "purer" way to use OO
  • Since Entities should be used via local interfaces, why not just do Session Facade -> JDO objects
  • CMP in Sun AppServer uses JDO

Some argue that JDO complements Entity Beans because Entity beans can use JDO.

EJB3 is totally moving directorys with regards to Entity Beans, and they are much more like JDO.

EJB3 EntityManager == JDO PersistenceManager == Hibernate Session

JDO and Connector Architecture - JDO is NOT a framework, but plays well with others!

The JDO architecture uses the J2EE Connector architecture for application servers. The JDO PersistenceManager is a caching manager as defined by the J2EE Connector architecture.

A PersistenceManager may define the following Connector components:

  • ResourceAdapter
  • ConnectionManager
  • ManagedConnectionFactory
  • ManagedConnection
  • LocalTransaction

Persistence Contract (behind the scenes)
- To achieve transparence, JDO:

  • Defines a PersistenceCapable interface
  • Used too mandate binary compatibility among all vendors (optional in JDO 2)
  • Uses tools to make a class persistence capable

- Declares any fields available for persistence storeage

- Defines methods that allow JDO instance management

  • jdoIsDirty()
  • jdoIsDeleted()
  • jdoMakeDirty()

JDO has a number of callbacks that you can implement: jdoPostLoad(), jdoPreStore(), jdoPreClear(), jdoPreDelete().

In JDO 1: one interface: InstanceCallbacks
In JDO 2: InstanceCallbacks purely extend interfaces: LoadCallback, StoreCallback, etc.

Ways to make classes persistence capable: byte code enhancement, annotations (maybe for JDO 2.1).

JDO Interfaces: PersistenceManagerFactory, PersistenceManager, Transaction (new set/getRollbackOnly() in JDO 2) and JDOHelper (class with static methods, for use by persistence-aware classes), Query, Extent. You'll probably never use an Extent; like "select * from table". Represents all instances of a class or subclasses.

A persistence cabable class is just a POJO - you could use the same class for JDO and/or Hibernate. A default contructor is required in JDO 1, but not in 2.

JDO 2.0 has "use cases" for lazy-loading. This enables you to configure fetching based on certain situations. Sounds pretty cool.

Extent is usually optimized for better performance. If you're selecting all records from a table, you're probably better of using Extent vs. Query in order to avoid OutOfMemory errors.

New in JDO 2: ability to specify query filters in other languages - i.e. SQL or HQL or user-defined. These languages are up to the JDO vendor to implement.
JDO can use stored procedures if you map it in your metadata.

JDO 2.0's Query API looks very rich. It allows you to limit your results to certain properties/columns, as well as set what type of to return.

JDO 2.0 supports obtaining a java.sql.Connection from PersistenceManager. However, this may reduce portability since not all SQL is portable b/w databases.

Overall, I thought this was a great talk by Dion. If you're looking to start working with JDO 2.0, I'd recommend JPOX (also see JPOX with Spring or Tapestry). Unfortunately, their implementation still requires you to "enhance" your classes at build-time, but hopefully they'll have a transparent mechanism for manipulation (i.e. cglib) soon.

Posted in Java at Sep 09 2004, 10:06:42 AM MDT 6 Comments

Commons Validator with WebWork?

I'm in the midst of integrating WebWork into AppFuse. I started wiring validation last night. This morning, I realized that I could probably use Commons Validator to make validation a lot easier. Here's why:

  • WebWork validation rules are defined per-action, rather than per-object. This makes it difficult to define the validation rules with XDoclet. I can't just put tags in the model object to generate the validation rules. This works with Struts and Spring quite nicely.
  • Using a custom LabelTag, I've been able to hook into Commons Validator and mark fields as required. With WebWork's validation, it seems that this can only be accomplished by adding a required="true" attribute to my <ww:textfield>. I prefer the transparency of the custom tag.
  • I've never been able to get WebWork's client-side validation working. Commons Validator has excellent client-side validation support.
  • Spring has support classes for Commons Validator - leading me to believe that I can configure validation in Spring and re-use its JavascriptValidatorTag.

Now I just need to figure out 1) how to hook WebWork custom tags (or my own custom tag) into the validator to mark fields required and 2) how to write a validation interceptor that uses Commons Validator. Whaddya think? Are there advantages to using WW's validation over Commons Validator? Any tips for writing an interceptor or modifying the custom tags?

Posted in Java at Sep 04 2004, 11:10:08 AM MDT 4 Comments