23.2. Lend Me Your EAR: Enterprise Packaging and Deployment
There are lots of pieces that are needed to make Enterprise JavaBeans (EJBs) worknot only the classes and interfaces that we have defined, but supporting classes and other Web application pieces (e.g., JSP files) as well. They all have to be in the right place. The distributed nature of EJBs means that we need a way to distribute them across (
Let's take a look inside an EAR and examine its pieces. Knowing what it's made of will make an EAR look less intimidating, but will also help us understand what we'll need for our application.
Tip
An EAR file (whose
The budgetpro.ear file will be our example. We haven't yet discussed building this file, but let's peek ahead, to see how it will be put together (Example 23.1). Notice that, at the top level, there are two files and a directory, and inside the directory there are two other files (Table 23.1). Table 23.1. Files inside an EAR archive
From the standpoint of building an EAR yourself, you need to create all the files listed in Table 23.1 and then put them all together into a JAR file. So we need to understand those pieces. Example 23.1. Contents of a sample EAR file
$ jar -tvf budgetpro.ear
0 Wed May 19 05:58:02 CDT 2004 META-INF/
110 Wed May 19 05:58:00 CDT 2004 META-INF/MANIFEST.MF
295 Wed May 19 05:58:00 CDT 2004 META-INF/application.xml
11498 Wed May 19 05:58:02 CDT 2004 budgetpro.jar
12626 Wed May 19 05:58:02 CDT 2004 budgetpro.war
$
The plain files that appear in the META-INF directory are simple. The MANIFEST.MF file is like any JAR manifest and can contain simply the JAR version number: Manifest-Version: 1.0 The application.xml file is shown in Example 23.2
Two JAR files are mentioned in this XML description file. This
Example 23.2. Sample application.xml file
<?xml version="1.0" encoding="ISO-8859-1"?>
<application>
<display-name>BudgetPro</display-name>
<module>
<web>
<web-uri>budgetpro.war</web-uri>
<context-root>/budgetpro</context-root>
</web>
</module>
<module>
<ejb>budgetpro.jar</ejb>
</module>
</application>
That takes care of the two plain files. Let's also look inside the other two archives, the JAR file and the WAR file, and see what they hold. 23.2.1. What's in an EJB-JAR FileLet's look first at the content of the JAR file. After that we'll look at the specifics of the XML descriptor files. $ jar xf budgetpro.ear # unjar the EAR $ ls # see what we got META-INF budgetpro.ear budgetpro.jar budgetpro.war $ jar tf *.jar # list the JAR contents META-INF/ META-INF/MANIFEST.MF com/ com/jadol/ com/jadol/budgetpro/ net/ net/multitool/ net/multitool/util/ com/jadol/budgetpro/MoneyLocal.class com/jadol/budgetpro/SessionTestServlet.class com/jadol/budgetpro/MoneyEJBean.class com/jadol/budgetpro/MoneyHome.class com/jadol/budgetpro/Money.class com/jadol/budgetpro/MoneyLocalHome.class com/jadol/budgetpro/TestMoneyEJBean.class net/multitool/util/Save.class net/multitool/util/Cost.class net/multitool/util/Debt.class net/multitool/util/SAMoney.class META-INF/ejb-jar.xml META-INF/jboss.xml $ The EJB-JAR file contains the specifics for our EJB file (Table 23.2). Table 23.2. Contents of the EJB-JAR file
To keep Table 23.2 simpler and shorter, we didn't list each of the directories in the tree of directories down to each class file. When we show, for example,com/jadol/budgetpro/* , realize that each directory that is part of that structure ( com , com/jadol , and so on) is part of the JAR file. The class files are located in that tree. So what are the two XML files?
These XML files provide the EJB container with information on how the bean
The
ejb-jar.xml
file (Example 23.3) is part of the J2EE standard. It specifies the
Example 23.3. Sample ejb-jar.xml file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ejb-jar PUBLIC
"-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN"
"http://java.sun.com/dtd/ejb-jar_2_0.dtd">
<ejb-jar>
<description>BudgetPro</description>
<display-name>BudgetPro</display-name>
<enterprise-beans>
<!-- Session Beans -->
<session id="test_Money">
<display-name>Test Money Bean</display-name>
<ejb-name>test/Money</ejb-name>
<home>com.jadol.budgetpro.MoneyHome</home>
<remote>com.jadol.budgetpro.Money</remote>
<ejb-class>com.jadol.budgetpro.MoneyEJBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
</session>
</enterprise-beans>
<assembly-descriptor>
</assembly-descriptor>
</ejb-jar>
The name of the bean defined in the ejb-jar.xml file is not, however, the name we will use in our JNDI lookup. Rather, there is one more level of mapping used by JBoss. Look at the contents of the jboss.xml file (Example 23.4). Example 23.4. Sample jboss.xml file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jboss PUBLIC "-//JBoss//DTD JBOSS//EN"
"http://www.jboss.org/j2ee/dtd/jboss.dtd">
<jboss>
<enterprise-beans>
<session>
<ejb-name>test/Money</ejb-name>
<jndi-name>ejb/Money</jndi-name>
</session>
</enterprise-beans>
<resource-managers>
</resource-managers>
</jboss>
The two tags define the mapping: You use the jndi-name in the lookup() method and it will (try to) find the EJB named with the ejb-name tag. The ejb-name tag is also used in the ejb-jar.xml file. This provides the association between the two, and the mapping from the JNDI name to EJB is thereby defined. To summarize, if we want to build an EJB-JAR file, we will need to gather all the class files in their appropriate classpath directory structures. Then we will need to write two XML files and place them in the META-INF directory along with the MANIFEST.MF file. The two XML files will define the EJB pieces and provide a name mapping for locating this bean. Then put all these pieces together into a JAR file, and you have an EJB-JAR file. 23.2.2. Using Our BeanWe have put a lot of pieces in place to get a bean that we can call from across the enterprise. But what does that call look like? How might we make use of the bean? The first step is to make contact with the JNDI service and locate the home interface for the bean. It looks like the section of code in Example 23.5. Example 23.5. Locating the home interface
//Look up home interface
InitialContext initctxt = new InitialContext();
Object obj = initctxt.lookup("ejb/Money");
MoneyHome homer = (MoneyHome) PortableRemoteObject.narrow(obj, MoneyHome.class);
We're putting this code in the init() method of a servlet; it could also be in a test program, or in a JSP. It needs to happen only once for our servlet (which is why we put it in the init() method) and then the connection can be used many times, once for each contact with the bean. We get to the actual bean this way: Money mrbean; mrbean = homer.create(); We then use the bean, making the calls on its remote interface (a Money object, that extends EJBObject ) as if it were just a simple method call on an ordinary class: car = mrbean.save(20000.00, 0.04, 250.00); The math is done in the actual SessionBean , out there in the network, and the results are sent back to this application. Our application goes on to display this number as part of an HTML page. Then when we're done with the bean, we need to clean up: mrbean.remove(); 23.2.3. Packaging the ServletWe will now package up the servlet, along with a simple startup page to invoke it. We'll look at the WAR file and see how it's built. 23.2.3.1 What is in the WAR FileThe other JAR-like file in the EAR is the WAR file. Let's see what is in one of those (Table 23.3). Table 23.3. Contents of the WAR file
{% if main.adsdop %}{% include 'adsenceinline.tpl' %}{% endif %} Notice that the WAR file puts its XML descriptor not in the META-INF directory but in a WEB-INF directory along with the classes. 23.2.3.2 Weaving the Web
The
web.xml
file is the descriptor for the Web application part of all this. Using the
servlet
tag, it defines a servlet associating a name with this servlet (a name which can be used elsewhere in this XML file) and
Then the servlet-mapping tag is used to map a URL pattern to a servlet. The URL pattern is the portion of the URL that signals to the server that the request is not for a simple HTML page, but rather for our servlet. Example 23.6 is a sample web.xml; notice in particular how the mapping from URLs to the Java class is accomplished. 23.2.3.3 Connecting the Pieces
So now that you have seen all the pieces, know that you can edit the XML files with your favorite editor, and can build the JAR/WAR/EAR files with the
jar
command, it's not that hard to put it all together. It is, however,
The key to making it work, whether by hand or by automation, is a
Example 23.6. Sample web.xml file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<servlet>
<servlet-name>SessionServlet</servlet-name>
<display-name>Simple Session Servlet</display-name>
<servlet-class>com.jadol.budgetpro.SessionTestServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SessionServlet</servlet-name>
<url-pattern>/servlet/test</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>0</session-timeout>
</session-config>
</web-app>
|