| CONTENTS | PREV | NEXT | INDEX | J2EE BluePrints |
A deployment descriptor is an XML-based text file whose elements describe how to assemble and deploy the unit into a specific environment. Each element consists of a tag and a value expressed in the following syntax: <tag>value</tag>. Usually deployment descriptors are automatically generated by deployment tools, so you will not have to manage them directly. Deployment descriptor elements contain behavioral information about components not included directly in code. Their purpose is to tell the Deployer how to deploy an application, not tell the server how to manage components at runtime.
There are different types of deployment descriptors: EJB deployment descriptor described in the Enterprise JavaBeans specification, Web deployment descriptor described in the Servlet specification, and application and application client deployment descriptors described in the J2EE specification.
Deployment descriptors specify two kinds of information:
- Structural information describes the different components of the JAR file, their relationship with each other, and their external dependencies. An Application Assembler or Deployer risks breaking the functionality of the component if this information is changed. Environment entries and resource requirements are part of structural information.
- Assembly information describes how contents of a JAR file can be composed into a deployable unit. Assembly information is optional. Assembly information can be changed without breaking the functionality of the contents, although doing so may alter the behavior of the assembled application.
The remainder of this section describes how to specify the most commonly used deployment descriptor elements.
This section describes how to specify commonly used elements in the various deployment descriptors. First we describe elements common to various J2EE component types. Then we describe elements specific to enterprise beans, in particular, the elements related to transactions and persistence. Finally we cover Web component elements. For the definitions of each type of deployment descriptor, see the J2EE, EJB, and servlet specifications.
7.3.1.1 Common Elements
This section describes the deployment descriptor elements common across the different J2EE component types. These include environment entries, references to enterprise beans, references to connection factories, and security-related elements.
Naming environment entries allow customization of a component during deployment or assembly without the need to access or change the component's source code. The container implements the naming environment, and provides it to the component instance through a JNDI naming context.
The Deployer must ensure that the values of all the environment entries declared by a component are set to meaningful values. The Deployer can modify values of environment entries that have been previously set by the Application Component Provider and/or Application Assembler. The Deployer must set the values of those environment entries for which no value has been specified. The description elements provided by the Application Component Provider or Application Assembler help the Deployer with this task.
Naming environment entries are specified with the env-entry element.
Code Example 7.3 uses an environment
entry to determine whether confirmation email is sent when an order is processed.
Code Example 7.4 shows how to set
the value of the environment entry.
public static boolean sendConfirmationMail() {
boolean boolVal = false;
try {
InitialContext ic = new InitialContext();
Boolean bool = (Boolean)
ic.lookup("java:comp/env/sendConfirmationMail");
if (bool != null) {
boolVal = bool.booleanValue();
}
} catch (NamingException ne) {
...
}
return boolVal;
}
| Code Example 7.3 Looking up a Naming Environment Entry |
<env-entry> <env-entry-name>sendConfirmationMail</env-entry-name> <env-entry-type>java.lang.Boolean</env-entry-type> <env-entry-value>false</env-entry-value> </env-entry>
| Code Example 7.4 Environment Entry Element |
There are two parts to the mechanism for establishing connections to enterprise beans in a J2EE application: the Java language interface for accessing a bean and the deployment descriptor declarations for identifying those references. The Application Component Provider looks up the references in the source code of the referring component using the Java interfaces, then identifies these references in the deployment descriptor when packaging the component. A Deployer binds enterprise bean references to the enterprise beans' homes in the target environment. The deployment descriptor also allows an Application Assembler to link an enterprise bean reference declared in one enterprise bean to other enterprise beans contained in the same EJB module, or in other EJB modules in the same J2EE application unit. The link is an instruction to the tools used by the Deployer that the enterprise bean reference must be bound to the home of the specified enterprise bean.
Code Example 7.5 illustrates how
a component obtains a reference to the home interface of another enterprise
bean. In the example, the Application Component Provider of the ShoppingClientControllerEJB
assigned the environment entry cart as the name to refer to the
home of another enterprise bean, ShoppingCartHome. ShoppingClientControllerEJB
calls a utility method getShoppingCartHome, which performs a JNDI lookup of
cart in the ejb subcontext of the environment naming
context java:comp/env. ShoppingClientControllerEJB caches the reference
to the home interface in the cart variable so that the lookup need
only be performed once.
public class ShoppingClientControllerEJB implements SessionBean {
public ShoppingCart getShoppingCart() {
if (cart == null) {
try {
ShoppingCartHome cartHome =
EJBUtil.getShoppingCartHome();
cart = cartHome.create();
} catch (CreateException ce) {
...
}
}
return cart;
}
}
public static ShoppingCartHome getShoppingCartHome() {
try {
InitialContext initial = new InitialContext();
Object objref = initial.lookup("java:comp/env/ejb/cart");
return (ShoppingCartHome) PortableRemoteObject.
narrow(objref, ShoppingCartHome.class);
} catch (NamingException ne) {
throw new GeneralFailureException(ne);
}
}
| Code Example 7.5 Locating a Home Interface |
An Application Component Provider must use the ejb-ref element of the deployment descriptor to declare all enterprise bean references. Similarly, the deployment descriptor for a Web component must contain ejb-ref elements for the enterprise beans that it uses. Such declarations allow the EJB module consumer (that is, Application Assembler or Deployer) to discover all the enterprise beans used by the components.
Code Example 7.6 illustrates the
declaration of an enterprise bean reference to ShoppingCart in
the deployment descriptor for ShoppingClientController. Note the
ejb-ref-name element, which contains string ejb/cart
used in the JNDI lookup performed in Code
Example 7.5.
<session> <display-name>TheShoppingClientController</display-name> <ejb-name>TheShoppingClientController</ejb-name> <home>com.sun.estore.control.ejb. ShoppingClientControllerHome</home> <remote>com.sun.estore.control.ejb. ShoppingClientController</remote> <ejb-class>com.sun.estore.control.ejb. ShoppingClientControllerEJB</ejb-class> ... <ejb-ref> <ejb-ref-name>ejb/cart</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <home>com.sun.estore.cart.ejb.ShoppingCartHome</home> <remote>com.sun.estore.cart.ejb.ShoppingCart</remote> <ejb-link>TheCart</ejb-link> </ejb-ref> ... </session>
| Code Example 7.6 Enterprise Bean Reference Element |
An Application Assembler uses the ejb-link element in the deployment descriptor to link an enterprise bean reference to a target enterprise bean. The ejb-link element is a subelement of the ejb-ref element. The value of the ejb-link element is the name of the target enterprise bean, that is, the name defined in the ejb-name element of the target enterprise bean. The target enterprise bean can be in the same EJB module or in another EJB module in the same J2EE application as the referencing enterprise bean. The Application Assembler needs to ensure that the target enterprise bean is type compatible with the declared enterprise bean reference. This means that the target enterprise bean must be of the type indicated in the ejb-ref-type element, and that the home and remote elements of the target enterprise bean must be type compatible with the home and remote elements declared in the enterprise bean reference.
The ejb-link element in Code
Example 7.6 indicates that the enterprise bean reference cart
declared in ShoppingClientController is linked to the enterprise
bean TheCart shown in Code
Example 7.7.
<session> <display-name>TheCart</display-name> <ejb-name>TheCart</ejb-name> <home>com.sun.estore.cart.ejb.ShoppingCartHome</home> <remote>com.sun.estore.cart.ejb.ShoppingCart</remote> <ejb-class>com.sun.estore.cart.ejb.ShoppingCartEJB</ejb-class> <session-type>Stateful</session-type> transaction-type>Container</transaction-type> </session>
| Code Example 7.7 Enterprise Bean Element |
A connection factory is an object used to create connections to a resource manager. For example, an object that implements the javax.sql.DataSource interface is a connection factory for java.sql.Connection objects which provide connections to database management systems.
An Application Component Provider must obtain connections to resources as follows:
- Declare a connection factory reference in the component's naming environment.
For each connection factory that is used by a component, an Application Component Provider declares a connection factory reference in the deployment descriptor using theresource-refelement. This allows the EJB module consumer (that is, Application Assembler or Deployer) to discover all the connection factory references used by an enterprise bean. All connection factory references should be organized in the subcontexts of a component's environment, using a different subcontext for each resource manager type. For example, all JDBCDataSourcereferences might be declared in thejava:comp/env/jdbcsubcontext (see Section 6.9.3.1), and all email sessions in thejava:comp/env/mailsubcontext. Connection factory references are also used to refer to URL resources and JMS connections.- Look up the connection factory object in the component's naming environment using the JNDI interface.
- Invoke the appropriate method on the connection factory method to obtain a connection to the resource. The factory method is specific to the resource type. It is possible to obtain multiple connections by calling the factory object multiple times.
A Deployer binds connection factory references to actual connection factories that are configured in the Container.
Code Example 7.8 illustrates the
mail connection factory reference in the entry for the Mailer enterprise
bean.
<session> <display-name>TheMailer</display-name> <ejb-name>TheMailer</ejb-name> <home>com.sun.estore.mail.ejb.MailerHome</home> <remote>com.sun.estore.mail.ejb.Mailer</remote> ... <resource-ref> <res-ref-name>mail/MailSession</res-ref-name> <res-type>javax.mail.Session</res-type> <res-auth>Container</res-auth> </resource-ref> </session>
| Code Example 7.8 Connection Factory Reference Element |
Note that the connection factory type must be compatible with the type declared
in the res-type element. The res-auth subelement of
the resource-ref element specifies whether resource signon is managed
by an application component or its container. See Section
6.9.3 for more information on resource signon.
The Mailer enterprise bean calls MailHelper to open
a mail session. Code Example 7.9 contains
the code from the MailHelper class that requests a mail session
object declared as java:comp/env/mail/MailSession in the JNDI context.
public void createAndSendMail(String to, String subject,
String htmlContents) {
try {
InitialContext ic = new InitialContext();
Session session = (Session) ic.
lookup("java:comp/env/mail/MailSession");
...
}
}
| Code Example 7.9 Looking Up a Connection Factory |
The Deployer must bind the connection factory references to the actual resource factories configured in the target environment. A Deployer can use the JNDI LinkRef mechanism to create a symbolic link to the actual JNDI name of the connection factory. The Deployer also needs to provide any additional configuration information that the resource manager needs for opening and managing the resource.
An Application Component Provider uses the security-role element
to define logical security roles that can be assumed by an authenticated principal.
Code Example 7.10 illustrates how
the sample application defines the gold_customer security role.
<security-role> <role-name>gold_customer</role-name> </security-role>
| Code Example 7.10 Security Role Element |
The security-role-ref element is used to link a role name used by the isCallerInRole method with a security role. In the sample application, this method is used by the Order entity bean to enforce business rules based on whether the user is a preferred customer.
Code Example 7.11 and Code
Example 7.12 illustrate how the security-role-ref element establishes
a link between the string GOLD_CUSTOMER used by the isCallerInRole
method and the security role named gold_customer.
private int getBonusMiles() {
int miles = (totalPrice >= 100) ? 1000 : 500;
if (context.isCallerInRole("GOLD_CUSTOMER"))
miles += 1000;
return miles;
}
| Code Example 7.11 Referencing a Security Role Name |
<security-role-ref> <role-name>GOLD_CUSTOMER</role-name> <role-link>gold_customer</role-link> </security-role-ref>
| Code Example 7.12 Linking a Security Role Name and Security Role |
An Application Component Provider declaratively controls access to an enterprise
bean's methods by specifying the method-permission element
in the enterprise bean's deployment descriptor. The component provider defines
this element to list the set of methods that can be accessed by each security
role. The authorization scenario described in Section
9.3.8 illustrates how method-permission elements
affect the execution of enterprise bean methods.
7.3.1.2 Enterprise Bean Elements
The component-specific elements that must be specified for an enterprise bean are those related to transactions and those related to persistence.
Two transaction elements must be specified: whether the bean uses container- or bean-managed transaction demarcation, and for container-managed demarcation, the transaction attributes of the bean's methods.
An Application Assembler must ensure that the methods of the deployed enterprise
beans with container-managed transaction demarcation have been assigned a transaction
attribute. If the transaction attributes have not been assigned by the Application
Component Provider, they must be assigned by the Application Assembler. Code
Example 7.13 illustrates how transaction attributes are declared for an
Account entity bean. Recall that entity beans can only use container-managed
transactions. The container-transaction element for Account
specifies that when the changeContactInformation method is invoked,
it must be within the scope of a transaction. See Section
8.7.2.1 for detailed information about the values that a transaction
attribute can take.
<container-transaction> <method> <ejb-name>TheAccount</ejb-name> <method-intf>Remote</method-intf> <method-name>changeContactInformation</method-name> <method-params> <method-param>com.sun.estore.util. ContactInformation</method-param> </method-params> </method> <trans-attribute>Required</trans-attribute> </container-transaction>
| Code Example 7.13 Transaction Elements |
The Application Component Provider must specify whether a bean manages its
own persistence or uses container-managed persistence. When a bean uses container-managed
persistence, the Application Component Provider must specify the fields of the
bean. Code Example 7.14 illustrates
how the Account entity bean uses the persistence-type
element to declare that it will manage its own persistence.
<entity> <description>Account of a shopper</description> <display-name>TheAccount</display-name> ... <persistence-type>Bean</persistence-type> </entity>
| Code Example 7.14 Persistence Element |
7.3.1.3 Web Component Elements
Some of the more commonly used Web component deployment descriptor elements are discussed in this section.
The one deployment descriptor element that must be specified for a
Web component is the servlet element, shown in Code
Example 7.15. This element associates a logical identifier (servlet-name)
with the name of the servlet class or the JSP file associated with the component.
<servlet> <servlet-name>webTierEntryPoint</servlet-name> <display-name>centralJsp</display-name> <jsp-file>Main.jsp</jsp-file> </servlet>
| Code Example 7.15 Servlet Element |
The servlet-mapping element specifies the URLs that the Web component
is aliased to handle. While the element is called servlet-mapping,
it is used to map URLs to both servlets and JSP pages. Code
Example 7.16 aliases Main.jsp to handle all requests coming
to the set of URLs /control/*.
<servlet-mapping> <servlet-name>webTierEntryPoint</servlet-name> <url-pattern>/control/*</url-pattern> </servlet-mapping>
| Code Example 7.16 Servlet Mapping Element |
The error-page element can be used to invoke an error page automatically
when the Web application throws a Java language exception. Code
Example 7.17 shows how to enable the J2EE server to send errorpage.jsp
to the browser client if the Web application ever throws any exception of the
type java.lang.Exception or its subclass.
<error-page> <exception-type>java.lang.Exception</exception-type> <location>/errorpage.jsp</location> </error-page>
| Code Example 7.17 Error Page Element |
Form-based authentication is the preferred mechanism for authenticating application
users in the J2EE platform. Code Example
7.18 illustrates how to configure a Web application to activate form-based
authentication when the Web server receives a request for the URL /control/placeorder.
The security-constraint element specifies that the URL /control/placeorder
is a protected resource. The login-config element specifies that
the URL formbasedloginscreen will be displayed when an unauthenticated
user tries to access /control/placeorder. This page contains an
HTML form that prompts for a user name and password.
<security-constraint> <web-resource-collection> <web-resource-name>MySecureBit0</web-resource-name> <description>no description</description> <url-pattern>/control/placeorder</url-pattern> <http-method>POST</http-method> <http-method>GET</http-method> </web-resource-collection> <auth-constraint> <description>no description</description> <role-name>gold_customer</role-name> <role-name>customer</role-name> </auth-constraint> <user-data-constraint> <description>no description</description> <transport-guarantee>NONE</transport-guarantee> </user-data-constraint> </security-constraint> <login-config> <auth-method>FORM</auth-method> <realm-name>default</realm-name> <form-login-config> <form-login-page>formbasedloginscreen</form-login-page> <form-error-page>formbasedloginerrorscreen </form-error-page> </form-login-config> </login-config>
| Code Example 7.18 Form-Based Authentication Configuration |