6.11. Remote Versus Local EJB Calls
Since we're creating a buyCar( ) method, it could be called from any number of clients. We happen to be writing a web application, but the same transaction could conceivably be called from a Swing Application or even a web service.
This method is highly cohesiveit does only one thingbuy a car from our inventory. It is also loosely coupled to the other tiersthere is nothing that returns HTML that would tie it to the web tier, and since it calls a DAO, nothing ties it to a specific database or persistence strategy.
We now need to decide how the other tiers are going to make this buyCar( ) method call. The Servlet container is co-located on the same server in the same JVM as the EJB container, so we can use the Session Bean's Local interfaces. All objects are in the same memory space, so under the covers, JBoss will pass things around by reference (technically, the memory location of the objects).
As our application grows, we might decide to split out this functionality to physically separate servers. We might move our web tier outside the firewall, move the Persistence tier (or at least the database server) to a box of its own, and leave the EJBs on a third box in the middle. Once we've made this step, we can grow each tier to a cluster of serversa cluster of Tomcat servers, DB servers, and JBoss servers.
Once we move to separate boxes, we need to start making Remote calls to our EJB instead of local calls. Since our Servlets and EJBs are no longer in the same JVM and memory space, the container can no longer make calls by reference. It now has to make calls by valuethis is done by serializing the object, streaming it over the network from one box to the other and reconstituting it on the other side.
Another reason why you might create remote interfaces is if you are writing a Swing client. Since your application is truly distributed, your Swing client will need a way to make method calls on the remote server.
We'll create both local and remote interfaces so you can see what they look like. But remember YAGNIif you don't have any immediate plans to run on separate boxes, don't do it. We'll just use local calls in our Servlets for this example.
Before we develop a Stateless Session Bean, let's explore the new directory structure we'll use for our EJB development environment
6.11.1. Exploring the New Directory Structure
In previous chapters, we had the following sub-directories:
If you change to the ch06/ch06-a directory, you'll see that we've added an ejb sub-directorythis is our EJB development environment. The goal is to keep each portion of the application as autonomous as possible. Granted, most of the application will have dependencies on the common sub-project, but by providing individual Ant scripts we have the opportunity to build each portion of the project separately.
220.127.116.11. The ejb sub-project
Take a moment to explore the ejb sub-project. It has a single classInventoryFacadeBean. Notice that we've created a new package structure to store all of our EJBscom.jbossatwork.ejb.
The Ant build script in the ejb sub-directory generates EJB-specific programming artifacts, compiles the InventoryFacadeBean class, and bundles up everything into an EJB JAR (see the EJB JAR file section for details). Change to the ch06-a root directory and build the project by typing ant. Then, change to the ejb/build/distibution directory and type jar tvf ejb.jar to verify that the Inventory FacadeBean class is indeed stored in ejb.jar.
The main build.xml script in the ch06/ch06-a directory now invokes the ejb sub-directory's build.xml script to build the EJB JAR. Afterwards, the main build adds the EJB JAR file to the EAR. We also changed the webapp's build.xml script to include the EJB JAR in its classpath. Notice that the definition of my.ejb.jar.dir uses a relative path to step up one level from the basedir of the ejb sub-project and down into the ejb sub-project's build/distribution directory.
Now that we've shown the EJB development environment, let's start the EJB development process by showing the Local and Remote Interfaces for the InventoryFacadeBean.