Skip Headers
Oracle® Containers for J2EE Services Guide
10g Release 3 (10.1.3)
B14427-01
  Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
Next
Next
 

6 Using Remote Method Invocation in OC4J

This chapter includes the following topics:

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

6.1.1 Choosing RMI/ORMI or RMI/IIOP

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

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:

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:

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.

6.3.1 Setting JNDI Properties for RMI

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

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:


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

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 thejava.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:

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:

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:

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:

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.