Oracle8i Enterprise JavaBeans and CORBA Developer's Guide
Release 8.1.5

A64683-01

Library

Product

Contents

Index

Prev  Chap Top Next

Session Management

In the simple cases, a client starts a new server session implicitly when it activates a server object, such as an EJB or a CORBA server object. But Oracle8i also gives you the ability to control session start-up explicitly, either from the client or from a server object.

Starting a New Session

In general, when you lookup a published object using the URL notation, and you specify a hostname and port, then the object is activated in a new session. For example when an activated CORBA server object or an EJB looks up a second server object, using the same series of statements as the first client would use:

Hashtable env = new Hashtable();
env.put(Context.URL_PKG_PREFIXES, "oracle.aurora.jndi");
env.put(Context.SECURITY_PRINCIPAL, "scott");
env.put(Context.SECURITY_CREDENTIALS, "tiger");
env.put(Context.SECURITY_AUTHENTICATION, ServiceCtx.NON_SSL_LOGIN);
Context ic = new InitialContext(env);
SomeObject myObj =
   (SomeObject) ic.lookup("sess_iiop://localhost:5521:ORCL/test/someobject");

then the object myObj is activated in a separate session from the session in which the server object that did the lookup is running.

Using thisServer

If the server object must lookup and activate a new published object in the same session in which it is running, then the server object should use the thisServer/:thisSession notation in place of the hostname:port:SID in the URL. For example, to lookup and activate an object in the same session, do the following:

Hashtable env = new Hashtable();
env.put(Context.URL_PKG_PREFIXES, "oracle.aurora.jndi");
Context ic = new InitialContext(env);
SomeObject myObj =
   (SomeObject) 
ic.lookup("sess_iiop://thisSession/:thisSession/test/someobject");

In this case, myObj is activated in the same session in which the invoking object is running. Note that there is no need to supply login authentication information, as the client (a server object in this case) is already authenticated to Oracle8i.

It is important to realize that objects are not authenticated. Rather, clients must be authenticated to a session.

But when a separate session is to be started, then some form of authentication must be done (either login or SSL credential authentication).


Note:

The thisServer notation can only be used on the server side, that is, from server objects. It cannot be used in a client program.  


Starting a Named Session From a Client

In the simple case, you let the JNDI initial context lookup() method also start the session and authenticate the client. The session then becomes the default session (and has the name :default).

If you then create additional objects in the client, and activate them, the new objects run in the same session. Even if you create a new JNDI initial context, and look up the same or a new object using that context, the object is instantiated in the same session as the first object.

There are cases, however, when a client needs to activate an object in a separate session from any current objects. Do this as follows:

The following is a more complete code example that demonstrates this technique. There is a complete example that shows this in "twosessions".

Hashtable env = new Hashtable ();
env.put (Context.URL_PKG_PREFIXES, "oracle.aurora.jndi");
Context ic = new InitialContext (env);

// Get a SessionCtx that represents a database instance
ServiceCtx service = (ServiceCtx) ic.lookup ("sess_iiop://localhost:2481:ORCL");

// Create and authenticate a first session in the instance.  
SessionCtx session1 = (SessionCtx) service.createSubcontext (":session1");

// Authenticate
session1.login("scott", "tiger", null);

// Create and authenticate a second session in the instance.  
SessionCtx session2 = (SessionCtx) service.createSubcontext (":session2");

// Authenticate using a login object (not required, just shown for example).
LoginServer login_server2 = (LoginServer)session2.activate ("etc/login");
Login login2 = new Login (login_server2);
login2.authenticate ("scott", "tiger", null);

// Activate one Hello object in each session
Hello hello1 = (Hello)session1.activate (objectName);
Hello hello2 = (Hello)session2.activate (objectName);

// Verify that the objects are indeed different
hello1.setMessage ("Hello from Session1");
hello2.setMessage ("Hello from Session2");

System.out.println (hello1.helloWorld ());
System.out.println (hello2.helloWorld ());

Example: Activating Services and Sessions

This section describes in greater detail how you can explicitly activate a session IIOP service, and then activate one or more Oracle8i sessions in the context of the service. The simplest way to activate services and sessions is to use the JNDI methods provided in the ServiceCtx and SessionCtx classes.

This section demonstrates service and session activation, as well as explicit login authentication, by way of a useful example: lister.java. This program recursively lists the names of all published objects in the session namespace, along with the creation dates and owners.

Unlike most of the other example programs in this guide, the lister program does not start by activating a published object. In the other example programs, the service and session are usually started automatically, as a by-product of the published object look up. In this example the service and session must be specifically activated by the client program.

The example starts by instantiating a new hashtable for the environment properties to be passed to the server:

    Hashtable env = new Hashtable();
    env.put(Context.URL_PKG_PREFIXES, "oracle.aurora.jndi");
Note that only the URL_PKG_PREFIXES Context variable is filled in--the other information will be provided in the login.authenticate() method parameters.

Next, create a new JNDI Context. This is the necessary first step in all programs that will use JNDI methods. Pass in the hashtable, as usual.

    Context ic = new InitialContext(env);
Then use the JNDI lookup() method on the initial context, passing in the service URL, to establish a service context. This example uses a service URL with the service prefix, hostname, listener port, and SID:
    ServiceCtx service =
        (ServiceCtx) ic.lookup("sess_iiop://localhost:2481:ORCL");

The next step is to initiate a session. Do this by invoking the createSubcontext() method on the service context object, as follows:

    SessionCtx session = (SessionCtx) service.createSubcontext(":session1");

Note that you must name a new session when you create it. The session name must start with a colon (:), and cannot contain a slash ('/'), but is not otherwise restricted.

The final step before you can access the published object tables is to authenticate the client program to the database. Do this by calling the login() method on the session context object:

   session.login("scott", "tiger", null);    // role is null

Finally, the example starts listing by calling the listOneDirectory() static method, which recursively lists all directories (PublishingContexts) and leafs (PublishedObjects) in the published names hierarchy:

    listOneDirectory ("/", session);

The complete code for the example is reproduced in the following section. The code includes some minimal formatting to align the printed output. Follow the same procedures as for the sample applications in Appendix A, "Example Code: CORBA" to compile and run this example.

Lister.java

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingEnumeration;
import javax.naming.Binding;
import javax.naming.NamingException;
import javax.naming.CommunicationException;

import oracle.aurora.jndi.sess_iiop.ServiceCtx;
import oracle.aurora.jndi.sess_iiop.SessionCtx;
import oracle.aurora.jndi.sess_iiop.ActivationException;
import oracle.aurora.AuroraServices.PublishedObject;
import oracle.aurora.AuroraServices.objAttribsHolder;
import oracle.aurora.AuroraServices.objAttribs;
import oracle.aurora.AuroraServices.ctxAttribs;
import oracle.aurora.jts.client.AuroraTransactionService;
import oracle.aurora.AuroraServices.LoginServer;
import oracle.aurora.client.Login;

import javax.naming.Context;
import javax.naming.InitialContext;
import java.util.Hashtable;

public class Lister {

  public static void main (String[] args) throws Exception {
    if (args.length != 3) {
      System.out.println("usage: Lister serviceURL user password");
      System.exit(1);
    }
    String serviceURL = args [0];
    String username = args [1];
    String password = args [2];

    // Prepare a simplified Initial Context as we are going to do
    // everything by hand.
    Hashtable env = new Hashtable();
    env.put(Context.URL_PKG_PREFIXES, "oracle.aurora.jndi");
    Context ic = new InitialContext(env);

    // Get a SessionCtx that represents a database instance.
    ServiceCtx service = (ServiceCtx) ic.lookup(serviceURL);

    // Create a session in the instance.
    // The session name must start with a colon(:).
    SessionCtx session = (SessionCtx) service.createSubcontext(":session1");
    session.login(username, password, null);

    // Print a header line.
    System.out.println
      ("\n\nName                          Create Date              Owner");
    listOneDirectory ("/", session);
  }


  public static void listOneDirectory (String name, SessionCtx ctx)
       throws Exception  {
    System.out.print(name);
    for (int i = name.length(); i < 30; i++)
      System.out.print(" ");
    ctxAttribs attribs = null;
    try {
      attribs = ctx.getAttributes();
    } catch (org.omg.CORBA.NO_PERMISSION e) {
      return;
    }

    System.out.print(attribs.creation_ts);
    for (int i = 30 + attribs.creation_ts.length(); i < 55; i++)
      System.out.print(" ");
    System.out.print(attribs.owner);

    /*
     * You could also add output for the access permissions:
     *  attribs.read
     *  attribs.write
     *  attribs.execute
     */

    System.out.println();

    // Show the sub entries
    listEntries(ctx, name);
  }

  public static void listEntries (Context context, String prefix)
       throws Exception  {
    NamingEnumeration bindings = context.list("");
    while (bindings.hasMore()){
      Binding binding = (Binding) bindings.next();
      String name = binding.getName();
      Object object = context.lookup(name);
      if (object instanceof SessionCtx)
        listOneDirectory(prefix + name + "/", (SessionCtx) object);
      else if (object instanceof PublishedObject)
        listOneObject(prefix + name, (PublishedObject) object);
      else
        // We should never get here.
        System.out.println(prefix + name + ": " + object.getClass());
    }
  }


  public static void listOneObject (String name, PublishedObject obj)
       throws Exception  {
    objAttribsHolder holder = new objAttribsHolder();
    try {
      obj.get_attributes(holder);
    } catch (org.omg.CORBA.NO_PERMISSION e) {
      return;
    }

    objAttribs attribs = holder.value;
    System.out.print(name);
    for (int i = name.length(); i < 30; i++)
      System.out.print(" ");

    System.out.print(attribs.creation_ts);
    for (int i = 30 + attribs.creation_ts.length(); i < 55; i++)
      System.out.print(" ");
    System.out.print(attribs.owner);

    /*
     * You could also add output for:
     *  attribs.class_name
     *  attribs.schema
     *  attribs.helper
     * and the access permissions:
     *  attribs.read
     *  attribs.write
     *  attribs.execute
     */

    System.out.println();
  }
}

Starting a New Session From a Server Object

Starting a new session from a CORBA server object, or from an EJB, is exactly like starting a session from an application client. You can start the session implicitly by using lookup() on an initial context to look up and activate another published object, or you can start a new service context, and from that a new session, just as shown in "Starting a Named Session From a Client".

Hashtable env = new Hashtable ();
env.put (Context.URL_PKG_PREFIXES, "oracle.aurora.jndi");
Context ic = new InitialContext (env);
employee =
  (Employee)ic.lookup ("sess_iiop://thisServer/test/myEmployee");

Any new session connection must always authenticate itself to the database server. See "clientserverserver" for an example that starts a new session from a CORBA server object.

If you need to activate a new object in the same session from another server object, you use the thisServer indicator. See "Using thisServer" for more information.

Controlling Session Duration

A session normally ends when the last client connection terminates. However, a server object can control the session duration by using the oracle.aurora.net.Presentation.sessionTimeout() method. The method takes one parameter, the session timeout value in seconds. The session timeout clock starts ticking when the last client request completes. For example:

int timeoutValue = 30;
...
// set the timeout to 30 seconds
oracle.aurora.net.Presentation.sessionTimeout(timeoutValue);
...
// set the timeout to a very long time
oracle.aurora.net.Presentation.sessionTimout(Integer.MAX_INT);

See the example "timeout" for an example that sets session timeout on the server side.

Note: When you use the sessionTimeout() method, you must add $(ORACLE_HOME)/lib/aurora.zip to your CLASSPATH.

Ending a Session

To terminate a database session, use the exitSession() method. For example,

oracle.aurora.vm.OracleRuntime.exitSession(1);

The int parameter for exitSession(int x) is an exit value, similar to the value supplied for System.exit();

Note: System.exit() does not terminate a database session.




Prev

Top

Next
Oracle
Copyright © 1999 Oracle Corporation.

All Rights Reserved.

Library

Product

Contents

Index