• No results found

Creating an EJB

In document NetBeans IDE 8 Cookbook (Page 178-186)

Enterprise Java Beans (EJBs) are server-side managed classes intended to provide business functionality to applications. Since Java EE 5, EJBs have been made much simpler and more lightweight.

EJBs no longer have to be defined by XML descriptors, but are defined using Java annotations instead. This allows EJBs to be developed more quickly and probably more importantly, to be fully testable outside of the application server.

In Java EE 7, there are four types of EJB. They are Stateless, Stateful, Singleton, and Message Driven EJBs. J2EE also had Entity beans used for modeling data, but these have been deprecated since Java EE 5 to be replaced with POJOs and JPA.

Stateless EJBs, as their name suggest, maintain no state. When a request is made from a client to obtain an EJB, the application server returns one from a pool of EJBs. The client may or may not get the same EJB on subsequent requests.

A Stateful EJB on the other hand, maintains its state, so every time a request is made for an EJB of a particular type, the same EJB is supplied to the client. Stateful EJBs are therefore useful when a client needs to remember information between invocations. The classic example of using Stateful EJBs is to implement a shopping cart. In a web application, the HTTP protocol maintains no state so Stateful EJBs can be used to maintain information

A Singleton EJB has global state shared across the entire JVM. The application server guarantees that there is only one instance of a Singleton bean within the JVM and can provide a thread safe access to its data.

Message Driven Beans are built on top of the Java Message Service (JMS) API and listen for events to occur before being triggered. They are typically used for processing long-running asynchronous events or for sending data to multiple clients where each client can be listening to a JMS queue or topic.

For more information on Java EE 7 EJBs, check out the Oracle Java EE 7 Enterprise Beans Tutorial at http://docs.oracle.com/javaee/7/tutorial/doc/ejb-intro.htm. In this recipe, we're going to show how to create Stateless and Stateful EJBs and show how to invoke them. In the next recipe, Creating a Message Driven EJB, we'll see how to create Message Driven EJBs.

Getting ready

For this recipe, we will use the WildFly application server together with the Enterprise download bundle of NetBeans. Ensure that you have a working installation of WildFly configured within NetBeans before starting this recipe. If you need to configure WildFly within NetBeans, check out the Adding WildFly support to NetBeans recipe earlier in this chapter.

How to do it…

To deploy EJBs to the application server, we need to create a NetBeans project that will host the EJBs. EJBs can be deployed either within an Enterprise Archive (EAR) file, or within a Web application Archive (WAR) file. For this recipe, we'll be deploying our EJBs in a .war file together with a Servlet, which will act as the client by invoking the EJB.

For a lot of application types, the .war archive is a good choice for deployment as any included EJBs are co-located with web resources such as Servlets or JSF pages. For more flexibility, EJBs can be separated from the web application code and deployed as a Java archive within an .ear file. The .ear files can contain multiple standard Java archives as well as multiple .war files. This therefore enables greater flexibility for deployment, but comes at the cost of greater complexity.

Perform the following steps:

1. Click on File and then New Project…

2. Select Java Web from the list of Categories and Web Application from the list of Projects.

3. Click on Next.

4. Enter Project Name as EJBQuote. 5. Click on Next.

6. Ensure Add to Enterprise Application is unselected, Server is set to WildFly Application Server, Java EE Version is set to Java EE 7 Web, and Context Path is set to /EJBQuote.

7. Click on Finish.

We've now created an empty web project. Let's add an EJB to the project that will provide us with random quotes. Perform the following steps:

1. Right-click on the Source Packages node for the EJBQuote project within the Projects explorer and click on New, and then click on Other….

2. In the New File dialog, select Enterprise JavaBeans from the list of Categories and Session Bean from the list of File Types.

3. Click on Next.

4. Enter EJB Name as QuoteBean.

5. Enter the Package name as com.davidsalter.cookbook.quote. 6. Select Session Type as Singleton.

7. Check the Local tick-box as shown in the following screenshot:

The New Session Bean dialog will now close and NetBeans will create a new Singleton Session Bean along with a local interface for the bean.

We now need to add business logic to our bean to return a quote to callers. Perform the following steps:

1. Ensure that the QuoteBean.java file is open for editing and right-click within the body of the class and select Insert Code….

2. On the Generate pop-up window, click on Add Business Method….

3. The Add Business Method dialog will now open, where we can define method signatures for business methods within EJBs.

4. Enter Name as getQuote and Return Type as java.lang.String. 5. Since we're using a local interface to implement our EJB, ensure that the

Use in Interface option is set to Local as shown in the following screenshot:

6. Click on OK.

The getQuote business method is now created within the QuoteBean.java class.

Let's now implement the method. Perform the following steps:

1. Ensure that the QuoteBean.java file is open for editing.

2. Our QuoteBean class is going to maintain a list of quotes and return a random one to callers. We therefore need to initialize the list of quotes within the bean. Add the

@Startup annotation to the class definition so that the EJB will be started up as soon as it is deployed. The class definition should now look like:

@Startup

@Singleton

public class QuoteBean implements QuoteBeanLocal { 3. We now need to add a private member to the class to maintain a list of

quotes, and initialize it after the bean is constructed. Add the following code into the QuoteBean.java class:

private List<String> quotes;

@PostConstruct void initialize() {

quotes = new ArrayList<String>();

quotes.add("Always catch exceptions.");

quotes.add("Did you make that field final?");

quotes.add("Remember to implement a toString() method.");

}

4. Finally, we need to implement the getQuote() method that returns a random quote to the caller. Change the getQuote() method to read:

@Override

public String getQuote() { Random rand = new Random();

return quotes.get(rand.nextInt(quotes.size()));

}

5. Add the required imports to the class so that the entire class reads as follows:

@Startup

@Singleton

public class QuoteBean implements QuoteBeanLocal { private List<String> quotes;

@PostConstruct void initialize() {

quotes = new ArrayList<String>();

quotes.add("Always catch exceptions.");

quotes.add("Did you make that field final?");

quotes.add("Remember to implement a toString() method.");

}

@Override

public String getQuote() { Random rand = new Random();

return quotes.get(rand.nextInt(quotes.size()));

} }

Now that we've created an EJB, let's create a servlet that can invoke the EJB and return random quotes to us. Perform the following steps:

1. Right-click on the EJBQuote node within the Projects explorer and select New and then Other….

2. In the New File dialog, select Web from the Categories list and Servlet from the list of File Types.

3. Click on Next.

4. Enter Class Name as QuoteServlet and Package as com.davidsalter.

cookbook.quote. 5. Click on Next.

6. Ensure that Add information to deployment descriptor (web.xml) is checked and click on Finish.

7. The servlet class will now be created and opened for editing. Add a reference to the EJB's local interface at the top of the class:

@EJB

private QuoteBeanLocal quoteBean;

8. Locate the line within the class that begins with out.println("<h1>Servlet QuoteServlet… and replace it with:

out.println(quoteBean.getQuote());

9. Fix any imports with the class so that the javax.ejb.EJB package is included.

We've now completed the application, so deploy and run the application by right clicking on the QuoteServlet.java file in the Source Packages node of the Projects explorer and selecting the Run option. NetBeans will ask for confirmation of any query parameters.

Since there are none, click on OK to launch your default browser and run the servlet.

Refresh your browser a few times to get some good advice.

How it works…

In this recipe, we first created an EJB that implemented a local interface. We don't have to implement interfaces to define EJBs, but its good practice to do so.

To define a Singleton EJB, we annotated a POJO class with the @Singleton annotation. We also added the @Startup annotation to cause the EJB to start as soon as it was deployed.

Since we're using a local interface for the bean, the bean class must implement the local interface. The basic definition of our Singleton bean was therefore:

@Startup

@Singleton

public class QuoteBean implements QuoteBeanLocal {

In EJB 3, a local interface is just a plain old interface, but it must be annotated with the

@Local annotation. This is what differentiates a local interface from a remote interface (which is annotated with @Remote):

@Local

public interface QuoteBeanLocal {

To add business logic to the EJB, we used the insert code option within the NetBeans editor window. When adding business logic to an EJB, this wizard creates both the new method that we are creating and its interface definition. That is to say, both the interface and the EJB class are updated. Even though we're using interfaces, we don't need to edit two files as this is all taken care of for us by NetBeans.

To allow us to perform some initialization on the EJB, we annotated a method with the

@PostConstruct annotation. This method is called after the EJB is injected into clients, so is used as a place to perform initialization.

Since we created an EJB with only a local interface, it's only possible to access it from within the local JVM, hence making a call to it from within a servlet that is also running inside the same JVM. If we'd created the EJB to implement a @Remote interface, then we would have been able to access the EJB from outside of the application server, from a standalone client, or from a different application server.

In the servlet, we referenced the local interface for the EJB using the @EJB annotation.

This injects the EJB into the servlet class and allows us to use it without having to create a new instance of the class when we want to use it.

When we created the servlet, we allowed NetBeans to add information to the deployment descriptor file so that we could see the type of information added to this file. This is old-school servlet creation as the servlet is registered with the application server via XML instead of via annotations:

In the next recipe, Creating a Message Driven EJB, we'll see how to define a servlet using annotations instead of XML.

There's more

In this recipe, we saw how to create a Singleton session bean. What if we wanted to create a Stateful session bean, or a Stateless session bean? Well, the procedure for creating those is exactly the same as that outlined within this recipe except that on the New Session Bean dialog, we need to choose either Stateless or Stateful instead of Singleton.

What EJBs are deployed?

After EJBs are deployed to WildFly, we can get a list of what has been deployed via the Servers node within the Services explorer.

This view lists all of the EJB modules that are deployed and all of the EJBs that are deployed within each module.

In document NetBeans IDE 8 Cookbook (Page 178-186)