I set aside some time this weekend to learn Maven which I continue to hear a lot about and until this weekend knew very little about. I was definitely impressed, I'll be hard pressed to go back to using Ant after seeing the power of Maven. I got started with this article from the TheServerSide.com: Maven Magic.
After working with it a bit, the main areas I hope Maven will improve over time are:
- Documentation, primarily better docs for the plugins.
- A downloadable version with binaries and docs. Since I learned it where I only had a dialup connection I found it frustrating to have to dialup everytime I wanted to look for some basic information.
- Some packages on ibiblio are out of date so I had to use my local repository.
The things I really like about it are:
- Dependency management, amazing!
- Plugins plugins plugins plugins!
- Sensible build defaults for most types of projects.
- Great Ant integration and support if I need more control over the build process.
- Nice reporting system for continuous integration build processes.
Here was my one road block while learning Maven. I was missing a jar that one of unit tests required at runtime and here's the output I got when running maven -X test:
File...... C:\Documents and Settings\thuss\.maven\cache
com.werken.werkz.UnattainableGoalException: Unable to
obtain goal [test:test] -- C:\Documents and Settings
Any idea what class is missing based on the above? Me neither! I spent almost an hour searching forums and tearing my hair out until I finally tried setting the property maven.junit.fork=true in my project.properties file. Then JUnits log messages started to show on STDOUT so I could see that I had forgotten the hibernate jar in my dependencies (which was only a runtime dependency since I'm using the spring-orm support). Anyhow, there's probably a maven parameter I could set to show logging messages while running the test goal but I couldn't find it and maven -X was no help. One of the main goals of TDD is that the build process and unit tests will tell you what's broken so you can refactor with confidence. Kind of ironic that one of my unit tests was simply missing a runtime dependency and maven couldn't give me a better error message.
That minor frustration aside, Maven is a great tool!
On a very long flight to Germany and back I started digging into Howard Lewis Ship's book Tapestry in Action. I am very impressed with Tapestry so far. It does have a fairly steep learning curve compared to your more typical request/response frameworks such as Struts and Spring MVC. I attribute this to two main points:
- 1. Tapestry uses more of an event driven programming style rather than the more familiar web style request response which makes the overall programming model closer to regular GUI programming. The tough part for me as a web programmer is that I tend to think more in terms of request response so this required a bit of a shift in the way I think when develping with Tapestry. I'm told JSF is similar in this regard.
- 2. Tapestry uses its own templating language (which reminds me a bit of Enhydra's XMLC). I really like it because it's non-invasive unlike JSP. Once you've worked with one templating language for a while though (in my case JSP) switching to a new one takes time.
People tend to evaluate MVC frameworks (and software in general) based on what is easiest to get up and running with the fastest. I'm not convinced this is a sound approach though. It may be fine when your developing a simple page for a personal website. However, once you throw in a lot of complex requirements such as internationalization, complex client and server side validation, cobranding, etc… the framework that solves the complex requirements in the simplest and most elegant manner is going to be more cost effective in the long run, even if the up-front learning curve is steeper.
Things I'd like to see in Tapestry are resources that can be shared among pages and cleaner search engine friendly URL's (although that's a general gripe I have with the servlet spec as well). I don't think URL's are a showstopper though since on a real project I would probably just use Apache to transform a search engine friendly url like http://x.com/product/id/1234 to http://x.com/product?id=1234 for the servlet container.
With regards to the book I think Howard does a good job overall. The hangman sample application was interesting and illustrates Tapestry's elegance and power, however, I breezed through it to get to form handling since that's more relevant to the type of work I do. In summary, with very clean non-invasive templating, a nice per page XML file, graceful form handling and validation, internationalization, etc… Tapestry is definitely in the running for me as my MVC framework of choice. I now just need to get more real-world implementation experience with it.
I've been playing with Spring MVC and adding Commons Validator support for both client and server side form validation.
I'm always surprised (although I shouldn't be) by the number of web apps I run across in the corporate world that only do client side validation or do server side validation and then force you to hit the back button. Anyhow, the process was relatively painless and I had support added to my project and working in about 30 minutes. Adding validation to new forms in the project is a matter of minutes now. I followed Matt's tutorial Using Commons Validator with Spring Redux.
Now I have my controller use Spring's BeanValidator and can simply add my validation to my WEB-INF/classes/validation.xml file and voila, client and server side validation. I also like that Spring lets you use your model objects as MVC command objects. So on a basic detail page I only need to create my controller with a few lines of code, a JSP page, and edit my validation.xml file.
Next up I'm hoping to spend some time this weekend and look at Tapestry to get a better feeling for it. I just picked up Tapestry in Action which is proving to be an interesting read so far.
We're hiring a software development team lead/architect with a passion for continuous integration, agile software development, unit testing, MVC frameworks, IoC containers, and ORM. This person either lives in or near San Francisco. We're in the process of migrating our site from Perl to Java, so over the next month or so one of my main tasks will be to hire that person.
If you or someone you know fit the bill check out the job posting and apply.
Update 11/30: so far out of 50+ candidates applying for the job only 1 has Spring and Hibernate experience. I've talked with other folks trying to hire this same skillset and not surprisingly there are not a lot of people out there with it. I guess on the bright side, if you have production Spring and Hibernate experience you're probably in demand if you market yourself well.
Update 12/31: still looking and updated the URL to the craigslist posting. I have about 40 more resumes to review now so I'm hopeful…
Update 1/31: still looking. Enjoyed Mike's HOWTO on applying for a java job, it rings true with my experience so far. Updated the URL to point to our website instead of craigslist.
In working on a Spring MVC workshop for programmers at work I've been toying around with the JSP Display Tag library. On the downside, like most taglibs that generate HTML for you it's no good for an HTML designer since it doesn't render in a browser without a servlet runner, but for a programmer, all I can say is, wow! No more table,tbody,tr,td,td,td,td,tr,tr,td,td,td,…. uugggh!
The Displaytag Live Examples give you an idea what you can do with it. To get the CSS so it renders like the examples, I had to extract the CSS file from the displaytag demo WAR file. Would have been nice if they included the CSS global.css file in the same directory as the JAR and TLD files shipped with the distribution since most users starting out will want the CSS. First impressions: it's a pretty powerful tag for JSP work!
Between work and home I'll surf the web on one of many Windows, Linux, or MacOS X machines. A few years ago I used to be able to keep my bookmarks synchronized using Netscape and an Apache mod. My only requirement was that it be through an interface that's always present while I'm browsing so I can easily add a new bookmark. That pretty much eliminates those web sites that let you store bookmarks through a web interface.
I've finally found a solution that works for me with Firefox: the Bookmark Synchronizer. What a relief. Now I can add a new bookmarks on any machine and when I switch to a different machine, they're there. It supports an XML format called the XML Bookmark Exchange Language (XBEL) so I'm hopeful other synchronizers will eventually come out for IE, Safari, etc…
For you folks wanting a more cross browser solution, another alternative I played with for a bit was the Yahoo toolbar which does synchronized bookmarks as well (albeit through the toolbar and not the browser native bookmark interface). The Yahoo Companion For Firefox supports that as well. So with that you could at least switch between IE and Firefox, although why would you want to? 😉
I had a chance to play with Hibernate and Middlegen this afternoon for a few hours in preparation for doing a Hibernate workshop with some programmers at work. My preference has always been to design my database schema and then generate the ORM layer on-top of that. I guess my reasoning is that the database is the heart of any large application and in many cases will have a web-app running against it, a 3rd party reporting system, an automated emailing system, etc… so it feels unnatural to me to use my web-app codebase to generate the schema.
This article on Hibernate's website got me started with Middlegen. After mucking with my ant build.xml I had Middlegen and Hibernate's hbm2java generating my hibernate mapping files and java domain model. Not bad.
Next I created some DAO objects and respective JUnit tests to play with some Hibernate queries to fetch my domain objects. For simple stuff QBE (Query By Example) is by far my favorite since it in no way ties you to an ORM suite and is the most object oriented looking approach to simple querying (to me atleast). HQL is also simple (and of course familiar) for doing joins and other more involved queries. I have the least experience with QBC (Query By Criteria) so I tend to stick with HQL. I guess with QBC I find myself translating it to an SQL like syntax in my head anyhow so HQL just feels more natural.
Next I want to try adding Spring into the mix for IoC and to get the benefit of Spring's generic unchecked exception hierarchies so I can stop polluting my DAO's with all of those try/catch blocks that are only there to catch unrecoverable errors anyhow. My take is, if it's not a recoverable error than the exception should be unchecked. That way I can catch it if I want but otherwise it will go right up the call stack without me having to declare it everywhere.
Just finished Rod Johnson’s excellent and very accessible book Expert One-on-One J2EE Development without EJB. What I think this book does best is provide one with a good introduction and overview of:
- IoC containers
- MVC frameworks
- OR Mapping
- Unit testing (covers Mock objects as well)
- Vertical versus Horizontal scaling
Having taken a 2 year hiatus from Java (and EJB) programming, I came back to find the java architecture/framework landscape vastly improved but with a lot to learn (namely IoC, MVC beyond Struts, AOP, and Unit testing). I was also thrilled to find a good open-source OR mapping alternative to Toplink and Cocobase (the latter of which I used for 3 years). This is the 3rd book I’ve read on these topics and so far my favorite!
I hate having to test a site on multiple versions of Internet Explorer, not to mention my general dislike for IE as a browser. Anyhow, up until today, I’ve known which machines in our office have older versions of IE so I can use them to test.
No more! I discovered Ryan Parman’s site where he has created standalone IE. You just download the version of IE you want, unzip it, click ieexplore.exe, and you’ve got that version running and it doesn’t conflict with your installed version of IE. Great work Ryan!
I’ll have to try this out with Wine on Linux and see if it works…
I found this very informative thread over on the serverside with the authors of Hivemind and Spring discussing the differences in their approaches. Scroll down past the hivemind announcement for the juicy stuff:
I would sum up the differences (and I'm interested in others opinions here) as follows:
- Configuration: has better support for strongly typed configuration with its excellent configuration point schema support. Spring only supports this via Map, List, and Properties.
- AOP Interceptors: has a less verbose syntax for configuring interceptors which I find more readable and correct (not directly exposing the target) than Spring's
- Hivedoc: a great way to visually see how all your dependencies wire up
- 3rd party support: Hibernate, iBatis, Struts, Transaction management, etc…
- Generic exception heirarchies: for example for data access
- Large user base