Sun Java System Application Server Enterprise Edition 8.2 Developer's Guide

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:

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.

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.2 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

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.

?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:

For more information, see the Sun Java System Application Server Enterprise Edition 8.2 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

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

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:

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

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:

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

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.2 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

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:

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

This section covers the following topics:

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.2 Administration Guide and the Sun Java System Application Server Enterprise Edition 8.2 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:


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:

For information about how to work around these limitations, see the Sun Java System Application Server Enterprise Edition 8.2 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:


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.2 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.2 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.2 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.2 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.2 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

Advanced Web Application Features

This section includes summaries of the following topics:

Internationalization Issues

This section covers internationalization as it applies to the following:

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.2 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:

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:

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.2 Administration Guide.)

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

ProcedureTo 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.2 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.

ProcedureTo 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.

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.2 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

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.

The error page is displayed according to the following rules:

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.addXXXHeader() and HttpServletResponse.setXXXHeader() 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 redirect_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.2 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"/>

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:

For general information about enterprise beans (also called EJB components), read the chapters on enterprise beans, session beans, message-driven beans, and so on in the J2EE 1.4 Tutorial at http://java.sun.com/j2ee/1.4/docs/tutorial/doc/index.html.

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:

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

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:

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.2 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.

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

Using Session Beans

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

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:

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.2 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:

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.2 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

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

Choose the persistence store in one of the following ways:

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

Enabling Checkpointing

The following sections describe how to enable SFSB checkpointing:

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.2 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:

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

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:

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 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:

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:

Refreshing Read-Only Beans

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

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.


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

This section addresses the following configuration topics:

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.xmlfile 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):

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:

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.2 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.2 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

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.2 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:

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:

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

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:

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.2 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:

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

You might also want to read the chapters on CMP and Enterprise JavaBeans Query Language (EJB QL) in the J2EE 1.4 Tutorial at http://java.sun.com/j2ee/1.4/docs/tutorial/doc/index.html.

Sun Java System Application Server Support

Application Server support for CMP includes:

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

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:

The Mapping Deployment Descriptor File

Each module with CMP beans must have the following files:

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:

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.2 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.2 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

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.2 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 

Java DB, Derby, CloudScape 

Oracle  

DB2 

Sybase ASE 12.5 

MS-SQL Server 

BIT

SMALLINT

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

REAL

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:


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 javadb, db2, mssql, oracle, pointbase, derby (also for CloudScape), 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 javadb, db2, mssql, oracle, pointbase, derby (also for CloudScape), 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.2 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

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.2 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:

Configuring the CMP Resource

An EJB module that contains CMP beans requires the JNDI name of a JDBC resource in the jndi-name subelement of the cmp-resource element in the sun-ejb-jar.xml file. 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. Refer to the Sun Java System Application Server Enterprise Edition 8.2 Administration Guide for information on creating a new JDBC resource.

For a list of the JDBC drivers currently supported by the Application Server, see the Sun Java System Application Server Enterprise Edition 8.2 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>

Configuring Queries for 1.1 Finders

This section contains the following topics:

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:

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:


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:

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.


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).

ProcedureTo 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.

Access to CMR fields of read-only beans is not supported. Deployment will succeed, but an exception will be thrown at runtime if a get or set method is invoked.

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

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:

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

MySQL Database Restrictions

The following restrictions apply when you use a MySQL database with the Application Server for CMP.

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

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:

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

ProcedureTo 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.2 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.2 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

Connecting to a Remote EJB Module Through a Firewall

To deploy and run an application client that connects to an EJB module on an Application Server instance that is behind a firewall, you must set ORB Virtual Address Agent Implementation (ORBVAA) options. Use the asadmin create-jvm-options command as follows:

asadmin create-jvm-options --user adminuser -Dcom.sun.corba.ee.ORBVAAHost=public-IP-address 
asadmin create-jvm-options --user adminuser -Dcom.sun.corba.ee.ORBVAAPort=3700
asadmin create-jvm-options --user adminuser
-Dcom.sun.corba.ee.ORBUserConfigurators.com.sun.corba.ee.impl.plugin.hwlb.VirtualAddressAgentImpl=x

Set the ORBVAAHost and ORBVAAPort options to the host and port of the public address. The ORBUserConfigurators option tells the ORB to create an instance of the VirtualAddressAgentImpl class and invoke the configure method on the resulting object, which must implement the com.sun.corba.ee.spi.orb.ORBConfigurator interface. The ORBUserConfigurators value doesn't matter. Together, these options create an ORB that in turn creates Object references (the underlying implementation of remote EJB references) containing the public address, while the ORB listens on the private address specified for the IIOP port in the Application Server configuration.

ProcedureTo 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.2 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

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

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:

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>

ProcedureTo 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.2 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:

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

ProcedureTo 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.2 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

ProcedureTo 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.2 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

ProcedureTo 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.2 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.

You might also want to read the appendix on connector architecture in the J2EE 1.4 Tutorial at http://java.sun.com/j2ee/1.4/docs/tutorial/doc/index.html.

This chapter includes the following topics:

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:

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.2 Administration Guide. For information about using the asadmin command, see the Sun Java System Application Server Enterprise Edition 8.2 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.

ProcedureTo 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

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:

To associate a connector with a thread pool:

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:

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.2 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.2 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.2 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:

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

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

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:

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:

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:

You do not need to specify a classpath for the lifecycle module if you place it in the domain-dir/lib or domain-dir/lib/classes directory for the Domain Administration Server. Do not place it in the lib directory for a particular instance, or it will be deleted when that instance synchronizes with the Domain Administration Server.

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.