blob: 25f20e57c278aae37062b1943d3d84e0ce98e672 [file] [log] [blame]
type=page
status=published
title=Using Enterprise JavaBeans Technology
next=container_managed-persistence.html
prev=webapps.html
~~~~~~
= Using Enterprise JavaBeans Technology
[[GSDVG00010]][[beahl]]
[[using-enterprise-javabeans-technology]]
== 8 Using Enterprise JavaBeans Technology
This chapter describes how Enterprise JavaBeans ( EJB) technology is
supported in the {productName}.
The following topics are addressed here:
* link:#beahn[Value Added Features]
* link:#beahw[EJB Timer Service]
* link:#beahx[Using Session Beans]
* link:#beail[Using Read-Only Beans]
* link:#beait[Using Message-Driven Beans]
For general information about enterprise beans, see
https://eclipse-ee4j.github.io/jakartaee-tutorial/#enterprise-beans[Enterprise Beans]
in The Jakarta EE Tutorial.
[NOTE]
====
The Web Profile of the {productName} supports the EJB 3.1 Lite
specification, which allows enterprise beans within web applications,
among other features. The full {productName} supports the entire EJB
3.1 specification. For details, see
http://jcp.org/en/jsr/detail?id=318[JSR 318]
(`http://jcp.org/en/jsr/detail?id=318`).
The {productName} is backward compatible with 1.1, 2.0, 2.1, and 3.0
enterprise beans. However, to take advantage of version 3.1 features,
you should develop new beans as 3.1 enterprise beans.
====
[[beahn]][[GSDVG00145]][[value-added-features]]
=== Value Added Features
The {productName} provides a number of value additions that relate to
EJB development. References to more in-depth material are included.
The following topics are addressed here:
* link:#beaho[Read-Only Beans]
* link:#beahp[The `pass-by-reference` Element]
* link:#beahq[Pooling and Caching]
* link:#beahu[Priority Based Scheduling of Remote Bean Invocations]
* link:#beahv[Immediate Flushing]
[[beaho]][[GSDVG00420]][[read-only-beans]]
==== Read-Only Beans
Another feature that the {productName} provides is the read-only
bean, an EJB 2.1 entity bean that is never modified by an EJB client.
Read-only beans avoid database updates completely.
[NOTE]
====
Read-only beans are specific to the {productName} and are not part of
the Enterprise JavaBeans Specification, v2.1. Use of this feature for an
EJB 2.1 bean results in a non-portable application.
To make an EJB 3.0 entity read-only, use `@Column` annotations to mark
its columns `insertable=false` and `updatable=false`.
====
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 {productName} 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 `glassfish-ejb-jar.xml` file
and the `trans-attribute` element (or `@TransactionAttribute`
annotation) in the `ejb-jar.xml` file, it is easy to configure a
read-only bean that is one of the following:
* Always refreshed
* Periodically refreshed
* Never refreshed
* 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 link:#beail[Using Read-Only Beans].
[[beahp]][[GSDVG00421]][[the-pass-by-reference-element]]
==== The `pass-by-reference` Element
The `pass-by-reference` element in the `glassfish-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
"link:application-deployment-guide/dd-elements.html#GSDPG00219[pass-by-reference]" in {productName} Application Deployment Guide.
[[beahq]][[GSDVG00422]][[pooling-and-caching]]
==== Pooling and Caching
The EJB container of the {productName} 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 method calls. 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 `glassfish-ejb-jar.xml` file.
In addition, the {productName} 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 `glassfish-ejb-jar.xml` file.
Pooling and caching parameters for the `glassfish-ejb-jar.xml` file are
described in "link:application-deployment-guide/dd-elements.html#GSDPG00095[bean-cache]" in {productName} Application Deployment Guide.
[[beahr]][[GSDVG00285]][[pooling-parameters]]
===== Pooling Parameters
One of the most important parameters for {productName} pooling is
`steady-pool-size`. When `steady-pool-size` is set to a value greater
than 0, the container not only pre-populates the bean pool with the
specified number of beans, but also attempts to ensure that this number
of beans is always available in the free pool. This ensures that there
are enough beans in the ready-to-serve state to process user requests.
Note that the `steady-pool-size` and `max-pool-size` parameters only
govern the number of instances that are pooled over a long period of
time. They do not necessarily guarantee that the number of instances
that may exist in the JVM at a given time will not exceed the value
specified by `max-pool-size`. 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 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.
[[beahs]][[GSDVG00286]][[caching-parameters]]
===== Caching Parameters
{productName} 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
link:transaction-service.html#beajh[Commit Options].
The {productName} 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).
[[beahu]][[GSDVG00423]][[priority-based-scheduling-of-remote-bean-invocations]]
==== Priority Based Scheduling of Remote Bean Invocations
You can create multiple thread pools, each having its own work queues.
An optional element in the `glassfish-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.
[[beahv]][[GSDVG00424]][[immediate-flushing]]
==== 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
`glassfish-ejb-jar.xml` file. Only non-finder methods in an entity bean
can be flush-enabled. (For an EJB 2.1 bean, these methods must be in the
Local, Local Home, Remote, or Remote Home interface.) See
"link:application-deployment-guide/dd-elements.html#GSDPG00156[flush-at-end-of-method]" in {productName} Application Deployment Guide.
Upon completion of the method, the EJB container updates the database.
Any exception thrown by the underlying data store is wrapped as follows:
* If the method that triggered the flush is a `create` method, the
exception is wrapped with `CreateException`.
* If the method that triggered the flush is a `remove` method, the
exception is wrapped with `RemoveException`.
* For all other methods, the exception is wrapped with `EJBException`.
All normal end-of-transaction database synchronization steps occur
regardless of whether the database has been flushed during the
transaction.
[[beahw]][[GSDVG00146]][[ejb-timer-service]]
=== EJB Timer Service
The EJB Timer Service uses a database to store persistent information
about EJB timers. The EJB Timer Service in {productName} is
preconfigured to use an embedded version of the Apache Derby database.
The EJB Timer Service configuration can store persistent timer
information in any database supported by the {productName} for
persistence. For a list of the JDBC drivers currently supported by the
{productName}, see the link:release-notes.html#GSRLN[{productName} Release Notes]. For configurations of supported and other
drivers, see "link:administration-guide/jdbc.html#GSADG00579[Configuration Specifics for JDBC
Drivers]" in {productName} Administration Guide.
The timer service is automatically enabled when you deploy an
application or module that uses it. You can verify that the timer
service is running by accessing the following URL:
[source]
----
http://localhost:8080/ejb-timer-service-app/timer
----
To change the database used by the EJB Timer Service, set the EJB Timer
Service's Timer DataSource setting to a valid JDBC resource. If the EJB
Timer Service has already been started in a server instance, you must
also create the timer database table. DDL files are located in
as-install``/lib/install/databases``.
Using the EJB Timer Service is equivalent to interacting with a single
JDBC resource manager. If an EJB component or application accesses a
database either directly through JDBC or indirectly (for example,
through an entity bean's persistence mechanism), and also interacts with
the EJB Timer Service, its data source must be configured with an XA
JDBC driver.
You can change the following EJB Timer Service settings. You must
restart the server for the changes to take effect.
Minimum Delivery Interval::
Specifies the minimum time in milliseconds before an expiration for a
particular timer can occur. This guards against extremely small timer
increments that can overload the server. The default is `1000`.
Maximum Redeliveries::
Specifies the maximum number of times the EJB timer service attempts
to redeliver a timer expiration after an exception or rollback of a
container-managed transaction. The default is `1`.
Redelivery Interval::
Specifies how long in milliseconds the EJB timer service waits after a
failed `ejbTimeout` delivery before attempting a redelivery. The
default is `5000`.
Timer DataSource::
Specifies the database used by the EJB Timer Service. The default is
`jdbc/__TimerPool`.
+
[CAUTION]
====
Do not use the `jdbc/\__TimerPool` resource for timers in clustered
{productName} environments.
You must instead use a custom JDBC resource or the `jdbc/__default` resource.
See the instructions below, in link:#gktqo[To Deploy an EJB Timer to a Cluster].
Also refer to
"link:administration-guide/jdbc.html#GSADG00747[Enabling the jdbc/__default Resource in a Clustered Environment]"
in {productName} Administration Guide.
====
For information about the `asadmin list-timers` and
`asadmin migrate-timers` subcommands, see the link:reference-manual.html#GSRFM[{productName} Reference Manual]. For information about
migrating EJB timers, see "link:ha-administration-guide/instances.html#GSHAG00190[Migrating EJB Timers]" in
{productName} High Availability Administration
Guide.
You can use the `--keepstate` option of the `asadmin redeploy` command
to retain EJB timers between redeployments.
The default for `--keepstate` is false. This option is supported only on
the default server instance, named `server`. It is not supported and
ignored for any other target.
When the `--keepstate` is set to true, each application that uses an EJB
timer is assigned an ID in the timer database. The EJB object that is
associated with a given application is assigned an ID that is
constructed from the application ID and a numerical suffix. To preserve
active timer data, {productName} stores the application ID and the
EJB ID in the timer database. To restore the data, the class loader of
the newly redeployed application retrieves the EJB timers that
correspond to these IDs from the timer database.
For more information about the `asadmin redeploy` command, see the
link:reference-manual.html#GSRFM[{productName} Reference Manual].
[[gktqo]][[GSDVG00070]][[to-deploy-an-ejb-timer-to-a-cluster]]
==== To Deploy an EJB Timer to a Cluster
This procedure explains how to deploy an EJB timer to a cluster.
By default, the {productName} 7 timer service points to the
preconfigured `jdbc/__TimerPool` resource, which uses an embedded Apache
Derby database configuration that will not work in clustered
environments.
The problem is that embedded Apache Derby database runs in the {productName} Java VM, so when you use the `jdbc/__TimerPool` resource, each
DAS and each clustered server instance will have its own database table.
Because of this, clustered server instances will not be able to find the
database table on the DAS, and the DAS will not be able to find the
tables on the clustered server instances.
The solution is to use either a custom JDBC resource or the
`jdbc/__default` resource that is preconfigured but not enabled by
default in {productName}. The `jdbc/__default` resource does not use
the embedded Apache Derby database by default.
[[GSDVG547]]
Before You Begin
If creating a new timer resource, the resource should be created before
deploying applications that will use the timer.
[CAUTION]
====
Do not use the `jdbc/\__TimerPool` resource for timers in clustered
{productName} environments.
You must instead use a custom JDBC resource or the `jdbc/__default` resource.
See "link:GSADG00747[Enabling the jdbc/__default Resource in a Clustered Environment]"
in {productName} Administration Guide.
====
1. Execute the following command:
+
[source]
----
asadmin set configs.config.cluster_name-config.ejb-container.ejb-timer-service.timer-
datasource=jdbc/my-timer-resource
----
2. Restart the DAS and the target cluster(s).
+
[source]
----
asadmin stop-cluster cluster-name
asadmin stop-domain domain-name
asadmin start-domain domain-name
asadmin start-cluster cluster-name
----
[[GSDVG548]]
Troubleshooting
If you inadvertently used the `jdbc/__TimerPool` resource for your EJB
timer in a clustered {productName} environment, the DAS and the
clustered server instances will be using separate Apache Derby database
tables that are running in individual Java VMs. For timers to work in a
clustered environment, the DAS and the clustered server instances must
share a common database table.
If you attempt to deploy an application with EJB timers without setting
the timer resource correctly, the startup will fail, and you will be
left with a marker file, named `ejb-timer-service-app`, on the DAS that
will prevent the Timer Service from correctly creating the database
table.
The solution is to remove the marker file on the DAS, restart the DAS
and the clusters, and then redploy any applications that rely on the
offending EJB timer. The marker file is located on the DAS in
domain-dir`/generated/ejb/``ejb-timer-service-app`.
[[beahx]][[GSDVG00147]][[using-session-beans]]
=== Using Session Beans
This section provides guidelines for creating session beans in the
{productName} environment.
The following topics are addressed here:
* link:#beahy[About the Session Bean Containers]
* link:#beaib[Stateful Session Bean Failover]
* link:#beaii[Session Bean Restrictions and Optimizations]
Information on session beans is contained in the Enterprise JavaBeans
Specification, v3.1.
[[beahy]][[GSDVG00425]][[about-the-session-bean-containers]]
==== About the Session Bean Containers
Like an entity bean, a session bean can access a database through Java
Database Connectivity (JDBC) 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.
The following topics are addressed here:
* link:#beahz[Stateless Container]
* link:#beaia[Stateful Container]
[[beahz]][[GSDVG00287]][[stateless-container]]
===== 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 {productName} specific deployment descriptor file,
`glassfish-ejb-jar.xml`, contains the properties that define the pool:
* `steady-pool-size`
* `resize-quantity`
* `max-pool-size`
* `pool-idle-timeout-in-seconds`
For more information about `glassfish-ejb-jar.xml`, see
"link:application-deployment-guide/dd-files.html#GSDPG00079[The glassfish-ejb-jar.xml File]" in {productName} Application Deployment Guide.
The {productName} 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 link:reference-manual.html#GSRFM[{productName} Reference Manual].
[[beaia]][[GSDVG00288]][[stateful-container]]
===== 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
`glassfish-ejb-jar.xml` parameters:
* `max-cache-size`
* `resize-quantity`
* `cache-idle-timeout-in-seconds`
* `removal-timeout-in-seconds`
* `victim-selection-policy`
The `max-cache-size` element specifies the maximum number of session
beans that are held in cache. If the cache overflows (when the number of
beans exceeds `max-cache-size`), the container then passivates some
beans or writes out the serialized state of the bean into a file. The
directory in which the file is created is obtained from the EJB
container using the configuration APIs.
For more information about `glassfish-ejb-jar.xml`, see
"link:application-deployment-guide/dd-files.html#GSDPG00079[The glassfish-ejb-jar.xml File]" in {productName} Application Deployment Guide.
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 link:securing-apps.html#beabx[The
`server.policy` File].
====
The Session Store Location setting also determines where the session
state is persisted if it is not highly available; see
link:#beaic[Choosing a Persistence Store].
[[beaib]][[GSDVG00426]][[stateful-session-bean-failover]]
==== 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 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.
[[GSDVG549]][[sthref18]][[fvyed]]
Table 8-1 Object Types Supported for Jakarta EE Stateful Session Bean State
Failover
[width="100%",cols="45%,55%",options="header",]
|===
|Java Object Type |Failover Support
|Colocated or distributed stateless session, stateful session, or entity bean 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
|JavaMail Session
|No
|Connection Factory
|No
|Administered Object
|No
|Web service reference
|No
|Serializable Java types
|Yes
|Extended persistence context
|No
|===
For more information about the `InitialContext`, see
link:jndi.html#beans[Accessing the Naming Context]. For more information
about transaction recovery, see link:transaction-service.html#beanm[Using
the Transaction Service]. For more information about Administered
Objects, see "link:administration-guide/jms.html#GSADG00599[Administering JMS Physical Destinations]"
in {productName} Administration Guide.
[NOTE]
====
Idempotent URLs are supported along the HTTP path, but not the RMI-IIOP
path. For more information, see link:webapps.html#beage[Configuring
Idempotent URL Requests].
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
link:webapps.html#beahe[Distributed Sessions and Persistence].
If an SFSB that uses session persistence is undeployed while the
{productName} instance is stopped, the session data in the
persistence store might not be cleared. To prevent this, undeploy the
SFSB while the {productName} instance is running.
====
Configure SFSB failover by:
* link:#beaic[Choosing a Persistence Store]
* link:#beaid[Enabling Checkpointing]
* link:#beaih[Specifying Methods to Be Checkpointed]
[[beaic]][[GSDVG00289]][[choosing-a-persistence-store]]
===== Choosing a Persistence Store
The following types of persistent storage are supported for passivation
and checkpointing of the SFSB state:
* The local file system - Allows a single server instance to recover the
SFSB state after a failure and restart. This store also provides
passivation and activation of the state to help control the amount of
memory used. This option is not supported in a production environment
that requires SFSB state persistence. This is the default storage
mechanism if availability is not enabled.
* Other servers - Uses other server instances in the cluster for session
persistence. Clustered server instances replicate session state. Each
backup instance stores the replicated data in memory. This is the
default storage mechanism if availability is enabled.
Choose the persistence store in one of the following ways:
* To use the local file system, first disable availability. Select the
Availability Service component under the relevant configuration in the
Administration Console. Uncheck the Availability Service box. Then
select the EJB Container component and edit the Session Store Location
value. The default is domain-dir`/session-store`.
* To use other servers, select the Availability Service component under
the relevant configuration in the Administration Console. Check the
Availability Service box. To enable availability for the EJB container,
select the EJB Container Availability tab, then check the Availability
Service box. All instances in an {productName} cluster should have
the same availability settings to ensure consistent behavior.
For more information about SFSB state persistence, see the
link:ha-administration-guide.html#GSHAG[{productName} High Availability
Administration Guide].
[[gkpdg]][[GSDVG00033]][[using-the---keepstate-option]]
Using the `--keepstate` Option
If you are using the file system for persistence, you can use the
`--keepstate` option of the `asadmin redeploy` command to retain the
SFSB state between redeployments.
The default for `--keepstate` is false. This option is supported only on
the default server instance, named `server`. It is not supported and
ignored for any other target.
Some changes to an application between redeployments prevent this
feature from working properly. For example, do not change the set of
instance variables in the SFSB bean class.
If any active SFSB instance fails to be preserved or restored, none of
the SFSB instances will be available when the redeployment is complete.
However, the redeployment continues and a warning is logged.
To preserve active state data, {productName} serializes the data and
saves it in memory. To restore the data, the class loader of the newly
redeployed application deserializes the data that was previously saved.
For more information about the `asadmin redeploy` command, see the
link:reference-manual.html#GSRFM[{productName} Reference Manual].
[[gkpef]][[GSDVG00034]][[using-the---asyncreplication-option]]
Using the `--asyncreplication` Option
If you are using replication on other servers for persistence, you can
use the `--asyncreplication` option of the `asadmin deploy` command to
specify that SFSB states are first buffered and then replicated using a
separate asynchronous thread. If `--asyncreplication` is set to true
(default), performance is improved but availability is reduced. If the
instance where states are buffered but not yet replicated fails, the
states are lost. If set to false, performance is reduced but
availability is guaranteed. States are not buffered but immediately
transmitted to other instances in the cluster.
For more information about the `asadmin deploy` command, see the
link:reference-manual.html#GSRFM[{productName} Reference Manual].
[[beaid]][[GSDVG00290]][[enabling-checkpointing]]
===== Enabling Checkpointing
The following sections describe how to enable SFSB checkpointing:
* link:#beaie[Server Instance and EJB Container Levels]
* link:#beaif[Application and EJB Module Levels]
* link:#beaig[SFSB Level]
[[beaie]][[GSDVG00035]][[server-instance-and-ejb-container-levels]]
Server Instance and EJB Container Levels
To enable SFSB checkpointing at the server instance or EJB container
level, see link:#beaic[Choosing a Persistence Store].
[[beaif]][[GSDVG00036]][[application-and-ejb-module-levels]]
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 link:reference-manual.html#GSRFM[{productName}
Reference Manual].
[[beaig]][[GSDVG00037]][[sfsb-level]]
SFSB Level
To enable SFSB checkpointing at the SFSB level, set
`availability-enabled="true"` in the `ejb` element of the SFSB's
`glassfish-ejb-jar.xml` file as follows:
[source,xml]
----
<glassfish-ejb-jar>
...
<enterprise-beans>
...
<ejb availability-enabled="true">
<ejb-name>MySFSB</ejb-name>
</ejb>
...
</enterprise-beans>
</glassfish-ejb-jar>
----
[[beaih]][[GSDVG00291]][[specifying-methods-to-be-checkpointed]]
===== 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 `glassfish-ejb-jar.xml`.
For example:
[source,xml]
----
<glassfish-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>
</glassfish-ejb-jar>
----
For details, see "link:application-deployment-guide/dd-elements.html#GSDPG00108[checkpoint-at-end-of-method]" in
{productName} Application Deployment Guide.
The non-transactional methods in the `checkpoint-at-end-of-method`
element can be the following:
* `create` methods defined in the home or business interface of the
SFSB, if you want to checkpoint the initial state of the SFSB
immediately after creation
* For SFSBs using container managed transactions only, methods in the
remote interface of the bean marked with the transaction attribute
TX_NOT_SUPPORTED or TX_NEVER
* For SFSBs using bean managed transactions only, methods in which a
bean managed transaction is neither started nor committed
Any other methods mentioned in this list are ignored. At the end of
invocation of each of these methods, the EJB container saves the state
of the SFSB to persistent store.
[NOTE]
====
If an SFSB does not participate in any transaction, and if none of its
methods are explicitly specified in the `checkpoint-at-end-of-method`
element, the bean's state is not checkpointed at all even if
`availability-enabled="true"` for this bean.
For better performance, specify a small subset of methods. The methods
chosen should accomplish a significant amount of work in the context of
the Jakarta EE application or should result in some important modification
to the bean's state.
====
[[beaii]][[GSDVG00427]][[session-bean-restrictions-and-optimizations]]
==== Session Bean Restrictions and Optimizations
This section discusses restrictions on developing session beans and
provides some optimization guidelines.
* link:#beaij[Optimizing Session Bean Performance]
* link:#beaik[Restricting Transactions]
* link:#glanq[EJB Singletons]
[[beaij]][[GSDVG00292]][[optimizing-session-bean-performance]]
===== 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.
[[beaik]][[GSDVG00293]][[restricting-transactions]]
===== Restricting Transactions
The following restrictions on transactions are enforced by the container
and must be observed as session beans are developed:
* A session bean can participate in, at most, a single transaction at a
time.
* If a session bean is participating in a transaction, a client cannot
invoke a method on the bean such that the `trans-attribute` element (or
`@TransactionAttribute` annotation) in the `ejb-jar.xml` file would
cause the container to execute the method in a different or unspecified
transaction context or an exception is thrown.
* If a session bean instance is participating in a transaction, a client
cannot invoke the `remove` method on the session object's home or
business interface object, or an exception is thrown.
[[glanq]][[GSDVG00294]][[ejb-singletons]]
===== EJB Singletons
EJB Singletons are created for each server instance in a cluster, and
not once per cluster.
[[beail]][[GSDVG00148]][[using-read-only-beans]]
=== Using Read-Only Beans
A read-only bean is an EJB 2.1 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 the {productName} and are not part of
the Enterprise JavaBeans Specification, v2.1. Use of this feature for an
EJB 2.1 bean results in a non-portable application.
To make an EJB 3.0 entity bean read-only, use `@Column` annotations to
mark its columns `insertable=false` and `updatable=false`.
====
Read-only beans are best suited for situations where the underlying data
never changes, or changes infrequently.
The following topics are addressed here:
* link:#beaim[Read-Only Bean Characteristics and Life Cycle]
* link:#beain[Read-Only Bean Good Practices]
* link:#beaio[Refreshing Read-Only Beans]
* link:#beais[Deploying Read-Only Beans]
[[beaim]][[GSDVG00428]][[read-only-bean-characteristics-and-life-cycle]]
==== Read-Only Bean Characteristics and Life Cycle
Read-only beans are best suited for situations where the underlying data
never changes, or changes infrequently. For example, a read-only bean
can be used to represent a stock quote for a particular company, which
is updated externally. In such a case, using a regular entity bean might
incur the burden of calling `ejbStore`, which can be avoided by using a
read-only bean.
Read-only beans have the following characteristics:
* Only entity beans can be read-only beans.
* Either bean-managed persistence (BMP) or container-managed persistence
(CMP) is allowed. If CMP is used, do not create the database schema
during deployment. Instead, work with your database administrator to
populate the data into the tables. See
link:container_managed-persistence.html#beajj[Using Container-Managed
Persistence].
* Only container-managed transactions are allowed; read-only beans
cannot start their own transactions.
* Read-only beans don't update any bean state.
* `ejbStore` is never called by the container.
* `ejbLoad` is called only when a transactional method is called or when
the bean is initially created (in the cache), or at regular intervals
controlled by the bean's `refresh-period-in-seconds` element in the
`glassfish-ejb-jar.xml` file.
* The home interface can have any number of find methods. The return
type of the find methods must be the primary key for the same bean type
(or a collection of primary keys).
* If the data that the bean represents can change, then
`refresh-period-in-seconds` must be set to refresh the beans at regular
intervals. `ejbLoad` is called at this regular interval.
A read-only bean comes into existence using the appropriate find
methods.
Read-only beans are cached and have the same cache properties as entity
beans. When a read-only bean is selected as a victim to make room in the
cache, `ejbPassivate` is called and the bean is returned to the free
pool. When in the free pool, the bean has no identity and is used only
to serve any finder requests.
Read-only beans are bound to the naming service like regular read-write
entity beans, and clients can look up read-only beans the same way
read-write entity beans are looked up.
[[beain]][[GSDVG00429]][[read-only-bean-good-practices]]
==== Read-Only Bean Good Practices
For best results, follow these guidelines when developing read-only
beans:
* Avoid having any `create` or `remove` methods in the home interface.
* Use any of the valid EJB 2.1 transaction attributes for the
`trans-attribute` element.
+
The reason for having `TX_SUPPORTED` is to allow reading uncommitted
data in the same transaction. Also, the transaction attributes can be
used to force `ejbLoad`.
[[beaio]][[GSDVG00430]][[refreshing-read-only-beans]]
==== Refreshing Read-Only Beans
There are several ways of refreshing read-only beans, as addressed in
the following sections:
* link:#beaip[Invoking a Transactional Method]
* link:#beaiq[Refreshing Periodically]
* link:#beair[Refreshing Programmatically]
[[beaip]][[GSDVG00295]][[invoking-a-transactional-method]]
===== Invoking a Transactional Method
Invoking any transactional method invokes `ejbLoad`.
[[beaiq]][[GSDVG00296]][[refreshing-periodically]]
===== Refreshing Periodically
Use the `refresh-period-in-seconds` element in the
`glassfish-ejb-jar.xml` file to refresh a read-only bean periodically.
* If the value specified in `refresh-period-in-seconds` is zero or not
specified, which is the default, the bean is never refreshed (unless a
transactional method is accessed).
* If the value is greater than zero, the bean is refreshed at the rate
specified.
[NOTE]
====
This is the only way to refresh the bean state if the data can be
modified external to the {productName}.
====
By default, a single timer is used for all instances of a read-only
bean. When that timer fires, all bean instances are marked as expired
and are refreshed from the database the next time they are used.
Use the `-Dcom.sun.ejb.containers.readonly.relative.refresh.mode=true`
flag to refresh each bean instance independently upon access if its
refresh period has expired. The default is `false`. Note that each
instance still has the same refresh period. This additional level of
granularity can improve the performance of read-only beans that do not
need to be refreshed at the same time.
To set this flag, use the `asadmin create-jvm-options` command. For
example:
[source]
----
asadmin create-jvm-options -Dcom.sun.ejb.containers.readonly.relative.refresh.mode=true
----
[[beair]][[GSDVG00297]][[refreshing-programmatically]]
===== 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:
[source,java]
----
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:
[source,java]
----
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:
[source,java]
----
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`.
For Javadoc tool pages relevant to read-only beans, go to
`http://glassfish.java.net/nonav/docs/v3/api/` and click on the
`com.sun.appserv.ejb` package.
[[beais]][[GSDVG00431]][[deploying-read-only-beans]]
==== 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 `glassfish-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
`glassfish-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
"link:application-deployment-guide/dd-files.html#GSDPG00079[The glassfish-ejb-jar.xml File]" in {productName} Application Deployment Guide.
[[beait]][[GSDVG00149]][[using-message-driven-beans]]
=== Using Message-Driven Beans
This section describes message-driven beans and explains the
requirements for creating them in the {productName} environment.
The following topics are addressed here:
* link:#beaiu[Message-Driven Bean Configuration]
* link:#beaiy[Message-Driven Bean Restrictions and Optimizations]
[[beaiu]][[GSDVG00432]][[message-driven-bean-configuration]]
==== Message-Driven Bean Configuration
The following topics are addressed here:
* link:#beaiv[Connection Factory and Destination]
* link:#beaiw[Message-Driven Bean Pool]
* link:#beaix[Domain-Level Settings]
For information about setting up load balancing for message-driven
beans, see link:jms.html#beaop[Load-Balanced Message Inflow].
[[beaiv]][[GSDVG00298]][[connection-factory-and-destination]]
===== Connection Factory and Destination
A message-driven bean is a client to a Connector inbound resource
adapter. The message-driven bean container uses the JMS service
integrated into the {productName} 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 `glassfish-ejb-jar.xml` file
for a message-driven bean specifies the connection factory that creates
the container connection to the JMS provider.
The `jndi-name` element of the `ejb` element in the
`glassfish-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.
[[beaiw]][[GSDVG00299]][[message-driven-bean-pool]]
===== Message-Driven Bean Pool
The container manages a pool of message-driven beans for the concurrent
processing of a stream of messages. The `glassfish-ejb-jar.xml` file
contains the elements that define the pool (that is, the `bean-pool`
element):
* `steady-pool-size`
* `resize-quantity`
* `max-pool-size`
* `pool-idle-timeout-in-seconds`
For more information about `glassfish-ejb-jar.xml`, see
"link:application-deployment-guide/dd-files.html#GSDPG00079[The glassfish-ejb-jar.xml File]" in {productName} Application Deployment Guide.
[[beaix]][[GSDVG00300]][[domain-level-settings]]
===== Domain-Level Settings
You can control the following domain-level message-driven bean settings
in the EJB container:
Initial and Minimum Pool Size::
Specifies the initial and minimum number of beans maintained in the
pool. The default is `0`.
Maximum Pool Size::
Specifies the maximum number of beans that can be created to satisfy
client requests. The default is `2`.
Pool Resize Quantity::
Specifies the number of beans to be created if a request arrives when
the pool is empty (subject to the Initial and Minimum Pool Size), or
the number of beans to remove if idle for more than the Idle Timeout.
The default is `8`.
Idle Timeout::
Specifies the maximum time in seconds that a bean can remain idle in
the pool. After this amount of time, the bean is destroyed. The
default is `600` (10 minutes). A value of `0` means a bean can remain
idle indefinitely.
For information on monitoring message-driven beans, click the Help
button in the Administration Console. Select the Stand-Alone Instances
component, select the instance from the table, and select the Monitor
tab. Or select the Clusters component, select the cluster from the
table, select the Instances tab, select the instance from the table, and
select the Monitor tab.
[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 "olink:GSADG00011[Administering the Monitoring Service]" in
{productName} Administration Guide.
====
[[beaiy]][[GSDVG00433]][[message-driven-bean-restrictions-and-optimizations]]
==== Message-Driven Bean Restrictions and Optimizations
This section discusses the following restrictions and performance
optimizations that pertain to developing message-driven beans:
* link:#beaiz[Pool Tuning and Monitoring]
* link:#beaja[The `onMessage` Runtime Exception]
[[beaiz]][[GSDVG00301]][[pool-tuning-and-monitoring]]
===== 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
`glassfish-ejb-jar.xml` file). For example, you can tune the Open
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 "link:administration-guide/monitoring.html#GSADG00011[Administering the Monitoring Service]" in
{productName} Administration Guide for
information on how to get message-driven bean pool statistics.
[[beaja]][[GSDVG00302]][[the-onmessage-runtime-exception]]
===== The `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, v3.0 provides the following guidelines:
* If the bean method encounters a runtime exception or error, it should
simply propagate the error from the bean method to the container.
* If the bean method performs an operation that results in a checked
exception that the bean method cannot recover, the bean method should
throw the `javax.ejb.EJBException` that wraps the original exception.
* Any other unexpected error conditions should be reported using
`javax.ejb.EJBException` (`javax.ejb.EJBException` is a subclass of
`java.lang.RuntimeException`).
Under container-managed transaction demarcation, upon receiving a
runtime exception from a message-driven bean's `onMessage` method, the
container rolls back the container-started transaction and the message
is redelivered. This is because the message delivery itself is part of
the container-started transaction. By default, the {productName}
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. Here is an example `asadmin set` command that sets this
property:
[source]
----
asadmin set server-config.mdb-container.property.cmt-max-runtime-exceptions="5"
----
For more information about the `asadmin set` command, see the
link:reference-manual.html#GSRFM[{productName} Reference Manual].
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
`jakarta.jms.Message.getJMSRedelivered` method to check whether a received
message is a redelivered message.
[NOTE]
====
The `cmt-max-runtime-exceptions` property is deprecated.
====