Skip Headers

Oracle® Containers for J2EE Services Guide 10g Release 3 (10.1.3) B14427-01 |
| Home | Solution Area | Contents | Index

Previous | Next |

# 6 Using Remote Method Invocation in OC4J

This chapter includes the following topics:

- What Is RMI?

- Using Oracle Remote Method Invocation (RMI/ORMI)

- Remote Object Lookup Using RMI/ORMI

- Configuring ORMI Tunneling through HTTP

- Using ORMI/SSL (ORMIS) in OC4J

- Using J2EE Interoperability (RMI/IIOP)

- Switching from ORMI to IIOP Transport

## 6.1 What Is RMI?

Java Remote Method Invocation (RMI) enables you to create distributed Java-based to Java-based applications, in which the methods of remote Java objects can be invoked from other Java virtual machines (JVMs), possibly on different hosts.

OC4J supports RMI over both the proprietary Oracle Remote Method Invocation (ORMI) protocol and over the standard Internet Inter-ORB Protocol (IIOP). Objects running within OC4J instances can invoke one another using RMI/ORMI. Objects can invoke one another across different J2EE containers—for example, between OC4J and BEA WebLogic servers—using RMI/IIOP.

Additional Documentation

- The How-To document "How-To Propagate a transaction context between OC4J instances" and the ZIP file at the following site contains information and an example about transaction context propagation between OC4J instances using ORMI:

  `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/how-to-transaction-propagation/doc/how-to-transaction-propagation.html`

- The How-To documents at the following site provide additional information about OC4J 10g Release 3 (10.1.3) features, including feature overviews and code excerpts relevant to the feature.

  `http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/index.html`

### 6.1.1 Choosing RMI/ORMI or RMI/IIOP

When can you use RMI/ORMI versus RMI/IIOP?

- Use RMI/ORMI to invoke methods on remote objects within or across OC4J instances.

  See "Using Oracle Remote Method Invocation (RMI/ORMI)" for details.

- Use RMI/IIOP to invoke methods on remote objects across OC4J and non-Oracle J2EE containers, such as BEA WebLogic.

  See "Switching from ORMI to IIOP Transport" for details.

## 6.2 Using Oracle Remote Method Invocation (RMI/ORMI)

This section describes Oracle Containers for J2EE (OC4J) support for allowing objects—such as EJBs—to invoke one another across OC4J server instances using the proprietary Remote Method Invocation (RMI)/Oracle RMI (ORMI) protocol.

This section covers the following topics:

- Introducing RMI/ORMI

- Configuring RMI in a Standalone OC4J Installation

- Configuring RMI in an Oracle Application Server Environment

- Client-Side Requirements to Use RMI/ORMI

### 6.2.1 Introducing RMI/ORMI

The Oracle Remote Method Invocation (ORMI) is Oracle's proprietary implementation of the RMI protocol that is optimized for use with OC4J.

By default, EJBs within OC4J server instances exchange RMI calls over ORMI. Alternatively, you can convert an EJB to exchange RMI calls over IIOP, making it possible for EJBs to invoke one another across different EJB containers from different vendors, such as OC4J and BEA WebLogic. See "Switching from ORMI to IIOP Transport" for more.

Note: For the OC4J 10g Release 3 (10.1.3) implementation, load balancing and failover are supported only for ORMI, not for IIOP.

#### 6.2.1.1 Features of ORMI

ORMI is enhanced for OC4J and provides the following features:

- Increased RMI Message Throughput

- Enhanced Threading Support

- Co-Located Object Support

##### 6.2.1.1.1 Increased RMI Message Throughput

Using ORMI, OC4J can process at a very high transaction rate. This is reflected in Oracle's SpecJ Application Server benchmarks at `http://www.spec.org/`.

One way ORMI achieves this performance is by using messages that are much smaller than IIOP messages. Smaller messages take less bandwidth to send and receive, and less processing time to encode and decode.

ORMI message size is further reduced by optimizing how much state information is exchanged between client and server. Using ORMI, some state is cached on the server so that it does not need to be transmitted in every RMI call. This does not violate the RMI requirement to be stateless because in the event of a failover, the client code resends all the state information required by the new server.

##### 6.2.1.1.2 Enhanced Threading Support

ORMI is tightly coupled with the OC4J threading model to take full advantage of its queuing, pooling, and staging capabilities.

ORMI uses one thread per client. For multi-threaded clients, OC4J multiplexes each call through one connection. However, OC4J does not serialize them, so multiple threads do not block each other.

This feature ensures that each client (single-threaded or multi-threaded) has one connection to the remote server.

##### 6.2.1.1.3 Co-Located Object Support

For co-located objects, RMI/ORMI detects the co-located scenario and avoids the extra, unnecessary socket call.

The same is true when the JNDI registry is co-located.

##### 6.2.1.1.4 Compatibility Patches for 9.0.4.x and 10.1.2.x

In order to use ORMI to invoke a method on a remote object when the invoking object and the invoked object are running on different OC4J versions, you must install a patch on the older version. This applies when the newer version is 10.1.3 and the older version is 9.0.4.x or 10.1.2.x. This applies both ways; that is when invoking from the older version to the newer version or when invoking from the newer version to the older version.

Some examples:

- A servlet running on OC4J 9.0.4.3 invoking a method on an EJB running on OC4J 10.1.3.

- An EJB running on OC4J 10.1.3 invoking a JMS object running on OC4J 10.12.0.2.

- A JSP running on OC4J 10.1.2 invoking a method on an EJB running on OC4J 10.1.3.

Note: Invoking between 9.0.4.x and 10.1.2.x does not require a patch; these versions are compatible already.

The patches can be downloaded from `http://metalink.oracle.com`. The following table lists the older versions to be patched and the corresponding patch identifiers.

OC4J Version to be Patched | Patch Identifier
--- | ---
9.0.4.3 | BUG 4712885
10.1.2.2 | BUG 4712552
10.1.2.0.0 | BUG 4742351
10.1.2.0.2 | BUG 4740687

### 6.2.2 Configuring RMI in a Standalone OC4J Installation

In a standalone OC4J installation, you must specify RMI server data in the RMI configuration file, `rmi.xml`. You must also specify the location of this file in `server.xml`, the OC4J configuration file.

The `rmi.xml` file and the `server.xml` file are installed in `ORACLE_HOME/j2ee/home/config` by default

1. Specify the path to the RMI configuration file—`rmi.xml`—in the `<rmi-config>` element in `server.xml`, the OC4J server configuration file.

   The syntax is as follows:

       <rmi-config path="RMI_PATH" />

   The typical value for `RMI_PATH` is `./rmi.xml`.

2. Add an `<rmi-server>` element specifying the host, port, and user name and password to use to connect to (and accept connections from) remote RMI servers to the `rmi.xml` file on the OC4J instance. This file is installed in `ORACLE_HOME/j2ee/home/config` by default.

   For example:

       <rmi-server host="hostname" port="port">
       </rmi-server>

   The attributes of the `<rmi-server>` element are:

   - `host`: The host name or IP address from which the RMI server accepts RMI requests. If you omit this attribute, the RMI server accepts RMI requests from any host.

   - `port`: The port number on which the RMI server listens for RMI requests. In an OC4J standalone environment, if you omit this attribute, it defaults to `23791`.

3. Optionally configure the `<rmi-server>` element with one or more `<server>` elements that each specify a remote (point-to-point) RMI server that your application can contact over RMI.

   For example:

       <rmi-server host="hostname" port="port">
           <server host="serverhostname" username="username" port="serverport"
           password="password"/>
       </rmi-server>

   The `host` attribute is required; the remaining attributes are optional. Here are the user-replaceable attributes of the `server` element:

   - `serverhostname`: the host name or IP address on which the remote RMI server listens for RMI requests

   - `username`: the user name of a valid principal on the remote RMI server

   - `serverport`: the port number on which the remote RMI server listens for RMI requests

   - `password`: the password used by the principal username

#### 6.2.2.1 Access Restrictions

ORMI and ORMIS enable you to restrict incoming IP access by defining ACL masks within `rmi.xml` using the `<access-mask>` element.

Access controls can either be exclusive or inclusive.

- In the exclusive mode, access must be explicitly granted to an IP address or host name. The default mode for the access mask `default="deny"` specifies that the access control is exclusive.

- In the inclusive mode, access is available to all and exceptions must be granted individually. The default mode for the access mask `default="allow"` specifies that the access control is inclusive.

The `<host-access>` and `<ip-access>` sub elements are used to specify exceptions to the default access mode.

For additional information, see Appendix A, "Web Module Administration"", in the Oracle Containers for J2EE Servlet Developer's Guide

An example of an exclusive mode configuration to allow only `localhost` and the `192.168.1.*` subnet is shown in the following example:

    <rmi-server
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation=
       "http://xmlns.oracle.com/oracleas/schema/rmi-server-10_0.xsd"
      port="23791"
      ssl-port="23943"
      schema-major-version="10"
      schema-minor-version="0">

          <access-mask default="deny" >
             <host-access domain="localhost" mode="allow"/>
             <ip-access ip="192.168.1.0" netmask="255.255.255.0" mode="allow"/>
          </access-mask>

      <log>
        <file path="../log/rmi.log" />
      </log>

      <ssl-config
        keystore="../wallets/wallet-server-a/ewallet.p12"
        keystore-password="serverkey-a"
       />

       </rmi-server>

### 6.2.3 Client-Side Requirements to Use RMI/ORMI

This section lists the ZIP files that you use to install the Oracle and J2EE standard JAR files that enable EJB and JMS lookup using RMI/ORMI.

The following ZIP files are available from `http://www.oracle.com/technology/software/products/ias/htdocs/utilsoft.html`

- To enable EJB lookup using ORMI, download and expand `oc4j_client.zip`.

- To enable other lookups, such as JMS, download and expand `oc4j_extended.zip` instead of `oc4j_client.zip`.

Once the appropriate ZIP file is expanded, make sure that `oc4jclient.jar` is included in the CLASSPATH.

The ZIP files contain all the JAR files required by the client. The JAR files contain the classes necessary for client interaction. You must only add `oc4jclient.jar` to your `CLASSPATH`, because all other JAR files required by the client are referenced in the `oc4jclient.jar` manifest classpath.

To enable EJB lookup, make sure that the following JAR files are included on the client side.

Table 6-1 Client-side JAR Files Required for EJB Lookup

JAR | ORACLE_HOME Path
--- | ---
`oc4jclient.jar` | `/j2ee/<instance>`
`ejb.jar` | `/j2ee/<instance>/lib`

To enable resource adapter lookup, include the following JAR files on the client side.

Table 6-2 Client-side JAR Files Required for JMS Connector Lookup

JAR | ORACLE_HOME Path
--- | ---
`oc4jclient.jar` | `/j2ee/<instance>`
`jta.jar` | `/j2ee/<instance>/lib`
`jms.jar` | `/j2ee/<instance>/lib`
`jndi.jar` | `/j2ee/<instance>/lib`
`javax77.jar` | `/j2ee/<instance>/lib`
`adminclient.jar` | `/j2ee/<instance>/lib`
`oc4j-internal.jar` | `/j2ee/<instance>/lib`
`connector.jar` | `/j2ee/<instance>/lib`
`jmxri.jar` | `/j2ee/<instance>/lib`
`jazncore.jar` | `/j2ee/<instance>`
`oc4j.jar` | `/j2ee/<instance>`

To enable internal OEMS JMS In-Memory and File-Based lookup, make sure that the JAR files listed in Table 6-3, "Client-side JAR Files Required for OEMS JMS In-Memory and File-Based Lookup" are included on the client side.

Table 6-3 Client-side JAR Files Required for OEMS JMS In-Memory and File-Based Lookup

JAR | ORACLE_HOME Path
--- | ---
`oc4jclient.jar` | `/j2ee/<instance>`
`jta.jar` | `/j2ee/<instance>/lib`
`jms.jar` | `/j2ee/<instance>/lib`
`jndi.jar` | `/j2ee/<instance>/lib`
`javax77.jar` | `/j2ee/<instance>/lib`
`optic.jar` (Required only if the `opmn:ormi` prefix is used in Oracle Application Server environment.) | `/opmn/lib`

To enable internal OEMS JMS Database lookup directly from an application client, make sure that the JAR files listed in Table 6-4, "Client-side JAR Files Required for OEMS JMS Database Lookup" are included on the client side.

Table 6-4 Client-side JAR Files Required for OEMS JMS Database Lookup

JAR | ORACLE_HOME Path
--- | ---
`oc4jclient.jar` | `/j2ee/<instance>`
`ejb.jar` | `/j2ee/<instance>/lib`
`jta.jar` | `/j2ee/<instance>/lib`
`jms.jar` | `/j2ee/<instance>/lib`
`jndi.jar` | `/j2ee/<instance>/lib`
`javax77.jar` | `/j2ee/<instance>/lib`
`adminclient.jar` | `/j2ee/<instance>/lib`
`ojdbc14dms.jar` | `/j2ee/<instance>/../../oracle/jdbc/lib`
`dms.jar` | `/j2ee/<instance>/../../oracle/lib`
`bcel.jar` | `/j2ee/<instance>/lib`
`optic.jar` (Required only if the `opmn:ormi` prefix is used in Oracle Application Server environment.) | `/opmn/lib`

### 6.2.4 Configuring RMI in an Oracle Application Server Environment

In an Oracle Application Server environment, you must edit the `opmn.xml` file to specify the port range on which this local RMI server listens for RMI requests.

Note that manual changes to configuration files in an Oracle Application Server environment must be manually updated on each OC4J instance.

To configure the `opmn.xml` file:

1. Configure the `rmi` port range using the `port id="rmi"` element as shown in the following example `opmn.xml` file excerpt:

       <ias-component id="OC4J">
           <process-type id="home" module-id="OC4J">
               <port id="default-web-site" range="12501-12600" protocol="ajp" />
               <port id="rmi" range="12401-12500" />
               <port id="rmis" range="12801-12900" />
               <port id="jms" range="12601-12700" />
               <process-set id="default_group" numprocs="1"/>
           </process-type>
       </ias-component>

   For more information on configuring the `opmn.xml` file, see the Oracle Application Server Administrator's Guide.

2. Apply changes by running the following `opmnctl` command:

       opmnctl reload

## 6.3 Remote Object Lookup Using RMI/ORMI

To invoke methods on an object, you must first be able to locate the object.

- Setting JNDI Properties for RMI

- Configuring ORMI Request Load Balancing

- Example Lookups Using ORMI

### 6.3.1 Setting JNDI Properties for RMI

The following RMI/ORMI properties are specified in the client's `jndi.properties` file:

- `java.naming.provider.url` (see "Setting the Java Naming Provider URL")

- `java.naming.factory.initial` (see "Specifying the Context Factory")

#### 6.3.1.1 Setting the Java Naming Provider URL

Use the following syntax to define one or more OC4J hosts as the value of `java.naming.provider.url`:

    <protocol>://<host>:[<port>]:<oc4j_instance>/<appName>

For example, specify the following for an application running within Oracle Application Server:

    java.naming.provider.url=opmn:ormi://myHost:home/ejbsamples

Table 6-5 describes arguments used in this syntax.

Note: For details on setting the `java.naming.provider.url` for applications that will utilize HTTP tunneling, see "Configuring ORMI Tunneling through HTTP". For `java.naming.provider.url` values for applications using ORMI over SSL, see the CSIv2 chapter in the Oracle Containers for J2EE Security Guide.

Table 6-5 Naming Provider URL

Parameter | Description
--- | ---
`protocol` | Applications on Oracle Application Server: Use `opmn:ormi://` Applications on standalone OC4J: Use `ormi://` Applications that must interoperate with non-OC4J containers: Use `corbaname` (see "Specifying the corbaname URL").
`host` | Applications on Oracle Application Server: Specify the name of the OPMN host as defined in the `opmn.xml` file. Although OPMN is often located on the same node as the OC4J instance, specify the host name in case it is located on another machine. Applications on standalone OC4J: Specify the OC4J host name as defined by the `<rmi-server>` element `host` attribute in the `rmi.xml` file.
`port` | Applications on Oracle Application Server 10g Release 3 (10.1.3): Specify the OPMN `request` port. The `opmn` process will forward RMI requests to the RMI port that it selected for the appropriate OC4J instance (see "Specifying the opmn Request Port in Oracle Application Server 10g Release 3 (10.1.3)"). If omitted, the default OPMN `request` port value 6003 is used. Applications on Oracle Application Server 10g Release 2 (10.1.2) and earlier: Specify the RMI port that `opmn` selected for your OC4J instance (see "Specifying the RMI Port in Oracle Application Server 10g Release 2 (10.1.2) And Earlier"). Applications on standalone OC4J: Specify the port number defined in the `port` attribute of the `<rmi.server>` element in `rmi.xml`. Applications that must interoperate with non-OC4J containers and use the `corbaname` prefix: See "Specifying the corbaname URL" for information on what port to specify. The port is optional and is determined by the protocol. The ORMI protocol defaults to port `23791`. The ORMIS protocol defaults to port `23943`.
`oc4j_instance` | For Oracle Application Server applications: The name of the OC4J instance. The name of the default OC4J instance is `home`. For standalone OC4J applications: This variable is not applicable.
`appName` | The name of your application.

##### 6.3.1.1.1 Specifying the opmn Request Port in Oracle Application Server 10g Release 3 (10.1.3)

In Oracle Application Server 10g Release 3 (10.1.3), you can specify the port defined for the `request` attribute of the `notification-server` element's `port` element configured in the `opmn.xml` file (default: `6003`). When `opmn` receives an RMI request on its `request` port, it forwards the RMI request to the RMI port that it selected for the appropriate OC4J instance.

For example, consider the following `opmn.xml` file excerpt:

    <notification-server>
        <port local="6100" remote="6200" request="6004"/>
        <log-file path="$OLE_HOME/opmn/logs/ons.log" level="4"         rotation-size="1500000"/>
        <ssl enabled="true" wallet-file="$OLE_HOME/opmn/conf/ssl.wlt/default"/>
    </notification-server>

In this example, the port defined for the `request` attribute of the `notification-server` element's `port` element is `6004`, so you would use `6004` as the port in your JNDI naming provider URL.

For an example of how this URL is used, see "OC4J in Oracle Application Server 10g Release 3 (10.1.3)".

##### 6.3.1.1.2 Specifying the RMI Port in Oracle Application Server 10g Release 2 (10.1.2) And Earlier

In releases prior to Oracle Application Server 10g Release 3 (10.1.3), you must specify the RMI port assigned by `opmn` for each OC4J instance. To get the assigned RMI port, use the following `opmnctl` command on the OC4J host:

    opmnctl status -l

This outputs a table of data with one row per OC4J instance.

For example (some columns are omitted for clarity):

    Processes in Instance: server817.company.us.com
    -------------------+--------------------+-------+ ... +------
    ias-component      | process-type       |   pid | ... | ports
    -------------------+--------------------+-------+ ... +------
    OC4J               | home               |  2012 | ... | iiop:12701,jms:12601,rmi:12401
    HTTP_Server        | HTTP_Server        | 28818 | ... | http2:7200,http1:7778,http:7200

In this example, `opmn` has selected port `12401` for RMI on the OC4J instance. Use this value as the port in your JNDI naming provider URL for this OC4J instance.

#### 6.3.1.2 Specifying the Context Factory

The initial context factory creates the initial context class for the client.

Set the`java.naming.factory.initial` property to one of the following:

- `oracle.j2ee.naming.ApplicationClientInitialContextFactory`

- `com.evermind.server.ApplicationInitialContextFactory`

- `oracle.j2ee.rmi.RMIInitialContextFactory`

Note: The following initial context factories are deprecated: `com.evermind.server.ApplicationClientInitialContextFactory` `com.evermind.server.RMIInitialContextFactory`

The `ApplicationClientInitialContextFactory` is used when looking up remote objects from standalone application clients. It uses the `refs` and `ref-mappings` found in `application-client.xml` and `orion-application-client.xml`. It is the default initial context factory when the initial context is instantiated in a Java application.

The `RMIInitialContextFactory` is used when looking up remote objects between different OC4J server instances using the ORMI protocol.

The type of initial context factory that you use depends on what the client is:

- If the client is a pure Java client outside the OC4J container, then use the `ApplicationClientInitialContextFactory` class.

- If the client is an EJB or servlet client within the OC4J container, then use the `ApplicationInitialContextFactory` class. This is the default class; thus, each time you create a new `InitialContext` without specifying an initial context factory class, your client uses the `ApplicationInitialContextFactory` class.

- If the client is an administrative class that is going to manipulate or traverse the JNDI tree, then use the `RMIInitialContextFactory` class.

- If the client is going to use DNS load balancing, then use the `RMIInitialContextFactory` class.

### 6.3.2 Configuring ORMI Request Load Balancing

Load balancing of client ORMI requests made to EJBs deployed into multiple clustered OC4J instances is supported in OC4J.

The default behavior is for the client to connect to the same OC4J instance with each call. Specifically, each time the client calls `InitialContext()` using the same `user/password/provider` URL combination, the cached `Context` object created the first time the client was invoked will be returned. Thus, the client will send requests to the same OC4J instance defined by this `Context` object.

In situations where the number of client calls is fairly low, connecting in this manner is efficient and results in the best performance.

However, in situations where heavy request volume is expected, load balancing of requests across OC4J instances may be desired. Load balancing is configurable using the `oracle.j2ee.rmi.loadBalance` property, which can be set in the client's `jndi.properties` file or in a Hashtable in the client code. The values for this property are outlined in the following table.

Table 6-6 oracle.j2ee.rmi.loadBalance Property Values

Value | Description
--- | ---
`client` | If specified, the client interacts with the OC4J process that was initially chosen at the first lookup for the entire conversation.
`context` | Used for a Web client (servlet or JSP) that will access EJBs in a clustered OC4J environment. If specified, a new `Context` object for a randomly-selected OC4J instance will be returned each time `InitialContext()` is invoked.
`lookup` | Used for a standalone client that will access EJBs in a clustered OC4J environment. If specified, a new `Context` object for a randomly-selected OC4J instance will be created each time the client calls `Context.lookup()`.

The following example illustrates how this property can be set to `lookup` in a `Hashtable`:

    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY,"com.evermind.server.rmi.RMIInitialContextFactory");
    env.put(Context.SECURITY_PRINCIPAL, "jazn.com/admin");
    env.put(Context.SECURITY_CREDENTIALS, "password");
    env.put(Context.PROVIDER_URL,"opmn:ormi://<hostname>:oc4j_inst1/ejbsamples");
    env.put("oracle.j2ee.rmi.loadBalance","lookup");

### 6.3.3 Example Lookups Using ORMI

This section provides examples of how to look up an EJB using ORMI in:

- Standalone OC4J 10g Release 3 (10.1.3)

- OC4J in Oracle Application Server 10g Release 3 (10.1.3)

- OC4J in Oracle Application Server Releases Before 10g Release 3 (10.1.3)

#### 6.3.3.1 Standalone OC4J 10g Release 3 (10.1.3)

The following example shows how to look up an EJB called `MyCart` in the J2EE application `ejbsamples` deployed in a standalone OC4J instance. The application is located on a node configured to listen on RMI port 23792:

    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY,"oracle.j2ee.rmi.RMIInitialContextFactory");
    env.put(Context.SECURITY_PRINCIPAL, "admin");
    env.put(Context.SECURITY_CREDENTIALS, "password");
    env.put(Context.PROVIDER_URL, "ormi://<hostname>:23792/ejbsamples");

    Context context = new InitialContext(env);
    Object homeObject = context.lookup("MyCart");
    CartHome home = (CartHome)PortableRemoteObject.narrow(homeObject,CartHome.class);

#### 6.3.3.2 OC4J in Oracle Application Server 10g Release 3 (10.1.3)

In Oracle Application Server 10g Release 3 (10.1.3), you can use the following type of lookup in the URL to look up an EJB in an Oracle Application Server environment.

The following example shows how to look up the EJB named `MyCart` in the J2EE application `ejbsamples` in an Oracle Application Server 10g Release 3 (10.1.3) environment. The differences between this invocation and the standalone invocation are: the `opmn` prefix to `ormi`, the specification of the OC4J instance name `oc4j_inst1` to which the EJB application is deployed, and no requirement to specify the RMI port:

    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY,"oracle.j2ee.rmi.RMIInitialContextFactory");
    env.put(Context.SECURITY_PRINCIPAL, "jazn.com/admin");
    env.put(Context.SECURITY_CREDENTIALS, "password");
    env.put(Context.PROVIDER_URL,"opmn:ormi://<hostname>:oc4j_inst1/ejbsamples");

    Context context = new InitialContext(env);
    Object homeObject = context.lookup("MyCart");
    CartHome home = (CartHome)PortableRemoteObject.narrow(homeObject,CartHome.class);

#### 6.3.3.3 OC4J in Oracle Application Server Releases Before 10g Release 3 (10.1.3)

In an OC4J instance in an Oracle Application Server environment, RMI ports are assigned dynamically, and `JAZNUserManager` is the default user manager.

In Oracle Application Server releases before 10g Release 3 (10.1.3), if you are accessing an EJB in Oracle Application Server, you have to know the RMI ports assigned by `opmn`. If you have only one JVM for your OC4J instance, then you have to limit the port ranges for RMIs to a specific number, for example: 3101-3101.

The following example shows how to look up an EJB called `MyCart` in the J2EE application `ejbsamples` in an Oracle Application Server environment in releases before 10g Release 3 (10.1.3). The application is located on a node configured to listen on RMI port 12401:

    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY,"com.evermind.server.rmi.RMIInitialContextFactory");
    env.put(Context.SECURITY_PRINCIPAL, "jazn.com/admin");
    env.put(Context.SECURITY_CREDENTIALS, "welcome");
    env.put(Context.PROVIDER_URL, "ormi://<hostname>:12401/ejbsamples");

    Context context = new InitialContext(env);
    Object homeObject = context.lookup("MyCart");
    CartHome home = (CartHome)PortableRemoteObject.narrow(homeObject,CartHome.class);

## 6.4 Configuring ORMI Tunneling through HTTP

To enable EJB communication through firewalls, ORMI utilizes HTTP tunneling to wrap RMI calls within an HTTP POST request. The request is then forwarded to the `default` Web application within the target OC4J instance. Note that tunneling is supported only with RMI/ORMI; you cannot perform HTTP tunneling using RMI/IIOP.

The HTTP tunneling URL set as the value of `java.naming.provider.url` has the following syntax. See "Setting JNDI Properties for RMI" for details on this URL.

    ormi:http://<hostname:[http_port]>/<context_uri>/<appName>

Table 6-7 HTTP tunneling URL syntax

Parameter | Description
--- | ---
`OHS_hostname` | The name of the Oracle HTTP Server host that will receive the request.
`http_port` | The Oracle HTTP Server port. This value is optional; if omitted, it defaults to `80`.
`context_uri` | The value of the root attribute in the `<default-web-app>` element in `ORACLE_HOME/j2ee/<instanceName>/default-web-site.xml`. The value for the OC4J `home` instance is `/j2ee`.
`appName` | The name of the target application.

You can target an application deployed to a specific OC4J instance - for example, `home` or `home2` - by specifying the URI context for the `default` Web application instance within the OC4J instance hosting the target application. This context URI is defined in `default-web-site.xml` as the value of the `root` attribute of the `<default-web-app>` element.

The following entry in `ORACLE_HOME/j2ee/home/default-web-site.xml` defines the context URI as `/j2ee` for `default` Web application in the `home` instance:

    <default-web-app application="default" name="defaultWebApp" root="/j2ee" />

To target a request to the `acme` application deployed to the `home` instance, you would specify this context URI in the ORMI tunneling URL (assuming Oracle HTTP Server is configured to listen on port 7777):

    ormi:http://OHShost:7777/j2ee/acme

If your HTTP traffic goes through a proxy Web server, specify the `proxyHost` and (optionally) `proxyPort` in the command line that starts the EJB client:

    -Dhttp.proxyHost=<proxy_host> -Dhttp.proxyPort=<proxy_port>

If omitted, `proxy_port` defaults to `80`.

## 6.5 Using ORMI/SSL (ORMIS) in OC4J

ORMI over SSL (ORMIS) is a new feature in Oracle Application Server 10g Release 3 (10.1.3). With this feature, OC4J now supports Secure Socket Layer (SSL) RMI communication between objects across OC4J server instances.

ORMIS is disabled by default in OC4J, client and server keystores must be created before this feature can be used.

See the Oracle Containers for J2EE Security Guide for information on the following topics:

- Creating keystores and wallets

- Enabling ORMI/SSL (ORMIS) in OC4J

- Configuring OC4J to Use ORMIS

- Configuring Clients to Use ORMIS

- EJB Server Security Properties (internal-settings.xml)

- CSIv2 Security Properties

- CSIv2 Security Properties (internal-settings.xml)

- CSIv2 Security Properties (ejb_sec.properties)

- CSIv2 Security Properties (orion-ejb-jar.xml)

- EJB Client Security Properties (ejb_sec.properties)

## 6.6 Using J2EE Interoperability (RMI/IIOP)

This section describes OC4J support for EJBs and other objects to invoke one another across different J2EE containers—for example, between OC4J and BEA WebLogic servers—using the standard Remote Method Invocation (RMI)/Internet Inter-Orb Protocol (IIOP).

This section covers the following topics:

- Introduction to RMI/IIOP

- Switching from ORMI to IIOP Transport

- Configuring OC4J for Interoperability

### 6.6.1 Introduction to RMI/IIOP

Java Remote Method Invocation (RMI) enables you to create distributed Java-based to Java-based applications, in which the methods of remote Java objects can be invoked from other Java virtual machines (JVMs), possibly on different hosts.

Version 2.0 of the EJB specification introduced features that make it easy for EJB-based applications to invoke one another across different containers. You can make your existing EJB interoperable without changing a line of code: simply edit the bean's properties and redeploy. "Switching from ORMI to IIOP Transport" discusses redeployment details.

EJB interoperability consists of the following:

- Transport interoperability, through CORBA IIOP Internet Inter-ORB Protocol, where ORB is Object Request Broker)

- Naming interoperability, through the CORBA CosNaming Service (CORBA Object Service Naming, part of the OMG CORBA Object Service specification)

- Security interoperability, through Common Secure Interoperability Version 2 (CSIv2)

- Transaction interoperability, through the CORBA Transaction Service (OTS)

OC4J furnishes transport, naming, and security interoperability.

#### 6.6.1.1 Transport

By default, OC4J EJBs use RMI/Oracle Remote Method Invocation (ORMI), a proprietary protocol, to communicate as described in "Using Oracle Remote Method Invocation (RMI/ORMI)".

However, you can easily convert an EJB to use RMI/IIOP, making it possible for EJBs to invoke one another across different EJB containers. This section describes configuring and using RMI/IIOP.

Note: For the OC4J 10g Release 3 (10.1.3) implementation, load balancing and failover are supported only for ORMI, not for IIOP.

#### 6.6.1.2 Naming

OC4J supports the CORBA CosNaming service. OC4J can publish `EJBHome` object references in a CosNaming service and provides a JNDI CosNaming implementation that allows applications to look up JNDI names using CORBA. You can write your applications using either the JNDI or CosNaming APIs.

#### 6.6.1.3 Security

OC4J supports Common Secure Interoperability Version 2 (CSIv2), which specifies different conformance levels; OC4J complies with the EJB specification, which requires conformance level 0.

For information about security topics, see the CSIv2 chapter in the Oracle Containers for J2EE Security Guide.

#### 6.6.1.4 Transactions

The EJB2.0 specification stipulates an optional transactional interoperability feature. Conforming implementations must choose one of the following:

- Transactionally interoperable: transactions are supported between beans that are hosted in different J2EE containers.

- Transactionally noninteroperable: transactions are supported only among beans in the same container.

The current release of OC4J is transactionally noninteroperable, so when a transaction spans EJB containers, OC4J raises a specified exception.

#### 6.6.1.5 The rmic.jar Compiler

To invoke or be invoked by CORBA objects, RMI objects must have corresponding stubs, skeletons, and Internet Description Language (IDL). Use the `rmic.jar` compiler to generate stubs and skeletons from Java classes or to generate IDL.

For use with RMI/IIOP, be sure to compile using the `-iiop` option.

### 6.6.2 Configuring OC4J for Interoperability

To add interoperability support to your EJB, you must specify interoperability properties. Some of these properties are specified when starting OC4J and others in bean properties that are specified in deployment files.

#### 6.6.2.1 Interoperability OC4J Flags

The following OC4J startup flags support RMI interoperability:

- `-DGenerateIIOP=true` generates new stubs and skeletons whenever you redeploy an application.

- `-Diiop.debug=true` generates deployment-time debugging messages, most of which have to do with code generation.

- `-Diiop.runtime.debug=true` generates runtime debugging messages.

#### 6.6.2.2 Interoperability Configuration Files

Before EJBs can communicate, you must configure the parameters in the configuration files listed in Table 6-8.

Table 6-8 Interoperability Configuration Files

Context | File | Description
--- | --- | ---
Server | `server.xml` | The `<sep-config>` element in this file specifies the path name, normally `internal-settings.xml`, for the server extension provider properties. For example: `<sep-config path="./internal-settings.xml">`
| `internal-settings.xml` | This file specifies server extension provider properties that are specific to RMI/IIOP.
Application | `orion-ejb-jar.xml` | The `<ior-security-config>` subentity of the `<session-deployment>` and `<entity-deployment>` entities specifies Common Secure Interoperability Version 2 (CSIv2) security properties for the server.
| `ejb_sec.properties` | This file specifies client-side security properties for an EJB.
| `jndi.properties` | This file specifies the URL of the initial naming context used by the client. See "JNDI Properties for Interoperability (jndi.properties)" for details.

For information about security topics, see the CSIv2 chapter in the Oracle Containers for J2EE Security Guide.

#### 6.6.2.3 JNDI Properties for Interoperability (jndi.properties)

The following RMI/IIOP properties are controlled by the client's `jndi.properties` file:

- `java.naming.provider.url` may be an OPMN or a corbaname URL for the bean to be interoperable.

  If you configure your client's JNDI property `java.naming.provider.url` to use an OPMN URL, then your client cannot connect to `ssl-port` and `ssl-client-server-auth-port` ports because OPMN-allocated ports are not reported to OC4J.

  For details on corbaname URLs, see "Specifying the corbaname URL". For details on the OPMN URL, see "Specifying the OPMN URL".

- `contextFactory` can be either `ApplicationClientInitialContextFactory` or the class `IIOPInitialContextFactory`.

  If your application has an `application-client.xml` file, then leave `contextFactory` set to `ApplicationClientInitialContextFactory`. If your application does not have an `application-client.xml` file, then change `contextFactory` to `IIOPInitialContextFactory`.

##### 6.6.2.3.1 Context Factory Usage

- `oracle.j2ee.naming.ApplicationClientInitialContextFactory` is used when looking up remote objects from standalone application clients. It uses the `refs` and `ref-mappings` found in `application-client.xml` and `orion-application-client.xml`. It is the default initial context factory when the initial context is instantiated in a Java application.

- `oracle.j2ee.iiop.IIOPInitialContextFactory` is used when looking up remote objects between different containers using the IIOP protocol.

### 6.6.3 Client-Side Requirements to Use IIOP

This section lists the ZIP files that you use to install the Oracle and J2EE standard JAR files that enable EJB and JMS lookup using RMI/IIOP.

The following ZIP files are available from `http://www.oracle.com/technology/software/products/ias/index.html`:

- To enable EJB lookup using IIOP, download and expand `oc4j_iiop_client.zip`.

- To enable other lookups, such as JMS, you must also download and expand `oc4j_extended.zip`.

Once these ZIP files are expanded, make sure that `oc4jclient.jar` is included in the CLASSPATH.

The ZIP files contain all the JAR files required by the client. The JAR files contain the classes necessary for client interaction. You must only add `oc4jclient.jar` to your `CLASSPATH`, because all other JAR files required by the client are referenced in the `oc4jclient.jar` manifest classpath.

While running the IIOP Client, the following properties must be set for IIOP clients:

- `-Dorg.omg.CORBA.ORBInitialHost=${orb.host}`

- `-Dorg.omg.CORBA.ORBInitialPort=${orb.port`}

- `-Djavax.rmi.CORBA.PortableRemoteObjectClass=com.sun.corba.ee.impl.javax.rmi.PortableRemoteObject`

- `-Dcom.oracle.CORBA.OrbManager=com.oracle.corba.ee.impl.orb.ORBManagerImpl`

## 6.7 Switching from ORMI to IIOP Transport

In OC4J, EJBs use RMI/ORMI, a proprietary protocol, to communicate (as described in "Using Oracle Remote Method Invocation (RMI/ORMI)"). You can convert an EJB to use RMI/IIOP, making it possible for EJBs to invoke one another across different EJB containers from different vendors, such as OC4J and BEA WebLogic.

Note: RMI/IIOP support is based on the CORBA 2.3.1 specification. Applications that were compiled using earlier releases of CORBA may not work correctly.

The following sections provide details on making the conversions:

- Configuring an EJB for Interoperability in a Standalone OC4J Environment

- Configuring an EJB for Interoperability in an Oracle Application Server Environment

- Specifying the corbaname URL

- Specifying the OPMN URL

- Exception Mapping

- Invoking OC4J-Hosted Beans from a Non-OC4J Container

### 6.7.1 Configuring an EJB for Interoperability in a Standalone OC4J Environment

Follow these steps to convert an EJB to use RMI/IIOP in a standalone OC4J environment:

1. Specify CSIv2 security policies for the bean in `orion-ejb-jar.xml` and in `internal-settings.xml`.

   For information about security topics, see the CSIv2 chapter in the Oracle Containers for J2EE Security Guide.

2. Restart OC4J with the `-DGenerateIIOP=true` flag.

3. Deploy your application using `admin.jar`. You must obtain the client's stub JAR file, using the `-iiopClientJar` switch. Here is an example:

       java -jar $J2EE_HOME/admin.jar ormi://localhost admin welcome -deploy -file filename -deployment_name application_name -iiopClientJar stub_jar_filename

   Note: You must use the `-iiopClientJar` switch to enable interoperability (IIOP) for the application you are deploying. In OC4J, interoperability is enabled on a per-application basis.

4. Change the client's `classpath` to include the stub JAR file that was obtained during deployment, by running `admin.jar` with the `-iiopClientJar` switch.

   A copy of the stub JAR file that was generated by OC4J can also be found in the server's deployment directory at:

       application_deployment_directory/appname/ejb_module/_iiopClient.jar

5. Edit the client's JNDI property `java.naming.provider.url` to use a `corbaname` URL instead of an `ormi` URL. For details on the `corbaname` URL, see "Specifying the corbaname URL".

   Note: IIOP stub and tie class code generation occurs at deployment time, unlike ORMI stub generation, which occurs at runtime. This is why you must add the JAR file to the `classpath` yourself. If you run in the server, a list of generated classes required by the server and IIOP stubs is made available automatically.

6. (Optional) To make the bean accessible to CORBA applications, run `rmic.jar` to generate IDL describing its interfaces.

### 6.7.2 Configuring an EJB for Interoperability in an Oracle Application Server Environment

This section describes how to convert an EJB to use RMI/IIOP in an Oracle Application Server environment.

1. Specify CSIv2 security policies for the bean in `orion-ejb-jar.xml` and in `internal-settings.xml`.

   For information about security topics, see the CSIv2 chapter in the Oracle Containers for J2EE Security Guide.

2. By default, RMI/IIOP is disabled in an Oracle Application Server environment. To enable RMI/IIOP, confirm in the OPMN configuration file `J2EE_HOME``/opmn/conf/opmn.xml` that a unique `iiop`, `iiops1`, and `iiops2` port (or port range) exists for each OC4J instance to be managed by OPMN. These are the port meanings:

   `iiop`—standard IIOP port

   `iiops1`—IIOP/SSL port used for server-side authentication only

   `iiops2`—IIOP/SSL port used for both client and server authentication

   Note: You must specify an `iiop`, `iiops1`, and `iiops2` port (or port range) for each OC4J instance in which interoperability with CSIv2 is to be enabled. Failure to do so causes OC4J to not configure an IIOP listener, thus automatically disabling interoperability, regardless of the configuration in the `internal-settings.xml` file of OC4J.

   Here is an example:

       <ias-component id="OC4J">
           <process-type id="home" module-id="OC4J">
               <port id="ajp" range="3000-3100"/>
               <port id="rmi" range="23791-23799"/>
               <port id="jms" range="3201-3300"/>
               <port id="iiop" range="3401-3500"/>
               <port id="iiops1" range="3501-3600"/>
               <port id="iiops2" range="3601-3700"/>
               <process-set id="default_group" numprocs="1"/>
           </process-type>
       </ias-component>

   Note: If you choose to configure your client's JNDI property `java.naming.provider.url` to use an `OPMN` URL, then your client cannot connect to `iiops1` or `iiops2` ports because OPMN-allocated ports are not reported to OC4J.

3. Use `opmnctl` to restart all OC4J instances that are managed by OPMN. Use the `-DGenerateIIOP=true` flag.

       opmnctl -DGenerateIIOP=true startall

4. Deploy your application specifying the `-enableIIOP` option. For information about deployment, see the Oracle Containers for J2EE Deployment Guide.

5. Change the client's `classpath` to include the stub JAR file that was generated by OC4J. This is normally found in the server's deployment directory:

       application_deployment_directory/appname/ejb_module/_iiopClient.jar

6. Edit the client's JNDI property `java.naming.provider.url` to use an `OPMN` or `corbaname` URL instead of an `ormi` URL. For details on the `corbaname` URL, see "Specifying the corbaname URL". For details on the OPMN URL, see "Specifying the OPMN URL".

   Note: IIOP stub and tie class code generation occurs at deployment time, unlike ORMI stub generation, which occurs at runtime. This is why you must add the JAR file to the `classpath` yourself. If you run in the server, a list of generated classes required by the server and IIOP stubs is made available automatically.

7. (Optional) To make the bean accessible to CORBA applications, run `rmic.jar` to generate IDL describing its interfaces.

### 6.7.3 Specifying the corbaname URL

To interoperate, an EJB must look up other beans using `CosNaming`. This means that the URL for looking up the root `NamingContext` must use the `corbaname` URL scheme instead of the `ormi` URL scheme. This section discusses the `corbaname` subset that EJB developers use most often. For a full discussion of the `corbaname` scheme, see section 2.5.3 of the CORBA Naming Service specification. The `corbaname` scheme is based on the `corbaloc` scheme, which section 13.6.10.1 of the CORBA specification discusses.

The most common form of the `corbaname` URL scheme is:

    corbaname::host[:port]

This `corbaname` URL specifies a conventional DNS host name or IP address, and a port number. For example,

    corbaname::example.com:8000

A `corbaname` URL can also specify a naming context by following the host and port by `#` and `NamingContext` in string representation. The `CosNaming` service on the specified host is responsible for interpreting the naming context.

    corbaname::host[:port]#namingcontext

For example:

    corbaname::example.com:8000#Myapp

### 6.7.4 Specifying the OPMN URL

This section describes OPMN URL details that are specific to RMI/IIOP. For general information about the OPMN URL, see "Setting JNDI Properties for RMI".

In an Oracle Application Server environment, IIOP ports for all OC4J processes within each Oracle Application Server instance are dynamically managed by OPMN. Because of this, it may not be possible for clients to know the ports on which OC4J processes are actively listening for IIOP requests. To enable clients to successfully make RMI/IIOP requests in an Oracle Application Server environment without having to know the IIOP ports for all active OC4J processes, modify the `jndi.naming.provider.url` property (in the client's `jndi.properties` file) with a URL of the following format:

opmn:corbaname::host[:port][#instance-name]#appname

For example:

    opmn:corbaname::dlsun74:6003#oc4j_inst1#ejbsamples

Notes: For the OC4J 10g Release 3 (10.1.3) implementation, load balancing and failover are supported only for ORMI, not for IIOP. If you use an OPMN URL, your client cannot connect to `iiops1` or `iiops2` (`ssl-port` or `ssl-client-server-auth-port`) ports.

### 6.7.5 Exception Mapping

When EJBs are invoked over IIOP, OC4J must map system exceptions to CORBA exceptions. Table 6-9 lists the exception mappings.

Table 6-9 Java-CORBA Exception Mappings

OC4J System Exception | CORBA System Exception
--- | ---
`javax.transaction.` `TransactionRolledbackException` | `TRANSACTION_ROLLEDBACK`
`javax.transaction.` `TransactionRequiredException` | `TRANSACTION_REQUIRED`
`javax.transaction.` `InvalidTransactionException` | `INVALID_TRANSACTION`
`java.rmi.NoSuchObjectException` | `OBJECT_NOT_EXIST`
`java.rmi.AccessException` | `NO_PERMISSION`
`java.rmi.MarshalException` | `MARSHAL`
`java.rmi.RemoteException` | `UNKNOWN`

### 6.7.6 Invoking OC4J-Hosted Beans from a Non-OC4J Container

EJBs that are not hosted in OC4J must add the file `oc4j_interop.jar` to the `classpath` to invoke OC4J-hosted EJBs. OC4J expects the other container to make the `HandleDelegate` object available in the JNDI name space at `java:comp/HandleDelegate`. The `oc4j_interop.jar` file contains the standard portable implementations of home and remote handles, and metadata objects.