Enterprise grade Java.
You'll read about Conferences, Java User Groups, Java, Integration, Reactive, Microservices and other technologies.

Monday, March 12, 2012

The Java EE 6 Example - Galleria - Part 1

12:33 Monday, March 12, 2012 Posted by Markus Eisele 10 comments:
, ,
Have you ever been wondering where to find some good end-to-end examples build with Java EE 6? I have. Most of the stuff you find on the net is very basic and doesn't solve the real world problems. This is true for the Java EE 6 tutorial. All the other stuff, like most of what Adam Bien publishes are a very tight scoped examples which also doesn't point you to a more complete solution.
So, I was very pleased to stumble over a more complex example done by Vineet Reynolds. It's called "Java EE 6 Galleria" and you can download the source code from bitbucket. Vineet is a software engineer contributing to the Arquillian project; more specifically, he contributed bugs fixes and worked on a few feature requests for Arquillian Core, and the GlassFish, WebLogic and Tomcat integrations for Arquillian. This is where I first came across his name. And following the Arquillian guys and him a little closer directly send me to this example. A big thanks to Vineet for a helping hand during my first tries to get this up and running. Follow him if you like on twitter @VineetReynolds.
Here is a brief explanation about it's background and this is also kicking of a series about running it in different settings and pointing you to a few more details under the hood. This is the basic introduction.
There is more to discover: Read about running it on GlassFish, running it on WebLogic, testing it, enhanced security and about dealing gracefully with exceptions.

About the Galleria
The high level description of the project is the following: The Java EE 6-Galleria is a demo application demonstrating the use of JSF 2.0 and JPA 2.0 in a Java EE project using Domain Driven Design. It was written to serve as a showpiece for domain driven design in Java EE 6. The domain model of the application is not anemic, and is constituted of JPA entities. The entities are then used in session EJBs that act as the application layer. JSF facelets are used in the presentation tier, using Mojarra and PrimeFaces. The project seeks to achieve comprehensive coverage through the use of both unit and integration tests, written in JUnit 4. The unit and integration tests for EJBs and the domain model rely on the EJB 3.1 container API. The integration tests for the presentation layer relies on the Arquillian project and its Drone extension (for execution of Selenium tests).

Domain driven design using Java EE 6
DDD as an architectural approach, is feasible in Java EE 6. This is primarily due to the changes made in EJB 3.x and in the introduction of JPA. The improvements made in the EJB 3.x and JPA specifications allow for a domain and application layer to be modeled in Java EE 6 using DDD. The basic idea here is to design an application ensuring that persistence services are injected into the application layer, and used to access/persist the entities within a transactional context established by the application layer.

Domain Layer
The application contains four domain entities for now - User, Group, Album and Photo which are the same as the JPA entities in the logical data model.


Repository Layer
On top of the logical data model you can find four repositories - UserRepository, GroupRepository, AlbumRepository and PhotoRepository. Each for one of the four domain entities. Even if the DDD requires that you only have repositories for an aggregated root, and not for all domain entities it is designed this way to allow the application layer to access the Album and Photo domain entities without having to navigate Albums and Photos via the UserRepository. The repositories are Stateless Session Beans with a no-interface view and are constructed using the Generic CRUD Service pattern published by Adam Bien.

Application layer
The application layer exposes services to be consumed by the presentation layer. It is also responsible for transaction management, while also serving as a fault barrier for the below layer(s). The application layer co-ordinates with the domain repositories and the domain objects to fulfill the desired objectives of the exposed services. In a way, this layer is the equivalent to a service layer in traditional applications. The application layer exposes it's services through the UserService, GroupService, AlbumService and PhotoService interfaces and is also responsible for validating the providing domain objects from the above layers, before co-ordinating actions among objects in the domain layer. This is done via JSR-303 constraints on the domain objects.

How it looks like
And this is, how this example looks like if you are running it on latest GlassFish 3.1.2. Curious to set this up yourself? Wait for the next post or give it a try yourself ;)


The second part guides you through the setup on GlassFish. Read on!
If you are interested in running this on latest WebLogic 12. Read the third part!

10 comments:

  1. Hi, I wonder what software you've used to design the logical model? The picture looks really nice.

    ReplyDelete
    Replies
    1. Hi Dalibor,

      Vineet did it. He told me, that he did the logical data model with the Eclipse JPA Diagram editor (Dali plugin) and the physical data model with the Hibernate Tools for Eclipse.

      Thanks for asking,
      -Markus

      Delete
  2. Hi Markus,
    This is really helpful JavaEE Showcase app.

    But one thing I couldn't understand is, in Authenticator.authenticate() method he used request.login(userId, new String(password));

    Here request is of type javax.servlet.http.HttpServletRequest.

    HttpServletRequest doesn't have login() and logout() methods..How come it is compiling/working?

    Thanks,
    Siva

    ReplyDelete
    Replies
    1. Hi Siva,

      thanks for asking. If you look at the
      http://docs.oracle.com/javaee/6/api/javax/servlet/http/HttpServletRequest.html JavaDoc you see, that there are both:

      void login(java.lang.String username, java.lang.String password)
      Validate the provided username and password in the password validation realm used by the web container login mechanism configured for the ServletContext.
      void logout()
      Establish null as the value returned when getUserPrincipal, getRemoteUser, and getAuthType is called on the request.

      -M

      Delete
  3. Hi Markus,
    Thanks for sharing this wonderful JEE example. As far as I know that the EntityManager is not thread safe, so should it be declared as local variable instead of instance variable? Thanks

    ReplyDelete
    Replies
    1. Hi John,

      here is what the JPA 2.0 spec (7.2) has to say:
      "An entity manager must not be shared among multiple concurrently executing threads, as the entity manager and persistence context are not required to be threadsafe. Entity managers must only be accessed in a single-threaded manner."

      Answered?

      Thanks,
      M

      Delete
    2. Hi Markus,
      Thanks for your clarification, you certainly answered my question, as long as the stateless bean is thread-safe the EntityManager is safe.

      Thanks
      John

      Delete
  4. Hi Markus,
    thanks for your post, but I need a clarification.
    I read that, according to DDD, entities should be compared for equality by their id values and not by any of their properties such as happen for value objects (told in a easy way).
    I noticed that, for example, name and description in Album domain object are not declared as a unique tuple in JPA, even though they are used for equals and hashcode.

    I'm wrong or is there a particular reason why you choosen this implementation?
    I noticed you put jpa implementation inside service layer package, should not it be placed in the infrastructure layer package?

    Thanks

    ReplyDelete
    Replies
    1. Hi Alessio,

      I am only _showcasing_ the App here. Vineet is the one who wrote it and he has some more explanations on his bitbucket wiki. I also pointed him to your question, so you might end up having some more explanations here soon.

      Thanks for asking,
      -M

      Delete
    2. Hi Alessio,
      There were some compromises in implementing the equals and hashcode contracts for the Album and Photo entities. Most of them are documented in the Data model - https://bitbucket.org/VineetReynolds/java-ee-6-galleria/wiki/DataModel.
      To answer your question specifically, an Album domain object in the domain cannot be identified by a name and description alone, since multiple users could use the same name and description. This is why they're not declared as a unique tuple (or a composite key in the physical data model). In a later version, I might consider bringing in the User attribute to fulfill the identity contracts in the domain model and in the data model, but that would be after I understand all the implications.
      The application can survive with this equals and hashcode implementations for now, since the collections created by either the app or by the ORM do not reference domain objects across users.
      As for the repository implementations, these would undergo further refining (during conversion of the app to a complete DDD example). I'll extract interfaces out, to abstract out the repository contracts, that would be a part of the domain model itself. The JPA implementations would then exist in a different package (not necessarily in the app/service layer) that could be used by the presentation tier for fast-lane access.

      Thanks,
      Vineet

      Delete