Archive for the ‘seam’ Category

Google App Engine for Java — First Impressions

Thursday, April 9th, 2009

Today’s big news is Google’s announcement for Java support on the App Engine. At Ringful, our hardware strategy is two words: cloud computing. We have multiple apps on both Amazon EC3/S3 and GAE.

EC2 is obviously more flexible since it provides a virtualized Linux environment, where you can do anything you want. GAE, on the other hand, feels much more restrictive since it is basically an app server in a scalable infrastructure. For instance, up until today, Python on Django is the only application model supported on GAE. However, as we use both services, I have grown to like GAE a lot more than EC2:

  • GAE provides automatic scaling that would just add in more resources based on the real time load of your app; EC2 requires you to actually monitor the load and bring up additional servers yourself.
  • GAE’s restrictive programming model also forces you to write apps that are horizontally scalable; With EC2, you could well write apps that cannot scale at all no matter how many server instances you start. In another word, with EC2, there could be well a false sense of scalability — until you really hit a traffic spike …
  • GAE is truly usage based — it only charges for CPU cycles that are actually used, as opposed to EC2 which charges CPU time as long as your virtual machine is up, even if it is idle. That makes GAE potentially a lot more cost effective for small apps.

So, in short, I am very excited that Java finally comes to GAE. I immediately applied for Java support in GAE accounts and wrote a couple of small apps to try it out. Overall, it feels great. I am definitely porting my Python apps to GAE Java as soon as I get around to do it. :) Here is a short summary of my first impression.

The good

* It is based on the standard JDK — not the mutilated Android Java stuff as once rumored.

* Standard servlet + JSP + JSTL stack for web apps. The same kind of setup Tomcat ships out of the box, and should be sufficient for a lot of apps.

* GWT integration if you want an advenced web framework to use with your app.

* JPA support for data persistence in Google’s BigTable.

* Standard WAR deployment. That allows developers to use any tool of their choice — ANT, Maven, Eclipse, NetBeans — as long as it can build standard WAR files.

* Most JVM languages, such as JRuby, Jython, Groovy, and Scala, are already working since the runtime is standard JDK-based.

* A lot of frameworks are already working — or can be made to work with some tweak.

* Cron and scheduler support out of the box. It is a lot better than EJB Timer.

* Direct integration with Google’s data APIs for user authentication, email sending, image manipulation and much more!

The bad

* Most of the Java EE stuff is not supported. Noticeably missing are RMI, JDNI, and JDBC. That means commonly used frameworks such as session beans and Hibernate are not supported. I have heard that JSF 1.2 does not work out of box. I do not expect Seam to work out of the box either. Bummer.

* The persistence store is not a SQL database. I understand that a non-relational data store is needed to support the kind of scalability Google needs. But, BigTable does not even provide full text search! This is Google we are talking about! The lack of SQL supports means that you probably need to re-write significant amount of code if you are porting an app to/from GAE.

* The lack of access to file system would break a lot frameworks that uses XML configuration files — think Struts! But I expect this can be fixed with tweaks in the frameworks.

* The lack of the ability to create and manage threads is probably not a big deal, since technically you should not create threads yourself in a Java EE container anyway. But still, it would be nice to create threads that processes data in the background.

* The HTTP session support in the Java runtime uses BigTable to store session data as opposed to in-memory cache. There got to be a performance for this … But I guess they have to do it this way. In a truly load balanced environment, replicating in-memory sessions is a very complicated task.

* What is the deal with JDO? They really should focus the effort on getting better JPA support. ;)

* No JMS support is a bummer.

The ugly

There is really none I can think of! Despite my numerous mis-givings, Google did a great job bringing Java into a scalable infrastructure and provide very low hosting options for the masses. I look forward to developing more apps on this platform!

Win a free book at JavaRanch

Tuesday, March 31st, 2009

Jacob and I are promoting our “Seam Framework” book at JavaRanch this week. Stop by and ask a question in the JBoss Forum to win a free copy of the book. :) See you there!

“Seam Framework” Finally came out in Paperback (and spotted in China)

Saturday, February 7th, 2009

I just received a hard copy of my book “Seam Framework” from my publisher today. That means you should be able to get it from Amazon and Barnes and Noble very soon. :)

The book is the “second edition” of the original JBoss Seam book I wrote back in 2006, which was a JavaOne and Amazon best seller. But, it is much more than a “sequel” of the original book, my co-author Jacob Orshalick has made many major contributions to the book to address the latest and greatest features in Seam and WebBeans. Check it out!

The picture shows both the original “JBoss Seam” book and the “Seam Framework” book side by side — the photo on the cover of the original book was taken by Ju during our trip to the Death Valley in 2005.

Two books

In a related story, my friend Norman Richards (also a core developer on the Seam team) spotted the Chinese translation of the original Seam book while he was in vacation in China last month. Now, anyone in China wants to buy one and send to me? :)

A Mobile Companion for SXSW 2008

Tuesday, February 26th, 2008

If you are among the 6000+ technologists / entrepreneurs / designers attending this year’s SXSW conference (or are just interested in following what’s going on in the conference), check this out: The SXSW 2008 Mobile Companion (http://webclip2go.com/sxsw08) is a free mobile web application that lets you access everything about the South by Southwest conference right there on your mobile phone. Try it in a web-based iphone simulator (Safari and Firefox only). It works on iphone, Blackberry, Palm, Windows Mobile, Nokia, and just about any smartphone out there. The way it works is that it takes live content about the conferences from all over the web, and make the content suitable for display on small mobile phone browsers. Through the companion, you can check:

* Panel / presentation schedules by day
* Session abstracts
* Film / music performance schedules by day
* Official and unofficial conference news, blogs and wikis
* Blogs of conference speakers (full posts w/ comments)
* SXSW parties!
* Austin local news
* Music and film listings by venue in the Austin area
* and much more …

All you need is to load the following URL in your mobile phone browser. Or, if you do not want to type the URL, simply text the word sxsw08 to phone number 41411 to get a link returned in an SMS message (the SMS works in the US only!).

http://webclip2go.com/sxsw08 (Try web-based iphone simulator in your Safari or Firefox browser)

Picture 41.pngScreenshot0114.jpg

Why did I create it? Well, as a veteran technology conference speaker / attendee, I can tell you that conference WIFI is flaky at best in most big conferences. In fact, WIFI was the #1 problem in SXSW 2007. It is quite frustrating to take out your 8 lbs laptop just to find out that the WIFI is down or has no coverage in the Hall. Well, with the mobile companion, you can check out just about anything about the conference / speakers in real time on your phone. I personally would use it a lot. And I encourage you to try it out if you have an iphone / blackberry or other connected device. I plan to do the same for most other conferences I attend this year as well. :)

The technology behind the SXSW Mobile Companion is WebClip2Go. The goal was to let people clip live content from any existing web site / blog, so that those content can be viewed from mobile phones. It has become a hit among my friends — especially those with iphones, since the web content loads much faster and requires simpler navigation in WebClip2Go, compared with directly loading the original web site in iphone. Much still needs to be done to make WebClip2Go ready for the general Internet audience (e.g., we need a Firefox plugin that lets people “clip” web content via drag and drop). In any case, I will blog about WebClip2Go in a separate blog entry later this week. Stay tuned!

BTW, for my Seam readers, it might be comforting to know that the application is built on top of JBoss Seam technology.

Seam conversations made easy

Friday, February 15th, 2008

One of the most interesting concepts in Seam is “conversation” — it allows your web application to have separate internal states for each browser tab, or for each logical multi-page web operation. Conversations can even be nested to manage multi-level wizards. Conversations let you break away from the monolithic session-based web application state management. However, while the concept is easy to grasp, conversations are not as widely understood as sessions. Many web developers are intimidated by the powerful conversation management APIs in Seam.

Well, no more! Jacob Orshalick just released three draft chapters from our 2nd edition of the JBoss Seam book. Those chapters provide very good explanations on conversations should be used in Seam applications. Thanks Jacob! Go check them out!

2.5 Sessions Accepted in JavaOne 2008

Monday, February 4th, 2008

Cool! Out of 4 sessions I submitted to JavaOne 2008, 2.5 are accepted! Given that JavaOne accepts less than 5% of all session proposals, this sounds like pretty good success rate. :) So, what exactly will I talk about in JavaOne?

First off, I will be giving a technical session on Building Interactive Mobile Messaging Applications. I will discuss how to build a SMS service like the Google SMS on a Java EE server. I think the information presented in the session will be useful for a large number of developers — for instance, for web application developers, it is often nice to have a “send to phone” button on your pages to send small pieces of information (e.g., alerts / reminders / links) to the user’s mobile phone. In the session, you will also learn how to make your application respond to requests from SMS (e.g., the user sends in a SMS to reschedule an appointment etc.). The session covers technologies used in such a solution, common design patterns / pitfalls, and third party players involved.

I will also run a BoF session on JBoss Seam: The Deep Integration Framework for Web Applications. I will try to dispel the notion that Seam is somehow a mere “web framework”. Yes, Seam is used in many web applications, but you can just use PHP or Ruby for a simple web site. The real value of Seam is to bring real Java enterprise infrastructure (e.g., business process engine, rules engine, asynchronous messaging infrastructure, advanced transaction services, scheduling service etc.) to the web application. That saves you from hard coding business workflow or rolling your own middleware frameworks in the web application. Come to the session and join the discussion!

Finally, they accepted my proposal on Developing Compelling Mobile Web Applications as a backup session — that is the 0.5 session here. :) This session covers mobile browser detection, multi-template based web site design, and special UI tricks for the iphone. From what I was told, there is a pretty good chance for backup sessions to be presented in the conference since some session presenters drop out at last minute for various reasons. We will see.

Hope to see y’all in JavaOne again this year!

Seam book examples updated to Seam 2.0.0.GA

Tuesday, November 13th, 2007

As a service to my readers, I have updated all examples in my JBoss Seam book to Seam 2.0.0.GA.

Go download the zip file here

The example applications are fully tested against JBoss AS 4.2.0 GA.

NOTE: To build the examples, you now need to download and unzip Seam 2.0.0.GA first, and then set the build.properties file to point to the Seam installation directory.

Running Seam on non-JBoss Application Servers

Wednesday, November 7th, 2007

UPDATE: Several people commented that Seam works just fine with the TopLink JPA provider. I stand corrected. Thanks guys.

Here is what I posted to TSS today …

First, we try very hard to make Seam as generic as possible — so it would not require JBoss AS to run. The proof of this effort is that Seam runs on plain Tomcat (using RESOURCE_LOCAL transactions). So, in theory, it should run on all application servers out there. However, since all Seam developers use JBoss AS on a daily basis (we happen to believe that JBoss AS is the best AS out there :)), it is natural that Seam is tested most extensively on JBoss AS. Also, as an open source project, we do not have access to commercial WLS, WAS, ORA licenses, and do not have access to their support. So, our testing on those servers is not very comprehensive. I have personally installed the trial versions of those servers multiple times since they expire all the time. It is extremely time consuming …

So, the testing on commercial app servers is not very good at this moment. If you encounter issues with non-JBoss servers, raising them on the Seam forum is your best bet. Now here is a breakdown of what works and what not (to the best of my knowledge).

* Tomcat 5.5 and 6: Seam applications work out of the box on those servers if you use the RESOURCE_LOCAL transaction (see examples/jpa). You can use EJB3 features if you install JBoss Embeddable on top of Tomcat.

* Glassfish: Glassfish v2 is known to work with Seam (see examples/jee5 for an example). But we strongly recommend you use Hibernate as the JPA provider — not the default TopLink.

* Oracle: Oracle 10 is known to work with Seam (see examples/jee5 and examples/jpa). Again, choose Hibernate as the JPA provider.

* WebLogic: WebLogic 9.2 and 10 can be made to work with JPA + JTA transaction (see examples/jpa). However, EJB3 on WLS 10 does not yet work. There is a reflection error from the EJB proxy the last time I checked.

* WebSphere: I think the examples/jpa can work against WAS 6.1.0.9. You do need to tweak stuff a lot to make JSF 1.2 and Facelets work on that server. We have not tried WebSphere EJB3. However, anything beyond a simple CRUD app might have problems on WAS. One of the reasons is that the IBM JVM5 has a bug that complains about unknown annotations (the correct way is to ignore unknown annotations as the Sun JVM does). Unless IBM fixes this, you will have problems running Seam on WAS.

So, that’s it. If any of you can help us testing this stuff, please let us know! :)

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:

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!

Seam and SOA

Tuesday, July 31st, 2007

I am in Atlanta for our internal JBoss ESB / SOA training this week. Burr Sutter and his team are doing a great job conveying our SOA vision -- to mesh and reuse services you already built in your "single silo" applications (e.g., a web store and a warehouse management app can share an "order" object when the user confirms an order. Each application then process and save the order in their own ways.).

I have been thinking how Seam fits into this picture. With the support for web services in Seam 2.0, it is actually quite easy to fit a Seam application into a SOA environment. In this post, I'd like to discuss some work I did with the seambay example (a spoof auction site) to make it share its listings with other services, and receive listings from other services.

@Out

To make the seambay application share its auction listings with other services in the SOA environment, we need to serialize the Auction object and push it to the ESB, while it is being saved into the database by the Seam application. The least intrusive way to do this is to use an EJB3 interceptor to "steal" the Auction object when the confirm() method is called. This way, we do not need to make any change to the Seam application code.

JAVA:
  1. public class AuctionInterceptor {
  2.  
  3.   @AroundInvoke
  4.   public Object sendAuctionToESB (InvocationContext ctx) throws Exception {
  5.  
  6.     System.out.println("*** Entering AuctionInterceptor");
  7.  
  8.     Object target = ctx.getTarget ();
  9.     if (target instanceof AuctionAction) {
  10.       if (ctx.getMethod().getName().equals("confirm")) {
  11.         System.out.println("We will send the following Auction object to ESB");
  12.         Auction auction = ((AuctionAction) target).getAuction ();
  13.         // Send the following XML string to JMS
  14.         formatMessage(auction);
  15.       }
  16.     }
  17.  
  18.     try {
  19.       return ctx.proceed();
  20.     } finally {
  21.        System.out.println("*** Exiting AuctionInterceptor");
  22.     }
  23.   }
  24.   ... ...
  25. }

When the user enters a new auction listing on the site, the server console prints the following message.

Picture 18.png

@In

To make the Seam application as a SOA service end-point requires external applications to invoke its business logic through web services. The challenge here is that most business logic in Seam are managed in "conversations", which holds finer grained application state than Http sessions. How do you keep the conversation state across multiple SOAP calls? Well, here is where the Seam Web Service comes into play.

To expose business logic methods in Seam components as Web Service methods, you need to write a facade SLSB to wrap around the methods you want to expose. You can use the Seam.getComponent() method to get any Seam component by its name and then proceed to invoke any method on the component.

JAVA:
  1. @Stateless
  2. @WebService(name = "AuctionService", serviceName = "AuctionService")
  3. public class AuctionService implements AuctionServiceRemote
  4. {
  5.    @WebMethod
  6.    public boolean login(String username, String password)
  7.    {
  8.       Identity.instance().setUsername(username);
  9.       Identity.instance().setPassword(password);
  10.       Identity.instance().login();
  11.       return Identity.instance().isLoggedIn();
  12.    }
  13.  
  14.    @WebMethod
  15.    public void createAuction(String title, String description, int categoryId)
  16.    {
  17.       AuctionActionInt action = getAuctionAction();
  18.       action.createAuction();
  19.       action.setDetails(title, description, categoryId);
  20.    }
  21.  
  22.    @WebMethod
  23.    public Auction getNewAuctionDetails()
  24.    {
  25.       return getAuctionAction().getAuction();
  26.    }
  27.  
  28.     @WebMethod
  29.    public void setAuctionPrice(double price)
  30.    {
  31.       getAuctionAction().getAuction().setPrice(price);
  32.    }
  33.  
  34.    @WebMethod
  35.    public void confirmAuction()
  36.    {
  37.       getAuctionAction().confirm();
  38.    }
  39.  
  40.    private AuctionActionInt getAuctionAction()
  41.    {
  42.       // Get seam component named "auctionAction" from context
  43.       return (AuctionActionInt) Component.getInstance("auctionAction", true);
  44.    }
  45.    ... ...
  46. }

Notice that the createAuction(), setAuctionDuration(), setAuctionPrice() and confirmAuction() methods all need to happen in the same conversation so that they can access the same "auctionAction" component. But we do not explicitly pass the conversation id to the web service calls. Instead, when the createAuction() method returns, it inserts a conversation id in the SOAP header, and expect the client to use the same conversation id in the header until the caller reaches confirmAuction(), which ends the conversation. The SOAP request inside a conversation looks like the following:

XML:
  1. <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
  2.                            xmlns:seam="http://seambay.example.seam.jboss.org/">
  3.    <soapenv:Header>
  4.       <seam:conversationId>2</seam:conversationId>
  5.    </soapenv:Header>
  6.    <soapenv:Body>
  7.       <seam:setAuctionPrice>
  8.          <arg0>20</arg0>
  9.       </seam:setAuctionPrice>
  10.    </soapenv:Body>
  11. </soapenv:Envelope>

As a proof of concept to demonstrate that Seam web service is well supported by existing SOAP tools, I build a SoapUI script to demonstrate how to add an auction to the Seam app via web services. Notice the "transfer" elements in the script. They are used to maintain the conversation id header across SOAP requests in a conversation.

Picture 17.png

Finally, I'd like to make the SOA version of the seambay example available for download. You can find the ready built EAR file in the dist directory, as well as the SoapUI script in the root directory.

JBoss Seam: A “Deep Integration” Framework

Monday, July 30th, 2007

TheServerSide is running my article this week:

JBossSeamFramework.gif

I like the artwork visualizing "Seam" in an origami bird. Elegant, balanced, and lightweight. Perfect for Seam. The article is based on presentations I recently did on Seam. It targets experienced Java EE developers (i.e., the JUG, NFJS crowd), and goes into depth on some of ideas behind Seam (instead of just a CRUD demo). I hope you enjoy it and let me know your comments. Thanks. Here are some slides from my presentations that are relevant to the article.

Picture 8.png

Picture 9.png

Picture 10.png

Picture 11.png

Picture 12.png

Seam 2.0 and Tomcat

Tuesday, July 24th, 2007

Darryl Smith pointed out that we can actually use non-JTA transactions with JPA in Tomcat now. So, I just added tomcat 5.5 and 6.0 build targets for the jpa example in CVS based on his suggestions.

In JBoss Seam 2.0, we made some changes to the way Tomcat is supported as a Seam runtime. It has caused some confusion. So, let me try to clarify here ...

As you recall, in Seam 1.0 to 1.2, we can run Seam applications on Tomcat by bundling the JBoss Embeddable EJB3 library or the JBoss micro-container inside the WAR application. The application will need to bootstrap the EJB3 container or micro-container upon startup. However, the EJB3 library Jars is more than 20 MB. The idea of bootstraping the entire thing for each application is not very efficient. In Seam 2, we leverage the "Embeddable JBoss" library to provide shared EJB3 service to all WAR applications deployed in the Tomcat instance. You have two ways to run Seam 2 applications in Tomcat:

1. If you need to use EJB3 beans, you will need to install the "Embeddable JBoss" libraries as shared library in Tomcat. It is an easy process. You can find instructions for Tomcat 5.5 and 6.0 respectively. Once you do that, you can deploy Seam applications without any restrictions. You will be able to use full EJB3 features including session beans, entity beans, message driven beans, and web services etc.

Of course, you still cannot deploy EAR files on Tomcat. But you can bundle EJB3 JARs in the WEB-INF/lib directory of your WAR application -- essentially re-creating the EAR structure in a WAR. Just run the tomcat.war ANT target on any of the official Seam examples to see how this is done.

2. If you absolutely cannot install any shared library or shared configuration on Tomcat, you can still run Seam applications. However, you will not be able to use EJB3 features -- you must use Seam POJOs instead. You can, however, use JPA in local transaction mode. Seam manages the transaction manager and entity manager for you in this case.

Checkout the jpa and hibernate2 examples in Seam distribution and build for the tomcat55 or tomcat6 targets to see how this works. The jpa shows how to use JPA EntityManager with Seam POJOs and the hibernate2 example shows how to use Hibernate sessions with Seam POJOs. You will need to copy hsqldb.jar into Tomcat's shared lib directory since the example app assumed that we will use a HSQL DB from JNDI (see META-INF/context.xml). Obviously, you do not have to do that in your own apps.

Okay, so much for Tomcat support. What about Seam 2 support for J2EE 1.4 application servers and non-JBoss Java EE 5 application servers? Here are the status:

  • J2EE 1.4 application servers: Try the jpa example in Seam distribution. It uses Seam POJOs to replace EJB3 session beans in other examples. The jpa example builds for JBoss 4.0.5/4.2.x, WebSphere 6.1.0.9, and WebLogic 9.2.
  • Java EE 5 application servers: Try the jee5 example in Seam distribution. It builds for JBoss AS 5.x, Glassfish V1/V2, and Oracle OC4J 11. We are currently working on WebLogic 10, which has some weird reflection issues.

Hope that helps!

Seam makes JSF sexy again

Thursday, May 31st, 2007

Kito Mann of JSFCentral just posted the PDF slides for our JavaOne talk on Seam and JSF. The slides cover what is hot about JSF and what is not, and more importantly, how Seam enhances and improves JSF in 14 important ways. :) Just to wet your appetite, here are the 14 key points elaborated in the slides:

1. Reduces Boilerplate code
2. Dependency bijection
3. No XML hell
4. Integrated ORM support (a.k.a, use Hibernate as Gavin intended! ;))
5. RESTful URLs and page actions (for GET requests)
6. Extensive and expanded use of JSF Expression Language (EL)
7. Fine-grained stateful conversations (web transaction, multi-tab support etc.)
8. Direct JavaScript integration for Ajax (use Dojo with your JSF apps)
9. Elegant input validation
10. Graceful exception handling
11. Easy-to-use and rule-based security
12. Business process and rules integration
13. Very easy to test (both unit test and integration test)
14. Tools support (Seam Gen for RoR-like experience for CURD apps)

Go check it out!