Skip Headers

Oracle Application Server Containers for J2EE Services Guide 10g (9.0.4) Part Number B10326-01 |
| Home | Contents | Index

# 5
Oracle Remote Method Invocation

This chapter describes Oracle Application Server Containers for J2EE (OC4J) support for allowing EJBs to invoke one another across OC4J containers using the proprietary Remote Method Invocation (RMI)/Oracle RMI (ORMI) protocol.

This chapter covers the following topics:

- Introduction to RMI/ORMI

- Configuring OC4J for RMI

- Configuring ORMI Tunneling through HTTP

## Introduction to RMI/ORMI

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.

By default, OC4J EJBs exchange RMI calls over the Oracle Remote Method Invocation (ORMI) protocol, an Oracle proprietary protocol optimized for use with OC4J.

Alternatively, you can convert an EJB to use RMI/IIOP, making it possible for EJBs to invoke one another across different EJB containers as described in Chapter 6, "J2EE Interoperability".

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

### ORMI Enhancements

ORMI is enhanced for OC4J and provides the following features:

- Increased RMI Message Throughput

- Enhanced Threading Support

- Co-located Object Support

#### 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 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 will resend all the state information required by the new server.

#### 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 ensures that each client (single- or multi-threaded) will have one connection to the remote server.

#### Co-located Object Support

For co-located objects, RMI/ORMI will detect the co-located scenario and avoid the extra, unnecessary socket call.

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

### Client-Side Requirements

In order to access EJBs, you must do the following on the client-side:

1. Download the `oc4j_client.zip` file from `http://otn.oracle.com/software/products/ias/devuse.html`

2. Unzip it into a client-side directory (for example, `d:\oc4jclient`)

3. Add `d:\oc4jclient\oc4jclient.jar` to your CLASSPATH

The oc4j_client.zip file contains all the JAR files required by the client (including `oc4jclient.jar` and `optic.jar`). These JARs contain the classes necessary for client interaction. You only need to add `oc4jclient.jar` to your CLASSPATH because all other JAR files required by the client are referenced in the `oc4jclient.jar` manifest classpath.

If you download this file into a browser, you must grant certain permissions as described in the "Granting Permissions" section of the Security chapter in the Oracle Application Server Containers for J2EE Enterprise JavaBeans Developer's Guide.

## Configuring OC4J for RMI

You can configure OC4J for RMI in one of two ways:

- Configuring RMI Using Oracle Enterprise Manager

- Configuring RMI Manually

Oracle recommends that you configure OC4J using the Oracle Enterprise Manager.

Once OC4J is configured for RMI, you must specify RMI properties as described in "RMI Configuration Files".

### Configuring RMI Using Oracle Enterprise Manager

Oracle recommends that you configure OC4J to use RMI by using Oracle Enterprise Manager as follows:

1. Navigate to an OC4J instance in which you want to allow access to applications through RMI.

   Figure 5-1 shows an OC4J instance called `home`.

   #### Figure 5-1 Oracle Enterprise Manager System Components

   Text description of the illustration emsyscp4.gif

2. Click the OC4J instance name.

3. Click the Administration tab.

4. Click Server Properties.

5. By default, RMI is disabled in an Oracle Application Server environment. To enable RMI, set a unique RMI port (or port range) for each OC4J instance by entering the value in the RMI Ports field, as shown in Figure 5-2.

   #### Figure 5-2 Oracle Enterprise Manager Server Properties Port Configuration

   Text description of the illustration emports.gif

6. Click Apply.

7. Click the Back button on your browser.

8. Click Replication Properties.

9. Check the Replicate State field as shown in Figure 5-3.

   The remaining attributes on the EJB Applications screen are ignored if Replicate State is not checked.

   #### Figure 5-3 Oracle Enterprise Manager Replication Properties

   Text description of the illustration emrmi.gif

10. Configure the RMI Server Host field as shown in Figure 5-3.

    Enter a particular host name or IP address from which your server will accept RMI requests. The OC4J server accepts only RMI requests from this particular host.

    Note: The other attributes on the Replication Properties window apply only to EJB clustering. For details, see the Oracle Application Server Containers for J2EE Enterprise JavaBeans Developer's Guide section "Configure the Multicast Address for EJB Clustering".

11. Click Apply.

### Configuring RMI Manually

Oracle recommends that you configure OC4J using the Oracle Enterprise Manager as described in "Configuring RMI Using Oracle Enterprise Manager". If you choose to manually configure RMI, you must:

1. Edit property file `server.xml` (see "Editing server.xml").

2. Choose the configuration files appropriate for your environment:

   - In an OC4J standalone environment, edit the `rmi.xml` file (see "Editing rmi.xml") only.

   - In an Oracle Application Server environment, edit both the `rmi.xml` file (see "Editing rmi.xml") and the `opmn.xml` file (see "Editing opmn.xml").

     Note: In an Oracle Application Server environment, `opmn` selects an RMI port for each OC4J instance from the range of RMI ports defined in the `opmn.xml` file (see "Editing opmn.xml"); the `rmi.xml` file `rmi-server` element `port` attribute is ignored. Manual changes to configuration files in an Oracle Application Server environment are not applied until you synchronize the configuration repository by running the following on the Oracle Application Server command line: `dcmctl updateConfig`

#### Editing server.xml

Your `server.xml` file must specify the path name of the RMI configuration file in the`<rmi-config>` element. Here is the syntax:

    <rmi-config path="RMI_PATH" />

The usual `RMI_PATH` is `./rmi.xml`; you can name the file whatever you like.

In an Oracle Application Server environment only, apply changes by running the following on the Oracle Application Server command line:

    dcmctl updateConfig

#### Editing rmi.xml

Edit the `rmi.xml` file to specify which host, port, and user name and password to use to connect to (and accept connections from) remote RMI servers by configuring an `rmi-server` element.

To configure the `rmi.xml` file:

1. Add an `rmi-server` element for this local RMI server.

   For example:

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

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

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

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

     Note: In an OC4J standalone environment, if you omit this attribute, it defaults to 23791. In an Oracle Application Server environment, `opmn` selects an RMI port for each OC4J instance from the range of RMI ports defined in the `opmn.xml` file (see "Editing opmn.xml"); the `rmi-server` element `port` attribute is ignored.

2. Configure the `rmi-server` element with zero 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. The user-replaceable attributes of the `server` element are:

   - `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`

3. Configure the `rmi-server` element with zero or more `log` elements that each specify a file to which RMI-specific notifications are written.

   For example, using the `file` element:

       <rmi-server host="hostname" port="port">
           <log>
               <file path="logfilepathname" />
           </log>
       </rmi-server>

   Or using the `odl` element:

       <rmi-server host="hostname" port="port">
           <log>
               <odl path="odlpathname" max-file-size="size" max-num-files="num"/>
           </log>
       </rmi-server>

   You can use either the `file` element or the `odl` element (but not both).

   The user-replaceable attributes of the `log` element are:

   - `odlpathname`--is the path and folder name of the log folder for this area. You can use an absolute path or a path relative to the `J2EE_HOME``/config` directory. This denotes where the RMI log files will reside.

   - `size`--is the maximum size in bytes of each individual log file.

   - `num`--is the maximum number of log files.

   - `logfilepathname`--is the path name of a log file (`logfilepathname`) to which the server writes all RMI requests.

   The `<odl>` element is new in the OC4J 10g (9.0.4) implementation. The ODL log entries are each written out in XML format in its respective log file. The log files have a maximum limit. When the limit is reached, the log files are overwritten.

   When you enable ODL logging, each message goes into its respective log file, named `log` `N``.xml`, where `N` is a number starting at 1. The first log message starts the log file `log1.xml`. When the log file size maximum is reached, the second log file is opened to continue the logging, `log2.xml`. When the last log file is full, the first log file, `log1.xml`, is erased and a new one is opened for the new messages. Thus, your log files are constantly rolling over and do not encroach on your disk space.

   For more information about ODL logging, see the Oracle Application Server Containers for J2EE User's Guide.

4. In an Oracle Application Server environment only, apply changes by running the following on the Oracle Application Server command line:

       dcmctl updateConfig

#### Editing opmn.xml

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

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="ajp" range="3301-3400" />
               <port id="rmi" range="3101-3200" />
               <port id="jms" range="3201-3300" />
               <process-set id="default-island" numprocs="1"/>
           </process-type>
       </ias-component>

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

2. Apply changes by running the following on the Oracle Application Server command line:

       dcmctl updateConfig

### RMI Configuration Files

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

##### Table 5-1 RMI 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. Example: `<sep-config path="./internal-settings.xml">`
Application | `jndi.properties` | This file specifies the URL of the initial naming context used by the client. See "JNDI Properties for RMI"

### JNDI Properties for RMI

This section summarizes JNDI properties specific to RMI/ORMI. For details, see "Accessing the EJB" in the EJB Primer chapter in Oracle Application Server Containers for J2EE Enterprise JavaBeans Developer's Guide.

The following RMI/ORMI properties are controlled by the `jndi.properties` file:

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

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

#### Naming Provider URL

Set the`java.naming.provider.url` using the following syntax:

    <prefix>://<host>:<port>:<oc4j_instance>/<application-name>

Table 5-2 describes arguments used in this syntax.

##### Table 5-2 Naming Provider URL

Variable | Description
--- | ---
`prefix` | Use `opmn:ormi` for Oracle Application Server applications. Use `ormi` for standalone OC4J applications. Use `http:ormi` for applications that use HTTP tunneling (see "Configuring ORMI Tunneling through HTTP"). Use `corbaname` for applications that must interoperate with non-OC4J containers (see "The corbaname URL").
`host` | For Oracle Application Server applications, the name of the OPMN host as defined in the `opmn.xml` file. Although OPMN is often located on the same machine as the OC4J instance. Specify the host name in case it is located on another machine. For standalone OC4J applications, the port number defined by the `rmi.xml` file `rmi-server` element `host` attribute.
`port` | In Oracle Application Server release 10g (9.0.4) when the `opmn:ormi` prefix is used, specify the `request` port on which the `opmn` process is listening and the `opmn` process will forward RMI requests to the RMI port that it selected for the appropriate OC4J instance (see "Using the opmn Request Port"). If omitted, the default `request` port value 6003 is used. In Oracle Application Server releases before 10g (9.0.4) when the ormi prefix is used, you must specify the RMI port that `opmn` selected for your OC4J instance (see "Using opmnctl to Show the Selected RMI Port"). For standalone OC4J applications when the `ormi` prefix is used, you must specify the port number defined by the `rmi.xml` file `rmi-server` element `port` attribute. For applications that use HTTP tunneling and use the `http:ormi` prefix, see "Configuring ORMI Tunneling through HTTP" for information on what port to specify. For applications that must interoperate with non-OC4J containers and use the `corbaname` prefix, see "The corbaname URL" for information on what port to specify.
`oc4j_instance` | For Oracle Application Server applications, the name of the OC4J instance as defined in the Enterprise Manager. For standalone OC4J applications, this is not applicable.
`application-name` | The name of your application.

For example:

    java.naming.provider.url=opmn:ormi://localhost:oc4j_inst1/ejbsamples

##### Using the opmn Request Port

In Oracle Application Server release 10g (9.0.4), 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 will forward 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="$ORACLE_HOME/opmn/logs/ons.log" level="4"
            rotation-size="1500000"/>
        <ssl enabled="true" wallet-file="$ORACLE_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 and 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 (9.0.4) Release".

##### Using opmnctl to Show the Selected RMI Port

To determine what RMI port has been selected by `opmn` for each OC4J instance, use the following command on the host on which `opmn` is running:

    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: core817.dsunrdb22.us.oracle.com
    -------------------+--------------------+-------+ ... +------
    ias-component      | process-type       |   pid | ... | ports
    -------------------+--------------------+-------+ ... +------
    WebCache           | WebCacheAdmin      | 28821 | ... | administration:4000
    WebCache           | WebCache           | 28820 | ... | statistics:4002,invalidation:4001,http:7777
    OC4J               | home               |  2012 | ... | iiop:3401,jms:3701,rmi:3201,ajp:3000
    HTTP_Server        | HTTP_Server        | 28818 | ... | http2:7200,http1:7778,http:7200
    dcm-daemon         | dcm-daemon         | 28811 | ... | N/A
    LogLoader          | logloaderd         |   N/A | ... | N/A

The `ports` column of this table lists the ports selected by `opmn`. For example:

    iiop:3401,jms:3701,rmi:3201,ajp:3000

In this example, `opmn` has selected port 3201 for RMI on the OC4J instance with process id 2012 and so you would use 3201 as the port in your JNDI naming provider URL for this OC4J instance.

#### Context Factory Usage

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

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

- `com.evermind.server.ApplicationClientInitialContextFactory`

- `com.evermind.server.ApplicationInitialContextFactory`

- `com.evermind.server.RMIInitialContextFactory`.

The `ApplicationClientInitialContextFactory` is used when looking up remote objects from stand-alone 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 containers using the ORMI protocol.

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

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

- If the client is an EJB or servlet client within the OC4J container, 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, use the `RMIInitialContextFactory` class.

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

### Example Lookups

This section provides examples that show how to lookup an EJB in:

- OC4J Standalone

- OC4J in Oracle Application Server: Releases Before 10g (9.0.4)

- OC4J in Oracle Application Server: 10g (9.0.4) Release

#### OC4J Standalone

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

    Hashtable env = new Hashtable();
    env.put(Context.INITIAL_CONTEXT_FACTORY,"com.evermind.server.rmi.RMIInitialContextFactory");
    env.put(Context.SECURITY_PRINCIPAL, "admin");
    env.put(Context.SECURITY_CREDENTIALS, "welcome");
    env.put(Context.PROVIDER_URL, "ormi://localhost:23792/ejbsamples");

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

#### OC4J in Oracle Application Server: Releases Before 10g (9.0.4)

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 (9.0.4), 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, you have to limit the port ranges for RMIs to a specific number, for example: 3101-3101.

The following example shows how to lookup an EJB called `MyCart` in the J2EE application `ejbsamples` in an Oracle Application Server environment in releases before 10g (9.0.4). The application is located on a machine named `localhost` configured to listen on RMI port 3101:

    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://localhost:3101/ejbsamples");

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

#### OC4J in Oracle Application Server: 10g (9.0.4) Release

In Oracle Application Server release 10g (9.0.4), you can use the following type of lookup in the URL to lookup an EJB in an Oracle Application Server environment without needing to know the RMI port assigned to your OC4J instance.

The following example shows how to lookup EJB called `MyCart` in the J2EE application `ejbsamples` in an Oracle Application Server environment in release 10g (9.0.4). The EJB application is located on a machine named `localhost`. The differences between this invocation and the stand-alone 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,"com.evermind.server.rmi.RMIInitialContextFactory");
    env.put(Context.SECURITY_PRINCIPAL, "jazn.com/admin");
    env.put(Context.SECURITY_CREDENTIALS, "welcome");
    env.put(Context.PROVIDER_URL,"opmn:ormi://localhost:oc4j_inst1/ejbsamples");

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

## Configuring ORMI Tunneling through HTTP

When EJBs communicate across firewalls, they can use tunneling to transmit RMI across HTTP. This tunneling is supported only with RMI/ORMI; you cannot perform HTTP tunneling with RMI/IIOP.

To configure OC4J to support RMI tunneling, do the following:

1. Verify that the following entries are in `global-web-application.xml` (the default installation has these entries preconfigured):

       <servlet>
           <servlet-name>rmi</servlet-name>
           <servlet-class>com.evermind.server.rmi.RMIHttpTunnelServlet
           </servlet-class>
       </servlet>
       <servlet>
           <servlet-name>rmip</servlet-name>
           <servlet-class>com.evermind.server.rmi.RMIHttpTunnelProxyServlet
           </servlet-class>
       </servlet>

2. Modify the JNDI provider URL (see "JNDI Properties for RMI"). The JNDI provider URL for accessing the OC4J EJB server takes the form:

       ormi://hostname:ormi_port/appName

   - To direct tunneling requests to the home instance of OC4J in an Oracle Application Server or standalone environment, set the URL to:

         http:ormi://hostname:http_port/appName

   - To direct tunneling requests to an instance mapped in an OC4J mount point in an Oracle Application Server environment only, configure oc4j_mount (see "Configuring an OC4J Mount Point") and set the URL to:

         http:ormi://hostname:http_port/appName@oc4j_mount

     Note: http_port is the HTTP port, not the ORMI port (if omitted, it defaults to 80) and appName is the name of the application, not the application context defined in `web-site.xml`.

3. If your HTTP traffic goes through a proxy server, specify the `proxyHost` and (optionally) `proxyPort` in the command line used to start the EJB client:

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

   Note: If omitted, proxy_port defaults to 80.

### Configuring an OC4J Mount Point

An OC4J mount point maps an OC4J instance to URLs that start with a specified path name. This mapping is specified in the OC4J `mod-oc4j.conf` file by Oracle Enterprise Manager at deployment time. This is an example of such a mapping:

    Oc4jMount /xyz inst1
    Oc4jMount /xyz/* inst1

In this example, the OC4J instance `inst1` receives all requests with URLs that start with `/xyz`.

An OC4J mount point is used to direct tunneling requests to an OC4J instance other than the home instance of OC4J.

The first part of "Configuring ORMI Tunneling through HTTP" showed the following URL:

    http:ormi://hostname:http_port/appName@oc4j_mount

In this URL, appName is the name of the application (defined by `default-web-site.xml` attribute `name`), not the application context (defined by `default-web-site.xml` attribute `application`).

Make sure that the context root for appName in the `default-web-site.xml` file is the same as that in the `mod-oc4j.conf` file. In this example, the application name is `demoApp` and its context root is `/xyz`: the actual line in the `default-web-site.xml` file for this application would be:

    <default-web-app application="default" name="demoApp" root="/xyz" />

Therefor, in this example, to direct tunneling requests from `defaultWebApp` to OC4J instance `inst1`, the URL would be:

    http:ormi://hostname:http_port/defaultWebApp@xyz

The `mod-oc4j.conf` file is a component of the Oracle HTTP server. For more information, see the Oracle HTTP Server Administrator's Guide.

The `default-web-site.xml` file is an OC4J configuration file. For more information, see the Oracle Application Server Containers for J2EE Servlet Developer's Guide.

Warning.: Do not manually modify these configuration files. The Oracle Enterprise Manager internally makes these changes when an application is deployed. Manual modification of these files may risk putting the repository out of synchronization.

| Copyright © 1996, 2003 Oracle Corporation. All Rights Reserved. |
| Home | Index