Taking the week off

I consider Kathy Sierra (and her husband Bert Bates) good friends of mine. I've seen them quite a few times over the years at various conferences. They're some of the nicest people I've ever met and I always enjoy our conversations.

The recent death threats she's received is sick and wrong. I don't know what to say, except that I hope they find the morons that are doing this and prosecute them appropriately.

I like Scoble's idea and will be taking the week off as well. Too bad, it looks like there won't be an April Fools entry this year.

Posted in General at Mar 26 2007, 09:26:38 PM MDT 5 Comments

Apache Struts 2 from Square One

Ted Husted has put together an impressive training course together for Struts 2 called Apache Struts 2 from Square One. He's released an initial version of the 127-page PDF on SourceForge.

Thanks Ted! The fact that you're contributing this hard work to the community (for free!) is amazing.

I'm teaching a 3-day training course in May that covers Spring, Hibernate, Maven 2, Ajax and AppFuse. I'm not sure if the client wants Struts 2 or Spring MVC for their web framework. If they want Struts 2, you can be sure I'll checkout Ted's course as a starting point.

Posted in Java at Mar 24 2007, 08:48:44 PM MDT Add a Comment

AppFuse 2.0 M4 Released

The AppFuse Team is pleased to announce the release of AppFuse 2.0 M4! This release marks a milestone in the usability of AppFuse 2.x. A lot of folks (including myself) have been using AppFuse 2.0 on projects and have fixed quite a few issues. In addition to polishing the tutorials, we've fixed a fair amount of i18n bugs and packaging issues with modular archetypes.

We were hoping to get AMP's code generation and XFire integrated in M4, but were it's going to have to wait until M5.

AppFuse 2.0 is available as a Maven archetype. For information on creating a new project using this release, please see the QuickStart Guide.

If you've used AppFuse 1.x, but not 2.x, you'll want to read the FAQ and join the user mailing list if you have any questions. The Maven Reference Guide has a map of Ant » Maven commands.

The 2.0 series of AppFuse has a minumum requirement of the following specification versions:

  • Java Servlet 2.4 and JavaServer Pages (JSP) 2.0
  • Java 5 for Development (Java 1.4 for deployment using the Retrotranslator Plugin)

For more information, please see the 2.0 M4 Release Notes. To see how AppFuse 2.x works, please see the video demos.

Comments and issues should be sent to the mailing list.

We appreciate the time and effort everyone has put toward contributing code and documentation, posting to the mailing lists, and logging issues. We also greatly appreciate the help from our sponsors, particularly Atlassian, Cenqua, Contegix, JetBrains, Java.net and KGBInternet. Without them, working on this project wouldn't be nearly as much fun.

Posted in Java at Mar 24 2007, 04:33:21 PM MDT 5 Comments

Comparing IDEs and Issue Trackers

A couple of good comparison articles came out today:

Issue Tracking Systems Conclusion
These products reviewed are among the most widely used in the Java community. Bugzilla, with an uninspiring user interface, is rich in features, but undeniably cumbersome to install and to maintain. Trac is a good, lightweight solution that should be seriously considered by any development team using Subversion. JIRA is a solid, powerful solution, providing almost all of the features of Bugzilla, and more, in an eminently more usable (and more productive) form ? but at a cost.

I agree with John's conclusion - Bugzilla was cool 5 years ago, but there's much better systems now. If you're running an open source project, it's a no-brainer to use JIRA. If you're working at a company and want to use an open-source solution, Trac works well.

IDE Wars Conclusion
For enterprise development, I'd say IDEA wins out with its rich support for both J2EE and Java EE 5, followed closely by NetBeans (which also does an impressive job here), and last is Eclipse/MyEclipse (mostly due to their current lack of support for Java EE 5).

I agree with Jacek as well. I've been using IDEA almost exclusively for the last 6 months - ever since I started to convert AppFuse to use Maven 2. Eclipse's support for sub-projects has been pretty pitiful and IDEA has *much* better support for web development - particularly JavaScript and CSS.

Lately, I've found myself advocating IDEA and JIRA to clients more and more. A few years ago it was Bugzilla and Eclipse. However, these IDEA and JIRA (as well as Confluence and FishEye) are so cheap in the relative scheme of things - I think they actually pay for themselves these days.

Disclaimer: I use IDEA, Confluence and JIRA on a daily basis. I use Trac and Eclipse on a weekly basis. I paid for my original IDEA license out of my own pocket, but I received my most recent license for speaking at Denver's JUG. Confluence and JIRA are provided free of charge by Atlassian for AppFuse.

Posted in Java at Mar 15 2007, 05:56:02 PM MDT 5 Comments

A New 17" Powerhouse

Yummy On my current project, we're using SQL Server as the backend database. To make this work on my MacBook Pro, I have to run Parallels in the background. While this setup works, it does have issues. The main problem is things slow down a fair amount when running two operating systems. Last week (or was it two weeks ago?), Parallels came out with their latest release, which includes a Coherence mode. If you're a Mac user, I highly recommend this software. It basically lets you run Windows and OS X at the same time, all integrated into the same screen, which the same dock and everything. It's really slick the first time you see it in action.

After working in this mode for a few days, I knew it was the perfect programming platform for me. I tend to use Windows and OS X each 50% of the time, so having them both running side-by-side rocks. But as I worked, I thought to myself, "I need more RAM and more real estate". It seems liked a no-brainer: it was time to upgrade to the 17" MacBook Pro - with all the performance goodies I could get. Against Ben's advice, I bought a new 17" MacBook Pro last week. 3 GB RAM and the fastest disk they had (100 GB 7200 RPM version). Sure, it'd be great to have more disk space, but I'm not going to give up speed for space. If this bad boy really is 40% faster than my current MBP, life is going to be very good.

Of course, my real reason for getting a new laptop was because Julie dropped her PowerBook a couple months ago. I was going to spend $1000 to get it fixed, but it didn't seem like a worthwhile investment. Julie's renovating a new house, so with me working from home, it can get contentious for her trying to get some computer time. So she needed a new laptop. She mentioned she wanted to buy a PC laptop. I shrieked when I heard this and knew I had to buck up and get a new one so she could have my MBP that runs Windows. Did this reasoning work with her? No, not at all. However, when she gets a new computer later this evening, I'm willing to bet she'll be pretty pumped. ;-)

I'll try to post some performance comparisons this evening after I get it all setup.

Update: It's gonna be a while before I can post any performance comparisons. I got the box setup thanks to Apple's "import from another box" feature. However, I'm wwaaaayyyy behind on a lot of commitments, so I'm scrambling to catch up. With any luck, I'll post something this weekend.

Posted in Mac OS X at Mar 13 2007, 10:20:35 AM MDT 11 Comments

The Playoffs Begin

DU Hockey A good weekend of hockey is about to begin: Pioneers Faceoff Against Wisconsin in WCHA Playoffs This Weekend. We have season tickets for tomorrow night's game, but not tonight's. Last night, I did my first search on craigslist and found a bunch - many selling for face value. One guy was giving away on-the-glass seats for free, but I missed him by a couple hours. Needless to say, I found some seats and will be attending tonight's game as well as all the other games this weekend. Go DU!

Update: While the games were good this weekend, they didn't end like I'd hoped. Oh well, better luck next year.

Posted in General at Mar 09 2007, 11:28:43 AM MST

Integrating Selenium with Maven 2

I spent some time this past week integrating Selenium with Maven 2. This post is designed to show you how to do this in your Maven 2 projects.

First of all, there were two types of testing scenarios I wanted to make possible. The first was to allow HTML-based tests that web designers could create and run with Selenium IDE. As far as I know, Selenium IDE is capable of recording and exporting Java-based tests (powered by TestNG or JUnit), but I don't believe it's capable of playing them back. So for Java Developers, I wanted to allow them to write their tests in Java.

To get Maven to run HTML-based tests, the easiest way seems to be using the <selenese> Ant task. I tried Mavenium as well, but it 1) doesn't use the latest version of Selenium RC and 2) reports success when tests fail. Below is a Maven profile that I'm using in an AppFuse-based project to run HTML tests.

<profiles>
    <profile>
        <id>integration-test</id>
        <activation>
            <property>
                <name>!maven.test.skip</name>
            </property>
        </activation>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.codehaus.cargo</groupId>
                    <artifactId>cargo-maven2-plugin</artifactId>
                    <version>0.3-SNAPSHOT</version>
                    <configuration>
                        <wait>${cargo.wait}</wait>
                        <container>
                            <containerId>${cargo.container}</containerId>
                            <!--home>${cargo.container.home}</home-->
                            <zipUrlInstaller>
                                <url>${cargo.container.url}</url>
                                <installDir>${installDir}</installDir>
                            </zipUrlInstaller>
                        </container>
                        <configuration>
                            <home>${project.build.directory}/${cargo.container}/container</home>
                            <properties>
                                <cargo.hostname>${cargo.host}</cargo.hostname>
                                <cargo.servlet.port>${cargo.port}</cargo.servlet.port>
                            </properties>
                        </configuration>
                    </configuration>
                    <executions>
                        <execution>
                            <id>start-container</id>
                            <phase>pre-integration-test</phase>
                            <goals>
                                <goal>start</goal>
                            </goals>
                        </execution>
                        <execution>
                            <id>stop-container</id>
                            <phase>post-integration-test</phase>
                            <goals>
                                <goal>stop</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <artifactId>maven-antrun-plugin</artifactId>
                    <executions>
                        <execution>
                            <id>launch-selenium</id>
                            <phase>integration-test</phase>
                            <configuration>
                                <tasks>
                                    <taskdef resource="selenium-ant.properties">
                                        <classpath refid="maven.plugin.classpath"/>
                                    </taskdef>
                                    <selenese suite="src/test/resources/selenium/TestSuite.html"
                                              browser="*firefox" timeoutInSeconds="180" port="5555"
                                              results="${project.build.directory}/selenium-firefox-results.html"
                                              startURL="http://${cargo.host}:${cargo.port}/${project.build.finalName}/"/>
                                </tasks>
                            </configuration>
                            <goals>
                                <goal>run</goal>
                            </goals>
                        </execution>
                    </executions>
                    <dependencies>
                        <dependency>
                            <groupId>ant</groupId>
                            <artifactId>ant-nodeps</artifactId>
                            <version>1.6.5</version>
                        </dependency>
                        <dependency>
                            <groupId>org.openqa.selenium.server</groupId>
                            <artifactId>selenium-server</artifactId>
                            <version>0.9.1-SNAPSHOT</version>
                        </dependency>
                    </dependencies>
                </plugin>
            </plugins>
        </build>
    </profile>
    <profile>
        <id>selenium-ie</id>
        <activation>
            <os>
                <family>windows</family>
            </os>
        </activation>
        <build>
            <plugins>
                <plugin>
                    <artifactId>maven-antrun-plugin</artifactId>
                    <executions>
                        <execution>
                            <id>launch-selenium</id>
                            <phase>integration-test</phase>
                            <configuration>
                                <tasks>
                                    <taskdef resource="selenium-ant.properties">
                                        <classpath refid="maven.plugin.classpath"/>
                                    </taskdef>
                                    <selenese suite="src/test/resources/selenium/TestSuite.html"
                                              browser="*firefox" timeoutInSeconds="180" port="5555"
                                              results="${project.build.directory}/selenium-firefox-results.html"
                                              startURL="http://${cargo.host}:${cargo.port}/${project.build.finalName}/"/>
                                    <selenese suite="src/test/resources/selenium/TestSuite.html"
                                              browser="*iexplore" timeoutInSeconds="180" port="5555"
                                              results="${project.build.directory}/selenium-ie-results.html"
                                              startURL="http://${cargo.host}:${cargo.port}/${project.build.finalName}/"/>
                                </tasks>
                            </configuration>
                            <goals>
                                <goal>run</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

The above setup will allow you to run Selenium tests in Firefox, and in IE as well when you're on Windows. I tried to get Safari to work on the Mac, but it just opens Safari and hangs.

HTML tests are great for non-programmers, but what about developers that prefer Java and want test reports to be included in the surefire-plugin's reports? That's easy enough. First of all, put your tests in a particular package so they can be excluded from the normal testing cycle. I used a webapp.selenium package. I configured the surefire-plugin to exclude these tests:

<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
        <excludes>
            <exclude>**/selenium/*Test.java</exclude>
        </excludes>
    </configuration>
</plugin>

Then I added the newly released selenium-maven-plugin to my "integration-test" profile and configured surefire to run the Selenium Java tests.

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>selenium-maven-plugin</artifactId>
    <version>1.0-beta-1</version>  
    <executions>
        <execution>
            <id>start-selenium</id>
            <phase>pre-integration-test</phase>
            <goals>
                <goal>start-server</goal>
            </goals>
            <configuration>
                <background>true</background>
            </configuration>
        </execution>
    </executions>
</plugin>
<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <executions>
        <execution>
            <id>surefire-it</id>
            <phase>integration-test</phase>
            <goals>
                <goal>test</goal>
            </goals>
            <configuration>
                <excludes>
                    <exclude>none</exclude>
                </excludes>
                <includes>
                    <include>**/selenium/*Test.java</include>
                </includes>
            </configuration>
        </execution>
    </executions>
</plugin>

Yeah, Maven can be quite verbose when configuring profiles. I contacted the Maven list to see if it's possible to simplify all this XML, but so far haven't found a solution.

If you'd like to see a pom.xml with the Selenium bits and a profile that runs both HTML and Java-based tests, click here (JavaScript needs to be enabled for this to work).

NOTE: I used 0.9.1-SNAPSHOT of Selenium Server because it solves issues with the latest version of Firefox.

This brings up a related question I asked on the AppFuse mailing list a couple of days ago:

Do you use the Canoo WebTests? If not, how do you do UI testing? If so, would you prefer Selenium?

If you've tried AppFuse 2.x and have an opinion, please add a comment. Personally, I like Selenium, but I like how Canoo WebTest can be somewhat friendly to designers and allow i18n testing with Ant's property file support. With Selenium, you have to use parse/replace or Java tests to do i18n testing. Then again, if you need to test a lot of Ajax functionality, it's likely that Selenium will work much better for you.

Posted in Java at Mar 09 2007, 10:35:04 AM MST 17 Comments

Java CMS Systems

Michael Levin is at the JavaPosse Roundup this week. Today, they're discussing Java CMS Systems. I recently had an e-mail discussion with a reader regarding Java-based CMS Systems. In hopes of getting these questions answered by Michael today, here's that thread:

Original E-Mail:
OpenCMS, Magnolia CE/EE, Atleap, Alfresco, Liferay.

Magnolia EE, Day Communique, Hannon Hill, Refresh, Vertical Site.

We are leaning towards Magnolia EE since we have a load balancer and two production server, but I bet we could hack in support in the community edition.

Any comments/recommendations?
-------- My response:
I'd check out Alfresco's new 2.0 WCM - just released last week. I haven't looked at many of the CMSes in a year or so, but I'm willing to bet that OpenCMS still has issues installing. I still like Drupal too and recommend it for folks just wanting a website they can edit.

In reality, my experience with CMS systems is outdated and you shouldn't consider me an authority. ;-)
-------- Thanks for the lead. We actually eliminated Alfresco, b/c I thought they were more of a portal.

The reason we were leaning towards Magnolia and Vertical Site was b/c of JSR 170 (which Alfesco claims to support).

I wonder about the scalability of JCR, do have an opinion?
-------- I don't have an opinion because I don't have much experience with it. It's supposed to be the JDBC of CMSs, so I imagine it's pretty scalable. However, it's pretty new, so I'm sure there will be growing pains. I know that Infoq.com uses Magnolia as their backend (and WebWork as their frontend), so obviously it scales well for them.

What are your thoughts on Java-based CMS Systems? Comments from experienced developers appreciated more than vendor pitches. ;-)

Posted in Java at Mar 08 2007, 08:45:50 AM MST 14 Comments

RE: Jetty Ant Plugin

It looks like Jetty has a new Plugin for Ant. If you've used the Jetty Maven Plugin, you know this is a slick way to quickly deploy your application. For those of you wondering about Tomcat, there's a similar Tomcat Maven Plugin that supports tomcat:run and tomcat:run-war. However, it's still in Mojo's sandbox.

I'm pumped to see this Jetty task for Ant because I've been thinking a lot about creating an exploded, full-source archetype for AppFuse 2.0. Of course, it's probably possible to start Jetty and monitor your project for changes w/o this task - but it does seem to make things a fair amount easier. If we do a full-source archetype, it makes sense to support Ant as well - especially since we can probably re-use the build.xml from AppFuse Light.

This brings up a related questions I asked on the AppFuse mailing list yesterday:

A couple of questions for folks using (or planning to use) 2.x:

1. As far as archetypes go, are you using basic or modular?

2. If there was a 3rd type of archetype that included the full source (like AppFuse 1.x), would you use it over the existing basic or modular archetypes? If yes, I'm assuming upgrading is not that big of an issue for you?

If you've tried AppFuse 2.x and would like to answer these questions, please add a comment.

There's another questions about Selenium vs. Canoo WebTest in that post, but that's reserved for another entry where I'll talk about Selenium options in Maven 2.

Posted in Java at Mar 08 2007, 08:13:08 AM MST 3 Comments

Zero Configuration in Struts 2

Struts 2 has a nifty zero configuration feature. However, it's only useful for registering actions, not for automatically registering results. In other words, you still have to use an @Result annotation to tell your action what page to dispatch to. To use default view names instead of requiring @Result, you can use the Codebehind Plugin. Also, did you know Struts 2 will autowire your Spring dependencies? It's pretty slick.

What does this all mean? It means you can write your Struts 2 application without writing any XML. Of course, you can still use XML to tweak behavior, but with these plugins enabled, you won't have to.

IMO, these plugins should be combined into a single zero configuration feature.

Here's how you can enable Struts 2's Zero Configuration feature in AppFuse 2.0:

  1. Add a packageNames parameter to the "struts" filter in your web.xml:
    <filter>
        <filter-name>struts</filter-name>
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
        <init-param>
            <param-name>actionPackages</param-name>
            <param-value>com.company.newapp.webapp.action</param-value>
        </init-param>
    </filter>
    
  2. Add the Codebehind Plugin as a dependency in your pom.xml:
    <dependency>
        <groupId>org.apache.struts</groupId>
        <artifactId>struts2-codebehind-plugin</artifactId>
        <version>2.0.6</version>
    </dependency>
    
  3. Add a struts.codebehind.pathPrefix constant in struts.xml for your default pages directory:
    <constant name="struts.codebehind.pathPrefix" value="/WEB-INF/pages/"/>
    

That's it - now you can code away without configuring anything!

How does this compare to other web frameworks in AppFuse? Tapestry has a similar feature, but Spring MVC and JSF don't. Spring MVC still requires you create a bean definition for Controllers and JSF requires you write a chunk of XML for each managed bean. Of course, if you know how to do something similar with Spring MVC or JSF, please let me know.

Posted in Java at Mar 07 2007, 05:19:18 PM MST 9 Comments