Showing posts with label example. Show all posts
Showing posts with label example. Show all posts

20100829

Now you can run AnalyzerBeans (from the shell)

Lately I've been blabbering a lot about the marvels of AnalyzerBeans - the project that is aimed at re-implementing an engine for data analysis based on my experience from DataCleaner.

An important milestone in any development project, especially those like AnalyzerBeans, that are implemented bottom-up, is when it is actually possible to use the application without having any developer skills. So far the development of AnalyzerBeans has been focused on making it work in a unittesting perspective, but now we've reached a point where it is also possible to invoke the engine from the command line.

Since we haven't released AnalyzerBeans yet, you will still have to check out the code and build it yourself. It's rather easy - it just requires Subversion and Maven. First, check out the code:

> svn co http://eobjects.org/svn/AnalyzerBeans/trunk AnalyzerBeans

Now build it:

> cd AnalyzerBeans
> mvn install

And now run the example job that's in there:

> java -jar target/AnalyzerBeans.jar \
> -configuration examples/conf.xml -job examples/employees_job.xml

The job will transform/standardize the "full name" and "email address" columns of a CSV-file (located in the examples-folder) and then print out value distribution and string analysis results for the standardized tokens: First name, Last name, Email username, Email domain.

If you've gone this far, you've probably also tried opening the xml-files employees_job.xml and conf.xml in the examples-folder. Maybe you've even figured out that the conf.xml describes the application setup and that the employees_job.xml file describes the job contents. You can edit these files as you please to further explore the application. I will be sure to update my blog soon with some more examples. Also one of the next features of the command line interface will be to print the available Analyzers and Transformers in order to make it easier to author the xml job-files.

If you're just trying this out now and if you are getting excited about AnalyzerBeans, here are my previous blog posts on the subject. Please don't hesistate to let me know what you think.

20090429

Seam, EJB's and EAR-packaging in Maven

Lately I've been designing a new course on the splendid JBoss Seam (2.1) Web and Java EE framework. One thing that strikes me, being an enterprise Java developer, is that almost no good examples of setting up Seam using Maven exist. I realize that Seam's appeal comes from a tradition of wanting things to be nice and easy, so the seam-gen tool has absolute merits for creating your project but to me the downside of this approach is that you're bound to use Ant as a build tool and for a lot of reasons I won't go into here, I strongly prefer using Maven.

The examples of using Maven to build Seam applications that I have been able to track down have been limited in a variety of ways:

  • Most of them required to use a specific Maven archetype which altered the default project layout.
  • Almost all of them where out of date and was bound to a very "custom" maven repository which I don't think is suitable for enterprise application infrastructure.
  • Those that didn't fall within the former two points where restricted to web-applications (WAR-files) only and thus didn't support using EJB's in the Seam applications.
So this blog post is going to be a walk-through of how I managed (after quite some effort) to configure Maven to be able to build an EAR file containing EJB's and a web-application that is able to utilize these EJB's as Seam components. I'm only highlighting the most interesting parts - You can download the complete example for free - and in contrast to the examples I have seen, it's very bare-boned and won't take more than a few seconds to alter to your needs.

Project structure
OK - to meet the demand of packaging an EAR file I've created a Maven project consisting of three modules. It's possible that this part can be optimized a bit since I use a seperate module for doing all the packaging (which to my understanding is the way to do it). The modules are:
  • ejbs - containing the EJB's and possibly other "backend"-stuff like JPA-classes and so on.
  • web - containing the web application
  • packaging - for packaging the EAR file containg the two other modules (and Seam)
Which module depends on what?
One of the big issues that I faced was figuring out how to configure Maven's dependency management framework to generate a correct set of EAR, JAR and WAR files. If this is done wrong it won't work and you'll waste hours (or at least I did) trying to figure out what is wrong.

All provided dependencies go into the parent project. These are all the dependencies provided by your container (plus Seam itself which will be packaged within the EAR file). You will need to add JBoss's Maven repository to resolve these dependencies. Here are the important parts of my parent project pom:
<repositories>
   <repository>
     <id>repository.jboss.org</id>
     <name>JBoss Repository</name>
     <url>http://repository.jboss.org/maven2</url>
   </repository>
</repositories>
<modules>
   <module>ejbs</module>
   <module>web</module>
   <module>packaging</module>
</modules>
<dependencies>
   <dependency>
     <groupId>org.jboss.seam</groupid>
     <artifactId>jboss-seam</artifactid>
     <version>2.1.1.GA</version>
     <scope>provided</scope>
   </dependency>
   <dependency>
     <groupId>javax.faces</groupid>
     <artifactId>jsf-api</artifactid>
     <version>1.2_02</version>
     <scope>provided</scope>
   </dependency>
   <dependency>
     <groupId>org.hibernate</groupid>
     <artifactId>hibernate-entitymanager</artifactid>
     <version>3.4.0.GA</version>
     <scope>provided</scope>
   </dependency>
   <dependency>
     <groupId>org.hibernate</groupid>
     <artifactId>hibernate-validator</artifactid>
     <version>3.1.0.GA</version>
     <scope>provided</scope>
   </dependency>
   <dependency>
     <groupId>javax.servlet</groupid>
     <artifactId>servlet-api</artifactid>
     <version>2.5</version>
     <scope>provided</scope>
   </dependency>
   <dependency>
     <groupId>javax.servlet.jsp</groupid>
     <artifactId>jsp-api</artifactid>
     <version>2.1</version>
     <scope>provided</scope>
   </dependency>
   <dependency>
     <groupId>javax.ejb</groupid>
     <artifactId>ejb-api</artifactid>
     <version>3.0</version>
   </dependency>
</dependencies>
In the ejbs module you will not need any dependencies!

In the web module you will need to add seam-ui (excluding the "core" seam, because it is provided within the EAR file), facelets and other web-dependencies such as RichFaces, seam-pdf or whatever. Here are the dependencies of my web module pom:
<dependencies>
   <dependency>
     <groupId>com.sun.facelets</groupid>
     <artifactId>jsf-facelets</artifactid>
     <version>1.1.11</version>
   </dependency>
   <dependency>
     <groupId>org.jboss.seam</groupid>
     <artifactId>jboss-seam-ui</artifactid>
     <version>2.1.1.GA</version>
     <exclusions>
       <exclusion>
         <groupId>org.jboss.seam</groupid>
         <artifactId>jboss-seam</artifactid>
       </exclusion>
     </exclusions>
   </dependency>
</dependencies>
If you want to write Seam components that pertain only to the web module, then you will probably also need to include the ejbs module as a dependency in the web module pom. But remember to set the scope as provided, because it's all within the same EAR.

Last but not least you will need to write the packaging module pom. The Seam Documentation have been used to guide how this pom is structured: The ejbs module needs to be a registered EJB module. The web module needs to be a registered WAR module. And Seam itself needs to be a registered EJB module as well! JBoss EL needs to be placed in the /lib directory of the EAR and you need to make sure to exclude the EL API dependency from several artifacts - otherwise you'll get weird classpath issues when deploying. The important parts of the packaging module pom looks like this (pay attention to the parts in bold):
<build>
   <plugins>
     <plugin>
       <artifactId>maven-ear-plugin</artifactid>
       <configuration>
         <modules>
           <jarmodule>
             <groupId>org.jboss.el</groupid>
             <artifactId>jboss-el</artifactid>
             <includeinapplicationxml>false</includeinapplicationxml>
             <bundledir>lib</bundledir>
           </jarmodule>
           <webmodule>
             <!-- add web module groupId and artifactId here -->
             <contextroot>/seam-ejb-ex</contextroot>
           </webmodule>
         </modules>
       </configuration>
     </plugin>
   </plugins>
</build>
<dependencies>
   <dependency>
     <!-- add ejbs module groupId, artifactId and version here -->
     <type>ejb</type>
   </dependency>
   <dependency>
     <!-- add web module groupId, artifactId and version here -->
     <type>war</type>
   </dependency>
   <dependency>
     <groupId>org.jboss.seam</groupid>
     <artifactId>jboss-seam</artifactid>
     <version>2.1.1.GA</version>
     <type>ejb</type>
     <exclusions>
       <exclusion>
         <groupId>javax.el</groupid>
         <artifactId>el-api</artifactid>
       </exclusion>
     </exclusions>
   </dependency>
   <dependency>
     <groupId>org.jboss.el</groupid>
     <artifactId>jboss-el</artifactid>
     <version>1.0_02.CR2</version>
     <type>jar</type>
     <exclusions>
       <exclusion>
         <groupId>javax.el</groupid>
         <artifactId>el-api</artifactid>
       </exclusion>
     </exclusions>
   </dependency>
</dependencies>
So that's all the Maven configuration. Now to some "gotchas" in regards to Seam configuration. A lot of these things are being "disguised" by seam-gen so consider this a list of things you might have forgotten if you're building the project from the bottom up:
  • Remember to put empty seam.properties files in to the resource folders of both the ejbs and web modules.
  • Remember to register the Seam interceptors (as described in the Seam Documentation) in the ejb-jar.xml file, located in the resources/META-INF folder ejbs module.
  • The components.xml file should be located in the web module's WEB-INF folder. But you can't just copy the file from a seam-gen project because seam-gen dynamically replaces some "magic strings" in it to see to container compliancy. Instead you will have to add this static entry to the components.xml file yourself:
    <core:init pattern="seam-ejb-ex/#{ejbName}/local"></core:init>
    Note the seam-ejb-ex part of that static jndi pattern string. You will have to replace this part of the string with the context root entry that was highlighted in the packaging module pom!

I hope this blog entry have cleared up some of the confusion that I met when I tried building Maven-based Seam/EJB projects. Please let me know if it works out and remember that you can download the full example and use it as a reference as you like.