Wednesday, April 9, 2008

Hudson Gadget For Google Desktop

I took a first stab at creating a google desktop gadget that can display the job names and statuses of any Hudson instance. Simply configure it to the Hudson server url and it will discover all the jobs and start polling the for blue dots.



Hudson Gadget, Version 0.9.0.

Let me know if you have any improvement ideas or other issues.

[update] This gadget has been contributed to the open source Hudson project.

Monday, March 31, 2008

Code Reuse Inside Your Own Company

A short read over on Dr. Dobbs, Where Are the Clients In a SOA? made some good observations about the mindset of creating reusable SOA components, especially when the reuse is likely to occur in your own back yard.

"The best "enterprise architecture" plan will never be realized as long as developers assume the client of a piece of code is another piece of code."
"As software developers we are not very good customers of the work our colleagues do. We are quicker to search the Internet for a utility or example than we are to search our own internal repositories."
"More importantly, we aren't thinking about other developers when we create the code. We don't create interfaces that make it easy for people to use our code in ways we have not considered. We don't provide design-level abstractions that help other programmers and architects fit our solution into theirs. We don't market the code to the rest of the team or to other teams within the organization. We don't do any market research to make sure the nontraditional customers of our code are going to make the most of it. We don't package it in ways that also make it easy to use outside our intended use."
The emphasis is mine, although it should be yours, too.

Friday, March 7, 2008

Jersey... Jetty and Maven style!

I recently created a webapp that due to time constraints, I implemented with plain old servlets which I am comfortable with. In reality, the project was a perfect candidate to implement in RESTful style. I had been loosely following the Jersey project, part of the larger java.net Metro project, so I decided to give Jersey a try.

"Jersey is the open source ... JAX-RS (JSR 311) Reference Implementation for building RESTful Web services. But, it is also more than the Reference Implementation. Jersey provides additional APIs and extension points (SPIs) so that developers may extend Jersey to suite their needs."


My only requirements were really around a quick turn-around dev setup. So I wanted to use maven and the jetty plugin to preview the results quickly.

Jersey is still only available as an early access preview (0.5-ea) , so some of the examples I found were "out of date", as the team is still refactoring the implementation.

So, first step: create a maven war project structure and configure the web.xml to look this this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<servlet>
<servlet-name>Jersey</servlet-name>
<servlet-class>com.sun.ws.rest.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.ws.rest.config.property.resourceConfigClass</param-name>
<param-value>com.sun.ws.rest.api.core.PackagesResourceConfig</param-value>
</init-param>
<init-param>
<param-name>com.sun.ws.rest.config.property.packages</param-name>
<param-value>org.naiade.tutorials.jersey;com.gestalt.gci.rest.resources</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
The two key things here are:
  • use the ServletContainer servlet (not ServletAdapter)
  • use the pluggable PackagesResourceConfig parameter value. This allows Jersey to auto find all REST resources based on the package names. This is configured in the additional parameter value. Here we provide a couple of packages to look in, semicolon separated.
For the code, I used the ShoeService example I found here.
As I mentioned before, Jersey is still evolving so I ended up making two code changes to still be able to compile under 0.5-ea:
  • @HttpMethod() changed to @GET or @POST
  • @UriTemplate() changed to @Path()
The maven project looks like:

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.shoe</groupId>
<artifactId>shoeservice</artifactId>
<version>1.0</version>
<name>Shoe Service REST</name>
<packaging>war</packaging>
<dependencies>
<!-- jersery.dev.java.net -->
<dependency>
<groupId>jersey</groupId>
<artifactId>jersey</artifactId>
<version>0.5-ea</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.8</version>
<configuration>
<scanIntervalSeconds>10</scanIntervalSeconds>
</configuration>
<dependencies>
<dependency>
<groupId>org.apache.geronimo.specs</groupId>
<artifactId>geronimo-j2ee_1.4_spec</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>

To bring it all together, it's as simple as
mvn jetty:run
Open you browser and hit http://localhost:8080/shoeservice/shoe

Easy.

I really see Jersey taking off as it is a good project and easy to work with. If you are looking for a good Java solution to creating a RESTful accessible services, give it a try.

Tuesday, February 12, 2008

NetBeans 6.0 Maven Integration

As a proponent of continuous integration, I naturally don't endorse one IDE over another. The choice should be free and open for developers to choice what works best for them. The important thing is that the project should not be reliant on an IDE to build. That is, there must be an independent build tool that can function outside of any IDE, whether it be ant or maven or whatever.

I have used several IDEs over the last couple of year to include Eclipse, IDEA and NetBeans . They all have their strengths and weakness and for the projects I have been working on, I ended up switching around quite a bit. With the recent announcement of the new Netbeans 6.0, I wanted to revisit it's capabilities and see what was new, particularly with its maven integration.

While the Netbeans installer was downloading, I started to search for what plugins I would need to do maven->Netbeans or Netbeans ->maven project conversions. Most of what I found looked outdated and didn't look easy to use. With a little stumbling around I found out that the Mevenide project does now support Netbeans 6.0 (this is not apparent on their Netbeans project page). So I installed the Mevenide Maven2 plugin.

And was blown away!

There is no conversion of project types from maven->NetBeans . It just works natively. File > Open Project and browse for your existing maven project. Bingo.

I actually started by opening a parent project, <packaging>pom</packaging>, thinking that the Mavenide wouldn't know what to do with a multi module project, but it just worked, too! It showed me the project files, libraries, test libraries and the modules that this parent included. Too cool.



So then I double clicked my war module name hoping for the best and was not disappointed. It opened the war project in the project pane and I was off and running.



Right click on the project name to run the more common maven goals from right inside NetBeans. To run custom goals, you can create a Custom > Goals... goal that you can use to chain together whatever goals you want for a maven execution. This is the only thing I did that actually created a custom file on my filesystem. Everything else was native.

How's that for a slice of fried gold?
So, here's a big high five to to the Mevenide team on a job well done! (And update your NetBeans project page to highlight that it works in Netbeans 6.0. This is important news to advertise!).

Tuesday, January 15, 2008

Global Collaboraton In the Second Grade



I just finished reading The World is Flat by Thomas L. Friedman. He had some good insights and specific example about how the world is increasingly connected and how it functions as a global marketplace. The most interesting take away I had was that simply providing the cabling into countries that had not been previously connected was enough of a spark to allow individuals with curiosity and an innovative spirit to engage a global community.

Those of us in the software business, take this interconnectedness for granted now. I find it fascinating, being a father of two, that my children will know no different; the world was always connected. In the span of a single generation the world got very small indeed. I have friends who grew up their entire life in single small town. Any road trip of more than 100 miles was a big deal. But my kids won't have to "go" anywhere to instantly know what is going on on the other side of the planet or to actively collaborate with people on other continents.


So with this in mind, I had an idea for an education software project. My second-grader already has computer lab class once a week where he and his classmates learn and solve problems on a standalone system. What better time to learn about teamwork, on a global scale, then now, while he is in school.

My idea is a collaborative system that lets kids work together to solve and reinforce basic school (and life) skills. As math is a universal language, it would be a good first subject.

Picture this:

  • The system is browser-based and has a easy to use, friendly RIA interface.
  • One student from the USA joins the "Collabmath" course; One student from India joins the same course and they are paired together to solve 5 math problems.
  • Each student will have a friendly avatar with their county's flag next to it. Each student's name can be clicked on to hear it pronounced in the native language. Google maps can show each student's school marked on a world map.
  • The math problem will be presented in a large left hand workspace, and a chat window could be in a right-hand pane.
  • The chat window can be used by the students to provide encouragement or ask for help. The chat would be I18N capable and feature emoticons that would make the session more personable.

  • Each student takes turns solving a problem a step at a time. When each step is complete, control transfers to the other student, and so on. So, for a simple example, if the problem is to draw an octagon, the first student will draw the first line segment, then the second student will draw a complementary line segment connected to the first. When the octagon is complete, the students will have worked together to solve the problem.
  • At the conclusion of each problem, a practical real world example of the use of that problem in each culture could be presented. In my example, the students would learn that in America, the octagon is the shape of a traffic stop sign; a related symbolic example could be presented that would be relevant in the country of India.

A wide range subjects and grade levels could be taught, of course, but for starters, this could get the ball rolling. I envision my kids being excited one day, coming home from school, "Dad! Guess what? I learned division and fractions with a kid from China today! Her name was Ming Wu! It was so cool!"

I can see it. Can you?


Tuesday, December 4, 2007

Continuous Integration Strategies (Part III)

How do you get your code to talk to you? Continuous integration is all about automated feedback. Beyond test reports and self-describing-code there are many techniques and tools that you can use to find out if you are producing "quality" code.

When you pick the right reports and integration them into the software build, the level of effort required to use these tools becomes very low (and we all know that developers are legendarily lazy).

Ideally, you should not have to remember to ask, the code should tell.

It's like being the parent of a teenager. At the dinner table you ask,

"So, how was school today?"
"I dunno."

"What did you learn?"
"Nothin'"

"Did anything interesting happen?"
"I dunno."

"How did you do on your history test"
(shrug)

You would rather he came home with the enthusiasm of a kindergartener eager to tell you about his day as soon as he gets home. No effort on your part to ask, he just gushes unprompted,

"Dad!! Guess what happened today at school?? It was so cool, I got an A+ on my spelling test!!"
That's what continuous integration can do for you.

So, recalling the computer adage, Garbage In, Garbage Out, we have carefully picked a select few reports that we feel give us a good measure of quality and integrated them into our build so that the feedback from CI is meaningful. Although several CI engines (we currently use Hudson) do have plugins to generate quality reports such as unit test results and test coverage, we feel it is important that developers have full access to run all the same reports that CI will run. Since we run maven, it is easy to plugin the reports of interest into the <reporting> section of the pom. That keeps the report configurations in source control along with the code.

So which reports do we run? Here's the rundown:

  • Checkstyle. Validates source code against coding standards and reports any violations. We customized the ruleset, packaged it in a versioned jar and deployed it to our maven repository. Additionally, we forced it to run as part of every build in the validate phase, and configured it to fail the build if violations are found. It's possible for an individual project to override the custom ruleset, but we don't encourage that.
  • PMD. Performs design time analysis of the source code against a standard ruleset. We customized the ruleset, packaged it in a versioned jar and deployed it to our maven repository. Additionally, we forced it to run as part of every build in the validate phase, and configured it to fail the build if violations are found.
  • Test Results (surefire). This is a no-brainer. You want to see the results of your tests.
  • Code Coverage (cobertura). Shows branch and line coverage for your source files. I think the key to using this metric is to not to set a percentage that the project team must meet, but to be smart about interpreting the trends. "Metrics are meant to help you think, not to do the thinking for you."
  • Javadoc. Creates the API documentation for your project.
  • Dashboard. Aggregates maven multiproject build reports into a single report page. This is critical so that developers and stakeholders don't have to hunt and drill down page after page to find the meaningful metrics you worked so hard to set up.


In addition, make full use of Maven's pom to declare all the sections that feed the default generated site, including:

  • <scm> Source control management. New team members, for example will need to know the subversion URL for checkout.
  • <developers> Identifies subject matter experts and feeds developer activity reports.
  • <ciManagement> Identifies the CI engine being used and the URL to see the live status and force new builds.
  • <issueManagement> Identifies the issue tracking system. I think there are maven plugins that will map issues to source control commits, providing bi-traceability of code to requirements.


Also, don't forget for maven multiproject builds to review the Dependency Convergence report. It will show all dependencies for all projects along with the versions of those dependencies. This will help you find dependencies your using inadvertently using multiple versions of.

Once you have these reports baked in, make the results easy to find. Use your CI engine to generate the maven site on a nightly basis and publish the results to a web server where developers or project stakeholders can find them.

After you spend the time and effort to identify which reports you want and get them configured and working correctly, make it repeatable for new projects by creating an archetype template project. This sets up a model pom.xml and project directory structure right off the bat for new projects. When it's there from the start, with no effort on the team's part, good things happen.

With a little up front effort, your code (with a little help from continuous integration) can talk to you. What are your strategies? How do you use CI to reveal code quality? I would be interested in hearing your strategies.