Programming Stand-alone Clients

     Previous  Next    Open TOC in new window    View as PDF - New Window  Get Adobe Reader - New Window
Content starts here

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:

 


How to Develop a J2SE Client

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

  1. Define your remote object’s public methods in an interface that extends java.rmi.Remote.
  2. 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:

    public interface Pinger extends java.rmi.Remote {
    public void ping() throws java.rmi.RemoteException;
    public void pingRemote() throws java.rmi.RemoteException;
    public void pingCallback(Pinger toPing) throws java.rmi.RemoteException;
    }
  3. Implement the interface in a class named interfaceNameImpl and bind it into the JNDI tree to be made available to clients.
  4. 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:

    public static void main(String args[]) throws Exception {
      if (args.length > 0)
      remoteDomain = args[0];
      Pinger obj = new PingImpl();
      Context initialNamingContext = new InitialContext();
      initialNamingContext.rebind(NAME,obj);
      System.out.println("PingImpl created and bound to "+ NAME);
    }
  5. 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 “ Understand ing WebLogic RMI”.
  6. 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:
  7. $ 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.

  8. 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.
  9. Obtain an initial context.
  10. 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. (WLInitialContextFactory is deprecated for this client in WebLogic Server 8.1) 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:
    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 WebLogic JNDI for more information
    private static Context getInitialContext()
      throws NamingException
    {
      return new InitialContext();
    }
    .
    .
    .
  11. Modify the client code to perform the lookup in conjunction with the javax.rmi.PortableRemoteObject.narrow() method.
  12. 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:

    Performing a lookup:
    .
    .
    .
    /**
     * RMI/IIOP clients should use this narrow function
     */
    private Object narrow(Object ref, Class c) {
      return PortableRemoteObject.narrow(ref, c);
    }
    /**
     * Lookup the EJBs home in the JNDI tree
     */
    private TraderHome lookupHome()
      throws NamingException
    {
      // Lookup the beans home using JNDI
      Context ctx = getInitialContext();
      try {
    Object home = ctx.lookup(JNDI_NAME);
    return (TraderHome) narrow(home, TraderHome.class);
    } catch (NamingException ne) {
    log("The client was unable to lookup the EJBHome. Please
    make sure ");
    log("that you have deployed the ejb with the JNDI name
    "+JNDI_NAME+" on the WebLogic server at "+url);
    throw ne;
      }
    }
    /**
     * Using a Properties object will work on JDK130
     * 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;
      }
    }
    .
    .
    .

    The url defines the protocol, hostname, and listen port for the WebLogic Server and is passed in as a command-line argument.

    public static void main(String[] args) throws Exception {
      log("\nBeginning statelessSession.Client...\n");
      String url       = "iiop://localhost:7001";
  13. Connect the client to the server over IIOP by running the client with a command such as:
  14. $ java -Djava.security.manager -Djava.security.policy=java.policy    examples.iiop.ejb.stateless.rmiclient.Client iiop://localhost:7001
  15. Set the security manager on the client:
  16. java -Djava.security.manager -Djava.security.policy==java.policy myclient

    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 security, see Sun’s site at http://java.sun.com/security/index.html. The following is an example of a java.policy file:

    grant {

    // Allow everything for now

    permission java.security.AllPermission;

    }


  Back to Top       Previous  Next