Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Developer's Guide

- Previous: Part I Developing and Deploying Applications
- Next: Part III Using Services and APIs

# Part II Developing Applications and Application Components

# Chapter 5 Developing Web Applications

This chapter describes how web applications are supported in the Sun Java System Application Server and includes the following sections:

- Introducing Web Applications

- Using Servlets

- Using JavaServer Pages

- Creating and Managing HTTP Sessions

For general information about web applications, see the J2EE 1.4 Tutorial at `http://java.sun.com/j2ee/1.4/docs/tutorial/doc/WebApp.html#wp76431`.

# Introducing Web Applications

This section includes summaries of the following topics:

- Internationalization Issues

- Virtual Servers

- Default Web Modules

- Classloader Delegation

- Using the default-web.xml File

- Configuring Logging in the Web Container

- Configuring Idempotent URL Requests

- Configuring HTML Error Pages

- Header Management

- Redirecting URLs

## Internationalization Issues

This section covers internationalization as it applies to the following:

- The Server

- Servlets

### The Server

To set the default locale of the entire Application Server, which determines the locale of the Administration Console, the logs, and so on, use the Administration Console. Select the Domain component, and type a value in the Locale field. For details, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Guide.

### Servlets

This section explains how the Application Server determines the character encoding for the servlet request and the servlet response. For encodings you can use, see `http://java.sun.com/j2se/1.4/docs/guide/intl/encoding.doc.html`.

#### Servlet Request

When processing a servlet request, the server uses the following order of precedence, first to last, to determine the request character encoding:

- The ```getCharacterEncoding()` method.

- A hidden field in the form, specified by the `form-hint-field` attribute of the `parameter-encoding` element in the `sun-web.xml` file.

- The character encoding set in the `default-charset` attribute of the `parameter-encoding` element in the `sun-web.xml` file.

- The default, which is `ISO-8859-1`.

For details about the `parameter-encoding` element, see parameter-encoding.

#### Servlet Response

When processing a servlet response, the server uses the following order of precedence, first to last, to determine the response character encoding:

- The `setCharacterEncoding()` or ```setContentType()` method.

- The ```setLocale()` method.

- The default, which is `ISO-8859-1`.

## Virtual Servers

A virtual server, also called a virtual host, is a virtual web server that serves content targeted for a specific URL. Multiple virtual servers can serve content using the same or different host names, port numbers, or IP addresses. The HTTP service directs incoming web requests to different virtual servers based on the URL.

When you first install the Application Server, a default virtual server is created. (You can also assign a default virtual server to each new HTTP listener you create. For details, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Guide.)

Web applications and J2EE applications containing web components can be assigned to virtual servers.

### To assign virtual servers

1. Deploy the application or web module and assign the desired virtual server to it.

   For more information, see Tools for Deployment.

2. In the Administration Console, open the HTTP Service component under the relevant configuration.

3. Open the Virtual Servers component under the HTTP Service component.

4. Select the virtual server to which you want to assign a default web module.

5. Select the application or web module from the Default Web Module drop-down list.

   For more information, see Default Web Modules.

##### See Also

For details, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Guide.

## Default Web Modules

A default web module can be assigned to the default virtual server and to each new virtual server. For details, see Virtual Servers. To access the default web module for a virtual server, point the browser to the URL for the virtual server, but do not supply a context root. For example:

    http://myvserver:3184/

A virtual server with no default web module assigned serves HTML or JSP content from its document root, which is usually domain-dir`/docroot`. To access this HTML or JSP content, point your browser to the URL for the virtual server, do not supply a context root, but specify the target file.

For example:

    http://myvserver:3184/hellothere.jsp

## Classloader Delegation

The Servlet specification recommends that the Web Classloader look in the local class loader before delegating to its parent. To make the Web Classloader follow the delegation model in the Servlet specification, set `delegate="false"` in the `class-loader` element of the `sun-web.xml` file. It’s safe to do this only for a web module that does not interact with any other modules.

The default value is `delegate="true"`, which causes the Web Classloader to delegate in the same manner as the other classloaders. Use `delegate="true"` for a web application that accesses EJB components or that acts as a web service client or endpoint. For details about `sun-web.xml`, see The sun-web.xml File.

For general information about classloaders, see Classloaders.

## Using the default-web.xml File

You can use the `default-web.xml` file to define features such as filters and security constraints that apply to all web applications.

### To use the default-web.xml file

1. Place the JAR file for the filter, security constraint, or other feature in the domain-dir`/lib` directory.

2. Edit the domain-dir`/config/default-web.xml` file to refer to the JAR file.

3. Restart the server.

##### The InvokerServlet

The `InvokerServlet` allows use of the `servlet-name` instead of the `servlet-mapping` for invoking a servlet with a URL, as described in Invoking a Servlet with a URL. The `InvokerServlet` is commented out in the `default-web.xml` file. To re-enable the `InvokerServlet`, remove the comment indicators (`<!--` and `-->`), then restart the server.

## Configuring Logging in the Web Container

For information about configuring logging and monitoring in the web container using the Administration Console, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Guide.

## Configuring Idempotent URL Requests

An idempotent request is one that does not cause any change or inconsistency in an application when retried. To enhance the availability of your applications deployed on an Application Server cluster, configure the load balancer to retry failed idempotent HTTP requests on all the Application Server instances in a cluster. This option can be used for read-only requests, for example, to retry a search request.

This section describes the following topics:

- Specifying an Idempotent URL

- Characteristics of an Idempotent URL

### Specifying an Idempotent URL

To configure idempotent URL response, specify the URLs that can be safely retried in idempotent-url-pattern elements in the `sun-web.xml` file. For example:

    <idempotent-url-pattern url-pattern="sun_java/*" no-of-retries="10"/>

For details, see idempotent-url-pattern.

If none of the server instances can successfully serve the request, an error page is returned. To configure custom error pages, see Configuring HTML Error Pages.

### Characteristics of an Idempotent URL

Since all requests for a given session are sent to the same application server instance, and if that Application Server instance is unreachable, the load balancer returns an error message. Normally, the request is not retried on another Application Server instance. However, if the URL pattern matches that specified in the `sun-web.xml` file, the request is implicitly retried on another Application Server instance in the cluster.

In HTTP, some methods (such as GET) are idempotent, while other methods (such as POST) are not. In effect, retrying an idempotent URL should not cause values to change on the server or in the database. The only difference should be a change in the response received by the user.

Examples of idempotent requests include search engine queries and database queries. The underlying principle is that the retry does not cause an update or modification of data.

A search engine, for example, sends HTTP requests with the same URL pattern to the load balancer. Specifying the URL pattern of the search request to the load balancer ensures that HTTP requests with the specified URL pattern is implicitly retried on another Application Server instance.

For example, if the request URL sent to the Application Server is of the type `/search/`something`.html`, then the URL pattern can be specified as `/search/*`.

Examples of non-idempotent requests include banking transactions and online shopping. If you retry such requests, money might be transferred twice from your account.

## Configuring HTML Error Pages

To specify an error page (or URL to an error page) to be displayed to the end user, use the `error-url` attribute of the sun-web-app element in the `sun-web.xml` file. For example:

    <sun-web-app error-url="webserver-install-dir/error/error1.html">
    ... subelements ...
    </sun-web-app>

For details, see sun-web-app.

If the `error-url` attribute is specified, it overrides all other mechanisms configured for error reporting.

Note –

This attribute should not point to a URL on the Application Server instance, because the `error-url` cannot be loaded if the server is down. Instead, specify a URL that points to a location on the web server.

The Application Server provides the following options for specifying the error page.

- You can specify the `error-url` to be an HTTP URL. The Application Server forwards the client request to the specified error URL.

- You can specify the `error-url` to be the name of an HTML page in the standard load balancer plug-in’s error pages directory. Do not specify an absolute path in the local file system. The location must be relative to the webserver-install-dir`/plugins/lbplugin/``errorpages` directory.

- If you do not specify the `error-url` attribute in the `sun-web.xml` file, a default error page , `sun-http-lberror.html`, from the standard error pages directory, `errorpages`, is displayed if present.

  As part of the load balancer plug-in installation, a directory called `errorpages` is created in the web server installation directory.

The error page is displayed according to the following rules:

- When an error is encountered for an application, the Application Server first checks if the `error-url` attribute is defined. If it is defined, the Application Server reads the URL attribute and loads the error page.

- If the `error-url` attribute is missing or invalid, the Application Server displays the default error page, `sun-http-lb-error.html`, from the `errorpages` directory of the load balancer plug-in.

- If the `error-url` has been defined but the page is missing, the Application Server loads the default error page, `sun-http-lb-error.html`.

- If the default error page is missing, the error is forwarded to the web server.

## Header Management

In the Platform Edition of the Application Server, the `Enumeration` from `request.``getHeaders()` contains multiple elements. In the Enterprise Edition, this `Enumeration` contains a single, aggregated value.

The header names used in `HttpServletResponse.add` XXX `Header()` and `HttpServletResponse.set` XXX `Header()` are returned differently to the HTTP client from the Platform Edition and the Enterprise Edition of the Application Server. The Platform Edition preserves the names as they were created. The Enterprise Edition capitalizes the first letter but converts all other letters to lower case. For example, if `sampleHeaderName2` is used in `response.addHeader()`, the response name in the Platform Edition is unchanged, but the response name in the Enterprise Edition is `Sampleheadername2`.

## Redirecting URLs

You can specify that a request for an old URL is treated as a request for a new URL. This is called redirecting a URL.

To specify a redirected URL for a virtual server, use the `redireect_`n property, where n is a positive integer that allows specification of more than one. This property is a subelement of a `virtual-server` element in the `domain.xml` file. For more information about this element, see `virtual-server` in Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Reference. Each of these `redirect_`n properties is inherited by all web applications deployed on the virtual server.

The value of each `redirect_`n property has two components, which may be specified in any order:

The first component, `from`, specifies the prefix of the requested URI to match.

The second component, `url-prefix`, specifies the new URL prefix to return to the client. The `from` prefix is simply replaced by this URL prefix.

For example:

    <property name="redirect_1" value="from=/dummy url-prefix=http://etude"/>

# Using Servlets

Application Server supports the Java Servlet Specification version 2.4.

Note –

Servlet API version 2.4 is fully backward compatible with version 2.3, so all existing servlets should work without modification or recompilation.

To develop servlets, use Sun Microsystems’ Java Servlet API. For information about using the Java Servlet API, see the documentation provided by Sun Microsystems at `http://java.sun.com/products/servlet/index.html`.

The Application Server provides the `wscompile` and `wsdeploy` tools to help you implement a web service endpoint as a servlet. For more information about these tools, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

This section describes how to create effective servlets to control application interactions running on an Application Server, including standard-based servlets. In addition, this section describes the Application Server features to use to augment the standards.

This section contains the following topics:

- Invoking a Servlet with a URL

- Servlet Output

- Caching Servlet Results

- About the Servlet Engine

## Invoking a Servlet with a URL

You can call a servlet deployed to the Application Server by using a URL in a browser or embedded as a link in an HTML or JSP file. The format of a servlet invocation URL is as follows:

    http://server:port/context-root/servlet-mapping?name=value

The following table describes each URL section.

Table 5–1 URL Fields for Servlets Within an Application

URL element | Description
--- | ---
server`:`port | The IP address (or host name) and optional port number. To access the default web module for a virtual server, specify only this URL section. You do not need to specify the context-root or servlet-name unless you also wish to specify name-value parameters.
context-root | For an application, the context root is defined in the `context-root` element of the `application.xml` or `sun-application.xml` file. For an individually deployed web module, the context root is specified during deployment. For both applications and individually deployed web modules, the default context root is the name of the WAR file minus the `.war` suffix.
servlet-mapping | The `servlet-mapping` as configured in the `web.xml` file. You can use the `servlet-name` instead if you enable the `InvokerServlet`; see Using the default-web.xml File.
`?`name`=`value`...` | Optional request parameters.

In this example, `localhost` is the host name, `MortPages` is the context root, and `calcMortgage` is the servlet mapping:

    http://localhost:8080/MortPages/calcMortgage?rate=8.0&per=360&bal=180000

When invoking a servlet from within a JSP file, you can use a relative path. For example:

    <jsp:forward page="TestServlet"/>
    <jsp:include page="TestServlet"/>

## Servlet Output

`ServletContext.log` messages are sent to the server log.

By default, the `System.out` and `System.err` output of servlets are sent to the server log, and during startup server log messages are echoed to the `System.err` output. Also by default, there is no Windows-only console for the `System.err` output.

To change these defaults using the Administration Console, select the Logger Settings component under the relevant configuration, then check or uncheck these boxes:

- Log Messages to Standard Error - If checked, `System.err` output is sent to the server log. If unchecked, `System.err` output is sent to the system default location only.

- Write to System Log - If checked, `System.out` output is sent to the server log. If unchecked, `System.out` output is sent to the system default location only.

For more information, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Guide.

## Caching Servlet Results

The Application Server can cache the results of invoking a servlet, a JSP, or any URL pattern to make subsequent invocations of the same servlet, JSP, or URL pattern faster. The Application Server caches the request results for a specific amount of time. In this way, if another data call occurs, the Application Server can return the cached data instead of performing the operation again. For example, if your servlet returns a stock quote that updates every 5 minutes, you set the cache to expire after 300 seconds.

Whether to cache results and how to cache them depends on the data involved. For example, it makes no sense to cache the results of a quiz submission, because the input to the servlet is different each time. However, it makes sense to cache a high level report showing demographic data taken from quiz results that is updated once an hour.

To define how an Application Server web application handles response caching, you edit specific fields in the `sun-web.xml` file.

Note –

A servlet that uses caching is not portable.

A sample caching application is in install-dir`/samples/webapps/apps/caching`.

For more information about JSP caching, see JSP Caching.

The rest of this section covers the following topics:

- Caching Features

- Default Cache Configuration

- Caching Example

- CacheKeyGenerator Interface

### Caching Features

The Application Server has the following web application response caching capabilities:

- Caching is configurable based on the servlet name or the URI.

- When caching is based on the URI, this includes user specified parameters in the query string. For example, a response from `/garden/catalog?category=roses` is different from a response from `/garden/catalog?category=lilies`. These responses are stored under different keys in the cache.

- Cache size, entry timeout, and other caching behaviors are configurable.

- Entry timeout is measured from the time an entry is created or refreshed. To override this timeout for an individual cache mapping, specify the `cache-mapping` subelement `timeout`.

- To determine caching criteria programmatically, write a class that implements the `com.sun.appserv.web.cache.CacheHelper` interface. For example, if only a servlet knows when a back end data source was last modified, you can write a helper class to retrieve the last modified timestamp from the data source and decide whether to cache the response based on that timestamp.

- To determine cache key generation programmatically, write a class that implements the `com.sun.appserv.web.cache.CacheKeyGenerator` interface. See CacheKeyGenerator Interface.

- All non-ASCII request parameter values specified in cache key elements must be URL encoded. The caching subsystem attempts to match the raw parameter values in the request query string.

- Since newly updated classes impact what gets cached, the web container clears the cache during dynamic deployment or reloading of classes.

- The following `HttpServletRequest` request attributes are exposed:

  - `com.sun.appserv.web.cachedServletName`, the cached servlet target

  - `com.sun.appserv.web.cachedURLPattern`, the URL pattern being cached

- Results produced by resources that are the target of a `RequestDispatcher.include()` or `RequestDispatcher.forward()` call are cached if caching has been enabled for those resources. For details, see the descriptions of the cache-mapping and dispatcher elements in the `sun-web.xml` file.

### Default Cache Configuration

If you enable caching but do not provide any special configuration for a servlet or JSP, the default cache configuration is as follows:

- The default cache timeout is 30 seconds.

- Only the HTTP GET method is eligible for caching.

- HTTP requests with cookies or sessions automatically disable caching.

- No special consideration is given to `Pragma:`, `Cache-control:`, or `Vary:` headers.

- The default key consists of the Servlet Path (minus `pathInfo` and the query string).

- A “least recently used” list is maintained to evict cache entries if the maximum cache size is exceeded.

- Key generation concatenates the servlet path with key field values, if any are specified.

- Results produced by resources that are the target of a `RequestDispatcher.include()` or `RequestDispatcher.forward()` call are never cached.

### Caching Example

Here is an example cache element in the `sun-web.xml` file:

    <cache max-capacity="8192" timeout="60">
    <cache-helper name="myHelper" class-name="MyCacheHelper"/>
    <cache-mapping>
    	<servlet-name>myservlet</servlet-name>
    	<timeout name="timefield">120</timeout>
    	<http-method>GET</http-method>
    	<http-method>POST</http-method>
    </cache-mapping>
    <cache-mapping>
    	<url-pattern> /catalog/* </url-pattern>
    	<!-- cache the best selling category; cache the responses to
    	   -- this resource only when the given parameters exist. Cache
    	   -- only when the catalog parameter has 'lilies' or 'roses'
    	   -- but no other catalog varieties:
    	  -- /orchard/catalog?best&category='lilies'
    	  -- /orchard/catalog?best&category='roses'
    	  -- but not the result of
    	   -- /orchard/catalog?best&category='wild'
    	-->
    	<constraint-field name='best' scope='request.parameter'/>
    	<constraint-field name='category' scope='request.parameter'>
    		<value> roses </value>
    		<value> lilies </value>
    	</constraint-field>
    	 <!-- Specify that a particular field is of given range but the
    	   -- field doesn't need to be present in all the requests -->
    	<constraint-field name='SKUnum' scope='request.parameter'>
    		<value match-expr='in-range'> 1000 - 2000 </value>
    	</constraint-field>
    	<!-- cache when the category matches with any value other than
    	   -- a specific value -->
    	<constraint-field name="category" scope="request.parameter>
    		<value match-expr="equals" cache-on-match-failure="true">
           bogus
    		</value>
    	</constraint-field>
    </cache-mapping>
    <cache-mapping>
    	<servlet-name> InfoServlet </servlet-name>
    	<cache-helper-ref>myHelper</cache-helper-ref>
    </cache-mapping>
    </cache>

For more information about the `sun-web.xml` caching settings, see cache.

### CacheKeyGenerator Interface

The built-in default `CacheHelper` implementation allows web applications to customize the key generation. An application component (in a servlet or JSP) can set up a custom `CacheKeyGenerator` implementation as an attribute in the `ServletContext`.

The name of the context attribute is configurable as the `value` of the `cacheKeyGeneratorAttrName` property in the `default-helper` element of the `sun-web.xml` deployment descriptor. For more information, see default-helper.

## About the Servlet Engine

Servlets exist in and are managed by the servlet engine in the Application Server. The servlet engine is an internal object that handles all servlet meta functions. These functions include instantiation, initialization, destruction, access from other components, and configuration management. This section covers the following topics:

- Instantiating and Removing Servlets

- Request Handling

### Instantiating and Removing Servlets

After the servlet engine instantiates the servlet, the servlet engine calls the servlet’s `init()` method to perform any necessary initialization. You can override this method to perform an initialization function for the servlet’s life, such as initializing a counter.

When a servlet is removed from service, the servlet engine calls the `destroy()` method in the servlet so that the servlet can perform any final tasks and deallocate resources. You can override this method to write log messages or clean up any lingering connections that won’t be caught in garbage collection.

### Request Handling

When a request is made, the Application Server hands the incoming data to the servlet engine. The servlet engine processes the request’s input data, such as form data, cookies, session information, and URL name-value pairs, into an `HttpServletRequest` request object type.

The servlet engine also creates an `HttpServletResponse` response object type. The engine then passes both as parameters to the servlet’s `service()` method.

In an HTTP servlet, the default `service()` method routes requests to another method based on the HTTP transfer method: `POST`, `GET`, `DELETE`, `HEAD`, `OPTIONS`, `PUT`, or `TRACE`. For example, HTTP `POST` requests are sent to the `doPost()` method, HTTP `GET` requests are sent to the `doGet()` method, and so on. This enables the servlet to process request data differently, depending on which transfer method is used. Since the routing takes place in the service method, you generally do not override `service()` in an HTTP servlet. Instead, override `doGet()`, `doPost()`, and so on, depending on the request type you expect.

To perform the tasks to answer a request, override the `service()` method for generic servlets, and the `doGet()` or `doPost()` methods for HTTP servlets. Very often, this means accessing EJB components to perform business transactions, then collating the information in the request object or in a JDBC `ResultSet` object.

# Using JavaServer Pages

The Application Server supports the following JSP features:

- JavaServer Pages (JSP) Specification version 2.0

- Precompilation of JSP files, which is especially useful for production servers

- JSP tag libraries and standard portable tags

For information about creating JSP files, see Sun Microsystem’s JavaServer Pages web site at `http://java.sun.com/products/jsp/index.html`.

For information about Java Beans, see Sun Microsystem’s JavaBeans web page at `http://java.sun.com/beans/index.html`.

This section describes how to use JavaServer Pages (JSP files) as page templates in an Application Server web application. This section contains the following topics:

- JSP Tag Libraries and Standard Portable Tags

- JSP Caching

- Options for Compiling JSP Files

## JSP Tag Libraries and Standard Portable Tags

Application Server supports tag libraries and standard portable tags. For more information, see the JavaServer Pages Standard Tag Library (JSTL) page at `http://java.sun.com/products/jsp/jstl/index.jsp`.

Web applications don’t need to bundle copies of the `jsf-impl.jar` or `appserv-jstl.jar` JSP tag libraries (in install-dir`/lib`) to use JavaServerTM Faces technology or JSTL, respectively. These tag libraries are automatically available to all web applications.

However, the install-dir`/lib/``appserv-tags.jar` tag library for JSP caching is not automatically available to web applications. See JSP Caching, next.

## JSP Caching

JSP caching lets you cache tag invocation results within the Java engine. Each can be cached using different cache criteria. For example, suppose you have invocations to view stock quotes, weather information, and so on. The stock quote result can be cached for 10 minutes, the weather report result for 30 minutes, and so on.

For more information about response caching as it pertains to servlets, see Caching Servlet Results.

JSP caching is implemented by a tag library packaged into the install-dir`/lib/``appserv-tags.jar` file, which you can copy into the `WEB-INF/lib` directory of your web application. The `appserv-tags.tld` tag library descriptor file is in the `META-INF` directory of this JAR file.

Note –

Web applications that use this tag library are not portable.

To allow all web applications to share this tag library, change the following elements in the `domain.xml` file. Change this:

    <jvm-options>
    -Dcom.sun.enterprise.taglibs=appserv-jstl.jar,jsf-impl.jar
    </jvm-options>

to this:

    <jvm-options>
    -Dcom.sun.enterprise.taglibs=appserv-jstl.jar,jsf-impl.jar,appserv-tags.jar
    </jvm-options>

and this:

    <jvm-options>
    -Dcom.sun.enterprise.taglisteners=jsf-impl.jar
    </jvm-options>

to this:

    <jvm-options>
    -Dcom.sun.enterprise.taglisteners=jsf-impl.jar,appserv-tags.jar
    </jvm-options>

For more information about the `domain.xml` file, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Reference.

Refer to these tags in JSP files as follows:

    <%@ taglib prefix="prefix" uri="Sun ONE Application Server Tags" %>

Subsequently, the cache tags are available as `<`prefix`:cache>` and `<`prefix`:flush>`. For example, if your prefix is `mypfx`, the cache tags are available as `<mypfx:cache>` and `<mypfx:flush>`.

The tags are as follows:

- cache

- flush

### cache

The cache tag caches the body between the beginning and ending tags according to the attributes specified. The first time the tag is encountered, the body content is executed and cached. Each subsequent time it is run, the cached content is checked to see if it needs to be refreshed and if so, it is executed again, and the cached data is refreshed. Otherwise, the cached data is served.

#### Attributes

The following table describes attributes for the `cache` tag.

Table 5–2 `cache` Attributes

Attribute | Default | Description
--- | --- | ---
`key` | ServletPath`_`Suffix | (optional) The name used by the container to access the cached entry. The cache key is suffixed to the servlet path to generate a key to access the cached entry. If no key is specified, a number is generated according to the position of the tag in the page.
`timeout` | `60s` | (optional) The time in seconds after which the body of the tag is executed and the cache is refreshed. By default, this value is interpreted in seconds. To specify a different unit of time, add a suffix to the timeout value as follows: `s` for seconds, `m` for minutes, `h` for hours, `d` for days. For example, `2h` specifies two hours.
`nocache` | `false` | (optional) If set to `true`, the body content is executed and served as if there were no `cache` tag. This offers a way to programmatically decide whether the cached response is sent or whether the body has to be executed, though the response is not cached.
`refresh` | `false` | (optional) If set to `true`, the body content is executed and the response is cached again. This lets you programmatically refresh the cache immediately regardless of the `timeout` setting.

#### Example

The following example represents a cached JSP file:

    <%@ taglib prefix="mypfx" uri="Sun ONE Application Server Tags" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <mypfx:cache                 key="${sessionScope.loginId}"
    			nocache="${param.nocache}"
    			refresh="${param.refresh}"
    			timeout="10m">
    <c:choose>
    	<c:when test="${param.page == 'frontPage'}">
    		<%-- get headlines from database --%>
    	</c:when>
    	<c:otherwise>
    		...
    	</c:otherwise>
    </c:choose>
    </mypfx:cache>
    <mypfx:cache timeout="1h">
    <h2> Local News </h2>
    	<%-- get the headline news and cache them --%>
    </mypfx:cache>

### flush

Forces the cache to be flushed. If a `key` is specified, only the entry with that key is flushed. If no key is specified, the entire cache is flushed.

#### Attributes

The following table describes attributes for the `flush` tag.

Table 5–3 `flush` Attributes

Attribute | Default | Description
--- | --- | ---
`key` | ServletPath`_`Suffix | (optional) The name used by the container to access the cached entry. The cache key is suffixed to the servlet path to generate a key to access the cached entry. If no key is specified, a number is generated according to the position of the tag in the page.

#### Examples

To flush the entry with `key="foobar"`:

    <mypfx:flush key="foobar"/>

To flush the entire cache:

    <c:if test="${empty sessionScope.clearCache}">
       <mypfx:flush />
    </c:if>

#### Options for Compiling JSP Files

Application Server provides the following ways of compiling JSP 2.0 compliant source files into servlets:

- JSP files are automatically compiled at runtime.

- The `asadmin deploy` command has a `precompilejsp` option. For details, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

- The `sun-appserv-jspc` Ant task allows you to precompile JSP files; see sun-appserv-jspc.

- The `jspc` command line tool allows you to precompile JSP files at the command line. For details, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

# Creating and Managing HTTP Sessions

This chapter describes how to create and manage a session that allows users and transaction information to persist between interactions.

This chapter contains the following sections:

- Configuring Sessions

- Session Managers

- Sample Session Persistence Applications

## Configuring Sessions

This section covers the following topics:

- Sessions, Cookies, and URL Rewriting

- Coordinating Session Access

- Distributed Sessions and Persistence

### Sessions, Cookies, and URL Rewriting

To configure whether and how sessions use cookies and URL rewriting, edit the `session-properties` and `cookie-properties` elements in the `sun-web.xml` file for an individual web application. See session-properties and cookie-properties for more about the properties you can configure.

For information about configuring default session properties for the entire web container, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Guide and the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 High Availability Administration Guide.

### Coordinating Session Access

Make sure that multiple threads don’t simultaneously modify the same session object in conflicting ways. If the persistence type is `ha` (see The ha Persistence Type), the following message in the log file indicates that this might be happening:

    Primary Key Constraint violation while saving session session_id

This is especially likely to occur in web applications that use HTML frames where multiple servlets are executing simultaneously on behalf of the same client. A good solution is to ensure that one of the servlets modifies the session and the others have read-only access.

### Distributed Sessions and Persistence

A distributed session can run in multiple Application Server instances, provided the following criteria are met:

- Each server instance has access to the same high-availability database (HADB). For information about how to enable this database, see the description of the `configure-ha-cluster` command in the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

- Each server instance has the same distributable web application deployed to it. The `web-app` element of the `web.xml` deployment descriptor file must have the `distributable` subelement specified.

- The web application uses high-availability session persistence. If a non-distributable web application is configured to use high-availability session persistence, an error is written to the server log. See The ha Persistence Type.

- All objects bound into a distributed session must be of the types listed in Table 5–4.

- The web application must be deployed using the `deploy` or `deploydir` command with the `--availabilityenabled` option set to `true`. See the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

Note –

Contrary to the Servlet 2.4 specification, Application Server does not throw an `IllegalArgumentException` if an object type not supported for failover is bound into a distributed session.

Keep the distributed session size as small as possible. Session size has a direct impact on overall system throughput.

A servlet that is not deployed as part of a web application is implicitly deployed to a default web application and has the default `ServletContext`. The default `ServletContext` is not distributed. (A web application with an empty context root does not have the default `ServletContext`.)

In the event of an instance or hardware failure, another server instance can take over a distributed session, with the following limitations:

- If a distributable web application references a J2EE component or resource, the reference might be lost. See Table 5–4 for a list of the types of references that HTTPSession failover supports.

- References to open files or network connections are lost.

For information about how to work around these limitations, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Deployment Planning Guide.

In the following table, No indicates that failover for the object type might not work in all cases and that no failover support is provided. However, failover might work in some cases for that object type. For example, failover might work because the class implementing that type is serializable.

For more information about the `InitialContext`, see Accessing the Naming Context. For more information about transaction recovery, see Chapter 12, Using the Transaction Service. For more information about Administered Objects, see Creating Physical Destinations.

Table 5–4 Object Types Supported for J2EE Web Application Session State Failover

Java Object Type | Failover Support
--- | ---
Stateless session, stateful session, and entity bean local home reference, local object reference | Yes
Colocated and distributed stateless session, stateful session, and entity bean remote home reference, remote reference | Yes
JNDI Context | Yes, `InitialContext` and `java:comp/env`
UserTransaction | Yes, but if the instance that fails is never restarted, any prepared global transactions are lost and might not be correctly rolled back or committed
JDBC DataSource | No
JavaTM Message Service (JMS) ConnectionFactory, Destination | No
JavaMailTM Session | No
Connection Factory | No
Administered Object | No
Web service reference | No
Serializable Java types | Yes

## Session Managers

A session manager automatically creates new session objects whenever a new session starts. In some circumstances, clients do not join the session, for example, if the session manager uses cookies and the client does not accept cookies.

Application Server offers these session management options, determined by the session-manager element’s `persistence-type` attribute in the `sun-web.xml` file:

- The memory Persistence Type, the default

- The file Persistence Type, which uses a file to store session data

- The ha Persistence Type, which uses the high-availability database for session persistence

Note –

If the session manager configuration contains an error, the error is written to the server log and the default (`memory`) configuration is used.

### The memory Persistence Type

This persistence type is not designed for a production environment that requires session persistence. It provides no session persistence. However, you can configure it so that the session state in memory is written to the file system prior to server shutdown.

To specify the `memory` persistence type for the entire web container, use the `configure-ha-persistence` command. For details, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

To specify the `memory` persistence type for a specific web application, edit the `sun-web.xml` file as in the following example. The `persistence-type` property is optional, but must be set to `memory` if included. This overrides the web container availability settings for the web application.

    <sun-web-app>
    ...
    <session-config>
    	<session-manager persistence-type=memory />
    		<manager-properties>
    			<property name="sessionFilename" value="sessionstate" />
    		</manager-properties>
    	</session-manager>
    	...
    </session-config>
    ...
    </sun-web-app>

The only manager property that the `memory` persistence type supports is sessionFilename, which is listed under manager-properties.

For more information about the `sun-web.xml` file, see The sun-web.xml File.

### The file Persistence Type

This persistence type provides session persistence to the local file system, and allows a single server domain to recover the session state after a failure and restart. The session state is persisted in the background, and the rate at which this occurs is configurable. The store also provides passivation and activation of the session state to help control the amount of memory used. This option is not supported in a production environment. However, it is useful for a development system with a single server instance.

Note –

Make sure the `delete` option is set in the `server.policy` file, or expired file-based sessions might not be deleted properly. For more information about `server.policy`, see The server.policy File.

To specify the `file` persistence type for the entire web container, use the `configure-ha-persistence` command. For details, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

To specify the `file` persistence type for a specific web application, edit the `sun-web.xml` file as in the following example. Note that `persistence-type` must be set to `file`. This overrides the web container availability settings for the web application.

    <sun-web-app>
    ...
    <session-config>
    	<session-manager persistence-type=file>
    		<store-properties>
    			<property name=directory value=sessiondir />
    		</store-properties>
    	</session-manager>
    	...
    </session-config>
    ...
    </sun-web-app>

The `file` persistence type supports all the manager properties listed under manager-properties except `sessionFilename`, and supports the `directory` store property listed under store-properties.

For more information about the `sun-web.xml` file, see The sun-web.xml File.

### The ha Persistence Type

The ha persistence type uses the high-availability database (HADB) for session persistence. The HADB allows sessions to be distributed. For details, see Distributed Sessions and Persistence. In addition, you can configure the frequency and scope of session persistence. The HADB is also used as the passivation and activation store. Use this option in a production environment that requires session persistence.

The HADB must be configured and enabled before you can use distributed sessions. For configuration details, see the description of the `configure-ha-cluster` command in the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

To enable the HADB, select the Availability Service component under the relevant configuration in the Administration Console. Check the Instance Level Availability box. To enable availability for the web container, select the Web Container Availability tab, then check the Availability Service box. For details, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 High Availability Administration Guide.

To change settings such as persistence frequency and persistence scope for the entire web container, see the description of the `configure-ha-persistence` command in the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

To specify the `ha` persistence type for a specific web application, edit the `sun-web.xml` file as in the following example. Note that `persistence-type` must be set to `ha`. This overrides the web container availability settings for the web application.

    <sun-web-app>
    ...
    <session-config>
    	<session-manager persistence-type=fileha>
    		<manager-properties>
    			<property name=persistenceFrequency value=web-method />
    		</manager-properties>
    		<store-properties>
    			<property name=persistenceScope value=session />
    		</store-properties>
    	</session-manager>
    	...
    </session-config>
    ...
    </sun-web-app>

The `ha` persistence type supports all the manager properties listed under manager-properties except `sessionFilename`, and supports the `persistenceScope` store property listed under store-properties.

For more information about the `sun-web.xml` file, see The sun-web.xml File.

## Sample Session Persistence Applications

The following directories contain sample applications that demonstrate HTTP session persistence:

    install-dir/samples/ee-samples/highavailability

    install-dir/samples/ee-samples/failover

# Chapter 6 Using Enterprise JavaBeans Technology

This chapter describes how Enterprise JavaBeansTM (EJBTM) technology is supported in the Sun Java System Application Server. This chapter addresses the following topics:

- Summary of EJB 2.1 Changes

- Value Added Features

- EJB Timer Service

- Using Session Beans

- Using Read-Only Beans

- Using Message-Driven Beans

- Handling Transactions with Enterprise Beans

# Summary of EJB 2.1 Changes

The Application Server supports the Sun Microsystems Enterprise JavaBeans (EJB) architecture as defined by the Enterprise JavaBeans Specification, v2.1 and is compliant with the Enterprise JavaBeans Specification, v2.0.

Note –

The Application Server is backward compatible with 1.1 and 2.0 enterprise beans. However, to take advantage of version 2.1 features, you should develop new beans as 2.1 enterprise beans.

The changes in the Enterprise JavaBeans Specification, v2.1 that impact enterprise beans in the Application Server environment are as follows:

- EJB Timer Service: This is a container-managed, reliable, and transactional notification service that provides methods to allow callbacks to be scheduled for time-based events. See EJB Timer Service.

- Message-driven beans: This type of enterprise bean can consume any inbound messages from a Connector 1.5 inbound resource adapter, primarily but not exclusively JMS messages. See Using Message-Driven Beans.

- EJB Web Services: A stateless session bean can serve as a web service endpoint. In addition, all EJB component types can act as web service clients. For details, see the web service elements in the `sun-ejb-jar.xml` file, described in The sun-ejb-jar.xml File.

# Value Added Features

The Application Server provides a number of value additions that relate to EJB development. These capabilities are discussed in the following sections (references to more in-depth material are included):

- Read-Only Beans

- pass-by-reference

- Pooling and Caching

- Bean-Level Container-Managed Transaction Timeouts

- Priority Based Scheduling of Remote Bean Invocations

- Immediate Flushing

## Read-Only Beans

Another feature that the Application Server provides is the read-only bean, an entity bean that is never modified by an EJB client. Read-only beans avoid database updates completely. A read-only bean is not portable.

A read-only bean can be used to cache a database entry that is frequently accessed but rarely updated (externally by other beans). When the data that is cached by a read-only bean is updated by another bean, the read-only bean can be notified to refresh its cached data.

The Application Server provides a number of ways by which a read-only bean’s state can be refreshed. By setting the `refresh-period-in-seconds` element in the `sun-ejb-jar.xml` file and the `trans-attribute` element in the `ejb-jar.xml` file, it is easy to configure a read-only bean that is (a) always refreshed, (b) periodically refreshed, (c) never refreshed, or (d) programmatically refreshed.

Read-only beans are best suited for situations where the underlying data never changes, or changes infrequently. For further information and usage guidelines, see Using Read-Only Beans.

## pass-by-reference

The `pass-by-reference` element in the `sun-ejb-jar.xml` file allows you to specify the parameter passing semantics for colocated remote EJB invocations. This is an opportunity to improve performance. However, use of this feature results in non-portable applications. See pass-by-reference.

## Pooling and Caching

The EJB container of the Application Server pools anonymous instances (message-driven beans, stateless session beans, and entity beans) to reduce the overhead of creating and destroying objects. The EJB container maintains the free pool for each bean that is deployed. Bean instances in the free pool have no identity (that is, no primary key associated) and are used to serve the method calls of the home interface. The free beans are also used to serve all methods for stateless session beans.

Bean instances in the free pool transition from a Pooled state to a Cached state after `ejbCreate` and the business methods run. The size and behavior of each pool is controlled using pool-related properties in the EJB container or the `sun-ejb-jar.xml` file.

In addition, the Application Server supports a number of tunable parameters that can control the number of “stateful” instances (stateful session beans and entity beans) cached as well as the duration they are cached. Multiple bean instances that refer to the same database row in a table can be cached. The EJB container maintains a cache for each bean that is deployed.

To achieve scalability, the container selectively evicts some bean instances from the cache, usually when cache overflows. These evicted bean instances return to the free bean pool. The size and behavior of each cache can be controlled using the cache-related properties in the EJB container or the `sun-ejb-jar.xml` file.

Pooling and caching parameters for the `sun-ejb-jar.xml` file are described in bean-cache.

### Pooling Parameters

One of the most important parameters of Application Server pooling is `steady-pool-size`. When `steady-pool-size` is set to greater than 0, the container not only pre-populates the bean pool with the specified number of beans, but also attempts to ensure that there is always this many beans in the free pool. This ensures that there are enough beans in the ready to serve state to process user requests.

This parameter does not necessarily guarantee that no more than `steady-pool-size` instances exist at a given time. It only governs the number of instances that are pooled over a long period of time. For example, suppose an idle stateless session container has a fully-populated pool with a `steady-pool-size` of `10`. If 20 concurrent requests arrive for the EJB component, the container creates 10 additional instances to satisfy the burst of requests. The advantage of this is that it prevents the container from blocking any of the incoming requests. However, if the activity dies down to 10 or fewer concurrent requests, the additional 10 instances are discarded.

Another parameter, `pool-idle-timeout-in-seconds`, allows the administrator to specify, through the amount of time a bean instance can be idle in the pool. When `pool-idle-timeout-in-seconds` is set to greater than 0, the container removes or destroys any bean instance that is idle for this specified duration.

### Caching Parameters

Application Server provides a way that completely avoids caching of entity beans, using commit option C. Commit option C is particularly useful if beans are accessed in large number but very rarely reused. For additional information, refer to Commit Options.

The Application Server caches can be either bounded or unbounded. Bounded caches have limits on the number of beans that they can hold beyond which beans are passivated. For stateful session beans, there are three ways (LRU, NRU and FIFO) of picking victim beans when cache overflow occurs. Caches can also passivate beans that are idle (not accessed for a specified duration).

## Bean-Level Container-Managed Transaction Timeouts

The default transaction timeout for the domain is specified using the Transaction Timeout setting of the Transaction Service. A transaction started by the container must commit (or rollback) within this time, regardless of whether the transaction is suspended (and resumed), or the transaction is marked for rollback.

To override this timeout for an individual bean, use the optional `cmt-timeout-in-seconds` element in `sun-ejb-jar.xml`. The default value, `0`, specifies that the default Transaction Service timeout is used. The value of `cmt-timeout-in-seconds` is used for all methods in the bean that start a new container-managed transaction. This value is not used if the bean joins a client transaction.

## Priority Based Scheduling of Remote Bean Invocations

You can create multiple thread pools, each having its own work queues. An optional element in the `sun-ejb-jar.xml` file, `use-thread-pool-id`, specifies the thread pool that processes the requests for the bean. The bean must have a remote interface, or `use-thread-pool-id` is ignored. You can create different thread pools and specify the appropriate thread pool ID for a bean that requires a quick response time. If there is no such thread pool configured or if the element is absent, the default thread pool is used.

## Immediate Flushing

Normally, all entity bean updates within a transaction are batched and executed at the end of the transaction. The only exception is the database flush that precedes execution of a finder or select query.

Since a transaction often spans many method calls, you might want to find out if the updates made by a method succeeded or failed immediately after method execution. To force a flush at the end of a method’s execution, use the flush-at-end-of-method element in the `sun-ejb-jar.xml` file. Only non-finder methods in the Local, Local Home, Remote, and Remote Home interfaces of an entity bean can be flush-enabled.

Upon completion of the method, the EJB container updates the database. Any exception thrown by the underlying data store is wrapped as follows:

- If the method that triggered the flush is a `create` method, the exception is wrapped with `CreateException`.

- If the method that triggered the flush is a `remove` method, the exception is wrapped with `RemoveException`.

- For all other methods, the exception is wrapped with `EJBException`.

All normal end-of-transaction database synchronization steps occur regardless of whether the database has been flushed during the transaction.

# EJB Timer Service

The EJB Timer Service uses a database to store persistent information about EJB timers. The EJB Timer Service configuration can store persistent timer information in any database supported by the Application Server CMP container.

For a list of the JDBC drivers currently supported by the Application Server, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Release Notes. For configurations of supported and other drivers, see Configurations for Specific JDBC Drivers.

To change the database used by the EJB Timer Service, set the EJB Timer Service’s Timer DataSource setting to a valid JDBC resource. You must also create the timer database table. DDL files are located in install-dir`/lib/install/databases`. Ideally, each cluster should have its own timer table.

Using the EJB Timer Service is equivalent to interacting with a single JDBC resource manager. If an EJB component or application accesses a database either directly through JDBC or indirectly (for example, through an entity bean’s persistence mechanism), and also interacts with the EJB Timer Service, its data source must be configured with an XA JDBC driver.

You can change the following EJB Timer Service settings. You must restart the server for the changes to take effect.

- Minimum Delivery Interval - Specifies the minimum time in milliseconds before an expiration for a particular timer can occur. This guards against extremely small timer increments that can overload the server. The default is `7000`.

- Maximum Redeliveries - Specifies the maximum number of times the EJB timer service attempts to redeliver a timer expiration due for exception or rollback. The default is 1.

- Redelivery Interval - Specifies how long in milliseconds the EJB timer service waits after a failed `ejbTimeout` delivery before attempting a redelivery. The default is `5000`.

- Timer DataSource - Specifies the database used by the EJB Timer Service.

For information about configuring EJB Timer Service settings, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Guide. For information about the `asadmin list-timers` and `asadmin migrate-timers` commands, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

# Using Session Beans

This section provides guidelines for creating session beans in the Application Server environment. This section addresses the following topics:

- About the Session Bean Containers

- Stateful Session Bean Failover

- Restrictions and Optimizations

Extensive information on session beans is contained in the chapters 6, 7, and 8 of the Enterprise JavaBeans Specification, v2.1.

## About the Session Bean Containers

Like an entity bean, a session bean can access a database through JavaTM Database Connectivity (JDBCTM) calls. A session bean can also provide transaction settings. These transaction settings and JDBC calls are referenced by the session bean’s container, allowing it to participate in transactions managed by the container.

A container managing stateless session beans has a different charter from a container managing stateful session beans.

### Stateless Container

The stateless container manages stateless session beans, which, by definition, do not carry client-specific states. All session beans (of a particular type) are considered equal.

A stateless session bean container uses a bean pool to service requests. The Application Server specific deployment descriptor file, `sun-ejb-jar.xml`, contains the properties that define the pool:

- `steady-pool-size`

- `resize-quantity`

- `max-pool-size`

- `pool-idle-timeout-in-seconds`

For more information about `sun-ejb-jar.xml`, see The sun-ejb-jar.xml File.

The Application Server provides the `wscompile` and `wsdeploy` tools to help you implement a web service endpoint as a stateless session bean. For more information about these tools, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

### Stateful Container

The stateful container manages the stateful session beans, which, by definition, carry the client-specific state. There is a one-to-one relationship between the client and the stateful session beans. At creation, each stateful session bean (SFSB) is given a unique session ID that is used to access the session bean so that an instance of a stateful session bean is accessed by a single client only.

Stateful session beans are managed using cache. The size and behavior of stateful session beans cache are controlled by specifying the following `sun-ejb-jar.xml` parameters:

- `max-cache-size`

- `resize-quantity`

- `cache-idle-timeout-in-seconds`

- `removal-timeout-in-seconds`

- `victim-selection-policy`

The `max-cache-size` element specifies the maximum number of session beans that are held in cache. If the cache overflows (when the number of beans exceeds `max-cache-size`), the container then passivates some beans or writes out the serialized state of the bean into a file. The directory in which the file is created is obtained from the EJB container using the configuration APIs.

For more information about `sun-ejb-jar.xml`, see The sun-ejb-jar.xml File.

The passivated beans are stored on the file system. The Session Store Location setting in the EJB container allows the administrator to specify the directory where passivated beans are stored. By default, passivated stateful session beans are stored in application-specific subdirectories created under domain-dir`/session-store`.

Note –

Make sure the `delete` option is set in the `server.policy` file, or expired file-based sessions might not be deleted properly. For more information about `server.policy`, see The server.policy File.

The Session Store Location setting also determines where the session state is persisted if it is not highly available; see Choosing a Persistence Store.

## Stateful Session Bean Failover

An SFSB’s state can be saved in a persistent store in case a server instance fails. The state of an SFSB is saved to the persistent store at predefined points in its life cycle. This is called checkpointing. If SFSB checkpointing is enabled, checkpointing generally occurs after any transaction involving the SFSB is completed, even if the transaction rolls back.

However, if an SFSB participates in a bean-managed transaction, the transaction might be committed in the middle of the execution of a bean method. Since the bean’s state might be undergoing transition as a result of the method invocation, this is not an appropriate instant to checkpoint the bean’s state. In this case, the EJB container checkpoints the bean’s state at the end of the corresponding method, provided the bean is not in the scope of another transaction when that method ends. If a bean-managed transaction spans across multiple methods, checkpointing is delayed until there is no active transaction at the end of a subsequent method.

The state of an SFSB is not necessarily transactional and might be significantly modified as a result of non-transactional business methods. If this is the case for an SFSB, you can specify a list of checkpointed methods. If SFSB checkpointing is enabled, checkpointing occurs after any checkpointed methods are completed.

The following sample application demonstrates SFSB session persistence:

    install-dir/samples/ee-samples/failover/apps/sfsbfailover

The following table lists the types of references that SFSB failover supports. All objects bound into an SFSB must be one of the supported types. In the table, No indicates that failover for the object type might not work in all cases and that no failover support is provided. However, failover might work in some cases for that object type. For example, failover might work because the class implementing that type is serializable.

Table 6–1 Object Types Supported for J2EE Stateful Session Bean State Failover

Java Object Type | Failover Support
--- | ---
Stateless session, stateful session, and entity bean local home reference, local object reference | Yes
Colocated and distributed stateless session, stateful session, and entity bean remote home reference, remote reference | Yes
JNDI Context | Yes, `InitialContext` and `java:comp/env`
UserTransaction | Yes, but if the instance that fails is never restarted, any prepared global transactions are lost and might not be correctly rolled back or committed
JDBC DataSource | No
Java Message Service (JMS) ConnectionFactory, Destination | No
JavaMailTM Session | No
Connection Factory | No
Administered Object | No
Web service reference | No
Serializable Java types | Yes

For more information about the `InitialContext`, see Accessing the Naming Context. For more information about transaction recovery, see Chapter 12, Using the Transaction Service. For more information about Administered Objects, see Creating Physical Destinations.

Note –

Idempotent URLs are supported along the HTTP path, but not the RMI-IIOP path. For more information, see Configuring Idempotent URL Requests and the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Guide.

If a server instance to which an RMI-IIOP client request is sent crashes during the request processing (before the response is prepared and sent back to the client), an error is sent to the client. The client must retry the request explicitly. When the client retries the request, the request is sent to another server instance in the cluster, which retrieves session state information for this client.

HTTP sessions can also be saved in a persistent store in case a server instance fails. In addition, if a distributable web application references an SFSB, and the web application’s session fails over, the EJB reference is also failed over. For more information, see Distributed Sessions and Persistence.

If an SFSB that uses session persistence is undeployed while the Application Server instance is stopped, the session data in the persistence store might not be cleared. To prevent this, undeploy the SFSB while the Application Server instance is running.

Configure SFSB failover by:

- Choosing a Persistence Store

- Enabling Checkpointing

- Specifying Methods to Be Checkpointed (optional)

### Choosing a Persistence Store

Two types of persistent storage are supported for passivation and checkpointing of the SFSB state:

- The local file system - Allows a single server instance to recover the SFSB state after a failure and restart. This store also provides passivation and activation of the state to help control the amount of memory used. This option is not supported in a production environment that requires SFSB state persistence. This is the default storage mechanism.

- The high-availability database (HADB) - Allows a cluster of server instances to recover the SFSB state if any server instance fails. The HADB is also used as the passivation and activation store. Use this option in a production environment that requires SFSB state persistence. For information about how to set up and configure this database, see the description of the `configure-ha-cluster` command in the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

Choose the persistence store in one of the following ways:

- To use the local file system, first disable availability. Select the Availability Service component under the relevant configuration in the Administration Console. Uncheck the Instance Level Availability box. Then select the EJB Container component and edit the Session Store Location value. The default is domain-dir`/session-store`.

- To use the HADB, select the Availability Service component under the relevant configuration in the Administration Console. Check the Instance Level Availability box. To enable availability for the EJB container, select the EJB Container Availability tab, then check the Availability Service box.

For more information, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 High Availability Administration Guide.

### Enabling Checkpointing

The following sections describe how to enable SFSB checkpointing:

- Server Instance and EJB Container Levels

- Application and EJB Module Levels

- SFSB Level

#### Server Instance and EJB Container Levels

To enable SFSB checkpointing at the server instance or EJB container level, see Choosing a Persistence Store.

#### Application and EJB Module Levels

To enable SFSB checkpointing at the application or EJB module level during deployment, use the `asadmin deploy` or `asadmin deploydir` command with the `--availabilityenabled` option set to `true`. For details, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

#### SFSB Level

To enable SFSB checkpointing at the SFSB level, set `availability-enabled="true"` in the `ejb` element of the SFSB’s `sun-ejb-jar.xml` file as follows:

    <sun-ejb-jar>
       ...
       <enterprise-beans>
          ...
          <ejb availability-enabled="true">
             <ejb-name>MySFSB</ejb-name>
          </ejb>
       ...
       </enterprise-beans>
    </sun-ejb-jar>

### Specifying Methods to Be Checkpointed

If SFSB checkpointing is enabled, checkpointing generally occurs after any transaction involving the SFSB is completed, even if the transaction rolls back.

To specify additional optional checkpointing of SFSBs at the end of non-transactional business methods that cause important modifications to the bean’s state, use the checkpoint-at-end-of-method element within the `ejb` element in `sun-ejb-jar.xml`.

For example:

    <sun-ejb-jar>
       ...
       <enterprise-beans>
          ...
          <ejb availability-enabled="true">
             <ejb-name>ShoppingCartEJB</ejb-name>
             <checkpoint-at-end-of-method>
                <method>
                   <method-name>addToCart</method-name>
                </method>
             </checkpoint-at-end-of-method>
          </ejb>
          ...
       </enterprise-beans>
    </sun-ejb-jar>

The non-transactional methods in the `checkpoint-at-end-of-method` element can be:

- `create()` methods defined in the home interface of the SFSB, if you want to checkpoint the initial state of the SFSB immediately after creation

- For SFSBs using container managed transactions only, methods in the remote interface of the bean marked with the transaction attribute TX_NOT_SUPPORTED or TX_NEVER

- For SFSBs using bean managed transactions only, methods in which a bean managed transaction is neither started nor committed

Any other methods mentioned in this list are ignored. At the end of invocation of each of these methods, the EJB container saves the state of the SFSB to persistent store.

Note –

If an SFSB does not participate in any transaction, and if none of its methods are explicitly specified in the `checkpoint-at-end-of-method` element, the bean’s state is not checkpointed at all even if `availability-enabled="true"` for this bean.

For better performance, specify a small subset of methods. The methods chosen should accomplish a significant amount of work in the context of the J2EE application or should result in some important modification to the bean’s state.

## Restrictions and Optimizations

This section discusses restrictions on developing session beans and provides some optimization guidelines:

- Optimizing Session Bean Performance

- Restricting Transactions

### Optimizing Session Bean Performance

For stateful session beans, colocating the stateful beans with their clients so that the client and bean are executing in the same process address space improves performance.

### Restricting Transactions

The following restrictions on transactions are enforced by the container and must be observed as session beans are developed:

- A session bean can participate in, at most, a single transaction at a time.

- If a session bean is participating in a transaction, a client cannot invoke a method on the bean such that the `trans-attribute` element in the `ejb-jar.xml` file would cause the container to execute the method in a different or unspecified transaction context or an exception is thrown.

- If a session bean instance is participating in a transaction, a client cannot invoke the `remove` method on the session object’s home or component interface object or an exception is thrown.

# Using Read-Only Beans

A read-only bean is an entity bean that is never modified by an EJB client. The data that a read-only bean represents can be updated externally by other enterprise beans, or by other means, such as direct database updates.

Note –

Read-only beans are specific to Application Server and are not part of the Enterprise JavaBeans Specification, v2.1. Use of this feature results in a non-portable application.

Read-only beans are best suited for situations where the underlying data never changes, or changes infrequently. The following topics are addressed in this section:

- Read-Only Bean Characteristics and Life Cycle

- Read-Only Bean Good Practices

- Refreshing Read-Only Beans

- Deploying Read Only Beans

## Read-Only Bean Characteristics and Life Cycle

Read-only beans are best suited for situations where the underlying data never changes, or changes infrequently. For example, a read-only bean can be used to represent a stock quote for a particular company, which is updated externally. In such a case, using a regular entity bean might incur the burden of calling `ejbStore`, which can be avoided by using a read-only bean.

Read-only beans have the following characteristics:

- Only entity beans can be read-only beans.

- Either bean-managed persistence (BMP) or container-managed persistence (CMP) is allowed. If CMP is used, do not create the database schema during deployment. Instead, work with your database administrator to populate the data into the tables. See Chapter 7, Using Container-Managed Persistence for Entity Beans.

- Only container-managed transactions are allowed; read-only beans cannot start their own transactions.

- Read-only beans don’t update any bean state.

- `ejbStore` is never called by the container.

- `ejbLoad` is called only when a transactional method is called or when the bean is initially created (in the cache), or at regular intervals controlled by the bean’s `refresh-period-in-seconds` element in the `sun-ejb-jar.xml` file.

- The home interface can have any number of find methods. The return type of the find methods must be the primary key for the same bean type (or a collection of primary keys).

- If the data that the bean represents can change, then `refresh-period-in-seconds` must be set to refresh the beans at regular intervals. `ejbLoad` is called at this regular interval.

A read-only bean comes into existence using the appropriate find methods.

Read-only beans are cached and have the same cache properties as entity beans. When a read-only bean is selected as a victim to make room in the cache, `ejbPassivate` is called and the bean is returned to the free pool. When in the free pool, the bean has no identity and is used only to serve any finder requests.

Read-only beans are bound to the naming service like regular read-write entity beans, and clients can look up read-only beans the same way read-write entity beans are looked up.

## Read-Only Bean Good Practices

For best results, follow these guidelines when developing read-only beans:

- Avoid having any `create` or `remove` methods in the home interface.

- Use any of the valid EJB 2.1 transaction attributes for the `trans-attribute` element.

  The reason for having `TX_SUPPORTED` is to allow reading uncommitted data in the same transaction. Also, the transaction attributes can be used to force `ejbLoad`.

## Refreshing Read-Only Beans

There are several ways of refreshing read-only beans as addressed in the following sections:

- Invoking a Transactional Method

- Refreshing Periodically

- Refreshing Programmatically

### Invoking a Transactional Method

Invoking any transactional method invokes `ejbLoad`.

### Refreshing Periodically

Use the `refresh-period-in-seconds` element in the `sun-ejb-jar.xml` file to refresh a read-only bean periodically.

- If the value specified in `refresh-period-in-seconds` is zero or not specified, which is the default, the bean is never refreshed (unless a transactional method is accessed).

- If the value is greater than zero, the bean is refreshed at the rate specified.

Note –

This is the only way to refresh the bean state if the data can be modified external to the Application Server.

### Refreshing Programmatically

Typically, beans that update any data that is cached by read-only beans need to notify the read-only beans to refresh their state. Use `ReadOnlyBeanNotifier` to force the refresh of read-only beans.

To do this, invoke the following methods on the `ReadOnlyBeanNotifier` bean:

    public interface ReadOnlyBeanNotifier extends java.rmi.Remote {
       refresh(Object PrimaryKey) throws RemoteException;
     }

The implementation of the `ReadOnlyBeanNotifier` interface is provided by the container. The bean looks up `ReadOnlyBeanNotifier` using a fragment of code such as the following example:

    com.sun.appserv.ejb.ReadOnlyBeanHelper helper =
      new com.sun.appserv.ejb.ReadOnlyBeanHelper();
    com.sun.appserv.ejb.ReadOnlyBeanNotifier notifier =
      helper.getReadOnlyBeanNotifier("java:comp/env/ejb/ReadOnlyCustomer");
    notifier.refresh(PrimaryKey);

For a local read-only bean notifier, the lookup has this modification:

    helper.getReadOnlyBeanLocalNotifier("java:comp/env/ejb/LocalReadOnlyCustomer");

Beans that update any data that is cached by read-only beans need to call the `refresh` methods. The next (non-transactional) call to the read-only bean invokes `ejbLoad`.

Note –

Programmatic refresh of read-only beans is not supported in a clustered environment.

## Deploying Read Only Beans

Read-only beans are deployed in the same manner as other entity beans. However, in the entry for the bean in the `sun-ejb-jar.xml` file, the `is-read-only-bean` element must be set to true. That is:

`<is-read-only-bean>true</is-read-only-bean>`

Also, the `refresh-period-in-seconds` element in the `sun-ejb-jar.xml` file can be set to some value that specifies the rate at which the bean is refreshed. If this element is missing, no refresh occurs.

All requests in the same transaction context are routed to the same read-only bean instance. Set the `allow-concurrent-access` element to either `true` (to allow concurrent accesses) or `false` (to serialize concurrent access to the same read-only bean). The default is `false`.

For further information on these elements, refer to The sun-ejb-jar.xml File.

# Using Message-Driven Beans

This section describes message-driven beans and explains the requirements for creating them in the Application Server environment. This section contains the following topics:

- Message-Driven Bean Configuration

- Restrictions and Optimizations

- Sample Message-Driven Bean XML Files

## Message-Driven Bean Configuration

This section addresses the following configuration topics:

- Using Session Beans

- Message-Driven Bean Pool

- Domain-Level Settings

For information about setting up load balancing for message-driven beans, see Load-Balanced Message Inflow.

### Connection Factory and Destination

A message-driven bean is a client to a Connector 1.5 inbound resource adapter. The message-driven bean container uses the JMS service integrated into the Application Server for message-driven beans that are JMS clients. JMS clients use JMS Connection Factory- and Destination-administered objects. A JMS Connection Factory administered object is a resource manager Connection Factory object that is used to create connections to the JMS provider.

The `mdb-connection-factory` element in the `sun-ejb-jar.xml`file for a message-driven bean specifies the connection factory that creates the container connection to the JMS provider.

The `jndi-name` element of the `ejb` element in the `sun-ejb-jar.xml` file specifies the JNDI name of the administered object for the JMS `Queue` or `Topic` destination that is associated with the message-driven bean.

### Message-Driven Bean Pool

The container manages a pool of message-driven beans for the concurrent processing of a stream of messages. The `sun-ejb-jar.xml` file contains the elements that define the pool (that is, the `bean-pool` element):

- `steady-pool-size`

- `resize-quantity`

- `max-pool-size`

- `pool-idle-timeout-in-seconds`

For more information about `sun-ejb-jar.xml`, see The sun-ejb-jar.xml File.

### Domain-Level Settings

You can control the following domain-level message-driven bean settings in the EJB container:

- Initial and Minimum Pool Size - Specifies the initial and minimum number of beans maintained in the pool. The default is `0`.

- Maximum Pool Size - Specifies the maximum number of beans that can be created to satisfy client requests. The default is 3`2`.

- Pool Resize Quantity - Specifies the number of beans to be created if a request arrives when the pool is empty (subject to the Initial and Minimum Pool Size), or the number of beans to remove if idle for more than the Idle Timeout. The default is `8`.

- Idle Timeout - Specifies the maximum time in seconds that a bean can remain idle in the pool. After this amount of time, the bean is destroyed. The default is `600` (10 minutes). A value of `0` means a bean can remain idle indefinitely.

For information on monitoring message-driven beans, see the Application Server Administration Console online help and the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Guide.

Note –

Running monitoring when it is not needed might impact performance, so you might choose to turn monitoring off when it is not in use. For details, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Guide.

## Restrictions and Optimizations

This section discusses the following restrictions and performance optimizations that pertain to developing message-driven beans:

- Pool Tuning and Monitoring

- onMessage Runtime Exception

### Pool Tuning and Monitoring

The message-driven bean pool is also a pool of threads, with each message-driven bean instance in the pool associating with a server session, and each server session associating with a thread. Therefore, a large pool size also means a high number of threads, which impacts performance and server resources.

When configuring message-driven bean pool properties, make sure to consider factors such as message arrival rate and pattern, `onMessage` method processing time, overall server resources (threads, memory, and so on), and any concurrency requirements and limitations from other resources that the message-driven bean accesses.

When tuning performance and resource usage, make sure to consider potential JMS provider properties for the connection factory used by the container (the `mdb-connection-factory` element in the `sun-ejb-jar.xml` file). For example, you can tune the Sun Java System Message Queue flow control related properties for connection factory in situations where the message incoming rate is much higher than `max-pool-size` can handle.

Refer to the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Guide for information on how to get message-driven bean pool statistics.

### onMessage Runtime Exception

Message-driven beans, like other well-behaved MessageListeners, should not, in general, throw runtime exceptions. If a message-driven bean’s `onMessage` method encounters a system-level exception or error that does not allow the method to successfully complete, the Enterprise JavaBeans Specification, v2.1 provides the following guidelines:

- If the bean method encounters a runtime exception or error, it should simply propagate the error from the bean method to the container.

- If the bean method performs an operation that results in a checked exception that the bean method cannot recover, the bean method should throw the `javax.ejb.EJBException` that wraps the original exception.

- Any other unexpected error conditions should be reported using `javax.ejb.EJBException` (`javax.ejb.EJBException` is a subclass of `java.lang.RuntimeException`).

Under container-managed transaction demarcation, upon receiving a runtime exception from a message-driven bean’s `onMessage` method, the container rolls back the container-started transaction and the message is redelivered. This is because the message delivery itself is part of the container-started transaction. By default, the Application Server container closes the container’s connection to the JMS provider when the first runtime exception is received from a message-driven bean instance’s `onMessage` method. This avoids potential message redelivery looping and protects server resources if the message-driven bean’s `onMessage` method continues misbehaving. To change this default container behavior, use the `cmt-max-runtime-exceptions` property of the `mdb-container` element in the `domain.xml` file.

The `cmt-max-runtime-exceptions` property specifies the maximum number of runtime exceptions allowed from a message-driven bean’s `onMessage` method before the container starts to close the container’s connection to the message source. By default this value is 1; -1 disables this container protection.

A message-driven bean’s `onMessage` method can use the `javax.jms.Message` `getJMSRedelivered` method to check whether a received message is a redelivered message.

Note –

The `cmt-max-runtime-exceptions` property might be deprecated in the future.

## Sample Message-Driven Bean XML Files

This section includes the following sample files:

- Sample ejb-jar.xml File

- Sample sun-ejb-jar.xml File

For general information on the `sun-ejb-jar.xml` file, see The sun-ejb-jar.xml File.

### 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>
    <enterprise-beans>
    	<message-driven>
    		<ejb-name>MessageBean</ejb-name>
    		<ejb-class>samples.mdb.ejb.MessageBean</ejb-class>
    		<transaction-type>Container</transaction-type>
    		<message-driven-destination>
    			<destination-type>javax.jms.Queue</destination-type>
    		</message-driven-destination>
    		<resource-ref>
    			<res-ref-name>jms/QueueConnectionFactory</res-ref-name>
    			<res-type>javax.jms.QueueConnectionFactory</res-type>
    			<res-auth>Container</res-auth>
    		</resource-ref>
    	</message-driven>
    </enterprise-beans>
    	<assembly-descriptor>
    		<container-transaction>
    			<method>
    				<ejb-name>MessageBean</ejb-name>
    				<method-intf>Bean</method-intf>
    				<method-name>onMessage</method-name>
    				<method-params>
    					<method-param>javax.jms.Message</method-param>
    				</method-params>
    			</method>
    		<trans-attribute>NotSupported</trans-attribute>
    	</container-transaction>
    </assembly-descriptor
    </ejb-jar>

### Sample sun-ejb-jar.xml File

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE sun-ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Application
    Server 8.1 EJB 2.1//EN'
    'http://www.sun.com/software/appserver/dtds/sun-ejb-jar_2_1-1.dtd'>
    <sun-ejb-jar>
    <enterprise-beans>
    	<ejb>
    		<ejb-name>MessageBean</ejb-name>
    		<jndi-name>jms/sample/Queue</jndi-name>
    		<resource-ref>
    			<res-ref-name>jms/QueueConnectionFactory</res-ref-name>
    			<jndi-name>jms/sample/QueueConnectionFactory</jndi-name>
    			<default-resource-principal>
    				<name>guest</name>
    				<password>guest</password>
    			</default-resource-principal>
    		</resource-ref>
    		<mdb-connection-factory>
    			<jndi-name>jms/sample/QueueConnectionFactory</jndi-name>
    			<default-resource-principal>
    				<name>guest</name>
    				<password>guest</password>
    			</default-resource-principal>
    		</mdb-connection-factory>
    	</ejb>
    </enterprise-beans>
    </sun-ejb-jar>

# Handling Transactions with Enterprise Beans

This section describes the transaction support built into the Enterprise JavaBeans programming model for the Application Server.

As a developer, you can write an application that updates data in multiple databases distributed across multiple sites. The site might use EJB servers from different vendors. This section provides overview information on the following topics:

- Flat Transactions

- Global and Local Transactions

- Commit Options

- Administration and Monitoring

## Flat Transactions

The Enterprise JavaBeans Specification, v2.1 requires support for flat (as opposed to nested) transactions. In a flat transaction, each transaction is decoupled from and independent of other transactions in the system. Another transaction cannot start in the same thread until the current transaction ends.

Flat transactions are the most prevalent model and are supported by most commercial database systems. Although nested transactions offer a finer granularity of control over transactions, they are supported by far fewer commercial database systems.

## Global and Local Transactions

Understanding the distinction between global and local transactions is crucial in understanding the Application Server support for transactions. See Transaction Scope.

Both local and global transactions are demarcated using the `javax.transaction.UserTransaction` interface, which the client must use. Local transactions bypass the transaction manager and are faster. For more information, see Naming Environment for J2EE Application Components.

## Commit Options

The EJB protocol is designed to give the container the flexibility to select the disposition of the instance state at the time a transaction is committed. This allows the container to best manage caching an entity object’s state and associating an entity object identity with the EJB instances.

There are three commit-time options:

- Option A: The container caches a ready instance between transactions. The container ensures that the instance has exclusive access to the state of the object in persistent storage.

  In this case, the container does not have to synchronize the instance’s state from the persistent storage at the beginning of the next transaction.

  Note –

  Commit option A is not supported for this Application Server release.

- Option B: The container caches a ready instance between transactions, but the container does not ensure that the instance has exclusive access to the state of the object in persistent storage. This is the default.

  In this case, the container must synchronize the instance’s state by invoking `ejbLoad` from persistent storage at the beginning of the next transaction.

- Option C: The container does not cache a ready instance between transactions, but instead returns the instance to the pool of available instances after a transaction has completed.

  The life cycle for every business method invocation under commit option C looks like this:

      ejbActivate -> ejbLoad -> business method -> ejbStore -> ejbPassivate

  If there is more than one transactional client concurrently accessing the same entity `EJBObject`, the first client gets the ready instance and subsequent concurrent clients get new instances from the pool.

The Application Server deployment descriptor has an element, `commit-option`, that specifies the commit option to be used. Based on the specified commit option, the appropriate handler is instantiated.

## Administration and Monitoring

An administrator can control a number of domain-level Transaction Service settings. For details, see Configuring the Transaction Service.

The Transaction Timeout setting can be overridden by a bean. See Bean-Level Container-Managed Transaction Timeouts.

In addition, the administrator can monitor transactions using statistics from the transaction manager that provide information on such activities as the number of transactions completed, rolled back, or recovered since server startup, and transactions presently being processed.

For information on administering and monitoring transactions, see the Application Server Administration Console online help and the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Guide.

# Chapter 7 Using Container-Managed Persistence for Entity Beans

This section contains information on how container-managed persistence (CMP) works in the Sun Java System Application Server in the following topics:

- Sun Java System Application Server Support

- Container-Managed Persistence Mapping

- Automatic Schema Generation

- Schema Capture

- Configuring the CMP Resource

- Configuring Queries for 1.1 Finders

- Performance-Related Features

- Restrictions and Optimizations

Extensive information on CMP is contained in chapters 10, 11, and 14 of the Enterprise JavaBeans Specification, v2.1.

# Sun Java System Application Server Support

Application Server support for CMP includes:

- Full support for the J2EE v 1.4 specification’s CMP model.

  - Support for commit options B and C for transactions, as defined in the Enterprise JavaBeans Specification, v2.1. See Commit Options.

  - The primary key class must be a subclass of `java.lang.Object`. This ensures portability, and is noted because some vendors allow primitive types (such as `int`) to be used as the primary key class.

- The Application Server CMP implementation, which provides:

  - An Object/Relational (O/R) mapping tool that creates XML deployment descriptors for EJB JAR files that contain beans that use CMP

  - Support for compound (multi-column) primary keys

  - Support for sophisticated custom finder methods

  - Standards-based query language (EJB QL)

  - CMP runtime support. See Configuring the CMP Resource.

- Application Server performance-related features, including:

  - Version column consistency checking

  - Relationship prefetching

  - Read-Only Beans

  For details, see Performance-Related Features.

# Container-Managed Persistence Mapping

Implementation for entity beans that use CMP is mostly a matter of mapping CMP fields and CMR fields (relationships) to the database. This section addresses the following topics:

- Mapping Capabilities

- The Mapping Deployment Descriptor File

- Mapping Considerations

## Mapping Capabilities

Mapping refers to the ability to tie an object-based model to a relational model of data, usually the schema of a relational database. The CMP implementation provides the ability to tie a set of interrelated beans containing data and associated behaviors to the schema. This object representation of the database becomes part of the Java application. You can also customize this mapping to optimize these beans for the particular needs of an application. The result is a single data model through which both persistent database information and regular transient program data are accessed.

The mapping capabilities provided by the Application Server include:

- Mapping a CMP bean to one or more tables

- Mapping CMP fields to one or more columns

- Mapping CMP fields to different column types

- Mapping tables with compound primary keys

- Mapping tables with unknown primary keys

- Mapping CMP relationships to foreign keys

- Mapping tables with overlapping primary and foreign keys

## The Mapping Deployment Descriptor File

Each module with CMP beans must have the following files:

- `ejb-jar.xml`: The J2EE standard file for assembling enterprise beans. For a detailed description, see the Enterprise JavaBeans Specification, v2.1.

- `sun-ejb-jar.xml`: The Application Server standard file for assembling enterprise beans. For a detailed description, see The sun-ejb-jar.xml File.

- `sun-cmp-mappings.xml`: The mapping deployment descriptor file, which describes the mapping of CMP beans to tables in a database. For a detailed description, see The sun-cmp-mappings.xml File.

The `sun-cmp-mappings.xml` file can be automatically generated and does not have to exist prior to deployment. For details, see Generation Options.

The `sun-cmp-mappings.xml` file maps CMP fields and CMR fields (relationships) to the database. A primary table must be selected for each CMP bean, and optionally, multiple secondary tables. CMP fields are mapped to columns in either the primary or secondary table(s). CMR fields are mapped to pairs of column lists (normally, column lists are the lists of columns associated with primary and foreign keys).

Note –

Table names in databases can be case-sensitive. Make sure that the table names in the `sun-cmp-mappings.xml` file match the names in the database.

Relationships should always be mapped to the primary key field(s) of the related table.

The `sun-cmp-mappings.xml` file conforms to the `sun-cmp-mapping_1_2.dtd` file and is packaged with the user-defined bean classes in the EJB JAR file under the `META-INF` directory.

The Application Server or the deploytool creates the mappings in the `sun-cmp-mappings.xml` file automatically during deployment if the file is not present. For information on how to use the deploytool for mapping, see the “Create Database Mapping” topic in the deploytool’s online help.

To map the fields and relationships of your entity beans manually, edit the `sun-cmp-mappings.xml` deployment descriptor. Only do this if you are proficient in editing XML.

The mapping information is developed in conjunction with the database schema (`.dbschema`) file, which can be automatically captured when you deploy the bean (see Automatic Database Schema Capture). You can manually generate the schema using the `capture-schema` utility (Using the capture-schema Utility.

## Mapping Considerations

This section addresses the following topics:

- Join Tables and Relationships

- Automatic Primary Key Generation

- Fixed Length CHAR Primary Keys

- Managed Fields

- BLOB Support

- CLOB Support

The data types used in automatic schema generation are also suggested for manual mapping. These data types are described in Supported Data Types.

### Join Tables and Relationships

Use of join tables in the database schema is supported for all types of relationships, not just many-to-many relationships. For general information about relationships, see section 10.3.7 of the Enterprise JavaBeans Specification, v2.1.

### Automatic Primary Key Generation

The Application Server supports automatic primary key generation for EJB 1.1, 2.0, and 2.1 CMP beans. To specify automatic primary key generation, give the `prim-key-class` element in the `ejb-jar-xml` file the value `java.lang.Object`. CMP beans with automatically generated primary keys can participate in relationships with other CMP beans. The Application Server does not support database-generated primary key values.

If the database schema is created during deployment, the Application Server creates the schema with the primary key column, then generates unique values for the primary key column at runtime.

If the database schema is not created during deployment, the primary key column in the mapped table must be of type `NUMERIC` with a precision of 19 or more, and must not be mapped to any CMP field. The Application Server generates unique values for the primary key column at runtime.

### Fixed Length CHAR Primary Keys

If an existing database table has a primary key column in which the values vary in length, but the type is `CHAR` instead of `VARCHAR`, the Application Server automatically trims any extra spaces when retrieving primary key values. It is not a good practice to use a fixed length `CHAR` column as a primary key. Use this feature with schemas that cannot be changed, such as a schema inherited from a legacy application.

### Managed Fields

A managed field is a CMP or CMR field that is mapped to the same database column as another CMP or CMR field. CMP fields mapped to the same column and CMR fields mapped to exactly the same column lists always have the same value in memory. For CMR fields that share only a subset of their mapped columns, changes to the columns affect the relationship fields in memory differently. Basically, the Application Server always tries to keep the state of the objects in memory synchronized with the database.

A managed field can have any fetched-with subelement except `<default/>`.

### BLOB Support

Binary Large Object (BLOB) is a data type used to store values that do not correspond to other types such as numbers, strings, or dates. Java fields whose types implement `java.io.Serializable` or are represented as `byte[]` can be stored as BLOBs.

If a CMP field is defined as `Serializable`, it is serialized into a `byte[]` before being stored in the database. Similarly, the value fetched from the database is deserialized. However, if a CMP field is defined as `byte[]`, it is stored directly instead of being serialized and deserialized when stored and fetched, respectively.

To enable BLOB support in the Application Server environment, define a CMP field of type `byte[]` or a user-defined type that implements the `java.io.Serializable` interface. If you map the CMP bean to an existing database schema, map the field to a column of type BLOB.

To use BLOB or CLOB data types larger than 4 KB for CMP using the Inet Oraxo JDBC Driver for Oracle 8.1.7 and 9.x Databases, you must set the `streamstolob` property value to `true`.

For a list of the JDBC drivers currently supported by the Application Server, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Release Notes. For configurations of supported and other drivers, see Configurations for Specific JDBC Drivers.

For automatic mapping, you might need to change the default BLOB column length for the generated schema using the `schema-generator-properties` element in `sun-ejb-jar.xml`. See your database vendor documentation to determine whether you need to specify the length. For example:

    <schema-generator-properties>
       <property>
          <name>Employee.voiceGreeting.jdbc-type</name>
          <value>BLOB</value>
       </property>
       <property>
          <name>Employee.voiceGreeting.jdbc-maximum-length</name>
          <value>10240</value>
       </property>
       ...
    </schema-generator-properties>

### CLOB Support

Character Large Object (CLOB) is a data type used to store and retrieve very long text fields. CLOBs translate into long strings.

To enable CLOB support in the Application Server environment, define a CMP field of type `java.lang.String`. If you map the CMP bean to an existing database schema, map the field to a column of type CLOB.

To use BLOB or CLOB data types larger than 4 KB for CMP using the Inet Oraxo JDBC Driver for Oracle 8.1.7 and 9.x Databases, you must set the `streamstolob` property value to `true`.

For a list of the JDBC drivers currently supported by the Application Server, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Release Notes. For configurations of supported and other drivers, see Configurations for Specific JDBC Drivers.

For automatic mapping, you might need to change the default CLOB column length for the generated schema using the `schema-generator-properties` element in `sun-ejb-jar.xml`. See your database vendor documentation to determine whether you need to specify the length. For example:

    <schema-generator-properties>
       <property>
          <name>Employee.resume.jdbc-type</name>
          <value>CLOB</value>
       </property>
       <property>
          <name>Employee.resume.jdbc-maximum-length</name>
          <value>10240</value>
       </property>
       ...
    </schema-generator-properties>

# Automatic Schema Generation

The automatic schema generation feature provided in the Application Server defines database tables based on the fields in entity beans and the relationships between the fields. This insulates developers from many of the database related aspects of development, allowing them to focus on entity bean development. The resulting schema is usable as-is or can be given to a database administrator for tuning with respect to performance, security, and so on.

This section addresses the following topics:

- Supported Data Types

- Generation Options

## Supported Data Types

CMP supports a set of JDBC data types that are used in mapping Java data fields to SQL types. Supported JDBC data types are as follows: BIGINT, BIT, BLOB, CHAR, CLOB, DATE, DECIMAL, DOUBLE, FLOAT, INTEGER, NUMERIC, REAL, SMALLINT, TIME, TIMESTAMP, TINYINT, VARCHAR.

The following table contains the mappings of Java types to JDBC types when automatic mapping is used.

Table 7–1 Java Type to JDBC Type Mappings

Java Type | JDBC Type | Nullability
--- | --- | ---
`boolean` | `BIT` | No
`java.lang.Boolean` | `BIT` | Yes
`byte` | `TINYINT` | No
`java.lang.Byte` | `TINYINT` | Yes
`double` | `DOUBLE` | No
`java.lang.Double` | `DOUBLE` | Yes
`float` | `REAL` | No
`java.lang.Float` | `REAL` | Yes
`int` | `INTEGER` | No
`java.lang.Integer` | `INTEGER` | Yes
`long` | `BIGINT` | No
`java.lang.Long` | `BIGINT` | Yes
`short` | `SMALLINT` | No
`java.lang.Short` | `SMALLINT` | Yes
`java.math.BigDecimal` | `DECIMAL` | Yes
`java.math.BigInteger` | `DECIMAL` | Yes
`char` | `CHAR` | No
`java.lang.Character` | `CHAR` | Yes
`java.lang.String` | `VARCHAR` or `CLOB` | Yes
`Serializable` | `BLOB` | Yes
`byte[]` | `BLOB` | Yes
`java.util.Date` | `DATE` (Oracle only) `TIMESTAMP` (all other databases) | Yes
`java.sql.Date` | `DATE` | Yes
`java.sql.Time` | `TIME` | Yes
`java.sql.Timestamp` | `TIMESTAMP` | Yes

Note –

Java types assigned to CMP fields must be restricted to Java primitive types, Java `Serializable` types, `java.util.Date`, `java.sql.Date`, `java.sql.Time`, or `java.sql.Timestamp`. An entity bean local interface type (or a collection of such) can be the type of a CMR field.

The following table contains the mappings of JDBC types to database vendor-specific types when automatic mapping is used. For a list of the JDBC drivers currently supported by the Application Server, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Release Notes. For configurations of supported and other drivers, see Configurations for Specific JDBC Drivers.

Table 7–2 Mappings of JDBC Types to Database Vendor Specific Types

JDBC Type | PointBase | Oracle | DB2 | Sybase ASE 12.5 | MS-SQL Server
--- | --- | --- | --- | --- | ---
`BIT` | `BOOLEAN` | `SMALLINT` | `SMALLINT` | `TINYINT` | `BIT`
`TINYINT` | `SMALLINT` | `SMALLINT` | `SMALLINT` | `TINYINT` | `TINYINT`
`SMALLINT` | `SMALLINT` | `SMALLINT` | `SMALLINT` | `SMALLINT` | `SMALLINT`
`INTEGER` | `INTEGER` | `INTEGER` | `INTEGER` | `INTEGER` | `INTEGER`
`BIGINT` | `BIGINT` | `NUMBER` | `BIGINT` | `NUMERIC` | `NUMERIC`
`REAL` | `FLOAT` | `REAL` | `FLOAT` | `FLOAT` | `REAL`
`DOUBLE` | `DOUBLE PRECISION` | `DOUBLE PRECISION` | `DOUBLE` | `DOUBLE PRECISION` | `FLOAT`
`DECIMAL(p,s)` | `DECIMAL(p,s)` | `NUMBER(p,s)` | `DECIMAL(p,s)` | `DECIMAL(p,s)` | `DECIMAL(p,s)`
`VARCHAR` | `VARCHAR` | `VARCHAR2` | `VARCHAR` | `VARCHAR` | `VARCHAR`
`DATE` | `DATE` | `DATE` | `DATE` | `DATETIME` | `DATETIME`
`TIME` | `TIME` | `DATE` | `TIME` | `DATETIME` | `DATETIME`
`TIMESTAMP` | `TIMESTAMP` | `TIMESTAMP(9)` | `TIMESTAMP` | `DATETIME` | `DATETIME`
`BLOB` | `BLOB` | `BLOB` | `BLOB` | `IMAGE` | `IMAGE`
`CLOB` | `CLOB` | `CLOB` | `CLOB` | `TEXT` | `NTEXT`

## Generation Options

Deployment descriptor elements or `asadmin` command line options can control automatic schema generation by:

- Creating tables during deployment

- Dropping tables during undeployment

- Dropping and creating tables during redeployment

- Specifying the database vendor

- Specifying that table names are unique

- Specifying type mappings for individual CMP fields

Note –

Before using these options, make sure you have a properly configured CMP resource. See Configuring the CMP Resource.

You can also use the deploytool to perform automatic mapping. For more information about using the deploytool, see the “Create Database Mapping” topic in the deploytool’s online help.

For a read-only bean, do not create the database schema during deployment. Instead, work with your database administrator to populate the data into the tables. See Using Read-Only Beans.

Automatic schema generation is not supported for beans with version column consistency checking. Instead, work with your database administrator to create the schema and add the required triggers. See Version Column Consistency Checking.

The following optional data subelements of the `cmp-resource` element in the `sun-ejb-jar.xml` file control the automatic creation of database tables at deployment. For more information about the `cmp-resource` element, see cmp-resource and Configuring the CMP Resource.

Table 7–3 `sun-ejb-jar.xml` Generation Elements

Element | Default | Description
--- | --- | ---
create-tables-at-deploy | `false` | If `true`, causes database tables to be created for beans that are automatically mapped by the EJB container. If `false`, does not create tables.
drop-tables-at-undeploy | `false` | If `true`, causes database tables that were automatically created when the bean(s) were last deployed to be dropped when the bean(s) are undeployed. If `false`, does not drop tables.
database-vendor-name | none | Specifies the name of the database vendor for which tables are created. Allowed values are `db2`, `mssql`, `oracle`, `pointbase`, and `sybase`, case-insensitive. If no value is specified, a connection is made to the resource specified by the `jndi-name` subelement of the `cmp-resource` element in the `sun-ejb-jar.xml` file, and the database vendor name is read. If the connection cannot be established, or if the value is not recognized, SQL-92 compliance is presumed.
schema-generator-properties | none | Specifies field-specific column attributes in `property` subelements. Each property name is of the following format: bean-name`.`field-name`.`attribute For example:
    Employee.firstName.jdbc-type
Column attributes are described in Table A–98. Also allows you to set the `use-unique-table-names` property. If `true`, this property specifies that generated table names are unique within each application server domain. The default is `false`. For further information and an example, see schema-generator-properties.

The following options of the `asadmin deploy` or `asadmin deploydir` command control the automatic creation of database tables at deployment:

Table 7–4 `asadmin deploy` and `asadmin deploydir` Generation Options

Option | Default | Description
--- | --- | ---
`--createtables` | none | If `true`, causes database tables to be created for beans that need them. If `false`, does not create tables. If not specified, the value of the `create-tables-at-deploy` attribute in `sun-ejb-jar.xml` is used.
`--dropandcreatetables` | none | If `true`, and if tables were automatically created when this application was last deployed, tables from the earlier deployment are dropped and fresh ones are created. If `true`, and if tables were not automatically created when this application was last deployed, no attempt is made to drop any tables. If tables with the same names as those that would have been automatically created are found, the deployment proceeds, but a warning indicates that tables could not be created. If `false`, settings of `create-tables-at-deploy` or `drop-tables-at-undeploy` in the `sun-ejb-jar.xml` file are overridden.
`--uniquetablenames` | none | If `true`, specifies that table names are unique within each application server domain. If not specified, the value of the `use-unique-table-names` property in `sun-ejb-jar.xml` is used.
`--dbvendorname` | none | Specifies the name of the database vendor for which tables are created. Allowed values are `db2`, `mssql`, `oracle`, `pointbase`, and `sybase`, case-insensitive. If not specified, the value of the `database-vendor-name` attribute in `sun-ejb-jar.xml` is used. If no value is specified, a connection is made to the resource specified by the `jndi-name` subelement of the `cmp-resource` element in the `sun-ejb-jar.xml` file, and the database vendor name is read. If the connection cannot be established, or if the value is not recognized, SQL-92 compliance is presumed.

If one or more of the beans in the module are manually mapped and you use any of the `asadmin deploy` or `asadmin deploydir` options, the deployment is not harmed in any way, but the options have no effect, and a warning is written to the server log.

If the deploytool mapped one or more of the beans, the `--uniquetablenames` option of `asadmin deploy` or `asadmin deploydir` has no effect. The uniqueness of the table names was established when deploytool created the mapping.

The following options of the `asadmin undeploy` command control the automatic removal of database tables at undeployment:

Table 7–5 `asadmin undeploy` Generation Options

Option | Default | Description
--- | --- | ---
`--droptables` | none | If `true`, causes database tables that were automatically created when the bean(s) were last deployed to be dropped when the bean(s) are undeployed. If `false`, does not drop tables. If not specified, the value of the `drop-tables-at-undeploy` attribute in `sun-ejb-jar.xml` is used.

For more information about the `asadmin deploy`, `asadmin deploydir`, and `asadmin undeploy` commands, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

When command line and `sun-ejb-jar.xml` options are both specified, the `asadmin` options take precedence.

# Schema Capture

This section addresses the following topics:

- Automatic Database Schema Capture

- Using the capture-schema Utility

## Automatic Database Schema Capture

You can configure a CMP bean in Application Server to automatically capture the database metadata and save it in a `.dbschema` file during deployment. If the `sun-cmp-mappings.xml` file contains an empty `<schema/>` entry, the `cmp-resource` entry in the `sun-ejb-jar.xml` file is used to get a connection to the database, and automatic generation of the schema is performed.

Note –

Before capturing the database schema automatically, make sure you have a properly configured CMP resource. See Configuring the CMP Resource.

## Using the capture-schema Utility

You can use the `capture-schema` command to manually generate the database metadata (`.dbschema`) file. For details, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

The `capture-schema` utility does not modify the schema in any way. Its only purpose is to provide the persistence engine with information about the structure of the database (the schema).

Keep the following in mind when using the `capture-schema` command:

- The name of a `.dbschema` file must be unique across all deployed modules in a domain.

- If more than one schema is accessible for the schema user, more than one table with the same name might be captured if the `-schemaname` parameter of `capture-schema` is not set.

- The schema name must be upper case.

- Table names in databases are case-sensitive. Make sure that the table name matches the name in the database.

- An Oracle database user running the `capture-schema` command needs ANALYZE ANY TABLE privileges if that user does not own the schema. These privileges are granted to the user by the database administrator.

# Configuring the CMP Resource

An EJB module that contains CMP beans requires the JNDI name of a JDBC resource or Persistence Manager resource in the `jndi-name` subelement of the cmp-resource element in the `sun-ejb-jar.xml` file. If the JNDI name refers to a JDBC Resource, set `PersistenceManagerFactory` properties as properties of the `cmp-resource` element in the `sun-ejb-jar.xml` file.

In the Administration Console, open the Resources component, then select JDBC or Persistence Managers. Refer to the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Guide for information on creating a new CMP resource.

For a list of the JDBC drivers currently supported by the Application Server, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Release Notes. For configurations of supported and other drivers, see Configurations for Specific JDBC Drivers.

For example, if the JDBC resource has the JNDI name `jdbc/MyDatabase`, set the CMP resource in the `sun-ejb-jar.xml` file as follows:

    <cmp-resource>
       <jndi-name>jdbc/MyDatabase</jndi-name>
    </cmp-resource>

For another example, if the Persistence Manager has the JNDI name `jdo/``MyDatabase`, set the CMP resource in the `sun-ejb-jar.xml` file as follows:

    <cmp-resource>
       <jndi-name>jdo/MyDatabase</jndi-name>
    </cmp-resource>

# Configuring Queries for 1.1 Finders

This section contains the following topics:

- About JDOQL Queries

- Query Filter Expression

- Query Parameters

- Query Variables

- JDOQL Examples

## About JDOQL Queries

The Enterprise JavaBeans Specification, v1.1 spec does not specify the format of the finder method description. The Application Server uses an extension of Java Data Objects Query Language (JDOQL) queries to implement finder and selector methods. (For EJB 2.0 and later, the container automatically maps an EJB QL query to JDOQL.) You can specify the following elements of the underlying JDOQL query:

- Filter expression - A Java-like expression that specifies a condition that each object returned by the query must satisfy. Corresponds to the WHERE clause in EJB QL.

- Query parameter declaration - Specifies the name and the type of one or more query input parameters. Follows the syntax for formal parameters in the Java language.

- Query variable declaration - Specifies the name and type of one or more query variables. Follows the syntax for local variables in the Java language. A query filter might use query variables to implement joins.

- Query ordering declaration - Specifies the ordering expression of the query. Corresponds to the ORDER BY clause of EJB QL.

The Application Server specific deployment descriptor (`sun-ejb-jar.xml`) provides the following elements to store the EJB 1.1 finder method settings:

`query-filterquery-paramsquery-variablesquery-ordering`

The bean developer uses these elements to construct a query. When the finder method that uses these elements executes, the values of these elements are used to execute a query in the database. The objects from the JDOQL query result set are converted into primary key instances to be returned by the EJB 1.1 `ejbFind` method.

The JDO specification (see JSR 12) provides a comprehensive description of JDOQL. The following information summarizes the elements used to define EJB 1.1 finders.

## Query Filter Expression

The filter expression is a String containing a boolean expression evaluated for each instance of the candidate class. If the filter is not specified, it defaults to true. Rules for constructing valid expressions follow the Java language, with the following differences:

- Equality and ordering comparisons between primitives and instances of wrapper classes are valid.

- Equality and ordering comparisons of Date fields and Date parameters are valid.

- Equality and ordering comparisons of String fields and String parameters are valid.

- White space (non-printing characters space, tab, carriage return, and line feed) is a separator and is otherwise ignored.

- The following assignment operators are not supported:

  - =, +=, etc.

  - pre- and post-increment

  - pre- and post-decrement

- Methods, including object construction, are not supported, except for:

      Collection.contains(Object o)
      Collection.isEmpty()
      String.startsWith(String s)
      String.endsWith(String e)

  In addition, the Application Server supports the following nonstandard JDOQL methods:

      String.like(String pattern)
      String.like(String pattern, char escape)
      String.substring(int start, int length)
      String.indexOf(String str)
      String.indexOf(String str, int start)
      String.length()
      Math.abs(numeric n)
      Math.sqrt(double d)

- Navigation through a null-valued field, which throws a `NullPointerException`, is treated as if the sub-expression returned `false`.

Note –

Comparisons between floating point values are by nature inexact. Therefore, equality comparisons (== and !=) with floating point values should be used with caution. Identifiers in the expression are considered to be in the name space of the candidate class, with the addition of declared parameters and variables. As in the Java language, `this` is a reserved word, and refers to the current instance being evaluated.

The following expressions are supported:

- Operators applied to all types where they are defined in the Java language:

  - relational operators (==, !=, >, <, >=, <=)

  - boolean operators (&, &&, |, ||, ~, !)

  - arithmetic operators (+, -, *, /)

  String concatenation is supported only for String + String.

- Parentheses to explicitly mark operator precedence

- Cast operator

- Promotion of numeric operands for comparisons and arithmetic operations. The rules for promotion follow the Java rules (see the numeric promotions of the Java language specification) extended by BigDecimal, BigInteger, and numeric wrapper classes.

## Query Parameters

The parameter declaration is a String containing one or more parameter type declarations separated by commas. This follows the Java syntax for method signatures.

## Query Variables

The type declarations follow the Java syntax for local variable declarations.

## JDOQL Examples

This section provides a few query examples.

### Example 1

The following query returns all players called Michael. It defines a filter that compares the name field with a string literal:

    name == "Michael"

The `finder` element of the `sun-ejb-jar.xml` file looks like this:

    <finder>
       <method-name>findPlayerByName</method-name>
       <query-filter>name == "Michael"</query-filter>
    </finder>

### Example 2

This query returns all products in a specified price range. It defines two query parameters which are the lower and upper bound for the price: double low, double high. The filter compares the query parameters with the price field:

    low < price && price < high

Query ordering is set to `price ascending`.

The `finder` element of the `sun-ejb-jar.xml` file looks like this:

    <finder>
       <method-name>findInRange</method-name>
       <query-params>double low, double high</query-params>
       <query-filter>low &lt; price &amp;&amp; price &lt high</query-filter>
       <query-ordering>price ascending</query-ordering>
    </finder>

### Example 3

This query returns all players having a higher salary than the player with the specified name. It defines a query parameter for the name `java.lang.String name`. Furthermore, it defines a variable to which the player’s salary is compared. It has the type of the persistence capable class that corresponds to the bean:

        mypackage.PlayerEJB_170160966_JDOState player

The filter compares the salary of the current player denoted by the `this` keyword with the salary of the player with the specified name:

        (this.salary > player.salary) && (player.name == name)

The `finder` element of the `sun-ejb-jar.xml` file looks like this:

    <finder>
       <method-name>findByHigherSalary</method-name>
       <query-params>java.lang.String name</query-params>
       <query-filter>
          (this.salary &gt; player.salary) &amp;&amp; (player.name == name)
       </query-filter>
       <query-variables>
          mypackage.PlayerEJB_170160966_JDOState player
       </query-variables>
    </finder>

# Performance-Related Features

The Application Server provides the following features to enhance performance or allow more fine-grained data checking. These features are supported only for entity beans with container managed persistence.

- Version Column Consistency Checking

- Relationship Prefetching

- Read-Only Beans

Note –

Use of any of these features results in a non-portable application.

## Version Column Consistency Checking

The version consistency feature saves the bean state at first transactional access and caches it between transactions. The state is copied from the cache instead of being read from the database. The bean state is verified by primary key and version column values at flush for custom queries (for dirty instances only) and at commit (for clean and dirty instances).

### To use version consistency

1. Create the version column in the primary table.

2. Give the version column a numeric data type.

3. Provide appropriate update triggers on the version column.

   These triggers must increment the version column on each update of the specified row.

4. Specify the version column.

   This is specified in the check-version-of-accessed-instances subelement of the consistency element in the `sun-cmp-mappings.xml` file.

5. Map the CMP bean to an existing schema.

   Automatic schema generation is not supported for beans with version column consistency checking. Instead, work with your database administrator to create the schema and add the required triggers.

## Relationship Prefetching

In many cases when an entity bean’s state is fetched from the database, its relationship fields are always accessed in the same transaction. Relationship prefetching saves database round trips by fetching data for an entity bean and those beans referenced by its CMR fields in a single database round trip.

To enable relationship prefetching for a CMR field, use the default subelement of the fetched-with element in the `sun-cmp-mappings.xml` file. By default, these CMR fields are prefetched whenever `findByPrimaryKey` or a custom finder is executed for the entity, or when the entity is navigated to from a relationship. (Recursive prefetching is not supported, because it does not usually enhance performance.) To disable prefetching for specific custom finders, use the prefetch-disabled element in the `sun-ejb-jar.xml` file.

## Read-Only Beans

Another feature that the Application Server provides is the read-only bean, an entity bean that is never modified by an EJB client. Read-only beans avoid database updates completely.

A read-only bean can be used to cache a database entry that is frequently accessed but rarely updated (externally by other beans). When the data that is cached by a read-only bean is updated by another bean, the read-only bean can be notified to refresh its cached data.

The Application Server provides a number of ways by which a read-only bean’s state can be refreshed. By setting the `refresh-period-in-seconds` element in the `sun-ejb-jar.xml` file and the `trans-attribute` element in the `ejb-jar.xml` file, it is easy to configure a read-only bean that is (a) always refreshed, (b) periodically refreshed, (c) never refreshed, or (d) programmatically refreshed.

Read-only beans are best suited for situations where the underlying data never changes, or changes infrequently. For further information and usage guidelines, see Using Read-Only Beans.

# Restrictions and Optimizations

This section discusses restrictions and performance optimizations that pertain to using CMP entity beans.

- Eager Loading of Field State

- Restrictions on Remote Interfaces

- Sybase Finder Limitation

- Date and Time Fields as CMP Field Types

- No Support for lock-when-loaded on Sybase and DB2

- Set RECURSIVE_TRIGGERS to false on MSSQL

## Eager Loading of Field State

By default, the EJB container loads the state for all CMP fields (excluding relationship, BLOB, and CLOB fields) before invoking the `ejbLoad` method of the abstract bean. This approach might not be optimal for entity objects with large state if most business methods require access to only parts of the state. If this is an issue, use the fetched-with element in `sun-cmp-mappings.xml` for fields that are used infrequently.

## Restrictions on Remote Interfaces

The following restrictions apply to the remote interface of an entity bean that uses CMP:

- Do not expose the `get` and `set` methods for CMR fields or the persistence collection classes that are used in container-managed relationships through the remote interface of the bean.

  However, you are free to expose the `get` and `set` methods that correspond to the CMP fields of the entity bean through the bean’s remote interface.

- Do not expose the container-managed collection classes that are used for relationships through the remote interface of the bean.

- Do not expose local interface types or local home interface types through the remote interface or remote home interface of the bean.

Dependent value classes can be exposed in the remote interface or remote home interface, and can be included in the client EJB JAR file.

## Sybase Finder Limitation

If a finder method with an input greater than 255 characters is executed and the primary key column is mapped to a VARCHAR column, Sybase attempts to convert type VARCHAR to type TEXT and generates the following error:

    com.sybase.jdbc2.jdbc.SybSQLException: Implicit conversion from datatype
    'TEXT' to 'VARCHAR' is not allowed.  Use the CONVERT function to run this
    query.

To avoid this error, make sure the finder method input is less than 255 characters.

## Date and Time Fields as CMP Field Types

If a CMP field type is a Java date or time type (`java.util.Date`, `java.sql.Date`, `java.sql.Time`, `java.sql.Timestamp`), make sure that the field value exactly matches the value in the database.

For example, the following code uses a `java.sql.Date` type as a primary key field:

    java.sql.Date myDate = new java.sql.Date(System.currentTimeMillis())
    beanHome.create(myDate, ...);

For some databases, this code results in only the year, month, and date portion of the field value being stored in the database. Later on if the client tries to find this bean by primary key as follows:

    myBean = beanHome.findByPrimaryKey(myDate);

the bean is not found in the database because the value does not match the one that is stored in the database.

Similar problems can happen if the database truncates the timestamp value while storing it, or if a custom query has a date or time value comparison in its WHERE clause.

For automatic mapping to an Oracle database, fields of type `java.util.Date`, `java.sql.Date`, and `java.sql.Time` are mapped to Oracle’s DATE data type. Fields of type `java.sql.Timestamp` are mapped to Oracle’s TIMESTAMP(9) data type.

## No Support for lock-when-loaded on Sybase and DB2

The lock-when-loaded consistency level is implemented by placing update locks on the data corresponding to a bean when the data is loaded from the database. There is no suitable mechanism available on Sybase and DB2 databases to implement this feature. Therefore, the lock-when-loaded consistency level is not supported on Sybase and DB2 databases.

## Set RECURSIVE_TRIGGERS to false on MSSQL

For version consistency triggers on MSSQL, the property `RECURSIVE_TRIGGERS` must be set to `false`, which is the default. If set to `true`, triggers throw a `java.sql.SQLException`.

Set this property as follows:

    EXEC sp_dboption 'database-name', 'recursive triggers', 'FALSE'
    go

You can test this property as follows:

    SELECT DATABASEPROPERTYEX('database-name', 'IsRecursiveTriggersEnabled')
    go

# Chapter 8 Developing Java Clients

This chapter describes how to develop, assemble, and deploy J2EE Application Clients in the following sections:

- Introducing the Application Client Container

- Developing Clients Using the ACC

- Developing Clients Without the ACC

# Introducing the Application Client Container

The Application Client Container (ACC) includes a set of Java classes, libraries, and other files that are required for and distributed with Java client programs that execute in their own Java Virtual Machine (JVM). The ACC manages the execution of J2EE application client components, which are used to access a variety of J2EE services (such as JMS resources, EJB components, web services, security, and so on.) from a JVM outside the Sun Java System Application Server.

The ACC communicates with the Application Server using RMI-IIOP protocol and manages the details of RMI-IIOP communication using the client ORB that is bundled with it. Compared to other J2EE containers, the ACC is lightweight.

## Security

The ACC is responsible for collecting authentication data such as the username and password and sending the collected data to the Application Server. The Application Server then processes the authentication data using the configured JavaTM Authentication and Authorization Service (JAAS) module.

Authentication techniques are provided by the client container, and are not under the control of the application client component. The container integrates with the platform’s authentication system. When you execute a client application, it displays a login window and collects authentication data from the user. It also supports SSL (Secure Socket Layer)/IIOP if configured and when necessary.

## Naming

The client container enables the application clients to use the Java Naming and Directory Interface (JNDI) to look up J2EE services (such as JMS resources, EJB components, web services, security, and so on.) and to reference configurable parameters set at the time of deployment.

# Developing Clients Using the ACC

This section describes the procedure to develop, assemble, and deploy client applications using the ACC. This section describes the following topics:

- To access an EJB component from an application client

- To access a JMS resource from an application client

- Running an Application Client Using the ACC

- Packaging an Application Client Using the ACC

For information about Java-based clients that are not packaged using the ACC, see Developing Clients Without the ACC.

## To access an EJB component from an application client

1. In your client code, instantiate the `InitialContext` using the default (no argument) constructor:

       InitialContext ctx = new InitialContext();

   It is not necessary to explicitly instantiate a naming context that points to the CosNaming service.

2. In your client code, look up the home object by specifying the JNDI name of the home object as specified in the `ejb-jar.xml` file.

   For example:

       Object ref = ctx.lookup("java:comp/env/ejb-ref-name");
       BeanAHome = (BeanAHome)PortableRemoteObject.narrow(ref,BeanAHome.class);

   If load balancing is enabled as in Step 8 and the EJB components being accessed are in a different cluster, the endpoint list must be included in the lookup, as follows:

       corbaname:host1:port1,host2:port2,.../NameService#ejb/jndi-name

   For more information about naming and lookups, see Accessing the Naming Context.

3. Define the `ejb-ref` elements in the `application-client.xml` file and the corresponding `sun-application-client.xml` file.

   For more information on the `sun-application-client.xml` file, see The sun-application-client.xml file. For a general explanation of how to map JNDI names using reference elements, see Mapping References.

4. Deploy the application client and EJB component together in an application.

   For more information on deployment, see Tools for Deployment. To get the client JAR file, use the `--retrieve` option.

   To retrieve the stubs and ties whether or not you requested their generation during deployment, use the `asadmin get-client-stubs` command. For details, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

5. Ensure that the client JAR file includes the following files:

   - a Java class to access the bean

   - `application-client.xml` - J2EE 1.4 application client deployment descriptor.

   - `sun-application-client.xml` - Application Server specific client deployment descriptor. For information on the `sun-application-client.xml` file, see The sun-application-client.xml file.

   - `The MANIFEST.MF` file. This file contains the main class, which states the complete package prefix and class name of the Java client.

   You can package the application client using the `package-appclient` script. This is optional. See Packaging an Application Client Using the ACC.

6. Copy the following JAR files to the client machine and include them in the classpath on the client side:

   - `appserv-rt.jar` - available at install-dir`/lib`

   - `j2ee.jar` - available at install-dir`/lib`

   - The client JAR file

7. To access EJB components that are residing in a remote system, make the following changes to the `sun-acc.xml` file:

   - Define the target-server element’s `address` attribute to reference the remote server machine.

   - Define the target-server element’s `port` attribute to reference the ORB port on the remote server.

   This information can be obtained from the `domain.xml` file on the remote system. For more information on `domain.xml` file, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Reference.

   The `target-server` element in the `sun-acc.xml` file is not used if the `endpoints` property is defined as in Step 8. For more information about the `sun-acc.xml` file, see The sun-acc.xml File.

8. To set up load balancing and failover of remote EJB references, define the following property as a `property` subelement of the client-container element in the `sun-acc.xml` file:

       com.sun.appserv.iiop.endpoints

   The `endpoints` property specifies a comma-separated list of one or more IIOP endpoints used for load balancing. An IIOP endpoint is in the form host`:`port, where the host is an IPv4 address or host name, and the port specifies the port number.

   If the `endpoints` list is changed dynamically in the code, the new list is used only if a new `InitialContext` is created.

9. Run the application client. See Running an Application Client Using the ACC.

##### Example 8–1 Client Load Balancing and Failover

The following sample application demonstrates client load balancing and failover:

    install-dir/samples/ee-samples/failover/apps/sfsbfailover

## To access a JMS resource from an application client

1. Create a JMS client.

   For detailed instructions on developing a JMS client, see the J2EE 1.4 Tutorial at `http://java.sun.com/j2ee/1.4/docs/tutorial/doc/JMS.html#wp84181`.

2. Next, configure a JMS resource on the Application Server.

   For information on configuring JMS resources, see Creating JMS Resources: Destinations and Connection Factories.

3. Define the `resource-ref` elements in the `application-client.xml` file and the corresponding `sun-application-client.xml` file.

   For more information on the `sun-application-client.xml` file, see The sun-application-client.xml file. For a general explanation of how to map JNDI names using reference elements, see Mapping References.

4. Ensure that the client JAR file includes the following files:

   - A Java class to access the resource.

   - `application-client.xml` - J2EE 1.4 application client deployment descriptor.

   - `sun-application-client.xml` - Application Server specific client deployment descriptor. For information on the `sun-application-client.xml` file, see The sun-application-client.xml file.

   - `The MANIFEST.MF` file. This file contains the main class, which states the complete package prefix and class name of the Java client.

   You can package the application client using the `package-appclient` script. This is optional. See Packaging an Application Client Using the ACC.

5. Copy the following JAR files to the client machine and include them in the classpath on the client side:

   - `appserv-rt.jar` - available at install-dir`/lib`

   - `j2ee.jar` - available at install-dir`/lib`

   - `imqjmsra.jar` - available at install-dir`/lib/install/aplications/jmsra`

   - The client JAR file

6. Run the application client.

   See Running an Application Client Using the ACC.

## Running an Application Client Using the ACC

To run an application client, launch the ACC using the `appclient` script. For details, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

## Packaging an Application Client Using the ACC

The `package-appclient` script, located in the install-dir`/bin` directory, is used to package a client application into a single `appclient.jar` file. Packaging an application client involves the following main steps:

- Editing the Configuration File

- Editing the appclient Script

- Editing the sun-acc.xml File

- Setting Security Options

- To use the `package-appclient` script bundled with the Application Server

### Editing the Configuration File

Modify the environment variables in `asenv.conf` file located in the install-dir`/config` directory as shown below:

- `$AS_INSTALL` to reference the location where the package was un-jared plus `/appclient`. For example: `$AS_INSTALL=``/`install-dir`/appclient`.

- `$AS_NSS` to reference the location of the NSS libraries. For example:

  UNIX:

  `$AS_NSS=/`install-dir`/appclient/lib`

  WINDOWS:

  `%AS_NSS%=\`install-dir`\appclient\bin`

- `$AS_JAVA` to reference the location where the JDK is installed.

- `$AS_ACC_CONFIG` to reference the configuration XML file (`sun-acc.xml`). The `sun-acc.xml` is located at install-dir`/config`.

- `$AS_IMQ_LIB` to reference the imq home. Use domain-dir`/imq/lib`.

### Editing the appclient Script

Modify the `appclient` script file as follows:

UNIX:

Change `$CONFIG_HOME/asenv.conf` to your-ACC-dir`/config/asenv.conf`.

Windows:

Change `%CONFIG_HOME%\config\asenv.bat` to your-ACC-dir`\config\asenv.bat`

### Editing the sun-acc.xml File

Modify `sun-acc.xml` file to set the following attributes:

- Ensure that the `DOCTYPE` references install-dir`/lib/dtds` to your-ACC-dir`/lib/dtds`.

- Ensure that the `<target-server> address` attribute references the remote server machine.

- Ensure that the `<target-server> port` attribute references the ORB port on the remote server.

- To log the messages in a file, specify a file name for the `log-service` element’s `file` attribute. You can also set the log level. For example:

      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE client-container SYSTEM
      "file:install-dir/lib/dtds/sun-application-client-container_1_0.dtd">
      <client-container>
          <target-server name="qasol-e1" address="qasol-e1" port="3700">
          <log-service level="WARNING"/>
      </client-container>

For more information on the `sun-acc.xml` file, see The sun-acc.xml File.

### Setting Security Options

You can run the application client using SSL with certificate authentication. To set the security options, modify the `sun-acc.xml` file as shown in the code illustration below. For more information on the `sun-acc.xml` file, see The sun-acc.xml File.

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE client-container SYSTEM
    "file:install-dir/lib/dtds/sun-application-client-container_1_0.dtd">
    <client-container>
      <target-server name="qasol-e1" address="qasol-e1" port="3700">
        <security>
          <ssl cert-nickname="cts"
            ssl2-enabled="false"
            ssl2-ciphers="-rc4,-rc4export,-rc2,-rc2export,-des,-desede3"
            ssl3-enabled="true"
            ssl3-tls-ciphers="+rsa_rc4_128_md5,-rsa_rc4_40_md5,+rsa3_des_sha,
                +rsa_des_sha,-rsa_rc2_40_md5,-rsa_null_md5,-rsa_des_56_sha,
                -rsa_rc4_56_sha"
            tls-enabled="true"
            tls-rollback-enabled="true"/>
          <cert-db path="ignored" password="ignored"/> <!-- not used -->
        </security>
      </target-server>
      <client-credential user-name="j2ee" password="j2ee"/>
      <log-service level="WARNING"/>
    </client-container>

### To use the `package-appclient` script bundled with the Application Server

1. Under install-dir `/bin` directory, run the `package-appclient` script.

   For details, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

   This creates an `appclient.jar` file and stores it under install-dir`/lib/appclient/` directory.

   Note –

   The `appclient.jar` file provides an application client container package targeted at remote hosts and does not contain a server installation. You can run this file from a remote machine with the same operating system as where it is created. That is, `appclient.jar` created on a Solaris platform does not function on Windows.

2. Copy the install-dir `/lib/appclient/appclient.jar` file to the desired location.

   The `appclient.jar` file contains the following files:

   - `appclient/bin` - contains the `appclient` script used to launch the ACC.

   - `appclient/lib` - contains the JAR and runtime shared library files.

   - `appclient/lib/appclient` - contains the following files:

     - `sun-acc.xml` - the ACC configuration file.

     - client.policy file- the security manager policy file for the ACC.

     - `appclientlogin.conf` file - the login configuration file.

     - `client.jar` file - created during the deployment of the client application.

   - `appclient/lib/dtds` - contains `sun-application_client-container_1_0.dtd`, which is the DTD corresponding to `sun-acc.xml`.

## client.policy

The `client.policy` file is the J2SE policy file used by the application client. Each application client has a `client.policy` file. The default policy file limits the permissions of J2EE deployed application clients to the minimal set of permissions required for these applications to operate correctly. If an application client requires more than this default set of permissions, edit the `client.policy` file to add the custom permissions that your application client needs. Use the J2SE standard policy tool or any text editor to edit this file.

For more information on using the J2SE policy tool, see `http://java.sun.com/docs/books/tutorial/security1.2/tour2/index.html`.

For more information about the permissions you can set in the `client.policy` file, see `http://java.sun.com/j2se/1.4/docs/guide/security/permissions.html`.

# Developing Clients Without the ACC

This section describes the procedure to create, assemble, and deploy a Java-based client that is not packaged using the Application Client Container (ACC). This section describes the following topics:

- To access an EJB component from a stand-alone client

- To access an EJB component from a server-side module

- To access a JMS resource from a stand-alone client

For information about using the ACC, see Developing Clients Using the ACC.

## To access an EJB component from a stand-alone client

1. In your client code, instantiate the `InitialContext`:

       InitialContext ctx = new InitialContext();

   It is not necessary to explicitly instantiate a naming context that points to the CosNaming service.

2. In the client code, look up the home object by specifying the JNDI name of the home object.

   For example:

       Object ref = ctx.lookup("jndi-name");
       BeanAHome = (BeanAHome)PortableRemoteObject.narrow(ref,BeanAHome.class);

   If load balancing is enabled as in Step 6 and the EJB components being accessed are in a different cluster, the endpoint list must be included in the lookup, as follows:

       corbaname:host1:port1,host2:port2,.../NameService#ejb/jndi-name

   For more information about naming and lookups, see Accessing the Naming Context.

3. Deploy the EJB component to be accessed.

   For more information on deployment, see Tools for Deployment.

4. Copy the following JAR files to the client machine and include them in the classpath on the client side:

   - `appserv-rt.jar` - available at install-dir`/lib`

   - `j2ee.jar` - available at install-dir`/lib`

5. To access EJB components that are residing in a remote system, set the values for the Java Virtual Machine startup options:

       jvmarg value = "-Dorg.omg.CORBA.ORBInitialHost=${ORBhost}"
       jvmarg value = "-Dorg.omg.CORBA.ORBInitialPort=${ORBport}"

   Here ORBhost is the Application Server hostname and ORBport is the ORB port number (default is `3700` for the default instance).

   This information can be obtained from the `domain.xml` file on the remote system. For more information on `domain.xml` file, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Reference.

6. To set up load balancing and remote EJB reference failover, define the `endpoints` property as follows:

       jvmarg value = "-Dcom.sun.appserv.iiop.endpoints=host1:port1,host2:port2,..."

   The `endpoints` property specifies a comma-separated list of one or more IIOP endpoints used for load balancing. An IIOP endpoint is in the form host`:`port, where the host is an IPv4 address or host name, and the port specifies the port number.

   If the `endpoints` list is changed dynamically in the code, the new list is used only if a new `InitialContext` is created.

7. Run the stand-alone client.

   As long as the client environment is set appropriately and the JVM is compatible, you merely need to run the `main` class.

##### Example 8–2 Client Load Balancing and Failover

The following sample application demonstrates client load balancing and failover:

    install-dir/samples/ee-samples/failover/apps/sfsbfailover

## To access an EJB component from a server-side module

A server-side module can be a servlet, another EJB component, or another type of module.

1. In your module code, instantiate the `InitialContext`:

       InitialContext ctx = new InitialContext();

   It is not necessary to explicitly instantiate a naming context that points to the CosNaming service.

   To set up load balancing and remote EJB reference failover, define the `endpoints` property as follows:

       Hashtable env = new Hashtable();
       env.put("com.sun.appserv.iiop.endpoints","host1:port1,host2:port2,...");
       InitialContext ctx = new InitialConext(env);

   The `endpoints` property specifies a comma-separated list of one or more IIOP endpoints used for load balancing. An IIOP endpoint is in the form host`:`port, where the host is an IPv4 address or host name, and the port specifies the port number.

   If the `endpoints` list is changed dynamically in the code, the new list is used only if a new `InitialContext` is created.

2. In the module code, look up the home object by specifying the JNDI name of the home object. For example:

       Object ref = ctx.lookup("jndi-name");
       BeanAHome = (BeanAHome)PortableRemoteObject.narrow(ref,BeanAHome.class);

   If load balancing is enabled as in Step 1 and the EJB components being accessed are in a different cluster, the endpoint list must be included in the lookup, as follows:

       corbaname:host1:port1,host2:port2,.../NameService#ejb/jndi-name

   For more information about naming and lookups, see Accessing the Naming Context.

3. Deploy the EJB component to be accessed.

   For more information on deployment, see Tools for Deployment.

4. To access EJB components that are residing in a remote system, set the values for the Java Virtual Machine startup options:

   `jvmarg value = "-Dorg.omg.CORBA.ORBInitialHost=${`ORBhost`}"jvmarg value = "-Dorg.omg.CORBA.ORBInitialPort=${`ORBport`}"`

   Here ORBhost is the Application Server hostname and ORBport is the ORB port number (default is `3700` for the default instance).

   This information can be obtained from the `domain.xml` file on the remote system. For more information on `domain.xml` file, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Reference.

5. Deploy the module.

   For more information on deployment, see Tools for Deployment.

##### Example 8–3 Client Load Balancing and Failover

The following sample application demonstrates client load balancing and failover:

    install-dir/samples/ee-samples/failover/apps/sfsbfailover

## To access a JMS resource from a stand-alone client

1. Create a JMS client.

   For detailed instructions on developing a JMS client, see the J2EE 1.4 Tutorial at `http://java.sun.com/j2ee/1.4/docs/tutorial/doc/JMS.html#wp84181`.

2. Next, configure a JMS resource on the Application Server.

   For information on configuring JMS resources, see Creating JMS Resources: Destinations and Connection Factories.

3. Copy the following JAR files to the client machine and include them in the classpath on the client side:

   - `appserv-rt.jar` - available at install-dir`/lib`

   - `j2ee.jar` - available at install-dir`/lib`

   - `imqjmsra.jar` - available at install-dir`/lib/install/aplications/jmsra`

4. Set the values for the Java Virtual Machine startup options:

       jvmarg value = "-Dorg.omg.CORBA.ORBInitialHost=${ORBhost}"
       jvmarg value = "-Dorg.omg.CORBA.ORBInitialPort=${ORBport}"

   Here ORBhost is the Application Server hostname and ORBport is the ORB port number (default is `3700` for the default instance).

   This information can be obtained from the `domain.xml` file. For more information on `domain.xml` file, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Reference.

5. Run the stand-alone client.

   As long as the client environment is set appropriately and the JVM is compatible, you merely need to run the `main` class.

# Chapter 9 Developing Connectors

This chapter describes Sun Java System Application Server support for the J2EE Connector 1.5 architecture.

The J2EE Connector architecture provides a Java solution to the problem of connectivity between multiple application servers and existing enterprise information systems (EISs). By using the J2EE Connector architecture, EIS vendors no longer need to customize their product for each application server. Application server vendors who conform to the J2EE Connector architecture do not need to write custom code to add connectivity to a new EIS.

This chapter uses the terms connector and resource adapter interchangeably. Both terms refer to a resource adapter module that is developed in conformance with the J2EE Connector Specification 1.5.

For more information about connectors, see the J2EE Connector architecture home page, at `http://java.sun.com/j2ee/connector/`.

For connector examples, see http://developers.sun.com/prodtech/appserver/reference/techart/as8_connectors.

This chapter includes the following topics:

- Connector 1.5 Support in the Application Server

- Deploying and Configuring a Stand-Alone Connector Module

- Redeploying a Stand-Alone Connector Module

- Deploying and Configuring an Embedded Resource Adapter

- Advanced Connector Configuration Options

- Inbound Communication Support

- Configuring a Message Driven Bean to Use a Resource Adapter

# Connector 1.5 Support in the Application Server

The Application Server supports the development and deployment of resource adapters that are compatible with Connector 1.5 specification (and, for backward compatibility, the Connector 1.0 specification).

The Connector 1.0 specification defines the outbound connectivity system contracts between the resource adapter and the Application Server. The Connector 1.5 specification introduces major additions in defining system level contracts between the Application Server and the resource adapter with respect to the following:

- Inbound connectivity from an EIS - The Connector 1.5 defines the transaction and message inflow system contracts for achieving inbound connectivity from an EIS. The message inflow contract also serves as a standard message provider pluggability contract, thereby allowing various providers of messaging systems to seamlessly plug in their products with any application server that supports the message inflow contract.

- Resource adapter life cycle management and thread management - These features are available through the lifecycle and work management contracts.

## Connector Architecture for JMS and JDBC

In the Administration Console, connector, JMS, and JDBC resources are handled differently, but they use the same underlying Connector architecture. In the Application Server, all communication to an EIS, whether to a message provider or an RDBMS, happens through the Connector architecture. To provide JMS infrastructure to clients, the Application Server uses the Sun Java System Message Queue software. To provide JDBC infrastructure to clients, the Application Server uses its own JDBC system resource adapters. The application server automatically makes these system resource adapters available to any client that requires them.

For more information about JMS in the Application Server, see Chapter 14, Using the Java Message Service. For more information about JDBC in the Application Server, see Chapter 11, Using the JDBC API for Database Access.

## Connector Configuration

The Application Server does not need to use `sun-ra.xml`, which previous Application Server versions used, to store server-specific deployment information inside a Resource Adapter Archive (RAR) file. (However, the `sun-ra.xml` file is still supported for backward compatibility.) Instead, the information is stored in the server configuration. As a result, you can create multiple connector connection pools for a connection definition in a functional resource adapter instance, and you can create multiple user-accessible connector resources (that is, registering a resource with a JNDI name) for a connector connection pool. In addition, dynamic changes can be made to connector connection pools and the connector resource properties without restarting the Application Server.

# Deploying and Configuring a Stand-Alone Connector Module

You can deploy a stand-alone connector module using the Administration Console or the `asadmin` command. For information about using the Administration Console, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Guide. For information about using the `asadmin` command, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

Deploying a stand-alone connector module allows multiple deployed J2EE applications to share the connector module. A resource adapter configuration is automatically created for the connector module.

## To deploy and configure a stand-alone connector module

1. Deploy the connector module in one of the following ways.

   - In the Administration Console, open the Applications component and select Connector Modules. When you deploy the connector module, a resource adapter configuration is automatically created for the connector module.

   - Use the `asadmin deploy` or `asadmin deploydir` command. To override the default configuration properties of a resource adapter, if necessary, use the `asadmin create-resource-adapter-config` command.

2. Configure connector connection pools for the deployed connector module in one of the following ways:

   - In the Administration Console, open the Resources component, select Connectors, and select Connector Connection Pools.

   - Use the `asadmin create-connector-connection-pool` command.

3. Configure connector resources for the connector connection pools in one of the following ways.

   - In the Administration Console, open the Resources component, select Connectors, and select Connector Resources.

   - Use the `asadmin create-connector-resource` command.

   This associates a connector resource with a JNDI name.

4. Create an administered object for an inbound resource adapter, if necessary, in one of the following ways:

   - In the Administration Console, open the Resources component, select Connectors, and select Admin Object Resources.

   - Use the `asadmin create-admin-object` command.

# Redeploying a Stand-Alone Connector Module

Redeployment of a connector module maintains all connector connection pools, connector resources, and administered objects defined for the previously deployed connector module. You need not reconfigure any of these resources.

However, you should redeploy any dependent modules. A dependent module uses or refers to a connector resource of the redeployed connector module. Redeployment of a connector module results in the shared class loader reloading the new classes. Other modules that refer to the old resource adapter classes must be redeployed to gain access to the new classes. For more information about classloaders, see Classloaders.

During connector module redeployment, the server log provides a warning indicating that all dependent applications should be redeployed. Client applications or application components using the connector module’s resources may throw class cast exceptions if dependent applications are not redeployed after connector module redeployment.

To disable automatic redeployment, set the `--force` option to `false`. In this case, if the connector module has already been deployed, the Application Server provides an error message.

# Deploying and Configuring an Embedded Resource Adapter

A connector module can be deployed as a J2EE component in a J2EE application. Such connectors are only visible to components residing in the same J2EE application. Simply deploy this J2EE application as you would any other J2EE application.

You can create new connector connection pools and connector resources for a connector module embedded within a J2EE application by prefixing the connector name with app-name`#`. For example, if an application `appX.ear` has `jdbcra.rar` embedded within it, the connector connection pools and connector resources refer to the connector module as `appX#jdbcra`.

However, an embedded connector module cannot be undeployed using the name app-name`#`connector-name. To undeploy the connector module, you must undeploy the application in which it is embedded.

The association between the physical JNDI name for the connector module in the Application Server and the logical JNDI name used in the application component is specified in the Application Server specific XML descriptor `sun-ejb-jar.xml`. You can either hand code this association or use the deploytool to make this association. (For more information about using the deploytool, see deploytool.)

# Advanced Connector Configuration Options

You can use these advanced connector configuration options:

- Thread Pools

- Security Maps

- Overriding Configuration Properties

- Testing a Connection Pool

- Handling Invalid Connections

- Setting the Shutdown Timeout

- Using Last Agent Optimization of Transactions

## Thread Pools

Connectors can submit work instances to the Application Server for execution. By default, the Application Server services work requests for all connectors from its default thread pool. However, you can associate a specific user-created thread pool to service work requests from a connector. A thread pool can service work requests from multiple resource adapters. To create a thread pool:

- In the Administration Console, select Thread Pools under the relevant configuration. For details, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Guide.

- Use the `asadmin create-threadpool` command. For details, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

To associate a connector with a thread pool:

- In the Administration Console, open the Applications component and select Connector Modules. Deploy the module, or select the previously deployed module. Specify the name of the thread pool in the Thread Pool ID field. For details, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Guide.

- Use the `--threadpoolid` option of the `asadmin create-resource-adapter-config` command. For details, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

If you create a resource adapter configuration for a connector module that is already deployed, the connector module deployment is restarted with the new configuration properties.

## Security Maps

Create a security map for a connector connection pool to map an application principal or a user group to a back end EIS principal. The security map is usually used in situations where one or more EIS back end principals are used to execute operations (on the EIS) initiated by various principals or user groups in the application.

To create or update security maps for a connector connection pool:

- In the Administration Console, open the Resources component, select Connectors, select Connector Connection Pools, and select the Security Maps tab. For details, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Guide.

- Use the `asadmin create-connector-security-map` command. For details, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

If a security map already exists for a connector connection pool, the new security map is appended to the previous one. The connector security map configuration supports the use of the wildcard asterisk (`*`) to indicate all users or all user groups.

When an application principal initiates a request to an EIS, the Application Server first checks for an exact match to a mapped back end EIS principal using the security map defined for the connector connection pool. If there is no exact match, the Application Server uses the wild card character specification, if any, to determined the mapped back end EIS principal.

## Overriding Configuration Properties

You can override the properties specified in the `ra.xml` file of a resource adapter. Use the `asadmin create-resource-adapter-config` command to create a configuration for a resource adapter. Use this command’s `--property` option to specify a name-value pair for a resource adapter property.

You can use the `asadmin create-resource-adapter-config` command either before or after resource adapter deployment. If it is executed after deploying the resource adapter, the existing resource adapter is restarted with the new properties. For details, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

You can also use token replacement for overriding resource adapter configuration properties in individual server instances when the resource adapter is deployed to a cluster. For example, for a property called `inboundPort`, you can assign the value `${inboundPort}`. You can then assign a different value to this property for each server instance. Changes to system properties take effect upon server restart.

## Testing a Connection Pool

After configuring a connector connection pool, use the `asadmin ping-connection-pool` command to test the health of the underlying connections. For details, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

## Handling Invalid Connections

If a resource adapter generates a `ConnectionErrorOccured` event, the Application Server considers the connection invalid and removes the connection from the connection pool. Typically, a resource adapter generates a `ConnectionErrorOccured` event when it finds a `ManagedConnection` object unusable. Reasons can be network failure with the EIS, EIS failure, fatal problems with resource adapter, and so on. If the `fail-all-connections` property in the connection pool configuration is set to `true`, all connections are destroyed and the pool is recreated.

You can set the `fail-all-connections` configuration property during creation of a connector connection pool. Or, you can use the `asadmin set` command to dynamically reconfigure a previously set property. For details, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

The interface `ValidatingManagedConnectionFactory` exposes the method `getInvalidConnections` to allow retrieval of the invalid connections. The Application Server checks if the resource adapter implements this interface, and if it does, invalid connections are removed when the connection pool is resized.

## Setting the Shutdown Timeout

According to the Connector 1.5 specification, while an application server shuts down, all resource adapters should be stopped. A resource adapter might hang during shutdown, since shutdown is typically a resource intensive operation. To avoid such a situation, you can set a timeout that aborts resource adapter shutdown if exceeded. The default timeout is 30 seconds per resource adapter module. To configure this timeout:

- In the Administration Console, select JMS/Connector Service under the relevant configuration. For details, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Guide.

- Use the following command:

      asadmin set server-instance.connector-service.shutdown-timeout-in-seconds="num-secs"

  For details, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

The Application Server deactivates all message-driven bean deployments before stopping a resource adapter.

## Using Last Agent Optimization of Transactions

Transactions that involve multiple resources or multiple participant processes are distributed or global transactions. A global transaction can involve one non-XA resource if last agent optimization is enabled. Otherwise, all resources must be XA. For more information about transactions in the Application Server, see Chapter 12, Using the Transaction Service.

The Connector 1.5 specification requires that if a resource adapter supports `XATransaction`, the `ManagedConnection` created from that resource adapter must support both distributed and local transactions. Therefore, even if a resource adapter supports `XATransaction`, you can configure its connector connection pools as non-XA or without transaction support for better performance. A non-XA resource adapter becomes the last agent in the transactions in which it participates.

The value of the connection pool configuration property `transaction-support` defaults to the value of the `transaction-support` property in the `ra.xml` file. The connection pool configuration property can override the `ra.xml` file property if the transaction level in the connection pool configuration property is lower. If the value in the connection pool configuration property is higher, it is ignored.

# Inbound Communication Support

The Connector 1.5 specification defines the transaction and message inflow system contracts for achieving inbound connectivity from an EIS. The message inflow contract also serves as a standard message provider pluggability contract, thereby allowing various message providers to seamlessly plug in their products with any application server that supports the message inflow contract. In the inbound communication model, the EIS initiates all communication to an application. An application can be composed of enterprise beans (session, entity, or message-driven beans), which reside in an EJB container.

Incoming messages are received through a message endpoint, which is a message-driven bean. This message-driven bean asynchronously consumes messages from a message provider. An application can also synchronously send and receive messages directly using messaging style APIs.

A resource adapter supporting inbound communication provides an instance of an `ActivationSpec` JavaBean class for each supported message listener type. Each class contains a set of configurable properties that specify endpoint activation configuration information during message-driven bean deployment. The `required-config-property` element in the `ra.xml` file provides a list of configuration property names required for each activation specification. An endpoint activation fails if the required property values are not specified. Values for the properties that are overridden in the message-driven bean’s deployment descriptor are applied to the `ActivationSpec` JavaBean when the message-driven bean is deployed.

Administered objects can also be specified for a resource adapter, and these JavaBeans are specific to a messaging style or message provider. For example, some messaging styles may need applications to use special administered objects (such as `Queue` and `Topic` objects in JMS). Applications use these objects to send and synchronously receive messages using connection objects using messaging style APIs. For more information about administered objects, see Chapter 14, Using the Java Message Service.

# Configuring a Message Driven Bean to Use a Resource Adapter

The Connectors 1.5 specification’s message inflow contract provides a generic mechanism to plug in a wide-range of message providers, including JMS, into a J2EE-compatible application server. Message providers use a resource adapter and dispatch messages to message endpoints, which are implemented as message-driven beans.

The message-driven bean developer provides activation configuration information in the message-driven bean’s `ejb-jar.xml` file. Configuration information includes messaging-style-specific configuration details, and possibly message-provider-specific details as well. The message-driven bean deployer uses this configuration information to set up the activation specification JavaBean. The activation configuration properties specified in `ejb-jar.xml` override configuration properties in the activation specification definition in the `ra.xml` file.

According to the EJB specification, the messaging-style-specific descriptor elements contained within the activation configuration element are not specified because they are specific to a messaging provider. In the following sample message-driven bean `ejb-jar.xml`, a message-driven bean has the following activation configuration property names: `destinationType`, `SubscriptionDurability`, and `MessageSelector`.

    <!--  A sample MDB that listens to a JMS Topic -->
    <!-- message-driven bean deployment descriptor -->
    ...
     <activation-config>
       <activation-config-property>
         <activation-config-property-name>
           destinationType
         </activation-config-property-name>
         <activation-config-property-value>
           javax.jms.Topic
         </activation-config-property-value>
      </activation-config-property>
      <activation-config-property>
         <activation-config-property-name>
           SubscriptionDurability
         </activation-config-property-name>
         <activation-config-property-value>
           Durable
         </activation-config-property-value>
      </activation-config-property>
      <activation-config-property>
         <activation-config-property-name>
           MessageSelector
         </activation-config-property-name>
         <activation-config-property-value>
           JMSType = 'car' AND color = 'blue'
         </activation-config-property-value>
      </activation-config-property>
     ...
     </activation-config>
    ...

When the message-driven bean is deployed, the value for the `resource-adapter-mid` element in the `sun-ejb-jar.xml` file is set to the resource adapter module name that delivers messages to the message endpoint (to the message-driven bean). In the following example, the `jmsra` JMS resource adapter, which is the bundled resource adapter for the Sun Java System Message Queue message provider, is specified as the resource adapter module identifier for the `SampleMDB` bean.

    <sun-ejb-jar>
    <enterprise-beans>
    	<unique-id>1</unique-id>
    	<ejb>
    	   <ejb-name>SampleMDB</ejb-name>
    	   <jndi-name>SampleQueue</jndi-name>
        <!-- JNDI name of the destination from which messages would be
             delivered from MDB needs to listen to -->
        ...
    	</ejb>
    	<mdb-resource-adapter>
        <resource-adapter-mid>jmsra</resource-adapter-mid>
        <!-- Resource Adapter Module Id that would deliver messages to
             this message endpoint -->
    	</mdb-resource-adapter>
    ...
    </sun-ejb-jar>

When the message-driven bean is deployed, the Application Server uses the `resourceadapter-mid` setting to associate the resource adapter with a message endpoint through the message inflow contract. This message inflow contract with the application server gives the resource adapter a handle to the `MessageEndpointFactory` and the `ActivationSpec` JavaBean, and the adapter uses this handle to deliver messages to the message endpoint instances (which are created by the `MessageEndpointFactory`).

When a message-driven bean first created for use on the Application Server 7 is deployed, the Connector runtime transparently transforms the previous deployment style to the current connector-based deployment style. If the deployer specifies neither a `resource-adapter-mid` property nor the Message Queue resource adapter’s activation configuration properties, the Connector runtime maps the message-driven bean to the `jmsra` system resource adapter and converts the JMS-specific configuration to the Message Queue resource adapter’s activation configuration properties.

## Example Resource Adapter for Inbound Communication

The inbound sample connector bundled with the Application Server is a good example of an application utilizing the inbound connectivity contract of the J2EE Connector Architecture 1.5 specification. This sample connector is available at install-dir`/samples/connectors/apps/mailconnector`.

This example connector shows how to create an inbound J2EE Connector Architecture 1.5-compliant resource adapter and deploy its components. It shows how these resource adapters interact with other application components. The inbound sample resource adapter allows message endpoints (that is, message-driven beans) to receive email messages delivered to a specific mailbox folder on a given mail server.

The application that is bundled along with this inbound sample connector provides a simple Remote Method Invocation (RMI) back end service that allows the user to monitor the mailbox folders specified by the message-driven beans. The sample application also contains a sample message-driven bean that illustrates how the activation configuration specification properties of the message-driven bean provide the configuration parameters that the back end and resource adapter require to monitor a specific mailbox folder.

The `onMessage` method of the message-driven bean uses the JavaMail API to send a reply acknowledging the receipt of the message. This reply is sufficient to verify that the full process is working.

# Chapter 10 Developing Lifecycle Listeners

Lifecycle listener modules provide a means of running short or long duration Java-based tasks within the application server environment, such as instantiation of singletons or RMI servers. These modules are automatically initiated at server startup and are notified at various phases of the server life cycle.

All lifecycle module classes and interfaces are in the install-dir`/lib/``appserv-rt.jar` file.

The following sections describe how to create and use a lifecycle listener module:

- Server Life Cycle Events

- The LifecycleListener Interface

- The LifecycleEvent Class

- The Server Lifecycle Event Context

- Deploying a Lifecycle Module

- Considerations for Lifecycle Modules

# Server Life Cycle Events

A lifecycle module listens for and performs its tasks in response to the following events in the server life cycle:

- After the `INIT_EVENT`, the server reads the configuration, initializes built-in subsystems (such as security and logging services), and creates the containers.

- After the `STARTUP_EVENT`, the server loads and initializes deployed applications.

- After the `READY_EVENT`, the server is ready to service requests.

- After the `SHUTDOWN_EVENT`, the server destroys loaded applications and stops.

- After the `TERMINATION_EVENT`, the server closes the containers, the built-in subsystems, and the server runtime environment.

These events are defined in the `LifecycleEvent` class.

The lifecycle modules that listen for these events implement the `LifecycleListener` interface.

# The LifecycleListener Interface

To create a lifecycle module is to configure a customized class that implements the `com.sun.appserv.server.LifecycleListener` interface. You can create and simultaneously execute multiple lifecycle modules.

The `LifecycleListener` interface defines this method:

    public void handleEvent(com.sun.appserv.server.LifecycleEvent event)
    throws ServerLifecycleException

This method responds to a lifecycle event and throws a `com.sun.appserv.server.``ServerLifecycleException` if an error occurs.

A sample implementation of the `LifecycleListener` interface is the `LifecycleListenerImpl.java` file, which you can use for testing lifecycle events.

# The LifecycleEvent Class

The `com.sun.appserv.server.``LifecycleEvent` class defines a server life cycle event. The following methods are associated with the event:

- `public java.lang.Object` `getData()`

  This method returns the data associated with the event.

- `public int` `getEventType()`

  This method returns the type of the last event, which is `INIT_EVENT`, `STARTUP_EVENT`, `READY_EVENT`, `SHUTDOWN_EVENT`, or `TERMINATION_EVENT`.

- `public com.sun.appserv.server.LifecycleEventContext` `getLifecycleEventContext()`

  This method returns the lifecycle event context, described next.

A `LifecycleEvent` instance is passed to the `LifecycleListener.handleEvent` method.

# The Server Lifecycle Event Context

The `com.sun.appserv.server.``LifecycleEventContext` interface exposes runtime information about the server. The lifecycle event context is created when the `LifecycleEvent` class is instantiated at server initialization. The `LifecycleEventContext` interface defines these methods:

- `public java.lang.String[]` `getCmdLineArgs()`

  This method returns the server startup command-line arguments.

- `public java.lang.String` `getInstallRoot()`

  This method returns the server installation root directory.

- `public java.lang.String` `getInstanceName()`

  This method returns the server instance name.

- `public javax.naming.InitialContext` `getInitialContext()`

  This method returns the initial JNDI naming context. The naming environment for lifecycle modules is installed after the `STARTUP_EVENT`. A lifecycle module can look up any resource by its `jndi-name` attribute after the `READY_EVENT`.

If a lifecycle module needs to look up resources, it can do so after the `READY_EVENT`. It can use the `getInitialContext()` method to get the initial context to which all the resources are bound.

# Deploying a Lifecycle Module

You can deploy a lifecycle module using the following tools:

- In the Administration Console, open the Applications component and go to the Lifecycle Modules page. For details, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Administration Guide.

- Use the ```asadmin create-lifecycle-module` command. For details, see the Sun Java System Application Server Enterprise Edition 8.1 2005Q2 Reference Manual.

After you deploy a lifecycle module, you must restart the server to activate it. The server instantiates it and registers it as a lifecycle event listener at server initialization.

Note –

If the `is-failure-fatal` setting is set to `true` (the default is `false`), lifecycle module failure prevents server initialization or startup, but not shutdown or termination.

# Considerations for Lifecycle Modules

The resources allocated at initialization or startup should be freed at shutdown or termination. The lifecycle module classes are called synchronously from the main server thread, therefore it is important to ensure that these classes don’t block the server. Lifecycle modules can create threads if appropriate, but these threads must be stopped in the shutdown and termination phases.

The LifeCycleModule Classloader is the parent class loader for lifecycle modules. Each lifecycle module’s `classpath` in `domain.xml` is used to construct its class loader. All the support classes needed by a lifecycle module must be available to the LifeCycleModule Classloader or its parent, the Connector Classloader.

You must ensure that the `server.policy` file is appropriately set up, or a lifecycle module trying to perform a `System.exec()` might cause a security access violation. For details, see The server.policy File.

The configured properties for a lifecycle module are passed as properties after the `INIT_EVENT`. The JNDI naming context is not available before the `STARTUP_EVENT`. If a lifecycle module requires the naming context, it can get this after the `STARTUP_EVENT`, `READY_EVENT`, or `SHUTDOWN_EVENT`.

- Previous: Part I Developing and Deploying Applications
- Next: Part III Using Services and APIs

- © 2010, Oracle Corporation and/or its affiliates