This document takes you through the basics of developing an enterprise application using EJB 3.0 technology which is part of the Java EE 5 platform. This document shows how the EJB 3.0 technology can simplify the process of developing enterprise applications. This document uses the NetBeans IDE 6.0 Release.
Expected duration: 30 minutes
This document assumes you have some basic knowledge of, or programming experience with, the following technologies:
For this tutorial you need to have the following software installed on your computer:
For this tutorial you need to register a local instance of GlassFish/Sun Java System Application Server with the IDE.
The goal of this exercise is to create the NewsApp enterprise application project containing an EJB module and a web module. The NewsApp application uses a message-driven bean to receive and process messages sent to the queue by a servlet. The application uses servlets to send messages to the message-driven bean and to display messages.
In this exercise we created a Java EE 5 enterprise application containing an EJB module and a web module.
In this exercise we will create the objects in the EJB module. We will create an entity class, a message-driven bean and a session facade. We also will create a persistence unit to provide the container with information for managing our entities, and the Java Message Service (JMS) resources that our message-driven bean will use.
First we create a persistence unit that defines the data source and entity manager used in our application.
When you click Finish, the IDE creates persistence.xml and opens it in the Source Editor in Design view. Close persistence.xml.
In this exercise we will create the NewsEntity entity class. An entity class is a simple Java class. When you create the entity class, the IDE adds the @Entity annotation to define the class as an entity class. After we create the class, we will create fields in the class to represent the data that we want in our table.
Each entity class must have a primary key. When you create the entity class, the IDE adds the @Id annotation to declare which field to use as the primary key. The IDE also adds the @GeneratedValue annotation and specifies the key generation strategy for the primary Id.
To create the NewsEntity class, do the following:
When you click Finish, the entity class NewsEntity.java opens in the Source Editor. In the Source Editor, do the following:
private String title; private String body;
In the next step we will create the NewMessage message-driven bean.
Now we will create the NewMessage message-driven bean in our EJB module. We will use the New Message-Driven Bean wizard to create the bean and the necessary JMS resources.
To create the NewMessage message-driven bean, do the following:
When you click Finish, the new message-driven bean class NewMessage.java opens in the Source Editor. You can see that the @MessageDriven annotation and configuration properties are added to the class.
@MessageDriven(mappedName = "jms/NewMessage", activationConfig = { @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"), @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue") })
This annotation tells the container that the component is a message-driven bean and the JMS resource used by the bean. When the IDE generates the class, the Mapped Name of the resource (jms/NewMessage) is derived from the name of the class (NewMessage.java). The JMS resource is mapped to the JNDI name of the destination from which the bean receives messages. The New Message-Driven Bean wizard has already add the information for the JMS resources to sun-resources.xml. The EJB 3.0 API enables us to look up objects in the JNDI namespace from within the bean class so that we do not need to configure deployment descriptors to specify the JMS resources.
The EJB 3.0 specifications allow us to use annotations to introduce resources directly into a class. We will now use annotations to introduce the MessageDrivenContext resource into our class, and then inject the PersistenceContext resource which will be used by the EntityManager API to manage the persistent entity instances. We will add the annotations to the class in the Source Editor.
public class NewMessage implements MessageListener { @Resource private MessageDrivenContext mdc;
@PersistenceContext private EntityManager em;and generates the following method in your code:
public void persist(Object object) { em.persist(object); }
public void save(Object object) { em.persist(object); }
ObjectMessage msg = null; try { if (message instanceof ObjectMessage) { msg = (ObjectMessage) message; NewsEntity e = (NewsEntity) msg.getObject(); save(e); } } catch (JMSException e) { e.printStackTrace(); mdc.setRollbackOnly(); } catch (Throwable te) { te.printStackTrace(); }
Next we create a session facade for the NewsEntity entity class. To create the session facade, do the following:
When you click Finish, the session facade class NewsEntityFacade.java is created and opens in the Source Editor. The IDE also creates the local interface NewsEntityFacadeLocal.java.
EJB 3.0 technology simplifies the creation of session beans by reducing the amount of required code. You can see that the annotation @Stateless is used to declare the class as a stateless session bean component and that the class no longer needs a statement implementing javax.ejb.SessionBean. The code is also much cleaner because with EJB 3.0 technology the business methods no longer need to have code declaring they throw checked exceptions.
You can see that the PersistenceContext resource was injected directly into the session bean component when we created the session facade.
In this exercise, we coded an entity class and a message-driven bean in the EJB module. We then created a session facade for the entity class. We also created the JMS resources that will be used by our application.
We will now create the servlets ListNews and PostMessage in our web module. These servlets will be used to read and add messages.
In this exercise we will create a simple servlet for displaying our data. We will use annotations to call our entity bean from our servlet.
When you click Finish, the class ListNews.java opens in the Source Editor. In the Source Editor, do the following:
out.println("<h1>Servlet ListNews at " + request.getContextPath () + "</h1>"); List news = newsEntityFacade.findAll(); for (Iterator it = news.iterator(); it.hasNext();) { NewsEntity elem = (NewsEntity) it.next(); out.println(" <b>"+elem.getTitle()+" </b><br />"); out.println(elem.getBody()+"<br /> "); } out.println("<a href='PostMessage'>Add new message</a>"); out.println("</body>");
In this exercise we will create the PostMessage servlet that will be used to post messages. We will use annotations to inject the JMS resources we created directly into the servlet, specifying the variable name and the name to which it is mapped. We will then add the code to send the JMS message and the code for the HTML form for adding a message.
When you click Finish, the class PostMessage.java opens in the Source Editor. In the Source Editor, do the following:
public class PostMessage extends HttpServlet { @Resource(mappedName="jms/NewMessageFactory") private ConnectionFactory connectionFactory; @Resource(mappedName="jms/NewMessage") private Queue queue;
response.setContentType("text/html;charset=UTF-8"); // Add the following code to send the JMS message String title=request.getParameter("title"); String body=request.getParameter("body"); if ((title!=null) && (body!=null)) { try { Connection connection = connectionFactory.createConnection(); Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer messageProducer = session.createProducer(queue); ObjectMessage message = session.createObjectMessage(); // here we create NewsEntity, that will be sent in JMS message NewsEntity e = new NewsEntity(); e.setTitle(title); e.setBody(body); message.setObject(e); messageProducer.send(message); messageProducer.close(); connection.close(); response.sendRedirect("ListNews"); } catch (JMSException ex) { ex.printStackTrace(); } } PrintWriter out = response.getWriter();
out.println("Servlet PostMessage at " + request.getContextPath() + "</h1>"); // Add the following code to add the form to the web page out.println("<form>"); out.println("Title: <input type='text' name='title'><br/>"); out.println("Message: <textarea name='body'></textarea><br/>"); out.println("<input type='submit'><br/>"); out.println("</form>"); out.println("</body>");
We can now run our project. When we run the project, we want our browser to open to the page with the ListNews servlet. We do this by specifying the URL in the Properties dialog box for our Enterprise Application. The URL is relative to the context path for our application. After we enter the relative URL, we can build, deploy and run our application from the Projects window.
To set the relative URL and run our application, do the following:
When you run the project, the ListNews servlet opens in your browser and displays a list of the messages in the database. When you first run the project, the database is empty, but you can click Add Message to add a message.
When you add a message with the PostMessage servlet, the message is sent to the message-driven bean for writing to persistent storage, and the ListNews servlet is called to display the messages in the database. The list of messages in the database retrieved by ListNews often does not yet contain the new message because our message service is asynchronous.
The following are some of the problems you may encounter when creating your project.
When using the wizard to create JMS resources, you may see the following server error message in the output window:
[com.sun.enterprise.connectors.ConnectorRuntimeException: JMS resource not created : jms/Queue]
This message could indicate that the JMS resource was not created or was not registered with the application server. You can use the Admin Console of the Sun Java System Application Server to check, create and edit JMS resources.
To open the Admin Console, do the following:
You need to make sure that the JMS connection factory resource in the PostMessage servlet is mapped to the correct JNDI name of the JMS connection factory resource registered with the Sun Java System Application Server.
The following resources should be registered with the Sun Java System Application Server:
For more information about using NetBeans IDE 5.5 to develop Java EE applications, see the following resources:
You can find more information about using EJB 3.0 Enterprise Beans in the Java EE 5 Tutorial.