Java EE 6 / EJB 3.1 / JSF 2.0 WAR Modularization With Maven - Concrete Sample

The backing bean HelloView:

@ManagedBean

@RequestScoped

public class HelloView {

    @EJB HelloService helloService;

    public String getHelloMessage(){

        return helloService.hello();

    }

is packaged directly in the classes folder inside the Java EE 6 WAR. The boundary HelloService:

@Stateless

public class HelloService {

    @EJB CurrentTimeService currentTimeService;

    public String hello(){

        return "Hello: " + currentTimeService.getCurrentDate();

    }

Is located in the JAR-module with the following maven metadata:

[...] 

  <groupId>com.abien.patterns.business</groupId>

  <artifactId>ModularWarWithEJBsBoundary</artifactId>

  <packaging>jar</packaging>

  <version>1.0-SNAPSHOT</version>

  <name>ModularWarWithEJBsBoundary</name>

[...] 

 

It references the CurrentTimeService control,

@Stateless

public class CurrentTimeService {

    public Date getCurrentDate(){

        return new Date();

    }

which gets automatically injected. The CurrentTimeService resides in another module. The compile-scoped dependency is specified in the pom.xml:

    <dependency>

        <groupId>com.abien.patterns.business</groupId>

        <artifactId>ModularWarWithEJBsControl</artifactId>

        <version>1.0-SNAPSHOT</version>

        <scope>compile</scope>

    </dependency>

All EJBs are located in standard JARs. There is no need for special treatment / artifacts.

In the pom.xml of the WAR-project only the dependency to the boundary has to be specified. The transitive dependency to the control is automatically inherited:

<groupId>com.abien.patterns.business</groupId>

   <artifactId>ModularWarWithEJBs</artifactId>

   <packaging>war</packaging>

   <version>1.0-SNAPSHOT</version>

   <name>ModularWarWithEJBs Java EE 6 Webapp</name>

   <url>http://maven.apache.org</url>

   <dependencies>

      <dependency>

         <groupId>com.abien.patterns.business</groupId>

         <artifactId>ModularWarWithEJBsBoundary</artifactId>

         <version>1.0-SNAPSHOT</version>

         <scope>compile</scope>

      </dependency>

   </dependencies>

[...] 

You will find both JAR-modules in the WEB-INF/lib/ folder:

ModularWarWithEJBs/

+--WEB-INF/

+----lib/

+------ModularWarWithEJBsBoundary-1.0-SNAPSHOT.jar 

+------ModularWarWithEJBsControl-1.0-SNAPSHOT.jar 

 

Java EE 6 WAR is the "new" EAR - it allows easy packaging and pragmatic modularization of EJB-modules and web applications. Together with Maven it's the perfectly synergy.

The working maven projects (ModularWarWithEJBs Java EE 6 Webapp) were pushed in into: http://kenai.com/projects/javaee-patterns/.  

 [See Page 267 (Monolithic or Loosely Coupled?) in "Real World Java EE Patterns - Rethinking Best Practices" and Premature Encapsulation Is the Root of All Evil, Page 253]  

Comments:

excellent content, thanks for sharing! Could you also work a bit on the design? I find dzone-like code samples much much more readable w/ syntax highlight and whatnot..

Posted by Kristof Jozsa on December 09, 2009 at 11:44 AM CET #

@Kristof,

thanks for the feedback. The problem is my time - too much is going on in the Java EE land :-).

But I could use a widget for better highlighting - you are right.

Posted by Adam Bien on December 09, 2009 at 12:10 PM CET #

Hi Adam,

To get the javaee-api-6.0-SNAPSHOT, I had to add to the pom.xml of ModularWarWithEJBsControl this :

<repositories>
<repository>
<id>java.net2</id>
<name>Java.Net Maven2 Repository, hosts the javaee-api dependency</name>
<url>http://download.java.net/maven/2</url>
</repository>
</repositories>

Thank you for this maven example. Could you provide in the future the EAR packaging example ?

Posted by Bakann on December 10, 2009 at 02:02 AM CET #

Hi @Bakann,

EAR ist just a click with NetBeans 6.8. It will create and link the multi-module, ejb-jar, wars projects for you.

1. You are right - in my case I have the link to the repo in the settings.xml.

2. You are right - for a sample it is better to include the reference to the repo in the pom.xml,

thanks for your feedback!,

adam

Posted by Adam Bien on December 10, 2009 at 09:36 AM CET #

Excellent work, man. Nice content!

Posted by Flávio Albuquerque Camilo on December 16, 2009 at 04:10 AM CET #

Thank you for your example!

I wonder, would you be able to enhance it by extracting an interface from the CurrentTimeService class and showing the use of CDI to inject one of two (or more) possible implementations of this interface into the HelloService class?

Posted by Daniel Walker on February 22, 2010 at 11:03 PM CET #

Way to go Adam; thanks a bunch for clarifying this. Strangely enough, though EJB _development_ itself is more fun (and also easier) than ever with recent Java EE versions, finding a right build and module structure still feels painful at times. This one definitely helped, and it feels good to give up on EAR after all. ;)

Posted by Kristian Rink on July 29, 2011 at 01:49 PM CEST #

As an additional question however, as this seems to cause problems once in a while: Given such a setup, what would be a sane way to easily make HelloService accessible to another (external) web app? So far, I see a load of EJB 3.1 documentation focussing on things being easy as long as all the functionality lives inside one application context, be that jar or war or whatever. How, in such a situation, would an "external" webapp access this structure? I assume it would end up introducing a @Remote interface to HelloService and a dedicated external client jar (assuming the "external" webapp runs inside the same application server)?
Cheers,
Kristian

Posted by Kristian Rink on July 29, 2011 at 03:26 PM CEST #

Hello Adam,

first thx for your articles about Java EE - helped me a lot many times.

I would like to ask what is the proper JARs structure (which are then added to such Java EE WAR) if you have entities inside. Where should be persistence.xml? In every single JAR (under META-INF) or in top-level WAR (WEB-INF/classes/persistence.xml)? I can imagine that almost every such module would like to use same DB (~? DS/PU).

The real example could be AccountsService which is interface injected via CDI. It might have various implementations in various JARs. First impl might just delegate the requests to some external service/server while the other impl might want to use local DB to manage accounts (credentials..etc.) so it will have some AccountEntity which will need its persistence.xml, right?:)

Thanks a lot

Posted by Zdenek on April 24, 2012 at 03:40 AM CEST #

Post a Comment:
  • HTML Syntax: NOT allowed
...the last 150 posts
...the last 10 comments
License