Archive for October, 2007

New England Foliage

Wednesday, October 24th, 2007

I love to visit New England in the fall. At the first whim of winter, the entire forest explodes into bright red / yellow / orange. Last glory from the fleeting summer before the first snow turns them all white! The scenery is breath-taking no matter whether you are viewing from the air, along the highway, on a back road, or even just in front of a single tree. Well, I got to experience all these view points during my trip to Boston last week.

Despite the bad weather and horrendous flight delays, the magnificent view made the trip all the worthwhile. Click on the follow pictures to enter the photo album.

DSC_7289.jpg

DSC_7420.jpg

Slides for Seam talk at the New England JUG

Wednesday, October 24th, 2007

I gave a 2-hour talk on JBoss Seam in the New England Java User’s Group last Thursday. Although the talk was at the same night as a crucial game for Red Sox, it still managed to attract 250+ people — making it one of largest JUG meetings I have ever attended! I had a great time there, and learned first hand about how Java developers in the Boston area are using JBoss Seam to solve real world problems. For those who are interested, the presentation itself can be found here:

Slides for the JBoss Seam presentation in NEJUG, Oct 18th 2007

I enjoyed a “re-union” with my Red Hat colleagues in the Boston area: Shelly McGowan, Chantal Yang, Bill Burke, Kurt Stam, and Rajesh Rajasekaran. Thank you guys for making the meeting a success! In addition, I’d also like to thank Mark Johnson (the president of the NEJUG), Heather Fox (publicist at Prentice Hall), and Shaun Connolly (my sponsor at Red Hat) for organizing everything!

Finally, a couple of references to things I mentioned in the meeting:

Nominate your products / projects for the 18th Jolts Award

Tuesday, October 23rd, 2007

Dr Dobb’s Journal’s Jolt award is one of the longest running and most prestigious awards in the software industry. The 18th Jolt Award is now open for nominations:

http://www.joltnominations.com/Jolt/

Hint: If you develop tools for mobile applications, Jolt does have a category for mobile tools. I will participate in this category heavily this year.

To be qualified for Jolts, you have to submit your own product — there is a small submission fee ($50 for open source projects) to cover admin costs. As a Jolt judge for the past several years, I can tell you that none of the judges is paid. We are all volunteers contributing our time for free to go through the complicated software evaluation process. What do we get out of it? Well, we get exposure to the latest happenings in the industry and get to put “Jolts Judge” on our name cards. ;)

What do you get out of it? Well, if your product wins Jolts, that gives you some major bragging right! Even if your product does not win, by participating in the process, you get Jolt judges (most of them are consultants influencing purchasing decisions) to look carefully at your product. If some of the judges like your product, they might blog about it or recommend it in their consulting work.

In the past several years, we got an overwhelming number of submissions every year. It is nearly impossible to evaluate each of them in detail, if the judges are not already using the product in his/her daily work. So, it will be enormously helpful if you can prepare a flash or live demo of your product to illustrate the key features that differentiates your product from the rest.

JBoss Seam project setup with Maven — Part 2: EAR deployment

Tuesday, October 9th, 2007

In a previous post, I discussed how to setup a Maven project for your Seam WAR application. However, most Seam developers are probably working on applications with EJB3 components to fully take advantage of the service infrastructure of the JBoss AS container. So, to complete this series, I setup a maven project for Seam EAR deployment. The project structure is as follows. The ejb module builds the JAR for EJB3 components; the war project build the web application; and the ear module builds the EAR application with necessary library JARs.

CODE:
  1. .
  2.  |-- pom.xml
  3.  |
  4.  |-- ear
  5.  |   `-- pom.xml
  6.  |
  7.  |-- ejb
  8.  |   |-- pom.xml
  9.  |   |-- src
  10.  |       `-- main
  11.  |           |-- java
  12.  |           |    `-- com
  13.  |           |         `-- example
  14.  |           |               `-- ejb
  15.  |           |                    |-- MyEnterpriseBeanImpl.java
  16.  |           |                    `-- MyEnterpriseBean.java
  17.  |            `-- resources
  18.  |                |-- seam.properties
  19.  |                 `--  ejb-jar.xml
  20.  |
  21.  |-- war
  22.       |-- pom.xml
  23.        `-- src
  24.             `-- main
  25.                  |-- java
  26.                  |   `-- com
  27.                  |       `-- example
  28.                  |             `-- SampleAction.java (and other Java source files)
  29.                  |-- resources
  30.                  |   |-- META-INF
  31.                  |   |   `-- persistence.xml
  32.                  |   |-- messages.properties
  33.                  |   `-- seam.properties
  34.                  `-- webapp
  35.                      |-- WEB-INF
  36.                      |    | -- components.xml
  37.                      |    | -- pages.xml
  38.                      |    | -- face-config.xml
  39.                      |     `-- web.xml
  40.                      `-- hello.xhtml (and other web content, CSS, templates, and images)

The main pom.xml file defines the shared libraries required by all modules. It optionally uses the Seam parent POM to set the version numbers for the dependency JARs. Here is how it might look like:

XML:
  1. <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">
  2.  
  3.   <repositories>
  4.     <repository>
  5.       <id>jboss-snapshot</id>
  6.       <name>The JBoss maven repo</name>
  7.       <url>http://snapshots.jboss.org/maven2</url>
  8.     </repository>
  9.   </repositories>
  10.   <parent>
  11.     <groupId>org.jboss.seam</groupId>
  12.     <artifactId>root</artifactId>
  13.     <version>2.0.0-SNAPSHOT</version>
  14.   </parent>
  15.  
  16.   <modelVersion>4.0.0</modelVersion>
  17.   <groupId>mystuff</groupId>
  18.   <artifactId>mystuff</artifactId>
  19.   <packaging>pom</packaging>
  20.   <version>1.0</version>
  21.   <name>mystuff</name>
  22.   <url>http://maven.apache.org</url>
  23.  
  24.   <dependencies>
  25.  
  26.     <dependency>
  27.       <groupId>log4j</groupId>
  28.       <artifactId>log4j</artifactId>
  29.       <scope>provided</scope>
  30.     </dependency>
  31.  
  32.     <dependency>
  33.       <groupId>junit</groupId>
  34.       <artifactId>junit</artifactId>
  35.       <scope>test</scope>
  36.     </dependency>
  37.  
  38.   </dependencies>
  39.  
  40.   <modules>
  41.     <module>ejb</module>
  42.     <module>war</module>
  43.     <module>ear</module>
  44.   </modules>
  45.  
  46.   <build>
  47.     <plugins>
  48.       <plugin>
  49.         <groupId>org.apache.maven.plugins</groupId>
  50.         <artifactId>maven-compiler-plugin</artifactId>
  51.         <configuration>
  52.           <source>1.5</source>
  53.           <target>1.5</target>
  54.         </configuration>
  55.       </plugin>
  56.     </plugins>
  57.   </build>
  58. </project>

The ejb/pom.xml file defines the dependencies for the EJB3 module. Everything here is in the provided scope -- unless testing-specific libraries, which are in the test scope.

XML:
  1. <project>
  2.  
  3.   <parent>
  4.     <artifactId>mystuff</artifactId>
  5.     <groupId>mystuff</groupId>
  6.     <version>1.0</version>
  7.   </parent>
  8.  
  9.   <modelVersion>4.0.0</modelVersion>
  10.   <groupId>mystuff</groupId>
  11.   <artifactId>ejb</artifactId>
  12.   <name>mystuff - ejb</name>
  13.   <version>1.0</version>
  14.   <url>http://maven.apache.org</url>
  15.  
  16.   <build>
  17.     <finalName>ejb</finalName>
  18.   </build>
  19.  
  20.   <dependencies>
  21.  
  22.     <dependency>
  23.       <groupId>org.hibernate</groupId>
  24.       <artifactId>hibernate</artifactId>
  25.       <scope>provided</scope>
  26.     </dependency>   
  27.  
  28.     <dependency>
  29.       <groupId>org.hibernate</groupId>
  30.       <artifactId>hibernate-entitymanager</artifactId>
  31.       <scope>provided</scope>
  32.     </dependency>
  33.  
  34.     <dependency>
  35.       <groupId>org.hibernate</groupId>
  36.       <artifactId>hibernate-annotations</artifactId>
  37.       <scope>provided</scope>
  38.     </dependency>
  39.  
  40.     <dependency>
  41.       <groupId>org.hibernate</groupId>
  42.       <artifactId>hibernate-validator</artifactId>
  43.       <scope>provided</scope>
  44.     </dependency>
  45.  
  46.     <dependency>
  47.       <groupId>org.jboss.seam</groupId>
  48.       <artifactId>jboss-seam</artifactId>
  49.       <scope>provided</scope>
  50.     </dependency>
  51.  
  52.     <dependency>
  53.       <groupId>javax.ejb</groupId>
  54.       <artifactId>ejb-api</artifactId>
  55.       <scope>provided</scope>
  56.     </dependency>
  57.  
  58.     <dependency>
  59.       <groupId>hsqldb</groupId>
  60.       <artifactId>hsqldb</artifactId>
  61.       <version>1.7.2</version>
  62.       <scope>test</scope>
  63.     </dependency>
  64.  
  65.   </dependencies>
  66.  
  67. </project>

The war/pom.xml file defines the dependencies for the WAR module. It depends on the ejb module.

XML:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project>
  3.   <parent>
  4.     <artifactId>mystuff</artifactId>
  5.     <groupId>mystuff</groupId>
  6.     <version>1.0</version>
  7.   </parent>
  8.   <modelVersion>4.0.0</modelVersion>
  9.  
  10.   <groupId>mystuff</groupId>
  11.   <artifactId>war</artifactId>
  12.   <name>mystuff - web</name>
  13.   <version>1.0</version>
  14.   <packaging>war</packaging>
  15.   <url>http://maven.apache.org</url>
  16.  
  17.   <build>
  18.     <finalName>war</finalName>
  19.   </build>
  20.  
  21.   <dependencies>
  22.  
  23.     <dependency>
  24.       <groupId>mystuff</groupId>
  25.       <artifactId>ejb</artifactId>
  26.       <version>1.0</version>
  27.       <scope>provided</scope>
  28.       <type>ejb</type>
  29.     </dependency>
  30.  
  31.    <!-- The following 4 dependencies are included in the WEB-INF/lib of the war -->
  32.  
  33.     <dependency>
  34.       <groupId>org.jboss.seam</groupId>
  35.       <artifactId>jboss-seam-ui</artifactId>
  36.     </dependency>
  37.  
  38.     <dependency>
  39.       <groupId>org.jboss.seam</groupId>
  40.       <artifactId>jboss-seam-debug</artifactId>
  41.     </dependency>
  42.  
  43.     <dependency>
  44.       <groupId>com.sun.facelets</groupId>
  45.       <artifactId>jsf-facelets</artifactId>
  46.     </dependency>
  47.  
  48.     <dependency>
  49.       <groupId>org.richfaces.ui</groupId>
  50.       <artifactId>richfaces-ui</artifactId>
  51.     </dependency>
  52.  
  53.     <!-- The "provided" dependencies are only need for compilation -->
  54.  
  55.     <dependency>
  56.       <groupId>javax.servlet</groupId>
  57.       <artifactId>servlet-api</artifactId>
  58.       <scope>provided</scope>
  59.     </dependency>
  60.  
  61.     <dependency>
  62.       <groupId>org.jboss.seam</groupId>
  63.       <artifactId>jboss-seam</artifactId>
  64.       <scope>provided</scope>
  65.     </dependency>
  66.  
  67.     <dependency>
  68.       <groupId>javax.faces</groupId>
  69.       <artifactId>jsf-api</artifactId>
  70.       <scope>provided</scope>
  71.     </dependency>
  72.  
  73.     <dependency>
  74.       <groupId>javax.faces</groupId>
  75.       <artifactId>jsf-impl</artifactId>
  76.       <scope>provided</scope>
  77.     </dependency>
  78.  
  79.     <dependency>
  80.       <groupId>org.hibernate</groupId>
  81.       <artifactId>hibernate-validator</artifactId>
  82.       <scope>provided</scope>
  83.     </dependency>
  84.  
  85.   </dependencies>
  86. </project>

The ear/pom.xml file defines how the EAR application is assembled. You need to declare any JARs you want to include in the EAR as dependencies. I also used a JBoss-specific element to setup the class loader repository for the application. It is often needed in JPA applications. Yes, it is verbose -- if you have a better idea, let me know. :)

XML:
  1. <project>
  2.  
  3.   <parent>
  4.     <artifactId>mystuff</artifactId>
  5.     <groupId>mystuff</groupId>
  6.     <version>1.0</version>
  7.   </parent>
  8.  
  9.   <modelVersion>4.0.0</modelVersion>
  10.   <groupId>mystuff</groupId>
  11.   <artifactId>ear</artifactId>
  12.   <name>mystuff - ear</name>
  13.   <packaging>ear</packaging>
  14.   <version>1.0</version>
  15.   <url>http://maven.apache.org</url>
  16.  
  17.   <dependencies>
  18.  
  19.     <dependency>
  20.       <groupId>mystuff</groupId>
  21.       <artifactId>ejb</artifactId>
  22.       <version>1.0</version>
  23.       <type>ejb</type>
  24.     </dependency>
  25.  
  26.     <dependency>
  27.       <groupId>mystuff</groupId>
  28.       <artifactId>war</artifactId>
  29.       <version>1.0</version>
  30.       <type>war</type>
  31.     </dependency>
  32.  
  33.     <dependency>
  34.       <groupId>org.jboss.seam</groupId>
  35.       <artifactId>jboss-seam</artifactId>
  36.       <type>ejb</type>
  37.     </dependency>
  38.  
  39.     <dependency>
  40.       <groupId>org.jboss.seam</groupId>
  41.       <artifactId>jboss-el</artifactId>
  42.       <exclusions>
  43.         <exclusion>
  44.           <groupId>javax.el</groupId>
  45.           <artifactId>el-api</artifactId>
  46.         </exclusion>
  47.       </exclusions>
  48.       <type>jar</type>
  49.     </dependency>
  50.  
  51.     <dependency>
  52.       <groupId>commons-beanutils</groupId>
  53.       <artifactId>commons-beanutils</artifactId>
  54.       <exclusions>
  55.         <exclusion>
  56.           <groupId>commons-logging</groupId>
  57.           <artifactId>commons-logging</artifactId>
  58.         </exclusion>
  59.       </exclusions>
  60.       <type>jar</type>
  61.     </dependency>
  62.  
  63.   </dependencies>
  64.  
  65.   <build>
  66.     <plugins>
  67.       <plugin>
  68.         <groupId>org.apache.maven.plugins</groupId>
  69.         <artifactId>maven-ear-plugin</artifactId>
  70.         <configuration>
  71.           <jboss>
  72.             <version>4</version>
  73.             <loader-repository>mystuff:loader=mystuff.ear</loader-repository>
  74.           </jboss>
  75.  
  76.           <modules>
  77.             <webModule>
  78.               <groupId>mystuff</groupId>
  79.               <artifactId>war</artifactId>
  80.               <contextRoot>mystuff</contextRoot>
  81.             </webModule>
  82.  
  83.             <ejbModule>
  84.               <groupId>mystuff</groupId>
  85.               <artifactId>ejb</artifactId>
  86.             </ejbModule>
  87.  
  88.             <ejbModule>
  89.               <groupId>org.jboss.seam</groupId>
  90.               <artifactId>jboss-seam</artifactId>
  91.             </ejbModule>
  92.  
  93.             <!-- The stuff that needs to go in the lib directory.
  94.                  They will not be included in application.xml -->
  95.  
  96.             <jarModule>
  97.               <groupId>org.jboss.seam</groupId>
  98.               <artifactId>jboss-el</artifactId>
  99.               <bundleDir>lib</bundleDir>
  100.             </jarModule>
  101.  
  102.             <jarModule>
  103.               <groupId>commons-beanutils</groupId>
  104.               <artifactId>commons-beanutils</artifactId>
  105.               <bundleDir>lib</bundleDir>
  106.             </jarModule>
  107.  
  108.           </modules>
  109.         </configuration>
  110.       </plugin>
  111.     </plugins>
  112.   </build>
  113.  
  114. </project>

JBoss Seam project setup with Maven — Part 1: WAR deployment

Tuesday, October 2nd, 2007

Pete Muir recently posted that Seam 2.0 will support Maven integration. It is perfect timing for me since I have just started to use Maven in my new projects. So, I went through the exercise to setup simple Seam web projects in Maven. It is really quite easy. The project builds a single WAR for deployment (you can only use Seam POJO in the WAR -- no EJBs). You can configure it to generate WAR for JBoss AS or Tomcat 6. The beauty of using Maven is that you do not need to worry about things like finding the right version of JARs, setting up the project structure, managing build script etc. In fact, there is no build script to write. So, here is the structure of the source project.

CODE:
  1. .
  2.  |-- pom.xml
  3.  `-- src
  4.      `-- main
  5.          |-- java
  6.          |   `-- com
  7.          |       `-- example
  8.          |             `-- SampleAction.java (and other Java source files)
  9.          |-- resources
  10.          |   |-- META-INF
  11.          |   |   `-- persistence.xml
  12.          |   `-- seam.properties
  13.          `-- webapp
  14.              |-- WEB-INF
  15.              |    | -- components.xml
  16.              |    | -- pages.xml
  17.              |    | -- face-config.xml
  18.              |     `-- web.xml
  19.              `-- hello.xhtml (and other web content, CSS, templates, and images)

As you can see, you put your application code and configuration in the following directories.

  • All the Java source code (e.g., entity beans, Seam POJOs) go into src/main/java.
  • All Seam and web-related configuration files go into src/main/webapp/WEB-INF.
  • The JPA configuration goes into resources/META-INF/persistence.xml.
  • All web content goes into src/main/webapp.
  • The resources/seam.properties file is an empty file. It is require for Seam to scan annotations in this WAR

The dependency JARs are declared in the pom.xml file. Below is the pom.xml I used to generate a WAR for JBoss AS deployment. A couple of things to notice here:

  • I set the Seam official POM as my "parent" so that I can let Seam figure out the correct versions of the dependency JARs. Notice that I do not need to specify the Facelets JAR version in my POM. Seam will choose a compatible version for me.
  • The compiler setting must be "1.5" so that it can handle annotations.
  • The javax.el.el-api jar needs to be in the provided scope as it conflicts with the one already in JBoss and Tomcat 6.

That's it. Here is the pom.xml.

XML:
  1. <project xmlns="http://maven.apache.org/POM/4.0.0"
  2.          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3.          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  4.  
  5.   <repositories>
  6.     <repository>
  7.       <id>jboss-snapshot</id>
  8.       <name>The JBoss maven repo</name>
  9.       <url>http://snapshots.jboss.org/maven2</url>
  10.     </repository>
  11.   </repositories>
  12.  
  13.   <parent>
  14.     <groupId>org.jboss.seam</groupId>
  15.     <artifactId>root</artifactId>
  16.     <version>2.0.0-SNAPSHOT</version>
  17.   </parent>
  18.  
  19.   <modelVersion>4.0.0</modelVersion>
  20.  
  21.   <groupId>mytest</groupId>
  22.   <artifactId>seam-maven</artifactId>
  23.   <name>helloworld</name>
  24.   <version>1.0</version>
  25.   <packaging>war</packaging>
  26.   <url>http://maven.apache.org</url>
  27.  
  28.   <build>
  29.     <finalName>helloworld</finalName>
  30.     <plugins>
  31.       <plugin>
  32.         <groupId>org.apache.maven.plugins</groupId>
  33.         <artifactId>maven-compiler-plugin</artifactId>
  34.         <configuration>
  35.           <source>1.5</source>
  36.           <target>1.5</target>
  37.         </configuration>
  38.       </plugin>
  39.     </plugins>
  40.   </build>
  41.  
  42.   <dependencies>
  43.  
  44.     <dependency>
  45.       <groupId>org.jboss.seam</groupId>
  46.       <artifactId>jboss-seam</artifactId>
  47.     </dependency>
  48.  
  49.     <dependency>
  50.       <groupId>org.jboss.seam</groupId>
  51.       <artifactId>jboss-el</artifactId>
  52.       <exclusions>
  53.         <exclusion>
  54.           <groupId>javax.el</groupId>
  55.           <artifactId>el-api</artifactId>
  56.         </exclusion>
  57.       </exclusions>
  58.     </dependency>
  59.  
  60.     <dependency>
  61.       <groupId>org.jboss.seam</groupId>
  62.       <artifactId>jboss-seam-ui</artifactId>
  63.     </dependency>
  64.  
  65.     <dependency>
  66.       <groupId>com.sun.facelets</groupId>
  67.       <artifactId>jsf-facelets</artifactId>
  68.     </dependency>
  69.  
  70.   </dependencies>
  71.  
  72. </project>

Now, what if I want the WAR to be deployed in plain Tomcat 6? No problem, just add the JSF and Hibernate dependencies as follows. There is no need to meddle with commons jars and other 3rd party JARs since JSF and Hibernate dependencies automatically resolve them! Of course, plain Tomcat 6 does not provide a JTA transaction manager, so you will need to provide your own or use RESOURCE_LOCAL transaction -- but you should already knew that if you choose Tomcat ...

XML:
  1. <!-- The following dependencies are needed for Tomcat 6 deployment -->
  2.  
  3.     <dependency>
  4.       <groupId>javax.faces</groupId>
  5.       <artifactId>jsf-api</artifactId>
  6.     </dependency>
  7.  
  8.     <dependency>
  9.       <groupId>javax.faces</groupId>
  10.       <artifactId>jsf-impl</artifactId>
  11.     </dependency>
  12.  
  13.     <dependency>
  14.       <groupId>org.hibernate</groupId>
  15.       <artifactId>hibernate</artifactId>
  16.     </dependency>
  17.  
  18.     <dependency>
  19.       <groupId>org.hibernate</groupId>
  20.       <artifactId>hibernate-validator</artifactId>
  21.     </dependency>
  22.  
  23.     <dependency>
  24.       <groupId>org.hibernate</groupId>
  25.       <artifactId>hibernate-annotation</artifactId>
  26.     </dependency>
  27.  
  28.     <dependency>
  29.       <groupId>org.hibernate</groupId>
  30.       <artifactId>hibernate-entitymanager</artifactId>
  31.     </dependency>

So, go and have fun with Maven now! Let me know if there is any issues!

My personal tipping point for Maven

Monday, October 1st, 2007

I have always resisted using anything other than ANT to build my Java projects. I mean, if ANT can do the job and everyone else already has it, why do I need to learn anything else, right? However, Maven2 has finally reached the tipping point for me last week.

First, the Seam team has officially made Seam builds with all its dependencies available from a Maven repository. Seam has been using Maven to manage its own builds for quite sometime now. But the new Maven support makes it easy for developers to set up Seam application projects in Maven -- it is now quite easy to make sure that all 3rd party JARs you use in your application are the ones tested by the Seam team.

Second, Netbeans 6.0 released a beta, which boasts Maven project support. You can now open Maven project directories directly in Netbeans, and have all the source/resources/test packages listed in the project browser with all the correct classpaths. Okay, you still need to install the Mavenide plugin. As a long time Netbeans user, I found it reassuring to see that the Netbeans team is committed to bring first class Maven support to the IDE.

Last and most important, the R&D team at eZee has decided to use Maven to manage our internal projects. The rationale is that since we are starting brand new projects, we are not chained to legacy ANT scripts. We have an opportunity to start fresh from Maven. Why not try it? Even if Maven does not work out, we still have an opportunity to convert the projects to ANT -- but we will all learn a lot of the exercise.

So, how do I like Maven after a week of using it in real life? I have to say that I really liked it. Maven takes a very structured approach to build management. It is not as flexible as ANT. For most "standard" project types, Maven just supports them out of the box -- there is no build script to write -- just put your code and configuration files in the right default directories and you are ready to go. Speaking of "configuration by convention!" However, if you want to do anything not supported by default, you have to write code to plug into pre-defined integration points in Maven.

Maven really reminds me a lot about JSF -- it does not allow you to do random scriptlets like JSP, but it provides integration points where you can heavily customize the behavior of the system. Sure, it is more work to create code that conforms to the "framework". But you also get more stability and maintainability out of it. I am hoping that Maven can allow me to achieve the same!