Introduction to Java Enterprise Edition 6

Java Enterprise Edition (EE) started out as a way to replace Common Gateway Interface
(CGI) using the Servlet API in the late 90′s. The Servlet technologies promised developers a much easier and standardized way to create dynamic content on web sites. The problem was that Servlets were server code and didn’t offer a clean way to build the user interface. Sun then released Java Server Pages (JSP) which made it a little easier to separate the view from server code and provided an answer to Microsoft’s Active Server Pages (ASP) technology.

Java became the technology to use on the server side in the late 90′s which made companies like IBM and Oracle take notice. These companies worked with Sun to make Java more enterprise ready with features like ACID transactions, messaging and security. Java EE officially became a specification using Servlets and JSP as the first APIs. The specification grew quickly and became more complex attempting to encompass years of enterprise computing knowledge. Expensive application servers were created to run the applications, but creating these applications became cumbersome and the cost of entry to create an enterprise application exploded. Lighter weight technologies like the Spring framework were created to make development easier and cheaper. Java EE became a dirty word in most development circles and seemingly disappeared from most developers radars.

The latest Java EE specification (6) now makes application development a breeze.
Technologies like Enterprise Java Beans (EJB) version 3.1, Java Persistence (JPA) version 2.0, Java API for XML-Based Web Services (JAX-WS) version 2.2 and Contexts and Dependency Injection for Java (CDI) version 1.0 now make Java EE the easiest, most powerful version to date. Using these technologies, developers can easily begin building powerful enterprise applications. The addition of free application containers like GlassFish and JBoss remove the cost barrier that made startup prohibitive.

The Enterprise Java Beans (EJB) 3.1 specification has been updated to allow annotation
based bean identification reducing the amount XML that has to be written. Annotations are used to identify a bean, inject the bean and provide a JNDI name. Example 1 shows a class that has been annotated as a Stateless session bean and has another bean injected. Notice the mappedName attribute that provides the JNDI name. AOP style programming is also supported using the @Interceptors annotation (XML configuration also available) allowing developers the ability to wrap code around classes or method calls. The major draw back of EJB 3.1 dependency injection continues to be lack of POJO support forcing the developer to make all classes EJB beans.

Example 1

@Stateless(mappedName = "beans/component/MySessionBean")
@Local
@Remote
public class MySessionBean
{
   @EJB(mappedName = "beans/component/MyOtherSessionBean")
   private MyOtherSessionBean myOtherSessionBean;
   //Methods added here....
}

The Contexts and Dependency Injection for Java (CDI) specification is the missing link
for Java EE to help tie EJBs and POJOs together. Session beans are powerful in that they can be monitored and managed through the container, but not every object requires this overhead. Utility classes such as validation and logging do not make sense as beans but are still an important part of the application. Using the CDI API, these objects can be injected using the @Inject annotation. Example 2 provides an example of a factory that provides the logger object and a bean that consumes it.

Example 2

@Singleton
public class LoggingFactory
{
   @Produces
   @Named(value = "Logger")
   public Logger getLogger(InjectionPoint point)
   {
      String beanName = point.getBean().getBeanClass().getName();
      Logger.getLogger(beanName);
   }
}

@Stateless
public class MyLoggingBean
{
   @Inject
   @Named(value = "Logger")
   private Logger logger;
}

JPA 2.0 is a nice ORM layer and an alternative to the Entity bean in the EJB specification. JPA can work solely using annotations, XML files or a mixture of both. Example 3 shows a simple annotated entity with an id field that is generated using a sequence. Note the @NamedQuery annotation that provides a query allowing the EntityManager to search against the poName field. The query does not select fields to pull from the database table like standard SQL, but instead performs a selection on the object. Also note that the where clause references an object property instead of a table column.

Example 3

@Entity
@Table(name=”my_table”)
@NamedQuery(name="PersistentObject.findByName", query="SELECT persistentObject
            FROM PersistentObject persistentObject WHERE persistentObject.poName = :name")
public class PersistentObject
{
   @Id
   @Column(name="PO_ID")
   @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "PO_SEQ")
   @SequenceGenerator(name = "PO_SEQ", sequenceName = "po_seq", allocationSize = 1)
   private Integer poId;

   @Column(name="PO_NAME")
   private String poName;

   public Integer getPoId() { return poId; }
   public void setPoId(Integer id) { this.poId = id; }
   public String getPoName() { return poName; }
   public void setPoName(String name) { this.poName = name; }
}

Example 4 shows a Session bean with an injected EntityManager, a method that uses the
id field and EntityManager to find that entity and a method that changes the name. The example assumes that the calls are being made in a transactional system. Queries that are not based on the primary key can be stored in the entity using the @NamedQuery annotation or put into an external XML file.

Example 4

@Stateless(mappedName = "beans/component/MyPersistentService")
public class MyPersistentService
{
   @PersistenceContext(unitName = "my-db")
   private EntityManager em;
   public PersistentObject getPO(Integer id)
   {
      return em.find(PersistentObject .class, id);
   }
   public void changePOName(String name, Integer id)
   {
      PersistentObject po = em.find(PersistentObject .class, id);
      po.setPoName(name);
   }
}

The JAX-WS 2.2 specification provides annotation based web service visibility into java
applications. Instead of hand crafting the WSDL and XSD files, a developer can simply create a class and add annotations which will automatically create the contract. JAX-WS allows the developer to begin with a few annotations and then add more annotations to gain greater control over the generated WSDL and XSD contracts. Example 5 shows a simple stateless session bean that has been annotated as a web service. A single method exists with annotations to indicate that the method should be exposed in the WSDL as well as annotations to indicate the name of the return value and parameter.

Example 5

@WebService(name = "MyWebService", serviceName = "MyWebService", targetNamespace = "mine",
            portName = "MyWebService WS", endpointInterface = "com.mine.MyWebServiceBeanEndpoint")
@Stateless(mappedName = "ws/mine/MyWebService")
public class MyWebServiceBean implements MyWebServiceBeanEndpoint
{
   @EJB(mappedName = "beans/component/MyPersistentService")
   private MyPersistentService myPersistentService;

   @WebMethod
   @WebResult(name = "po")
   public PersistentObject getPO(@WebParam(name = "id") Integer id)
   {
      myPersistentService.getPO(id);
   }
}

Java EE has grown into a robust set of technologies that allow developers to quickly and
easily build enterprise applications, but to run the applications a developer still needs an
application container. The GlassFish server version 3.1.x is an open source Java EE version 6 container that provides advanced management features and has zero start up costs. GlassFish features a command line utility (asadmin) for managing the server and applications as well as a web console that provides a visual user interface. GlassFish is also the Java EE 6 reference implementation.

Java EE has come a long way since it was first introduced. Pressure from open source
frameworks have forced continual improvements in each specification that allow developers easier ways to provide enterprise applications at a more rapid pace, lower cost and with better results. A developer now has the option of starting a new application using just the basic features of Java EE and the embedded container then as the application grows larger, move to a server based container like GlassFish, JBoss, WebLogic or WebSphere. Java EE may have lost a step in the developers conscious, but with the latest specification it is ready to be placed back at the top of the list of frameworks being evaluated for new projects.

Written by David F.

About these ads
This entry was posted in Software and tagged , , , . Bookmark the permalink.

3 Responses to Introduction to Java Enterprise Edition 6

  1. henk says:

    Nice writeup really.

    One remark though, in the first example the @Local and @Remote annotations are completely useless. They are normally intended to designate an interface as being either local or remote (with the first one only needed if the bean implements more than 2 local interfaces), OR to point to such interfaces from the bean.

    Since neither happens here, they can be removed.

    In the same example, the mappedName is not necessary. mappedName is a vendor specific attribute (no use of mappedName is ever portable). It’s also not needed to create an entry in JNDI, since such an entry is always created automatically (with a portable naming scheme). A simple @Stateless without any attribute is enough here.

    The same goes for injection of the EJBs. If there’s only one implementation of a type, there’s no need to use any additional name or qualifier. Just use plain @EJB ;)

    • dafreels says:

      Thank you for your comment. These are very valid points. I wanted to keep the examples simple without creating the interfaces in a summary. The inclusion of the @Local and @Remote were purely there to show how much easier it is to create the local and remote interfaces in the newer versions of the specification. The older EJB specifications required a lot of boiler plate code that has now been eliminated. A deeper look into the EJB annotations is definitely warranted for anyone wishing to go forward.

      The “mappedName” attribute is not required and as of EJB 3.1 has been replaced with the attribute “lookup”. Also, the attribute is really only applicable to remote interface look up and should not be used for local beans. The “name” attribute should be used instead if you are trying to give a more predictable JNDI look up name.

      A follow up article will dive a little deeper into the EJB specification and I will explore more deeply the annotations and the individual attributes.

      • rokko says:

        >The inclusion of the @Local and @Remote were purely there to show how much easier it is to create the local and remote interfaces in the newer versions of the specification.

        They are indeed much easier, but in your example you should place them either on an actual interface, or use their class attribute. In the current situation they don’t do anything ;)

        >The “name” attribute should be used instead if you are trying to give a more predictable JNDI look up name.

        This is still a bit confusing perhaps, but “name” gives the bean a name in a different namespace than JNDI. It’s for referencing a bean via an easy name in the deployment descriptors, which you want to do if you need to override some thing in XML.

        By default this name is perfectly predictable though, as it’s specified to be the unqualified class name (see http://docs.oracle.com/javaee/6/api/javax/ejb/Stateless.html#name%28%29)

        You also don’t have to use any such name to make JNDI names more predictable, since they are already perfectly predictable. There’s a standard naming scheme (see eg http://en.wikipedia.org/wiki/Enterprise_JavaBean#Naming_and_directory_services).

        In older versions of EJB this wasn’t the case, and JNDI names were vendor specific. But in the current version it’s completely standardized.

        Just remove those “mappedName” attributes completely and re-test your code. It will still work ;)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s