This demo application showcases Oracle's support for EJB 3.0, highlighting
the use of interceptors.
EJB 3.0 interceptors provide the bean developer with fine grained control
over the method invocation flow. They can be used on stateless session beans,
stateful
session
beans, and message driven beans. The interceptor may be either a method
in the same bean class or an external class. You may define a default interceptor for all EJBs in the ejb-jar module.
We will take a HelloWorld EJB to demonstrate a couple of simple interceptors on a stateless session bean. The checkPermission interceptor method is defined in the bean class and the ProfilingInterceptor is defined as an external class. You will also learn how to define a default interceptor.
package oracle.ejb30;
import javax.interceptor.*;
import javax.ejb.*;
@Stateless
@Interceptor(ProfilingInterceptor.class)
public class HelloWorldBean implements HelloWorld {
@Resource
private javax.ejb.SessionContext ctx;
public void sayHello() {
System.out.println("Hello!");
}
@AroundInvoke
public Object myInterceptor(InvocationContext ic) throws Exception {
System.out.println("checkPermission interceptor invoked");
if (!userIsValid(ctx.getCallerPrincipal())) {
throw new SecurityException("Caller: '" +
ctx.getCallerPrincipal().getName() +
"' does not have p ermissions for method " +
ic.getMethod());
}
return ic.proceed();
}
}
The following is the code for the ProfilingInterceptor Class that acts as an external interceptor class for HelloWorld EJB.
package oracle.ejb30;
import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;
public class ProfilingInterceptor {
@AroundInvoke
public Object profile(InvocationContext ctx) throws
Exception {
System.out.println("profile interceptor invoked");
long startTime = 0;
try {
startTime
= System.currentTimeMillis();
return
ctx.proceed();
} finally {
System.out.println("Method " +
ctx.getMethod() +
" executed in " +
(System.currentTimeMillis()
- startTime)
+ "ms");
}
}
}
Things to note:
The @Interceptor annotation designates an interceptor
defined on another class. If more than one external interceptor is needed,
the @Interceptors annotation
is used instead.
The @AroundInvoke annotation designates the method to
act as the interceptor. Any such method must have a single InvocationContext
parameter
and returns
Object.
You can define interceptors at the bean level or method level. Next we will see how you can define a default interceptor for an EJB module.
Stateless Session Bean example using Interceptor
A default interceptor is invoked for all bean methods for all EJBs in the EJB-JAR module. A default interceptor is defined in the deployment descriptor.
<assembly-descriptor>
<interceptor-binding>
<ejb-name>*</ejb-name>
<interceptor-class>oracle.ejb30.DefaultInterceptor</interceptor-class>
</interceptor-binding>
</assembly-descriptor>
Prerequisites
What you need to know
In order to complete the example application, you should be familiar with the following:
For further information on EJB 3.0, see the following documents on OTN:
Software Requirements
This demonstration requires that the following software components are installed and configured correctly:
Notations
- %ORACLE_HOME% - The directory where you installed Oracle Application
Server 10g 10.1.3
- %JAVA_HOME% - The directory where your JDK is installed
- %HOWTO_HOME% - The directory where this demo is unzipped
Building the Application
The Javadoc for this application is located in the %HOWTO_HOME%/doc/javadoc/ directory.
The configuration files are located in the %HOWTO_HOME%/etc directory, including deployment descriptor files such as application.xml.
Running the Application
To run the sample application on a standalone instance of Oracle Application
Server 10g 10.1.3.1, follow these steps:
1. Examine the Sample File Directories
- build - temporary directory created during the build
- log - temporary directory holding build/deploy logs
- etc - all necessary files to package the application
- lib - holds the application archives that could be deployed
- doc - the How-to document and Javadoc's
- javadoc - the javadoc of the different source files
- how-to-ejb30-interceptor.html - this How-to page
- src - the source of the demo
- ejb - contains the sample interceptor code
- client - contains application client code
2. Configure the Environment
Ensure the following environment variables are defined:
- %ORACLE_HOME% - The directory where you installed OC4J.
- %JAVA_HOME% - The directory where you installed the JDK
- %PATH% - includes %ORACLE_HOME% /ant/bin
3. Start the Server
Start OC4J stand alone using the following command after you make the above changes.
>%ORACLE_HOME%/bin/oc4j -start
If you are using an OracleAS managed install, start using the following command after you make the above changes.
> %ORACLE_HOME%/opmn/bin/opmnctl startall
4. Generate, Compile, and Deploy the Application
Ant 1.6.2 is shipped with OC4J and you have to set your PATH environment variable to $ORACLE_HOME/ant/bin. On some operating systems, Ant does not currently support the use of environment variables. If this is the case for your operating system, please modify the ant-oracle.xml file located in the %HOWTO_HOME% directory.
Edit ant-oracle.properties (in the demo directory) and ensure the following properties are set to the correct values, as indicated below for OC4J standalone:
- oc4j.host: host where OC4J is running
(default localhost)
- oc4j.admin.port: RMI port number (default 23791)
- oc4j.admin.user: admin user name (default oc4jadmin)
- oc4j.admin.password: admin user password (default welcome)
- oc4j.binding.module: website name where deployed web modules are bound (default http-web-site)
If you are using OracleAS managed install then you have appropriately change the following properties beside changing oc4j.admin.user and oc4j.admin.password for your managed OC4J instance in OracleAS install.
- opmn.host: the hostname/IP where OracleAS is running
(default localhost)
- opmn.port: OPMN request port (default 6003) for the OracleAS install
- oc4j.instance: admin user name (default oc4jadmin)
You have to uncomment appropriate deployer.uri in the ant-oracle.properties based on your environment i.e. a single instance OC4J or a clustered OC4J instance/group managed by OPMN.
You have to make changes in jndi.properties such as provider.url, principal and credential appropriate to your environment. If you are using OracleAS install, you have to use provider.url in the following format: opmn:ormi://localhost:6003:home/ejb30interceptor.
To build the application, type the following command from the %HOWTO_HOME% directory:
>ant
You should now have the newly created ejb30interceptor.ear in your %HOWTO_HOME%/lib directory.
This command would also attempt to deploy the application if the build is successful. It will first test whether OC4J is running.
Note that you can also deploy the application separately . Ensure the %ORACLE_HOME% environment variable is defined, and from the %HOWTO_HOME% directory, type the command:
>ant deploy
5. Run the Application
Run the sample by providing the following command, including a name as the program argument:
>ant run
Return to the console where you started OC4J and you will see output generated by the interceptor methods of the HelloWorld EJB.
Summary
In this document, you should have learned how to:
- Develop and define simple Interceptor methods for Stateless Session
bean using EJB 3.0
- Deploy and execute a simple Stateless Session bean with interceptor
methods using Oracle Application Server 10g 10.1.3