Skip Headers

Oracle9iAS Containers for J2EE Enterprise JavaBeans Developer's Guide and Reference
Release 2 (9.0.2)

Part Number A95881-01
Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Go to previous page Go to next page

6
Advanced EJB Subjects

This chapter discusses how to extend beyond the basics mentioned in each of the previous chapters. This chapter covers the following subjects:

Accessing EJBs

You must retrieve an EJB reference to the target bean in order to execute methods on that bean. In OC4J, you use JNDI to retrieve this reference. Most of the time, you must specify the target bean in an <ejb-ref> element in the originator's XML configuration file that is used in the java:comp/env logical name to designate the target bean to JNDI.

The method for accessing EJBs depends on where your client is located relative to the bean it wants to invoke. Consider the following when implementing the JNDI retrieval of the EJB reference of the bean:

  1. Do you want to set up a logical name for the target bean?

    • Yes: Modify the XML configuration file to set up the <ejb-ref> element with the target bean information. The logical name specified in the <ejb-ref-name> element is used in the JNDI lookup.

    • No: The actual name of the bean is used in the JNDI lookup. This name has been specified in the target bean's XML deployment descriptors in the <ejb-name> element.

  2. Where does the client exist relative to the target bean?

    • Within the same application as the target bean? Or is the target bean part of an application that is this client's parent? You do not need to set up any JNDI properties.

    • Otherwise, you must set up JNDI properties. There are two methods for setting up JNDI properties. See "Setting JNDI Properties" for more information.

EJB Reference Information

Specify the EJB reference information for the remote EJB in the <ejb-ref> element in the application-client.xml, ejb-jar.xml, or web.xml files. A full description or how to set up the <ejb-ref> element is given in "Configuring Environment References".

For example, the following specifies the reference information for the employee example:

<?xml version="1.0"?>
<!DOCTYPE application-client PUBLIC "-//Sun Microsystems, Inc.//DTD J2EE 
Application Client 1.2//EN" 
"http://java.sun.com/j2ee/dtds/application-client_1_2.dtd">

<application-client>
        <display-name>EmployeeBean</display-name>
        <ejb-ref>
                <ejb-ref-name>EmployeeBean</ejb-ref-name>
                <ejb-ref-type>Session</ejb-ref-type>
                <home>employee.EmployeeHome</home>
                <remote>employee.Employee</remote>
        </ejb-ref>
</application-client>

OC4J maps the logical name to the actual JNDI name on the client-side. The server-side receives the JNDI name and resolves it within its JNDI tree.

Setting JNDI Properties

If the client exists within the same application as the target or the target exists within its parent, you do not need a JNDI properties file. If not, you must initialize your JNDI properties either within a jndi.properties file, in the system properties, or within your implementation, before the JNDI call. The following sections discuss these three options:

No JNDI Properties

A servlet that exists in the same application with the target bean automatically accesses the JNDI properties for the node. Thus, accessing the EJB is simple: no JNDI properties are required.

//Get the Initial Context for the JNDI lookup for a local EJB
InitialContext ic = new InitialContext();
//Retrieve the Home interface using JNDI lookup
Object empObject = ic.lookup("java:comp/env/employeeBean");

This is also true if the target bean is in an application that has been deployed as this application's parent. To specify parents, use the -parent option of the admin.jar command when deploying the originating application.

JNDI Properties File

If setting the JNDI properties within the jndi.properties file, set the properties as follows. Make sure that this file is accessible from the CLASSPATH.

Factory
java.naming.factory.initial=
com.evermind.server.ApplicationClientInitialContextFactory
Location

The ORMI default port number is 23791, which can be modified in config/rmi.xml. Thus, set the URL in the jndi.properties, in one of the two ways:

java.naming.provider.url=ormi://<hostname>/<application-name>

or

java.naming.provider.url=ormi://<hostname>:23791/<application-name>
Security

When you access EJBs in a remote container, you must pass valid credentials to this container. Stand-alone clients define their credentials in the jndi.properties file deployed with the client's code.

java.naming.security.principal=<username>
java.naming.security.credentials=<password>

JNDI Properties Within Implementation

Set the properties with the same values, just with different syntax. For example, JavaBeans running within the container pass their credentials within the InitialContext, which is created to look up the remote EJBs.

To pass JNDI properties within the Hashtable environment, set these as shown below:

Hashtable env = new Hashtable(); 
env.put("java.naming.provider.url", "ormi://localhost/ejbsamples"); 
env.put("java.naming.factory.initial", 
      "com.evermind.server.ApplicationClientInitialContextFactory"); 
env.put(Context.SECURITY_PRINCIPAL, "guest"); 
env.put(Context.SECURITY_CREDENTIALS, "welcome"); 
Context ic = new InitialContext (env); 
Object homeObject = ic.lookup("java:comp/env/employeeBean");

// Narrow the reference to a TemplateHome.
EmployeeHome empHome =
	 (EmployeeHome) PortableRemoteObject.narrow(homeObject,
                                                   EmployeeHome.class);

Using the Initial Context Factory Classes

For most clients, set the initial context factory class to ApplicationClientInitialContextFactory. If you are not using a logical name defined in the <ejb-ref> in your XML configuration file, then you must provide the actual JNDI name of the target bean. In this instance, you must use a different initial context factory class, the com.evermind.server.RMIInitialContextFactory class.

Example 6-1 Servlet Accessing EJB in Remote OC4J Instance

The following servlet uses the JNDI name for the target bean: /cmpapp/employeeBean. Thus, this servlet may provide the JNDI properties in an RMIInitialContext object, instead of the ApplicationClientInitialContext object. The environment is initialized as follows:

Accessing an EJB in a Remote Server

If an application is installed in the OC4J server with a JSP or servlet that wants to invoke an EJB in a remote server, do the following:

  1. Deploy the intended EJB with the JSP/servlet in the same application.

  2. Set "remote=true" attribute in the <ejb-module> element in orion-application.xml for the EJB module deployed in the local application. The local EJB will be ignored.

  3. Configure the remote server where the remote EJB has been deployed in the <server> element in rmi.xml. You provide the hostname, port number, username, and password, as follows:

    <server host=<remote_host> port=<remote_port> user=<username> 
    password=<password>
    
    

If multiple servers are configured, the OC4J container will search all remote servers for the intended EJB application. Thus, the JSP or servlet in one OC4J container will invoke an EJB deployed in another OC4J container.

Reusing or Dedicating Connections

When you execute a JNDI lookup, you retrieve a connection to the server. Each subsequent JNDI lookup for this same server uses the connection returned on the first JNDI lookup. That is, all requests are forwarded over and share the same connection. However, if you want to use a dedicated connection for each connection, specify the "dedicated.connection" JNDI property to be true before you retrieve the InitialContext, as follows:

env.put("dedicated.connection", "true");

One of the reasons for using this is if you need to retrieve multiple connections, where each uses a different username/password. If dedicated.connection is false (which is the default), the first username/password is used for all subsequent connections, even if an alternate username/password is supplied. If you want to connect using a different username/password for each connection, you must set dedicated.connection to true. Thus, you will retrieve a separate physical connection, each with its own designated username/password. It opens a new connection instead of reusing a cached connection.

Location of Commonly-Used Classes Through Parent

If you have classes that can be used by more than one EJB, you can centralize these classes in one of the following ways:

Changing XML Files After Deployment

Whenever you deploy an application, OC4J automatically generates the OC4J-specific XML files with the default elements. If you want to change these files or add to the existing XML files, you must copy the XML files to where your original development directory for the application and change it in this location. If you change the XML file within the deployed location, OC4J simply overwrites these changes when the application is deployed again. The changes only stay constant when changed in the development directories.

For all OC4J-specific XML files, you can add these files within the recommended development structure as shown in Figure 6-1.

Figure 6-1 Development Application Directory Structure

Text description of advance8.gif follows

Text description of the illustration advance8.gif

Entity Bean Concurrency and Database Isolation Modes

In order to avoid resource contention and overwriting each others changes to database tables while allowing concurrent execution, entity bean concurrency and database isolation modes are provided.

Database Isolation Modes

The java.sql.Connection object represents a connection to a specific database. Database isolation modes are provided to define protection against resource contention. When two or more users try to update the same resource, a lost update can occur. That is, one user can overwrite the other user's data without realizing it. The java.sql.Connection standard provides four isolation modes, of which Oracle only supports two of these modes. These are as follows:

You can configure one of these database isolation modes for a specific bean. That is, you can specify that when the bean starts a transaction, the database isolation mode for this bean be what is specified in the OC4J-specific deployment descriptor. Specify the isolation mode on what is important for the bean: parallel execution or data consistency. The isolation mode for this bean is set for the entire transaction.

The isolation mode can be set for each entity bean in the <entity-deployment> element in the isolation attribute. The values can be committed or serializable. The default is committed. To change it to serializable, configure the following in the orion-ejb-jar.xml for the intended bean:

<entity-deployment ...  isolation="serializable"
 ...
</entity-deployment>

There is always a trade-off between performance and data consistency. The serializable isolation mode provides data consistency; the committed isolation mode provides for parallel execution.


Note:

There is a danger of lost updates with the serializable mode if the max-tx-retries element in the OC4J-specific deployment descriptor is greater than zero. The default for this value is three. If this element is set to greater than zero, then the container retries the update if a second blocked client receives a ORA-8177 exception. The retry would find the row unlocked and the update would occur. Thus, the second client's update succeeds and overwrites the first client's update. If you use serializable, you should consider setting the max-tx-retries element to zero for data consistency.


If you do not set an isolation mode, you receive the mode that is configured in the database. Setting the isolation mode within the OC4J-specific deployment descriptor temporarily overrides the database configured isolation mode for the life of the global transaction for this bean. That is, if you define the bean to use the serializable mode, then the OC4J container will force the database to be serializable for this bean only until the end of the transaction.

Entity Bean Concurrency Modes

OC4J also provides concurrency modes for handling resource contention and parallel execution within container-managed persistence (CMP) entity beans. Bean-managed persistence entity beans manage the resource locking within the bean implementation themselves. The concurrency modes configure when to block to manage resource contention or when to execute in parallel.

The concurrency modes are as follows:

To enable the CMP entity bean concurrency mode, add the appropriate concurrency value of "pessimistic", "optimistic", or "read-only" to the locking-mode attribute of the <entity-deployment> element in the OC4J-specific deployment descriptor (orion-ejb-jar.xml). The default is "optimistic". To modify the concurrency mode to pessimistic, do the following:

<entity-deployment ...  locking-mode="pessimistic"
 ...
</entity-deployment>

These concurrency modes are defined per bean and the effects of locking apply on the transaction boundaries.

Parallel execution requires that the pool size for wrapper and bean instances are set correctly. For more information on how to configure the pool sizes, see "Configuring Pool Sizes For Entity Beans".

Exclusive Write Access to the Database

The exclusive-write-access attribute of the <entity-deployment> element states that this is the only bean that accesses its table in the database and that no external methods are used to update the resource. It informs the OC4J instance that any cache maintained for this bean will only be dirtied by this bean. Essentially, if you set this attribute to true, you are assuring the container that this is the only bean that will update the tables used within this bean. Thus, any cache maintained for the bean does not need to constantly update from the back-end database.

This flag does not prevent you from updating the table; that is, it does not actually lock the table. However, if you update the table from another bean or manually, the results are not automatically updated within this bean.

The default for this attribute is false. Because of the effects of the entity bean concurrency modes, this element is only allowed to be set to true for a read-only entity bean. OC4J will always reset this attribute to false for pessimistic and optimistic concurrency modes.

<entity-deployment ...  exclusive-write-access="true"
 ...
</entity-deployment>

Effects of the Combination of Isolation and Concurrency Modes

For the pessimistic and read-only concurrency modes, the setting of the database isolation mode does not matter. These isolation modes only matter if an external source is modifying the database.

If you choose optimistic with committed, you have the potential to lose an update. If you choose optimistic with serializable, you will never lose an update. Thus, your data will always be consistent. However, you can receive an ORA-8177 exception as a resource contention error.

Differences Between Pessimistic and Optimistic/Serializable

An entity bean with the pessimistic concurrency mode does not allow multiple clients to execute the bean instance. Only one client is allowed to execute the instance at any one moment. An entity bean with the optimistic concurrency mode allows multiple instances of the bean implementation to execute in parallel. Setting the database isolation mode to serializable does not allow these multiple bean implementation instances to update the same row at the same time. Thus, the only difference between a pessimistic concurrency bean and an optimistic/serializable bean is where the blocking occurs. A pessimistic bean blocks at the bean instance; the other blocks at the database row.

Affects of Concurrency Modes on Clustering

All concurrency modes behave in a similar manner whether they are used within a standalone or a clustered environment. This is because the concurrency modes are locked at the database level. Thus, even if a pessimistic bean instance is clustered across nodes, the instant one instance tries to execute, the database locks out all other instances.

Configuring Pool Sizes For Entity Beans

You can set the minimum and maximum number of both the following instance pools:

You can set the pool number of each instance type with the following attributes of the <entity-deployment> element.

Techniques for Updating Persistence

By default, the container persists only the modified fields in the bean. At the end of each call, a SQL command is created to update these fields. However, if you want to have all of your persistence fields updated, set the following attribute to false:

<entity-deployment ...  update-changed-fields-only="false"
 ...
</entity-deployment>

If you choose to have all fields updated, the SQL parsing cache is used. The same SQL command is used for each update.

Configuring Environment References

You can create three types of environment elements that are accessible to your bean during runtime: environment variables, EJB references, and resource managers. These environment elements are static and can not be changed by the bean.

ISVs typically develop EJBs that are independent from the EJB container. In order to distance the bean implementation from the container specifics, you can create environment elements that map to one of the following: defined variables, entity beans, or resource managers. This indirection enables the bean developer to refer to existing variables, EJBs, and a JDBC DataSource without specifying the actual name. These names are defined in the deployment descriptor and are linked to the actual names within the OC4J-specific deployment descriptor.

Environment variables

You can create environment variables that your bean accesses through a lookup on the InitialContext. These variables are defined within an <env-entry> element and can be of the following types: String, Integer, Boolean, Double, Byte, Short, Long, and Float. The name of the environment variable is defined within <env-entry-name>, the type is defined in <env-entry-type>, and its initialized value is defined in <env-entry-value>. The <env-entry-name> is relative to the "java:comp/env" context.

For example, the following two environment variables are declared within the XML deployment descriptor for java:comp/env/minBalance and java:comp/env/maxCreditBalance.

<env-entry>
     <env-entry-name>minBalance</env-entry-name>
     <env-entry-type>java.lang.Integer</env-entry-type>
     <env-entry-value>500</env-entry-value>
</env-entry>
<env-entry>
     <env-entry-name>maxCreditBalance</env-entry-name>
     <env-entry-type>java.lang.Integer</env-entry-type>
     <env-entry-value>10000</env-entry-value>
</env-entry>

Within the bean's code, you would access these environment variables through the InitialContext, as follows:

InitialContext ic = new InitialContext();
Integer min = (Integer)ic.lookup("java:comp/env/minBalance");
Integer max = (Integer) ic.lookup("java:comp/env/maxCreditBalance"));

Notice that to retrieve the values of the environment variables, you prefix each environment element with "java:comp/env/", which is the location that the container stored the environment variable.

If you wanted the value of the environment variable to be defined in the OC4J-specific deployment descriptor, you can map the <env-entry-name> to the <env-entry-mapping> element in the OC4J-specific deployment descriptor. This means that the value specified in the orion-ejb-jar.xml file overrides any value that may be specified in the ejb-jar.xml file. The type specified in the EJB deployment descriptor stays the same.

Figure 6-2 shows how the minBalance environment variable is defined as 500 within the OC4J-specific deployment descriptor.

Figure 6-2 Environment Variable Mapping

Text description of advanc16.gif follows

Text description of the illustration advanc16.gif

Environment References To Other Enterprise JavaBeans

You can define an environment reference to an EJB within the deployment descriptor. If your bean calls out to another bean, you can enable your bean to invoke the second bean using a reference defined within the deployment descriptors. You create a logical name within the EJB deployment descriptor, which is mapped to the concrete name of the bean within the OC4J-specific deployment descriptor.

Declaring the target bean as an environment reference provides a level of indirection: the originating bean can refer to the target bean with a logical name.

To define a reference to another EJB within the JAR or in a bean declared as a parent, you provide the following:

  1. Name--provide a name for the target bean. This name is what the bean uses within the JNDI URL for accessing the target bean. The name should begin with "ejb/", such as "ejb/myEmployee", and will be available within the "java:comp/env/ejb" context.

    • This name can be the actual name of the bean; that is, the name defined within the <ejb-name> element in the <session> or <entity> elements.

    • This name can be a logical name that you want to use in your implementation. But it is not the actual name of the bean. If you use a logical name, the actual name must either be specified in the <ejb-link> element in this <ejb-ref> element or in the <ejb-ref-mapping> element in the OC4J-specific deployment descriptor.

    These options are discussed below.

  2. Type--define whether the bean is a session or an entity bean. Value should be either "Session" or "Entity".

  3. Home--provide the fully qualified home interface name.

  4. Remote--provide the fully qualified remote interface name.

  5. Link--provide a name that links this EJB reference with the actual JNDI URL. This is optional.

If you have two beans in the JAR: BeanA and BeanB. If BeanB creates a reference to BeanA, you can define this reference in one of three methods:

As shown in Figure 6-3, the logical name for the bean is mapped to the JNDI name by providing the same name, "ejb/nextVal", in both the <ejb-ref-name> in the EJB deployment descriptor and the name attribute within the <ejb-ref-mapping> element in the OC4J-specific deployment descriptor.

Figure 6-3 EJB Reference Mapping

Text description of advance3.gif follows

Text description of the illustration advance3.gif

Example 6-2 Defining an EJB Reference Within the Environment

The following example defines a reference to the Hello bean, as follows:

  1. The logical name used for the target bean within the originating bean is "java:comp/env/ejb/HelloWorld".

  2. The target bean is a session bean.

  3. Its home interface is hello.HelloHome; its remote interface is hello.Hello.

  4. The link to the JNDI URL for this bean is defined in the OC4J-specific deployment descriptor under the "HelloWorldBean" name.

    Text description of advance4.gif follows

    Text description of the illustration advance4.gif

As shown in Figure 6-3, the <ejb-link> is mapped to the name attribute within the <ejb-ref-mapping> element in the OC4J-specific deployment descriptor by providing the same logical name in both elements. The Oracle-specific deployment descriptor would have the following definition to map the logical bean name of "java:comp/env/ejb/HelloWorld" to the JNDI URL "/test/myHello".

Text description of advance5.gif follows

Text description of the illustration advance5.gif

To invoke this bean from within your implementation, you use the <ejb-ref-name> defined in the EJB deployment descriptor. In EJB or pure Java clients, you prefix this name with "java:comp/env/ejb/", which is where the container places the EJB references defined in the deployment descriptor. Servlets only require the logical name defined in the <ejb-ref-name>.

The following is a lookup from an EJB client:

InitialContext ic = new InitialContext();
HelloHome hh = (HelloHome)ic.lookup("java:comp/env/ejb/HelloWorld");

The following is a lookup from a Servlet, if the Servlet defines the logical name of "ejb/HelloWorld" in <ejb-ref> in its web.xml file and maps it to the actual name of "/test/myHello" within the orion-web.xml file.

InitialContext ic = new InitialContext();
HelloHome hh = (HelloHome)ic.lookup("ejb/HelloWorld");

Environment References To Resource Manager Connection Factory References

The resource manager connection factory references can include resource managers such as JMS, Java mail, URL, and JDBC DataSource objects. Similar to the EJB references, you can access these objects from JNDI by creating an environment element for each object reference. However, these references can only be used for retrieving the object within the bean that defines these references. Each is fully described in the following sections:

JDBC DataSource

You can access a database through JDBC either using the traditional method or by creating an environment element for a JDBC DataSource. In order to create an environment element for your JDBC DataSource, you must do the following:

  1. Define the DataSource in the data-sources.xml file.

  2. Create a logical name within the <res-ref-name> element in the EJB deployment descriptor. This name should always start with "jdbc". In the bean code, the lookup of this reference is always prefaced by "java:comp/env/jdbc".

  3. Map the logical name within the EJB deployment descriptor to the JNDI name, created in step 1, within the OC4J-specific deployment descriptor.

  4. Lookup the object reference within the bean with the "java:comp/env/jdbc" preface and the logical name defined in the EJB deployment descriptor.

As shown in Figure 6-4, the JDBC DataSource uses the JNDI name "test/OrderDataSource". The logical name that the bean knows this resource as is "jdbc/OrderDB". These names are mapped together within the OC4J-specific deployment descriptor. Thus, within the bean's implementation, the bean can retrieve the connection to OrderDataSource by using the "java:comp/env/jdbc/OrderDB" environment element.

Figure 6-4 JDBC Resource Manager Mapping

Text description of advance7.gif follows

Text description of the illustration advance7.gif

Example 6-3 Defining an environment element for JDBC Connection

The environment element is defined within the EJB deployment descriptor by providing the logical name, "jdbc/OrderDB", its type of javax.sql.DataSource, and the authenticator of "Application".

Text description of advance9.gif follows

Text description of the illustration advance9.gif

The environment element of "jdbc/OrderDB" is mapped to the JNDI bound name for the connection, "test/OrderDataSource" within the Oracle-specific deployment descriptor.

Text description of advanc10.gif follows

Text description of the illustration advanc10.gif

Once deployed, the bean can retrieve the JDBC DataSource as follows:

javax.sql.DataSource db;
java.sql.Connection conn;
.
.
.
db = (javax.sql.DataSource) 
initCtx.lookup("java:comp/env/jdbc/OrderDB");
conn = db.getConnection();


Note:

This example assumes that a DataSource is specified in the data-sources.xml file with the JNDI name of "/test/OrderDataSource".


Mail Session

You can create an environment element for a Java mail Session object through the following:

  1. Bind the javax.mail.Session reference within the JNDI name space in the application.xml file using the <mail-session> element, as follows:

    <mail-session location="mail/MailSession"
       smtp-host="mysmtp.oraclecorp.com">
       <property name="mail.transport.protocol" value="smtp"/>
       <property name="mail.smtp.from" value="emailaddress@oracle.com"/>
    </mail-session>
    
    

    The location attribute contains the JNDI name specified in the location attribute of the <resource-ref-mapping> element in the OC4J-specific deployment descriptor.

  2. Create a logical name within the <res-ref-name> element in the EJB deployment descriptor. This name should always start with "mail". In the bean code, the lookup of this reference is always prefaced by "java:comp/env/mail".

  3. Map the logical name within the EJB deployment descriptor to the JNDI name, created in step 1, within the OC4J-specific deployment descriptor.

  4. Lookup the object reference within the bean with the "java:comp/env/mail" preface and the logical name defined in the EJB deployment descriptor.

As shown in Figure 6-5, the Session object was bound to the JNDI name "/test/myMailSession". The logical name that the bean knows this resource as is "mail/testMailSession". These names are mapped together within the OC4J-specific deployment descriptor. Thus, within the bean's implementation, the bean can retrieve the connection to the bound Session object by using the "java:comp/env/mail/testMailSession" environment element.

Figure 6-5 Session Resource Manager Mapping

Text description of advance6.gif follows

Text description of the illustration advance6.gif

This environment element is defined with the following information:

Element Description

<res-ref-name>

The logical name of the Session object to be used within the originating bean. The name should be prefixed with "mail/". In our example, the logical name for our ordering database is "mail/testMailSession".

<res-type>

The Java type of the resource. For the Java mail Session object, this is javax.mail.Session.

<res-auth>

Define who is responsible for signing on to the database. The value can be "Application" or "Container" based on who provides the authentication information.

Example 6-4 Defining an environment element for Java mail Session

The environment element is defined within the EJB deployment descriptor by providing the logical name, "mail/testMailSession", its type of javax.mail.Session, and the authenticator of "Application".

Text description of advanc11.gif follows

Text description of the illustration advanc11.gif

The environment element of "mail/testMailSession" is mapped to the JNDI bound name for the connection, "test/myMailSession" within the OC4J-specific deployment descriptor.

Text description of advanc12.gif follows

Text description of the illustration advanc12.gif

Once deployed, the bean can retrieve the Session object reference as follows:

InitialContext ic = new InitialContext();
Session session = (Session) 
ic.lookup("java:comp/env/mail/testMailSession");

//The following uses the mail session object
//Create a message object
MimeMessage msg = new MimeMessage(session);

//Construct an address array
String mailTo = "whosit@oracle.com";
InternetAddress addr = new InternetAddress(mailto);
InternetAddress addrs[] = new InternetAddress[1];
addrs[0] = addr;

//set the message parameters
msg.setRecipients(Message.RecipientType.TO, addrs);
msg.setSubject("testSend()" + new Date());
msg.setContent(msgText, "text/plain");

//send the mail message
Transport.send(msg);
URL

You can create an environment element for a Java URL object through the following:

  1. Create a logical name within the <res-ref-name> element in the EJB deployment descriptor. This name should always start with "url". In the bean code, the lookup of this reference is always prefaced by "java:comp/env/url".

  2. Map the logical name within the EJB deployment descriptor to the URL within the OC4J-specific deployment descriptor.

  3. Lookup the object reference within the bean with the "java:comp/env/url" preface and the logical name defined in the EJB deployment descriptor.

As shown in Figure 6-6, the URL object was bound to the URL "www.myURL.com". The logical name that the bean knows this resource as is "url/testURL". These names are mapped together within the OC4J-specific deployment descriptor. Thus, within the bean's implementation, the bean can retrieve the connection to the bound Session object by using the "java:comp/env/url/testURL" environment element.

Figure 6-6 URL Resource Manager Mapping

Text description of advanc13.gif follows

Text description of the illustration advanc13.gif

This environment element is defined with the following information:

Element Description

<res-ref-name>

The logical name of the URL object to be used within the originating bean. The name should be prefixed with "url/". In our example, the logical name for our ordering database is "url/testURL".

<res-type>

The Java type of the resource. For the Java URL object, this is java.net.URL.

<res-auth>

Define who is responsible for signing on to the database. At this time, the only value supported is "Application". The application provides the authentication information.

Example 6-5 Defining an environment element for JDBC Connection

The environment element is defined within the EJB deployment descriptor by providing the logical name, "url/testURL", its type of java.net.URL, and the authenticator of "Application".

Text description of advanc14.gif follows

Text description of the illustration advanc14.gif

The environment element of "url/testURL" is mapped to the URL "www.myURL.com" within the OC4J-specific deployment descriptor.

Text description of advanc15.gif follows

Text description of the illustration advanc15.gif

Once deployed, the bean can retrieve the URL object reference as follows:

InitialContext ic = new InitialContext();
URL url = (URL) ic.lookup("java:comp/env/url/testURL");

//The following uses the URL object
URLConection conn = url.openConnection();

Configuring Security

Choosing what security to use is a subject that involves more than the authorization details that we discuss in this section. For a full description of security, see the OC4J Services Guide.

This book focuses on EJBs and any XML configuration that belongs within the EJB deployment descriptors. Within the security spectrum, EJB authorization is specified within the EJB and OC4J-specific deployment descriptors. It involves assigning roles that are attached to EJBs to users and groups that are defined in the principals.xml file. Thus, this section describes assigning roles to EJBs and mapping these roles to specific users or groups.

You can manage the authorization piece of your security within the deployment descriptors, as follows:

Users, Groups, and Roles

Users and groups are identities known by the container. Roles are the logical identities each application uses to indicate access rights to its different objects. The username/passwords can be digital certificates and, in the case of SSL, private key pairs. The EJB deployment descriptor indicates what roles are needed to access the different parts of the application. The OC4J-specific deployment descriptor provides a mapping between the logical roles and the users/groups known by the container.

Defining users, groups, and roles are discussed in the following sections:

Specifying Users and Groups

OC4J supports the definition of users and groups--either shared by all deployed applications or specific to given applications.

The following excerpt from the principals.xml file shows how to define a group named managers and a user named guest with password, welcome.

<principals> 
 <groups> 
  <group name="managers"> 
   <description>Group for all managerial users</description> 
   <permission name="rmi:login" /> 
   <permission name="com.evermind.server.rmi.RMIPermission" /> 
  </group> 
....other groups... 
 </groups> 
 <users> 
  <user username="guest" password="welcome"> 
   <description>purchase order manager</description> 
   <group-membership group="managers" /> 
  </user> 
 </users> 
</principals> 

For a full description of the principals.xml file and how to specify users and groups, see the OC4J Services Guide.

Specifying Logical Roles in the EJB Deployment Descriptor

Specify the logical roles that your application uses in the EJB deployment descriptor. The roles are defined within the element named <security-role>.

Example 6-6 EJB JAR Security Role Definition

This example creates a logical role named POMGR in the ejb-jar.xml deployment descriptor.

  1. Define the logical security role, POMGR in the <security-role> element.

    <security-role> 
     <description>Purchase Order Manager</description> 
     <role-name>POMGR</role-name> 
    </security-role>
    
  2. Define the bean and methods that this role can access in the <method-permission> element.

    <method-permission> 
     <role-name>POMGR</role-name> 
     <method> 
      <ejb-name>PurchaseOrderBean</ejb-name> 
      <method-name>*</method-name> 
     </method> 
    </method-permission>
    

Mapping Logical Roles to Users and Groups

Map the logical roles defined in the application deployment descriptors to concrete users or groups through the <security-role-mapping> element in the OC4J-specific deployment descriptor.

Example 6-7 Mapping Logical Role to Actual Role

This example maps the logical role POMGR to the managers group in the orion-ejb-jar.xml file. Any user that can log in as part of this group is considered to have the POMGR role; thus, it can execute the methods of PurchaseOrderBean.

<security-role-mapping name="POMGR"> 
 <group name="managers" /> 
</security-role-mapping> 


Note:

You can map a logical role to a single group or to several groups.


To map this role to a specific user, do the following:

<security-role-mapping name="POMGR"> 
 <user name="guest" /> 
</security-role-mapping> 

Lastly, you can map a role to a specific user within a specific group, as follows:

<security-role-mapping name="POMGR"> 
 <group name="managers" />
 <user name="guest" /> 
</security-role-mapping> 

As shown in Figure 6-7, the logical role name for POMGR defined in the EJB deployment descriptor is mapped to SCOTT within the OC4J-specific deployment descriptor in the <security-role-mapping> element.

Figure 6-7 Security Mapping

Text description of advancea.gif follows

Text description of the illustration advancea.gif

Notice that the <role-name> in the EJB deployment descriptor is the same as the name attribute in the <security-role-mapping> element in the OC4J-specific deployment descriptor. This is what identifies the mapping.

Thus, the definition and mapping of roles is demonstrated in Figure 6-8.

Figure 6-8 Role Mapping

Text description of advance2.gif follows

Text description of the illustration advance2.gif

Default Role Mapping

To default all methods in EJBs that have not been associated with a method permission to a security role, use the <default-method-access> element.

The following example shows how all methods not associated with a method permission are mapped to the "managers" group:

 <default-method-access>
     <security-role-mapping name="users" impliesAll="true" />
        <group name="managers" />
      </security-role-mapping>
 </default-method-access>

The impliesAll attribute specifies that this includes all users.

Authenticating EJB Clients

When you access EJBs in a remote container, you must pass valid credentials to this container.

Credentials in JNDI Properties

Indicate the username (principal) and password (credentials) to use when looking up remote EJBs in the jndi.properties file.

For example, if you want to access remote EJBs as POMGR/welcome, define the following properties. The factory.initial property indicates that you will use the Oracle JNDI implementation:

java.naming.security.principal=POMGR
java.naming.security.credentials=welcome
java.naming.factory.initial=
com.evermind.server.ApplicationClientInitialContextFactory java.naming.provider.url=ormi://localhost/ejbsamples

In your application program, authenticate and access the remote EJBs, as shown below:

InitialContext ic = new InitialContext();
CustomerHome = 
(CustomerHome)ic.lookup("java:comp/env/purchaseOrderBean"); 

Credentials in the InitialContext

To access remote EJBs from a servlet or JavaBean, pass the credentials in the InitialContext object, as follows:

Hashtable env = new Hashtable(); 
env.put("java.naming.provider.url", "ormi://localhost/ejbsamples"); 
env.put("java.naming.factory.initial", 
        "com.evermind.server.ApplicationClientInitialContextFactory"); 
env.put(Context.SECURITY_PRINCIPAL, "POMGR"); 
env.put(Context.SECURITY_CREDENTIALS, "welcome"); 
Context ic = new InitialContext (env); 
CustomerHome = 
(CustomerHome)ic.lookup("java:comp/env/purchaseOrderBean") 

Common Errors

The following are common errors that may occur when executing EJBs:

NamingException Thrown

If you are trying to remotely access an EJB and you receive an javax.naming.NamingException error, your JNDI properties are probably not initialized properly. See "Accessing EJBs" for a discussion on setting up JNDI properties when accessing an EJB from a remote object or remote servlet.

Deadlock Conditions

If the call sequence of several beans cause a deadlock scenario, the OC4J container notices the deadlock condition and throws a Remote exception that details the deadlock condition in one of the offending beans.


Go to previous page Go to next page
Oracle
Copyright © 2002 Oracle Corporation.

All Rights Reserved.
Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index