3 Iterative Development of EJBs
This chapter includes the following sections:
- Overview of the EJB Development Process
- Create a Source Directory
- Program the Annotated EJB Class
- Program the EJB Interface
- Optionally Program Interceptors
- Optionally Program the EJB Timer Service
- Programming Access to EJB Clients
- Programming and Configuring Transactions
- Compile Java Source
- Optionally Create and Edit Deployment Descriptors
- Packaging EJBs
- Deploying EJBs
Overview of the EJB Development Process
This section is a brief overview of the EJB 3.2 development process. It describes the key implementation tasks and associated results.
The following section mostly discusses the EJB 3.2 programming model and points out the differences between the EJB 3.x and EJB 2.x programming model in only a few places. If you are an experienced EJB 2.x programmer and want the full list of differences between the two models, see New Features and Changes in EJB.
Table 3-1 EJB Development Tasks and Results
# | Step | Description | Result |
---|---|---|---|
1 |
Create the directory structure for your Java source files, and optional deployment descriptors. |
A directory structure on your local drive. |
|
2 |
Create the Java file that implements the interface and includes the EJB 3.2 metadata annotations that describe how your EJB behaves. |
|
|
3 |
Create no-interface client views or business interfaces that describe your EJB. |
|
|
4 |
Optionally, create the interceptor classes that describe the interceptors that intercept a business method invocation or a life cycle callback event. |
|
|
5 |
Optionally, create timers that schedule callbacks to occur when a timer object expires for timed event. |
Either metadata (for automatic timers) and/or bean class changes (for programmatic timers). |
|
6 |
Obtain a reference to an EJB through either dependency injection or JNDI lookup. |
Metadata (annotations and/or deployment descriptor settings) and/or code changes to the client. |
|
7 |
Program container-managed or bean-managed transactions. |
Metadata and possibly logic to handle exceptions (retry logic or calls to |
|
8 |
Compile source code. |
|
|
9 |
Optionally create the EJB-specific deployment descriptors, although this step is no longer required when using the EJB 3.2 programming model. |
|
|
10 |
Package compiled classes and optional deployment descriptors for deployment. If appropriate, you can leave your files unarchived in an exploded directory. |
Archive file (either an EJB JAR or Enterprise Application EAR) or equivalent exploded directory. |
|
11 |
Target the archive or application directory to desired Managed Server, or a WebLogic Server cluster, in accordance with selected staging mode. |
Deployed EJBs are ready to service invocations. |
Parent topic: Iterative Development of EJBs
Create a Source Directory
Create a source directory where you will assemble the EJB 3.2 module.
Oracle recommends a split development directory structure, which segregates source and output files in parallel directory structures. For instructions on how to set up a split directory structure and package your EJB 3.2 as an enterprise application archive (EAR), see Overview of the Split Development Directory Environment in Developing Applications for Oracle WebLogic Server.
Parent topic: Iterative Development of EJBs
Directory Structure for Packaging a JAR
If you prefer to package and deploy your EJBs in a JAR file, create a directory for your class files. If you are also using the EJB deployment descriptor (which is optional but supported in the EJB 3.2 programming model), you can package it as META-INF/ejb-jar.xml
.
For more information see, Packaging EJBs in a JAR.
Example 3-1 Directory Structure for Packaging a JAR
myEJBjar/ META-INF/ ejb-jar.xml weblogic-ejb-jar.xml weblogic-cmp-jar.xml foo.class fooBean.class
Parent topic: Create a Source Directory
Directory Structure for Packaging a WAR
EJBs can also be packaged directly in a web application module (WAR) by putting the EJB classes in a subdirectory named WEB-INF/classes
or in a JAR file within WEB-INF/lib
directory. Optionally, if you are also using the EJB deployment descriptor, you can package it as WEB-INF/ejb-jar.xml
.
Note:
EJB 2.1 Entity Beans and EJB 1.1 Entity Beans are not supported within WAR files. These component types must only be packaged in a stand-alone ejb-jar
file or an ejb-jar
file packaged within an EAR file.
For more information see, Packaging an EJB In a WAR.
Example 3-2 Directory Structure for Packaging a WAR
myEJBwar/ WEB-INF/ ejb-jar.xml weblogic.xml weblogic-ejb-jar.xml /classes foo.class fooServlet.class fooBean.class
Parent topic: Create a Source Directory
Program the Annotated EJB Class
The EJB bean class is the main EJB programming artifact. It implements the EJB business interface and contains the EJB metadata annotations that specify semantics and requirements to the EJB container, request container services, and provide structural and configuration information to the application deployer or the container runtime.
In the 3.2 programming model, there is only one required annotation: either @javax.ejb.Stateful
, @javax.ejb.Stateless
, or @javax.ejb.MessageDriven
to specify the type of EJB. Although there are many other annotations you can use to further configure your EJB, these annotations have typical default values so that you are not required to explicitly use the annotation in your bean class unless you want it to behave other than in the default manner. This programming model makes it very easy to program an EJB that exhibits typical behavior.
For additional details and examples of programming the bean class, see Programming the Annotated EJB Class.
Parent topic: Iterative Development of EJBs
Program the EJB Interface
Clients access enterprise beans either through a no-interface view or through a business interface.
Parent topic: Iterative Development of EJBs
Accessing EJBs Using the No-Interface Client View
The EJB 3.2 No-interface local client view type simplifies EJB development by providing local session bean access without requiring a separate local business interface, allowing components to have EJB bean class instances directly injected.
The no-interface view has the same behavior as the EJB 3.0 local view. For example, it supports features such as pass-by-reference calling semantics and transaction, and security propagation. However, a no-interface view does not require a separate interface. That is, all public methods of the bean class are automatically exposed to the caller. By default, any session bean that has an empty implements
clause and does not define any other local or remote client views, exposes a no-interface client view.
You can follow these links to explore code examples of a no-interface client view:
-
EJB 3.1: Example of Simplified No-interface Programming and Packaging in a WAR File.
-
EJB 3.2: Example of a Message-Driven Bean with No-Methods Listener.
For more detailed information about the implementing the no-interface client view, see "Accessing Local Enterprise Beans Using the No-Interface View" in the "Enterprise Beans" chapter of the Java EE 8 Tutorial at https://javaee.github.io/tutorial/ejb-intro004.html#GIPSC.
Parent topic: Program the EJB Interface
Accessing EJBs Using the Business Interface
The EJB 3.2 business interface is a plain Java interface that describes the full signature of all the business methods of the EJB. For example, assume an Account
EJB represents a client's checking account; its business interface might include three methods (withdraw
, deposit
, and balance
) that clients can use to manage their bank accounts.
The business interface can extend other interfaces. In the case of message-driven beans, the business interface is typically the message-listener interface that is determined by the messaging type used by the bean, such as javax.jms.MessageListener
in the case of JMS. The interface for a session bean has not such defining type; it can be anything that suits your business needs.
Note:
The only requirement for an EJB 3.2 business interface is That it must not extend javax.ejb.EJBObject
or javax.ejb.EJBLocalObject
, as required in EJB 2.x.
See Example of a Simple Business Interface Stateless EJB and Example of a Simple Stateful EJB for examples of business interfaces implemented by stateless and stateful session beans.
For additional details and examples of specifying the business interface, see Specifying the Business and Other Interfaces.
- Business Interface Application Exceptions
- Using Generics in EJBs
- Serializing and Deserializing Business Objects
Parent topic: Program the EJB Interface
Business Interface Application Exceptions
When you design the business methods of your EJB, you can define an application exception in the throws
clause of a method of the EJB's business interface. An application exception is an exception that you program in your bean class to alert a client of abnormal application-level conditions. For example, a withdraw()
method in an Account
EJB that represents a bank checking account might throw an application exception if the client tries to withdraw more money than is available in their account.
Application exceptions are different from system exceptions, which are thrown by the EJB container to alert the client of a system-level exception, such as the unavailability of a database management system. You should not report system-level errors in your application exceptions.
Finally, your business methods should not throw the java.rmi.RemoteException
, even if the interface is a remote business interface, the bean class is annotated with the @WebService
JWS annotation, or the method is annotated with @WebMethod
. The only exception is if the business interface extends java.rmi.Remote
. If the EJB container encounters problems at the protocol level, the container throws an EJBException
which wraps the underlying RemoteException
.
Note:
The @WebService
and @WebMethod
annotations are in the javax.jws
package; you use them to specify that your EJB implements a Web Service and that the EJB business will be exposed as public Web Service operations. For details about these annotations and programming Web Services in general, see Developing JAX-WS Web Services for Oracle WebLogic Server.
Parent topic: Accessing EJBs Using the Business Interface
Using Generics in EJBs
The EJB 3.2 programming model supports the use of generics in the business interface at the class level.
Oracle recommends as a best practice that you first define a super-interface that uses the generics, and then have the actual business interface extend this super-interface with a specific data type.
The following example shows how to do this. First, program the super-interface that uses generics:
public interface RootI<T> { public T getObject(); public void updateObject(T object); }
Then program the actual business interface to extend RootI<T>
for a particular data type:
@Remote public interface StatelessI extends RootI<String> { }
Finally, program the actual stateless session bean to implement the business interface; use the specified data type, in this case String
, in the implementation of the methods:
@Stateless public class StatelessSample implements StatelessI { public String getObject() { return null; } public void updateObject(String object) { } }
If you define the type variables on the business interface or class, they will be erased. In this case, the EJB application can be deployed successfully only when the bean class parameterizes the business interface with upper bounds of the type parameter and no other generic information. For example, in the following example, the upper bound is Object
:
public class StatelessSample implements StatelessI<Object> { public Object getObject() { return null; } public void updateObject(Object object) { } }
Parent topic: Accessing EJBs Using the Business Interface
Serializing and Deserializing Business Objects
Business object serialization and deserialization are supported by the following interfaces, which are implemented by all business objects:
-
weblogic.ejb.spi.BusinessObject
-
weblogic.ejb.spi.BusinessHandle
Use the BusinessObject._WL_getBusinessObjectHandle()
method to get the business handle object and serialize the business handle object.
To deserialize a business object, deserialize the business handle object and use the BusinessHandle.getBusinessObject()
method to get the business object.
Parent topic: Accessing EJBs Using the Business Interface
Optionally Program Interceptors
An interceptor is a method that intercepts the invocation of a business method or a life cycle callback event.
You can define an interceptor method within the actual bean class, or you can program an interceptor class (distinct from the bean class itself) and associate it with the bean class using the @javax.ejb.Interceptor
annotation.
See Specifying Interceptors for Business Methods or Life Cycle Callback Events for information on programming the bean class to use interceptors.
Parent topic: Iterative Development of EJBs
Optionally Program the EJB Timer Service
WebLogic Server supports the EJB timer service defined in the EJB 3.2 Specification. As per the EJB 3.2 "specification, the EJB Timer Service is a "container-managed service that allows callbacks to be scheduled for time-based events. The container provides a reliable and transactional notification service for timed events. Timer notifications may be scheduled to occur according to a calendar-based schedule, at a specific time, after a specific elapsed duration, or at specific recurring intervals."
The Timer Service is implemented by the EJB container. An enterprise bean accesses this service by means of dependency injection, through the EJBContext
interface, or through lookup in the JNDI namespace.
The Timer Service is intended to be used as a coarse-grained timer service. Rather than having a large number of timer objects performing the same task on a unique set of data, Oracle recommends using a small number of timers that perform bulk tasks on the data. For example, assume you have an EJB that represents an employee's expense report. Each expense report must be approved by a manager before it can be processed. You could use one EJB timer to periodically inspect all pending expense reports and send an email to the corresponding manager to remind them to either approve or reject the reports that are waiting for their approval.
- Overview of the Timer Service
- Calendar-based EJB Timers
- Automatically-created EJB Timers
- Non-persistent Timers
- Clustered Versus Local EJB Timer Services
- Configuring Clustered EJB Timers
- Using Java Programming Interfaces to Program Timer Objects
Parent topic: Iterative Development of EJBs
Overview of the Timer Service
The timer service provides methods for the programmatic creation and cancellation of timers, as well as for locating the timers that are associated with a bean. Timers can also be created automatically by the container at deployment time based on metadata in the bean class or in the deployment descriptor. Timer objects can be created for stateless session beans, singleton session beans, message-driven beans, and 2.1 entity beans. Timers cannot be created for stateful session beans.
Note:
The calendar-based timer, automatically-created timers, and non-persistent timer functionality is not supported for 2.1 Entity beans.
A timer is created to schedule timed callbacks. The bean class of an enterprise bean that uses the timer service must provide one or more timeout callback methods, as follows:
-
Programmatic Timers – For programmatically-created timers, this method may be a method that is annotated with the
Timeout
annotation, or the bean may implement thejavax.ejb.TimedObject
interface. Thejavax.ejb.TimedObject
interface has a single method, the timer callback methodejbTimeout
. -
Automatic Timers – For automatically-created timers, the timeout method may be a method that is annotated with the
Schedule
annotation. -
2.1 Entity Bean Timers – A timer that is created for a 2.1 entity bean is associated with the entity bean's identity. The timeout callback method invocation for a timer that is created for a stateless session bean or a message-driven bean may be called on any bean instance in the pooled state.
Parent topic: Optionally Program the EJB Timer Service
Calendar-based EJB Timers
The EJB 31. Timer Service supports calendar-based EJB Timer expressions. The scheduling functionality takes the form of CRON-styled schedule definitions that can be placed on EJB methods, in order to have the methods be automatically invoked according to the defined schedule.
Note:
Calendar-based timers are not supported for EJB 2.x entity beans.
Calendar-based timers can be created programmatically using the two methods in the javax.ejb.TimerService
that accept a javax.ejb.ScheduleExpression
as an argument. The ScheduleExpression
is constructed and populated prior to creating the Timer. For creating automatic calendar-base timers, the javax.ejb.Schedule
annotation (and its corresponding ejb-jar.xml
element) contains a number of attributes that allow for calendar-based timer expressions to be configured.
For detailed information about the seven attributes in a calendar-based time expression, see "Section 18.2.1, Calendar Based Timer Expressions" in the Enterprise JavaBeans 3.2 Specification (JSR-345) at http://jcp.org/en/jsr/summary?id=345
.
Parent topic: Optionally Program the EJB Timer Service
Automatically-created EJB Timers
The EJB 3.2 Timer Service supports the automatic creation of a timer based on metadata in the bean class or deployment descriptor. This allows the bean developer to schedule a timer without relying on a bean invocation to programmatically invoke one of the Timer Service timer creation methods. Automatically created timers are created by the container as a result of application deployment.
The javax.ejb.Schedule
annotation can be used to automatically create a timer with a particular timeout schedule. This annotation is applied to a method of a bean class (or super-class) that should receive the timer callbacks associated with that schedule. Multiple automatic timers can be applied to a single timeout callback method using the javax.ejb.Schedules
annotation.
When the clustered EJB Timer implementation is used, each Schedule
annotation corresponds to a single persistent timer, regardless of the number of servers across which the EJB is deployed.
Parent topic: Optionally Program the EJB Timer Service
Non-persistent Timers
By default, EJB timers are persistent. A non-persistent timer is a timer whose lifetime is tied to the JVM in which it is created. A non-persistent timer is considered canceled in the event of application shutdown, container crash, or a failure/shutdown of the JVM on which the timer was started.
Note:
Non-persistent timers are not supported for EJB 2.x Entity Beans.
Non-persistent timers can be created programmatically or automatically (using @Schedule
or the deployment descriptor).
Automatic non-persistent timers can be specified by setting the persistent attribute of the @Schedule
annotation to false. For automatic non-persistent timers, the container creates a new non-persistent timer during application initialization for each JVM across which the container is distributed.
Parent topic: Optionally Program the EJB Timer Service
Clustered Versus Local EJB Timer Services
You can configure two types of EJB timer services: clustered or local.
Parent topic: Optionally Program the EJB Timer Service
Clustered EJB Timer Services
Clustered EJB timer services provide the following advantages:
-
Better visibility.
Timers are accessible from any node in a cluster. For example, the
javax.ejb.TimerService.getTimers()
method returns a complete list of all stateless session or message-driven bean timers in a cluster that were created for the EJB. If you pass the primary key of the entity bean to thegetTimers()
method, a list of timers for that entity bean are returned. -
Automatic load balancing and failover.
Clustered EJB timer services take advantage of the load balancing and failover capabilities of the Job Scheduler.
For information about the configuring a clustered EJB timer service, see Configuring Clustered EJB Timers.
Parent topic: Clustered Versus Local EJB Timer Services
Local EJB Timer Services
Local EJB timer services execute only on the server on which they are created and are visible only to the beans on that server. With a local EJB timer service, you do not have to configure a cluster, database, JDBC data source, or leasing service, as you do for clustered EJB timer services.
You cannot migrate a local EJB timer object from one server to another; timer objects can only be migrated as part of an entire server. If a server that contains EJB timers goes down for any reason, you must restart the server or migrate the entire server in order for the timers to execute.
Caution:
In a clustered environment, the local timer implementation has severe limitations; therefore Oracle recommends not using local timers in a clustered environment. Instead, use the clustered timer implementation in a clustered environment. A deployment-time warning will be thrown when a local timer implementation is configured to be used in a clustered environment.
Parent topic: Clustered Versus Local EJB Timer Services
Configuring Clustered EJB Timers
Note:
To review the advantages of using clustered EJB timers, see Clustered Versus Local EJB Timer Services.
To configure the clustering of EJB timers, perform the following steps:
Please note the following changes in the behavior of the clustered EJB timer service:
-
The
weblogic.ejb.WLTimer*
interfaces are not supported with clustered EJB timer services. -
When creating a new clustered EJB timer using the
createTimer()
method, you may notice a delay in timeout execution during the initial setup of the timer. -
The Job Scheduler provides an "at least once" execution guarantee. When a clustered EJB timer expires, the database is not updated until the timer listener callback method completes. If the server were to crash before the database is updated, the timer expiration would be executed twice.
-
Timer configuration options related to the actions to take in the event of failure are not valid for the clustered EJB timer service. These configuration options include: retry delay, maximum number of retry attempts, maximum number of time-outs, and time-out failure actions.
-
The Job Scheduler queries the database every 30 seconds to identify timers that are due to expire. Execution may be delayed for timers with an interval duration less than 30 seconds.
-
Only transactional timers will be retried in the event of failure.
-
Fixed rate scheduling of timer execution is not supported.
Parent topic: Optionally Program the EJB Timer Service
Using Java Programming Interfaces to Program Timer Objects
This section summarizes the Java programming interfaces defined in the EJB 3.2 Specification that you can use to program timers. For detailed information on these interfaces, refer to the EJB 3.2 Specification. This section also provides details about the WebLogic Server-specific timer-related interfaces.
- EJB 3.2 Timer-related Programming Interfaces
- WebLogic Server-specific Timer-related Programming Interfaces
Parent topic: Optionally Program the EJB Timer Service
EJB 3.2 Timer-related Programming Interfaces
EJB 3.2 interfaces you can use to program timers are described in the following table.
Table 3-2 EJB 3.2 Timer-related Programming Interfaces
Programming Interface | Description |
---|---|
|
Create calendar-based EJB Timer expressions. |
|
Automatically create a timer with a particular timeout schedule. Multiple automatic timers can be applied to a single timeout callback method using the |
|
Implement for the enterprise bean class of a bean that will be registered with the timer service for timer callbacks. This interface has a single method, |
|
Access the timer service using the |
|
Create new EJB timers or access existing EJB timers for the EJB. |
|
Access information about a particular EJB timer. |
|
Define a serializable timer handle that can be persisted. Since timers are local objects, a |
For more information on EJB 2.1 timer-related programming interfaces, see the EJB 2.1 Specification.
WebLogic Server-specific Timer-related Programming Interfaces
WebLogic Server-specific interfaces you can use to program timers include:
-
weblogic.management.runtime.EJBTimerRuntimeMBean
—provides runtime information and administrative functionality for timers from a particularEJBHome
. Theweblogic.management.runtime.EJBTimerRuntimeMBean
interface is shown in Example 3-3.
Example 3-3 weblogic.management.runtime.EJBTimerRuntimeMBean Interface
public interface weblogic.management.runtime.EJBTimerRuntimeMBean { public int getTimeoutCount(); // get the number of successful timeout notifications that have been made public int getActiveTimerCount(); // get the number of active timers for this EJBHome public int getCancelledTimerCount(); // get the number of timers that have been cancelled for this EJBHome public int getDisabledTimerCount(); // get the number of timers temporarily disabled for this EJBHome public void activateDisabledTimers(); // activate any temporarily disabled timers }
-
weblogic.ejb.WLTimerService
interface—extends thejavax.ejb.TimerService
interface to allow users to specify WebLogic Server-specific configuration information for a timer. Theweblogic.ejb.WLTimerService
interface is shown in Example 3-4; for information on thejavax.ejb.TimerService
, see the EJB 2.1 Specification.Note:
The
weblogic.ejb.WLTimerService
interface is not supported by the clustered EJB timer service, as described in Configuring Clustered EJB Timers.
Example 3-4 weblogic.ejb.WLTimerService Interface
public interface WLTimerService extends TimerService { public Timer createTimer(Date initial, long duration, Serializable info, WLTimerInfo wlTimerInfo) throws IllegalArgumentException, IllegalStateException, EJBException; public Timer createTimer(Date expiration, Serializable info, WLTimerInfo wlTimerInfo) throws IllegalArgumentException, IllegalStateException, EJBException; public Timer createTimer(long initial, long duration, Serializable info WLTimerInfo wlTimerInfo) throws IllegalArgumentException, IllegalStateException, EJBException; public Timer createTimer(long duration, Serializable info, WLTimerInfo wlTimerInfo) throws IllegalArgumentException, IllegalStateException, EJBException; }
-
weblogic.ejb.WLTimerInfo
interface—used in theweblogic.ejb.WLTimerService
interface to pass WebLogic Server-specific configuration information for a timer. Theweblogic.ejb.WLTimerInfo
method is shown in Example 3-5.Note:
The
weblogic.ejb.WLTimerService
interface is not supported by the clustered EJB timer service, as described in Configuring Clustered EJB Timers.
Example 3-5 weblogic.ejb.WLTimerInfo Interface
public final interface WLTimerInfo { public static int REMOVE_TIMER_ACTION = 1; public static int DISABLE_TIMER_ACTION = 2; public static int SKIP_TIMEOUT_ACTION = 3; /** * Sets the maximum number of retry attempts that will be * performed for this timer. If all retry attempts * are unsuccesful, the timeout failure action will * be executed. */ public void setMaxRetryAttempts(int retries); public int getMaxRetryAttempts(); /** * Sets the number of milliseconds that should elapse * before any retry attempts are made. */ public void setRetryDelay(long millis); public long getRetryDelay(); /** * Sets the maximum number of timeouts that can occur * for this timer. After the specified number of * timeouts have occurred successfully, the timer * will be removed. */ public void setMaxTimeouts(int max); public int getMaxTimeouts(); /** * Sets the action the container will take when ejbTimeout * and all retry attempts fail. The REMOVE_TIMER_ACTION, * DISABLE_TIMER_ACTION, and SKIP_TIMEOUT_ACTION fields * of this interface define the possible values. */ public void setTimeoutFailureAction(int action); public int getTimeoutFailureAction(); }
-
weblogic.ejb.WLTimer
interface—extends thejavax.ejb.Timer
interface to provide additional information about the current state of the timer. Theweblogic.ejb.WLTimer
interface is shown in Example 3-6.Note:
The
weblogic.ejb.WLTimerService
interface is not supported by the clustered EJB timer service, as described in Configuring Clustered EJB Timers.
Example 3-6 weblogic.ejb.WLTimer Interface
public interface WLTimer extends Timer { public int getRetryAttemptCount(); public int getMaximumRetryAttempts(); public int getCompletedTimeoutCount(); }
Programming Access to EJB Clients
This section provides some guidelines in determining the client view to provide for accessing an enterprise bean.
- Remote Clients
- Local Clients
- Looking Up EJBs From Clients
- Configuring EJBs to Send Requests to a URL
- Specifying an HTTP Resource by URL
- Specifying an HTTP Resource by Its JNDI Name
- Accessing HTTP Resources from Bean Code
- Configuring Network Communications for an EJB
Parent topic: Iterative Development of EJBs
Remote Clients
As stated in the EJB 3.2 specification, a remote client accesses a session bean through the bean's remote business interface. For a session bean client and component written to the EJB 2.1 and earlier APIs, the remote client accesses the session bean through the session bean's remote home and remote component interfaces.
Note:
The EJB 2.1 and earlier API required that a remote client access the stateful or stateless session bean by means of the session bean's remote home and remote component interfaces. These interfaces remain available for use with EJB 3.x, and are described in Create EJB Classes and Interfaces in Developing Enterprise JavaBeans, Version 3.2, for Oracle WebLogic Server.
The remote client view of an enterprise bean is location independent. A client running in the same JVM as a bean instance uses the same API to access the bean as a client running in a different JVM on the same or different machine.
Parent topic: Programming Access to EJB Clients
Local Clients
As stated in the EJB 3.2 specification, a local client accesses a session bean through the bean's local business interface or through a no-interface client view representing all the public methods of the bean class. For a session bean or entity bean client and component written to the EJB 2.1 and earlier APIs, the local client accesses the enterprise bean through the bean's local home and local component interfaces. The container object that implements a local business interface or the no-interface local view is a local Java object.
A local client is a client that is collocated in the same application with the session bean that provides the local client view and which may be tightly coupled to the bean. A local client of a session bean may be another enterprise bean or a Web component. Access to an enterprise bean through the local client view requires the collocation in the same application of both the local client and the enterprise bean that provides the local client view. The local client view therefore does not provide the location transparency provided by the remote client view.
Parent topic: Programming Access to EJB Clients
Looking Up EJBs From Clients
The client of an enterprise bean obtains a reference to an instance of an enterprise bean through either dependency injection, using Java programming language annotations, or JNDI lookup, using the Java Naming and Directory Interface syntax to find the enterprise bean instance.
Note:
For instructions on how clients can look up 2.x or earlier enterprise beans using EJB Links, see Using EJB Links in Developing Enterprise JavaBeans, Version 3.2, for Oracle WebLogic Server.
Parent topic: Programming Access to EJB Clients
Using Dependency Injection
Dependency injection is when the EJB container automatically supplies (or injects) a bean's variable or setter method with a reference to a resource or another environment entry in the bean's context. Dependency injection is simply an easier-to-program alternative to using the javax.ejb.EJBContext interface
or JNDI APIs to look up resources.
You specify dependency injection by annotating a variable or setter method with one of the following annotations, depending on the type of resource you want to inject:
-
@javax.ejb.EJB
—Specifies a dependency on another EJB. -
@javax.annotation.Resource
—Specifies a dependency on an external resource, such as a JDBC datasource or a JMS destination or connection factory.
For detailed information, see Injecting Resource Dependency into a Variable or Setter Method.
Parent topic: Looking Up EJBs From Clients
Using the JNDI Portable Syntax
The Portable Global JNDI naming option in EJB 3.2 provides a number of common, well-known namespaces in which EJB components can be registered and looked up from using the patterns listed in this section. This standardizes how and where EJB components are registered in JNDI, and how they can be looked up and used by applications.
Three JNDI namespaces are used for portable JNDI lookups: java:global
, java:module
, and java:app
.
-
The
java:global
JNDI namespace is the portable way of finding remote enterprise beans using JNDI lookups. JNDI addresses are of the following form:java:global
[/application name]/module name/enterprise bean name[/interface name
]Application name and module name default to the name of the application and module minus the file extension. Application names are required only if the application is packaged within an EAR. The interface name is required only if the enterprise bean implements more than one business interface.
-
The
java:module
namespace is used to look up local enterprise beans within the same module. JNDI addresses using thejava:module
namespace are of the following form:java:module
/enterprise bean name/[interface name
]The interface name is required only if the enterprise bean implements more than one business interface.
-
The
java:app
namespace is used to look up local enterprise beans packaged within the same application. That is, the enterprise bean is packaged within an EAR file containing multiple Java EE modules. JNDI addresses using thejava:app
namespace are of the following form:java:app
[/module name]/enterprise bean name[/interface name
]The module name is optional. The interface name is required only if the enterprise bean implements more than one business interface.
For example, if an enterprise bean, MyBean
, is packaged within the Web application archive myApp.war
, the default module name is myApp
. (In this example, the module name could be explicitly configured in the web.xml
file.) The portable JNDI name is java:module/MyBean
. An equivalent JNDI name using the java:global
namespace is java:global/myApp/MyBean
.
Parent topic: Looking Up EJBs From Clients
Customizing JNDI Names
Though global JNDI bindings are registered by default, you can also customize the JNDI names of your EJB client view bindings by using the weblogic.javaee.JNDIName
and weblogic.javaee.JNDINames
annotations. For more information, see weblogic.javaee.JNDIName and weblogic.javaee.JNDINames.
For EJBs using deployment descriptors, you can specify the custom JNDI bindings in the weblogic-ejb-jar.xml
deployment descriptor by using the jndi-binding
element. See EJB Deployment Descriptors in Developing Enterprise JavaBeans, Version 3.2, for Oracle WebLogic Server.
Parent topic: Looking Up EJBs From Clients
Configuring EJBs to Send Requests to a URL
To enable an EJB to open an HttpURLConnection
to an external HTTP server using the java.net.URL
resource manager connection factory type, specify the URL, or specify an object bound in the JNDI tree that maps to a URL, using either the @Resource
annotation in the bean class, or if using deployment descriptors, by using the resource-ref
element in ejb-jar.xml
and the res-ref-name
element in weblogic-ejb-jar.xml
.
Parent topic: Programming Access to EJB Clients
Specifying an HTTP Resource by URL
When using annotations to specify the URL to which an EJB sends requests:
-
Annotate a URL field in your bean class with
@Resource
. -
Specify the URL value using the look-up element of
@Resource
.
When using deployment descriptors to specify the URL to which an EJB sends requests:
Parent topic: Programming Access to EJB Clients
Specifying an HTTP Resource by Its JNDI Name
When using annotations to specify an object that is bound in JNDI and maps to a URL, instead of specifying a URL:
-
Annotate a URL field in your bean class with
@Resource
. -
Specify the name by which the URL is bound in JNDI using the look-up element of
@Resource
.
When using deployment descriptors to specify an object that is bound in JNDI and maps to a URL, instead of specifying a URL:
Parent topic: Programming Access to EJB Clients
Accessing HTTP Resources from Bean Code
Regardless of how you specified an HTTP resource—by its URL or a JNDI name that maps to the URL—you can access it from EJB code in this way:
URL url = (URL) context.lookup("java:comp/env/url/MyURL"); connection = (HttpURLConnection)url.openConnection();
Parent topic: Programming Access to EJB Clients
Configuring Network Communications for an EJB
You can control the attributes of the network connection an EJB uses for communications by configuring a custom network channel and assigning it to the EJB. For information about WebLogic Server network channels and associated configuration instructions see Configure Network Resources in Administering Server Environments for Oracle WebLogic Server. After you configure a custom channel, assign it to an EJB using the network-access-point
element in weblogic-ejb-jar.xml
.
Parent topic: Programming Access to EJB Clients
Programming and Configuring Transactions
The following sections contain guidelines for programming transactions.
- Programming Container-Managed Transactions
- Configuring Automatic Retry of Container-Managed Transactions
- Programming Bean-Managed Transactions
- Programming Transactions That Are Distributed Across EJBs
Parent topic: Iterative Development of EJBs
Programming Container-Managed Transactions
Container-managed transactions are simpler to program than bean-managed transactions, because they leave the job of demarcation—starting and stopping the transaction—to the EJB container. You configure the desired transaction behaviors using EJB annotations javax.ejb.TransactionAttribute
or by using EJB deployment descriptors ejb-jar.xml
and weblogic-ejb-jar.xml
.
-
For more information about using EJB annotations to specify container-managed transactions in a bean file, see Specifying Transaction Management and Attributes.
-
For more information about using EJB deployment descriptors to specify container-managed transactions, see Container-Managed Transaction Elements in Developing Enterprise JavaBeans, Version 3.2, for Oracle WebLogic Server.
Key programming guidelines for container-managed transactions include:
-
Preserve transaction boundaries—Do not invoke methods that interfere with the transaction boundaries set by the container. Do not use:
-
The
commit
,setAutoCommit
, androllback
methods ofjava.sql.Connection
-
The
getUserTransaction
method ofjavax.ejb.EJBContext
-
Any method of
javax.transaction.UserTransaction
-
-
Roll back transactions explicitly—To cause the container to roll back a container-managed transaction explicitly, invoke the
setRollbackOnly
method of theEJBContext
interface. (If the bean throws a non-application exception, typically anEJBException
, the rollback is automatic.) -
Avoid serialization problems—Many data stores provide limited support for detecting serialization problems, even for a single user connection. In such cases, even with
transaction-isolation
inweblogic-ejb-jar.xml
set toTransactionSerializable
, exceptions or rollbacks in the EJB client might occur if contention occurs between clients for the same rows. To avoid such exceptions, you can:-
Include code in your client application to catch SQL exceptions, and resolve them appropriately; for example, by restarting the transaction.
-
For Oracle databases, use the transaction isolation settings described in
isolation-level
in the weblogic-ejb-jar.xml Deployment Descriptor Reference appendix in Developing Enterprise JavaBeans, Version 3.2, for Oracle WebLogic Server.
-
Parent topic: Programming and Configuring Transactions
Configuring Automatic Retry of Container-Managed Transactions
In Oracle WebLogic Server, you can specify that, if a business method that has started a transaction fails because of a transaction rollback that is not related to a system exception, the EJB container will start a new transaction and retry the failed method up to a specified number of times. If the method fails for the specified number of retry attempts, the EJB container throws an exception.
Note:
The EJB container does not retry any transactions that fail because of system exception-based errors.
To configure automatic retry of container-managed transactions:
Parent topic: Programming and Configuring Transactions
Programming Bean-Managed Transactions
This section contains programming considerations for bean-managed transactions.
-
Demarcate transaction boundaries—To define transaction boundaries in EJB or client code, you must obtain a
UserTransaction
object and begin a transaction before you obtain a Java Transaction Service (JTS) or JDBC database connection. To obtain theUserTransaction
object, use this command:ctx.lookup("javax.transaction.UserTransaction");
After obtaining the
UserTransaction
object, specify transaction boundaries withtx.begin()
,tx.commit()
,tx.rollback()
.If you start a transaction after obtaining a database connection, the connection has no relationship to the new transaction, and there are no semantics to "enlist" the connection in a subsequent transaction context. If a JTS connection is not associated with a transaction context, it operates similarly to a standard JDBC connection that has
autocommit
equal totrue
, and updates are automatically committed to the data store.Once you create a database connection within a transaction context, that connection is reserved until the transaction commits or rolls back. To optimize performance and throughput, ensure that transactions complete quickly, so that the database connection can be released and made available to other client requests.
Note:
You can associate only a single database connection with an active transaction context.
-
Setting transaction isolation level—For bean-managed transactions, you define isolation level in the bean code. Allowable isolation levels are defined on the j
ava.sql.Connection
interface. For information on isolation level behaviors, seeisolation-level
in the weblogic-ejb-jar.xml Deployment Descriptor Reference appendix in Developing Enterprise JavaBeans, Version 3.2, for Oracle WebLogic Server.See Example 3-7 for a code sample.
Example 3-7 Setting Transaction Isolation Level in BMT
import javax.transaction.Transaction; import java.sql.Connection import weblogic.transaction.TxHelper: import weblogic.transaction.Transaction; import weblogic.transaction.TxConstants; User Transaction tx = (UserTransaction) ctx.lookup("javax.transaction.UserTransaction"); //Begin user transaction tx.begin(); //Set transaction isolation level to TransactionReadCommitted Transaction tx = TxHelper.getTransaction(); tx.setProperty (TxConstants.ISOLATION_LEVEL, new Integer (Connection.TransactionReadCommitted)); //perform transaction work tx.commit();
-
Avoid restricted methods—Do not invoke the
getRollbackOnly
andsetRollbackOnly
methods of theEJBContext
interface in bean-managed transactions. These methods should be used only in container-managed transactions. For bean-managed transactions, invoke thegetStatus
and rollback methods of theUserTransaction
interface. -
Use one connection per active transaction context—You can associate only a single database connection with an active transaction context.
Parent topic: Programming and Configuring Transactions
Programming Transactions That Are Distributed Across EJBs
This section describes two approaches for distributing a transaction across multiple beans, which may reside on multiple server instances.
- Calling multiple EJBs from a client's transaction context
- Using an EJB "Wrapper” to Encapsulate a Cross-EJB Transaction
Parent topic: Programming and Configuring Transactions
Calling multiple EJBs from a client's transaction context
The code fragment below is from a client application that obtains a UserTransaction
object and uses it to begin and commit a transaction. The client invokes two EJBs within the context of the transaction.
import javax.transaction.*;
...
u = (UserTransaction) jndiContext.lookup("javax.transaction.UserTransaction");
u.begin();
account1.withdraw(100);
account2.deposit(100);
u.commit();
...
The updates performed by the account1
and account2
beans occur within the context of a single UserTransaction
. The EJBs commit or roll back together, as a logical unit, whether the beans reside on the same server instance, different server instances, or a WebLogic Server cluster.
All EJBs called from a single transaction context must support the client transaction—each beans' trans-attribute
element in ejb-jar.xml
must be set to Required
, Supports
, or Mandatory
.
Using an EJB "Wrapper” to Encapsulate a Cross-EJB Transaction
You can use a wrapper EJB that encapsulates a transaction. The client calls the wrapper EJB to perform an action such as a bank transfer, and the wrapper starts a new transaction and invokes one or more EJBs to do the work of the transaction.
The wrapper EJB can explicitly obtain a transaction context before invoking other EJBs, or WebLogic Server can automatically create a new transaction context, if the wrapper's trans-attribute
element in ejb-jar.xml
is set to Required
or RequiresNew
.
All EJBs invoked by the wrapper EJB must support the wrapper EJB's transaction context— their trans-attribute
elements must be set to Required
, Supports
, or Mandatory
.
Compile Java Source
Once you have written the Java source code for your EJB bean class and optional interceptor class, you must compile it into class files, typically using the standard Java compiler. The resulting class files can then be packaged into a target module for deployment. Typical tools to compile include:
-
javac
—Thejavac
compiler provided with the Java SE SDK provides Java compilation capabilities. Seehttp://www.oracle.com/technetwork/java/javase/documentation/index.html
. -
weblogic.appc
—To reduce deployment time, use theweblogic.appc
Java class (or its equivalent Ant taskwlappc
) to pre-compile a deployable archive file, (WAR, JAR, or EAR). Precompiling withweblogic.appc
generates certain helper classes and performs validation checks to ensure your application is compliant with the current Java EE specifications. See Building Modules and Applications Using wlappc in Developing Applications for Oracle WebLogic Server. -
wlcompile
Ant task—Invokes thejavac
compiler to compile your application's Java components in a split development directory structure. See Compiling Applications Using wlcompile in Developing Applications for Oracle WebLogic Server.
Parent topic: Iterative Development of EJBs
Optionally Create and Edit Deployment Descriptors
An important aspect of the EJB 3.x programming model was the introduction of metadata annotations. Annotations simplify the EJB development process by allowing a developer to specify within the Java class itself how the bean behaves in the container, requests for dependency injection, and so on. Annotations are an alternative to deployment descriptors that were required by older versions (2.x and earlier) of EJB.
However, EJB 3.2 fully supports the use of deployment descriptors, even though the standard Java EE ones are not required. For example, you may prefer to use the old 2.x programming model, or might want to allow further customizing of the EJB at a later development or deployment stage; in these cases you can create the standard deployment descriptors in addition to, or instead of, the metadata annotations.
Deployment descriptor elements always override their annotation counterparts. For example, if you specify the @javax.ejb.TransactionManagement(BEAN)
annotation in your bean class, but then create an ejb-jar.xml
deployment descriptor for the EJB and set the <transaction-type>
element to container
, then the deployment descriptor value takes precedence and the EJB uses container-managed transaction demarcation.
Note:
This version of EJB 3.2 also supports all 2.x WebLogic-specific EJB features. However, the features that are configured in the weblogic-ejb-jar.xml
or weblogic-cmp-rdbms-jar.xml
deployment descriptor files must continue to be configured that way for this release of EJB 3.2 because currently they do not have any annotation equivalent.
The 2.x version of Developing Enterprise JavaBeans, Version 3.2, for Oracle WebLogic Server provides detailed information about creating and editing EJB deployment descriptors, both the Java EE standard and WebLogic-specific ones. In particular, see the following sections:
Parent topic: Iterative Development of EJBs
Packaging EJBs
Oracle recommends that you package EJBs as part of an enterprise application. See Deploying and Packaging from a Split Development Directory in Developing Applications for Oracle WebLogic Server.
However, EJB 3.2 simplifies packaging by providing the ability to place EJB components directly inside of Web application archive (WAR) files, removing the need to produce separate archives to store the Web and EJB components and combine them together in an enterprise application archive (EAR) file.
Packaging EJBs in a JAR
WebLogic Server supports the use of ejb-client.jar
files for packaging the EJB classes that a programmatic client in a different application requires to access the EJB.
Specify the name of the client JAR in the ejb-client-jar
element of the bean's ejb-jar.xml
file. When you run the appc
compiler, a JAR file with the classes required to access the EJB is generated.
Make the client JAR available to the remote client. For Web applications, put the ejb-client.jar
in the /lib
directory. For non-Web clients, include ejb-client.jar
in the client's classpath.
Note:
WebLogic Server classloading behavior varies, depending on whether the client is stand-alone. Stand-alone clients with access to the ejb-client.jar
can load the necessary classes over the network. However, for security reasons, programmatic clients running in a server instance cannot load classes over the network.
Parent topic: Packaging EJBs
Packaging an EJB In a WAR
EJB 3.2 has removed the restriction that enterprise bean classes must be packaged in an ejb-jar
file. Therefore, EJB classes can be packaged directly inside a Web application archive (WAR) using the same packaging guidelines that apply to Web application classes. Simply put your EJB classes in the WEB-INF/classes
directory or in a JAR file within WEB-INF/lib
directory. Optionally, if you are also using the EJB deployment descriptor, you can package it as WEB-INF/ejb-jar.xml
. When you run the appc
compiler, a WAR file with the classes required to access the EJB components is generated.
In a WAR file there is a single component naming environment shared between all the components (web, enterprise bean, etc.) defined by the module. Each enterprise bean defined by the WAR file shares this single component environment namespace with all other enterprise beans defined by the WAR file and with all other web components defined by the WAR file.
Enterprise beans (and any related classes) packaged in a WAR file have the same class loading requirements as other non-enterprise bean classes packaged in a WAR file. This means, for example, that a servlet packaged within a WAR file is guaranteed to have visibility to an enterprise bean component packaged within the same WAR file, and vice versa.
Caution:
EJB 2.1 Entity Beans and EJB 1.1 Entity Beans are not supported within WAR files. These component types must only be packaged in a stand-alone ejb-jar
file or an ejb-jar
file packaged within an EAR file. Applications that violate this restriction will fail to deploy.
There is an example of using the simplified WAR packaging method bundled in the WebLogic Server distribution kit. See EJB 3.1: Example of Simplified No-interface Programming and Packaging in a WAR File.
Parent topic: Packaging EJBs
Deploying EJBs
Deploying an EJB enables WebLogic Server to serve the components of an EJB to clients. You can deploy an EJB using one of several procedures, depending on your environment and whether or not your EJB is in production.
For general instructions on deploying WebLogic Server applications and modules, including EJBs, see Deploying Applications to Oracle WebLogic Server. For EJB-specific deployment issues and procedures, see Deploying Standalone EJBs as Part of an Enterprise Application. and Deploying EJBs as Part of an Web Application.
For more information about deploying an EJB created with the 2.x programming model, see Deployment Guidelines For Enterprise JavaBeans in the Developing Enterprise JavaBeans, Version 3.2, for Oracle WebLogic Server guide, which concentrates on the 2.x programming model.
Parent topic: Iterative Development of EJBs