8 Developing a J2SE Client

A J2SE client is oriented towards the Java EE programming model; it combines the capabilities of RMI with the IIOP protocol without requiring WebLogic Server classes. The following sections provide information on developing a J2SE Client:

J2SE Client Basics

A J2SE client runs an RMI-IIOP-enabled ORB hosted by a Java EE or J2SE container, in most cases a 1.3 or higher JDK. A J2SE client has the following characteristics:

It provides a light-weight connectivity client that uses the IIOP protocol, an industry standard.

It is a J2SE-compliant model, rather than a Java EE-compliant model—it does not support many of the features provided for enterprise-strength applications. It does not support security, transactions, or JMS.

Distributed interoperability for EJBs, based on the EJB 3.0 specification, is supported by WebLogic Server through the EJB 2.1 remote client view from clients.

How to Develop a J2SE Client

To develop an application using RMI-IIOP with an RMI client:

Define your remote object's public methods in an interface that extends java.rmi.Remote.

This remote interface may not require much code. All you need are the method signatures for methods you want to implement in remote classes. For example:

Implement the interface in a class named interfaceNameImpl and bind it into the JNDI tree to be made available to clients.

This class should implement the remote interface that you wrote, which means that you implement the method signatures that are contained in the interface. All the code generation that will take place is dependent on this class file. Typically, you configure your implementation class as a WebLogic startup class and include a main method that binds the object into the JNDI tree. For example:

Compile the remote interface and implementation class with a Java compiler. Developing these classes in an RMI-IIOP application is no different than doing so in normal RMI. For more information on developing RMI objects, see Programming RMI for Oracle WebLogic Server.

Run the WebLogic RMI or EJB compiler against the implementation class to generate the necessary IIOP stub. Note that it is no longer necessary to use the -iiop option to generate the IIOP stubs:

$ java weblogic.rmic nameOfImplementationClass

A stub is the client-side proxy for a remote object that forwards each WebLogic RMI call to its matching server-side skeleton, which in turn forwards the call to the actual remote object implementation. Note that the IIOP stubs created by the WebLogic RMI compiler are intended to be used with the JDK 1.3.1_01 or higher ORB. If you are using another ORB, consult the ORB vendor's documentation to determine whether these stubs are appropriate.

Make sure that the files you have now created -- the remote interface, the class that implements it, and the stub -- are in the CLASSPATH of WebLogic Server.

Obtain an initial context.

RMI clients access remote objects by creating an initial context and performing a lookup (see next step) on the object. The object is then cast to the appropriate type.

In obtaining an initial context, you must use com.sun.jndi.cosnaming.CNCtxFactory when defining your JNDI context factory. Use com.sun.jndi.cosnaming.CNCtxFactory when setting the value for the "Context.INITIAL_CONTEXT_FACTORY" property that you supply as a parameter to new InitialContext().

Note:

The Sun JNDI client supports the capability to read remote object references from the namespace, but not generic Java serialized objects. This means that you can read items such as EJBHome out of the namespace but not DataSource objects. There is also no support for client-initiated transactions (the JTA API) in this configuration, and no support for security. In the stateless session bean RMI Client example, the client obtains an initial context as is done below:

Example 8-1 Obtaining an InitialContext

.
.
.
* Using a Properties object as follows will work on JDK13
* and higher clients.
*/
private Context getInitialContext() throws NamingException {
try {
// Get an InitialContext
Properties h = new Properties();
h.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.cosnaming.CNCtxFactory");
h.put(Context.PROVIDER_URL, url);
return new InitialContext(h);
} catch (NamingException ne) {
log("We were unable to get a connection to the WebLogic server at "+url);
log("Please make sure that the server is running.");
throw ne;
}
/**
* This is another option, using the Java2 version to get an * InitialContext.
* This version relies on the existence of a jndi.properties file in
* the application's classpath. See
* "Programming JNDI for Oracle WebLogic Server" for more information
private static Context getInitialContext()
throws NamingException
{
return new InitialContext();
}
.
.
.

Modify the client code to perform the lookup in conjunction with the javax.rmi.PortableRemoteObject.narrow() method.

RMI-IIOP clients differ from regular RMI clients in that IIOP is defined as the protocol when the client is obtaining an initial context. Because of this, lookups and casts must be performed in conjunction with the javax.rmi.PortableRemoteObject.narrow() method.

For example, an RMI client creates an initial context, performs a lookup on the EJBean home, obtains a reference to an EJBean, and calls methods on the EJBean.

You must use the javax.rmi.PortableRemoteObject.narrow() method in any situation where you would normally cast an object to a specific class type. A CORBA client may return an object that does not implement your remote interface; the narrow method is provided by your orb to convert the object so that it implements your remote interface. For example, the client code responsible for looking up the EJBean home and casting the result to the Home object must be modified to use the javax.rmi.PortableRemoteObject.narrow() as shown below:

To narrow an RMI interface on a client, the server needs to serve the appropriate stub for that interface. The loading of this class is predicated on the use of the JDK network classloader and this is not enabled by default. To enable it you set a security manager in the client with an appropriate java policy file. For more information on Java SE security, see http://java.sun.com/javase/technologies/security/index.jsp at Sun Microsystems. The following is an example of a java.policy file: