2.11 Remote Session Manager

The Remote Session Manager is available in the clientless version of NJCL. Clients are not required to run Novell Client software, but the client machines must be connected to a network that includes a NetWare 5.x server (if NetWare 5.0, the server must be upgraded to run JVM v1.2) which listens for remote calls.

The Remote Session Manager supplies a three-tier solution as follows:

The Remote Session Manager feature allows the user to specify the remote location where the SessionManager object is to reside. The local box will then access this remote SessionManager via the RMI protocol for any Session. This allows any JVM full access to all the features and functionality of the Novell JNDI providers and the session services. The local session layer will send all requests to the remote SessionManager, which will then return all results back to the local session layer. This process is transparent to the user. There is no need for the jncpv2r.dll or jncpv2r.nlm on the local box when using the remote SessionManager.

This allows an application to take full advantage of the multi-user capability of the session manager when running from any JVM. The multi-user capability is only available when running on a server when using the regular (non-clientless) version of the NJCL. See MultiUserSessionTest.java for sample code and Multi User Session Manager for more information about this functionality.

Java Cryptography Extension (JCE) 1.2.1 is needed to encrypt passwords sent from the client to the RMI server. The JCE 1.2.1 zip file is included with the NJCL — Clientless but must be unzipped and made available on both the client ant the server. See the installation instructions in the JCE zip file for details.

Users of NJCL are not required to do anything with JCE except make the jar files available to applications and grant permissions in a policy file. An example of a simple policy file that would not be used for production applications is:

   grant { permission java.security.AllPermission; };
   

Instructions and examples for more restrictive policy files are included in the JCE zip file.

The remote SessionManager must be running and listening for incoming requests before a local box tries to establish communication. This is done by running

   java -Xbootclasspath:sys:\java\lib\rt.jar;sys:\java\lib\i18n.jar; -Djava.security.policy=sys:\<policylocation>\<policy> com.novell.service.session.spi.SessionManagerServiceImpl
   

where policylocation is the path of the security policy and policy is the policy filename. This creates a server instance and starts it listening for a connection request.

Only private SessionManagers can be requested from the remote side. This is done by calling the SessionManagerFactory.getPrivate(env) method. See the Session Package for details.

The SessionEnv.SESSION_MANAGER_URL key controls running in RMI or non-RMI mode. The session mananger URL is the URL of the remote server location.

You can specify your own custom sockets for RMI to use with the SessionEnv.RMI_SOCKET_FACTORIES_OBJECT key. For more information, see the RMI documentation about custom sockets and the RMISocketFactories class.

The following sample code illustrates how to use the remote SessionManager.

   /***********************************************************************
    Copyright (c) 1999 Novell, Inc. All Rights Reserved.
    THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND TREATIES.
    USE AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO THE LICENSE AGREEMENT
    ACCOMPANYING THE SOFTWARE DEVELOPMENT KIT (SDK) THAT CONTAINS THIS WORK.
    PURSUANT TO THE SDK LICENSE AGREEMENT, NOVELL HEREBY GRANTS TO DEVELOPER A
    ROYALTY-FREE, NON-EXCLUSIVE LICENSE TO INCLUDE NOVELL’S SAMPLE CODE IN ITS
    PRODUCT. NOVELL GRANTS DEVELOPER WORLDWIDE DISTRIBUTION RIGHTS TO MARKET,
    DISTRIBUTE, OR SELL NOVELL’S SAMPLE CODE AS A COMPONENT OF DEVELOPER’S
    PRODUCTS. NOVELL SHALL HAVE NO OBLIGATIONS TO DEVELOPER OR DEVELOPER’S
    CUSTOMERS WITH RESPECT TO THIS CODE.
   ************************************************************************/
   import java.util.*;
   import javax.naming.*;
   import javax.naming.directory.*;
   import com.novell.service.session.*;
   
   public class RemoteSessionTest
   {
      public static void main(String args[])
      {
         if(args.length != 1)
         {
            System.out.println("Usage: Java RemoteSessionTest rmiServerName");
           System.out.println("Example: java RemoteSessionTest
                               137.65.255.255");
            System.exit(0);
         }
   
         try
         {
            String rmiServerName = args[0];
   
            SessionEnv env = new SessionEnv();
            //Comment out the next line to run in non-RMI mode.
            env.add(SessionEnv.SESSION_MANAGER_URL, rmiServerName);
            SessionManager sm = SessionManagerFactory.getPrivate(env);
   
            Context ctx1 = getNetWareDirContext(sm);
            printEnum(ctx1.toString(), ctx1.list(""));
            Context ctx2 = (Context)ctx1.lookup("Trees");
            printEnum(ctx2.toString(), ctx2.list(""));
   
            System.out.println("Successful");
         }
         catch(Exception e)
         {
            dumpException(e);
         }
      }
      public static Context getNetWareDirContext(SessionManager sm)
         throws Exception
      {
         Hashtable hash = new Hashtable();
         hash.put(Context.INITIAL_CONTEXT_FACTORY,
                  "com.novell.service.nw.NetWareInitialContextFactory");
   
         //This is the key piece - provide the SessionManager you want this
           provider to use.
        
   hash.put(com.novell.utility.naming.Environment.SESSION_MANAGER_OBJECT,
   sm);
         
         Context ctx1 = new InitialDirContext(hash);
         Context ctx2 = (Context)ctx1.lookup("");
            //eliminate middle man - (InitialContext)
         return ctx2;
      }
      
      public static void printEnum(String msg, NamingEnumeration ne)
      {
         int count=0;
         System.out.println(msg);
         while(ne.hasMoreElements())
         {
            count++;
            System.out.println(ne.nextElement());
         }
         System.out.println("Total Elements:" + count);
      }
      
      synchronized static public void dumpException(Throwable e)
      {
         System.out.flush();
         System.err.flush();
         System.out.println("Dumping Exception...");
         while(e != null)
         {
            e.printStackTrace();
            if (e instanceof HasRootCauses)
            {
               System.out.println("\nRoot causes...");
               Enumeration enum = ((HasRootCauses)e).getRootCauses();
               while (enum.hasMoreElements())
               {
                  dumpException((Throwable)enum.nextElement());
               }
            }
            if (e instanceof HasRootCause)
               e = ((HasRootCause)e).getRootCause();
            else if (e instanceof NamingException)
               e = ((NamingException)e).getRootCause();
            else if(e instanceof java.rmi.RemoteException)
               e = ((java.rmi.RemoteException)e).detail;
            else
               e = null;
            if(e != null)
               System.out.println("Root cause...");
         }
         System.err.flush();
         System.out.flush();
      }
   }