Programmer's Guide


Chapter 18   Writing External Java Clients

This chapter describes how to code external Java clients (outside the SilverStream development environment) to access a SilverStream server and use the objects, data, and services it provides. You'll learn about:

    To learn about configuring your external Java development environment to build this kind of client, see Coding Java for SilverStream Applications.

For J2EE applications   If you're committed to pure J2EE development, you'll typically want to build J2EE application clients instead of the external Java clients described in this chapter. J2EE application clients are hosted by a container that automatically handles deployment, connection to a server session, resource access, and other services. In contrast, external Java clients run on their own, requiring you to handle these chores manually and to use SilverStream API code.

    For more information, see Writing J2EE Application Clients.

 
Top of page

Designing your client

To design an external Java client, you need to know what's supported and what's required when accessing a SilverStream server.

The following sections outline the kinds of clients you can build, including the basic features a client can or must implement. You'll find the details on these topics later in the chapter.

 
Top of section

Client types

Your external Java client can be:

 
Top of section

Client requirements

Your external Java client must:

To perform the initialize and connect operations, you'll use the SilverStream API in your Java client source code.

    For an overview of the SilverStream API, see Coding Java for SilverStream Applications.

 
Top of section

Client features

Your external Java client can access a single SilverStream server or several at a time. It can also access server clusters.

Once connected to a server, your client can use the SilverStream and Java APIs to:

You can implement one or more of these features in any external Java client you code.

 
Top of section

Communication protocols

When connecting to a SilverStream server, your client determines the communication protocol to be used for that entire session. The choices are:

Which protocol you use will probably depend on several factors, including the architecture of your application and network, the policies and standards of your organization, and certain restrictions that apply to RMI-IIOP.

Restrictions when using RMI-IIOP

An external Java client that uses RMI-IIOP to communicate with a SilverStream server cannot:

 
Top of page

Accessing the server from your client

To access a SilverStream server from any external Java client, write the client code to:

  1. Initialize the SilverStream runtime environment on the client machine

  2. Connect to the SilverStream server to establish a server session

  3. Use the server session

  4. Close the server session

    To see some complete client classes that perform all of these steps, go to Application Techniques>Java Client Techniques in the help system: External Java clients.

 
Top of section

Initializing the SilverStream runtime environment

By default, the SilverStream runtime environment automatically gets initialized on the client machine when required. But you can optionally control this initialization yourself by calling the init() method of the com.sssw.rt.util.AgRuntime class.

The init() method enables you to specify a login handler object to use if the SilverStream server you're accessing requires user authentication. When your client tries to connect, the server will call back this object to obtain a user name and password.

Handling user login requests

To get a login handler object to use:

  1. Code a login handler class that implements the com.sssw.rt.util.AgiUserLogin interface.

    AgiUserLogin has one method: prompt(). You must code it to obtain the user name and password, then return those values to the server (in an instance of the AgoUserLoginInfo class from com.sssw.rt.util).

  2. Create a new instance of your login handler class to supply to the init() method.

For example, here's how you'd code init() to use a login handler class named LoginHandler:

  AgRuntime.init(new LoginHandler());

    To see some examples of login handler classes, go to Application Techniques>Java Client Techniques in the help system: Handling User Authentication from External Java Clients.

Initializing from an applet

If the client you're developing is an applet, call the initFromApplet() method of the AgRuntime class to initialize the SilverStream runtime environment on the client machine.

 
Top of section

Connecting to a SilverStream server

Call one of these methods of the com.sssw.rt.util.AgRuntime class:

Method

What it does

connect()

Connects to a SilverStream server, using HTTP as the communication protocol

connectRMI()

Connects to a SilverStream server, using RMI-IIOP as the communication protocol

Specify this argument:

For example, you could connect via HTTP to the SilverStream server on the host machine named myserver:

  AgrServerSession session;
  session = AgRuntime.connect("myserver");

or you could connect via RMI-IIOP:

  AgrServerSession session;
  session = AgRuntime.connectRMI("myserver");

The AgRuntime class provides several variations of the connect() and connectRMI() methods. They all establish a session on the specified server and return a session object (an instance of the com.sssw.rt.util.AgrServerSession class) for your client code to work with. (If a session is already established, they return the existing session object.)

    For guidance on choosing HTTP or RMI-IIOP for your connection, see Communication protocols.

Login alternative for RMI-IIOP connections   One variation of the connectRMI() method lets you specify a user name and password for logging into a SilverStream server. This is useful for server-to-server connections where login handler callbacks aren't supported.

Starting the client heartbeat

The AgrServerSession object returned to your client automatically starts a heartbeat to keep the session from timing out. It's simply a periodic communication that tells the SilverStream server your client is still there.

Because of this heartbeat, you must explicitly close the session when your client is done with it.

    For details, see Closing your server session.

Connecting to a cluster

To connect your client to a server cluster, you still use the connect() or connectRMI() method of the AgRuntime class. The difference is that you specify the host name of the cluster's dispatcher.

For example:

  AgrServerSession session;
  session = AgRuntime.connect("mydispatcher");

Once connected, you can call the getServerHostName() method of the AgrServerSession object to obtain the host name of the actual SilverStream server.

RMI-IIOP restriction for cluster access   If you call the connectRMI() method to establish an RMI-IIOP connection to a cluster, you must be using the SilverStream dispatcher. Third-party dispatchers are not supported in this situation.

    For more information on clusters and dispatchers, see the chapter on administering a cluster in the Administrator's Guide of the server's Core Help.

 
Top of section

Using your server session

Once your client is connected to a SilverStream server, it can use the objects, data, and services of that server (security permitting). This includes calling methods of the AgrServerSession object to:

More importantly, your client can:

    To learn how, see Developing the features for your client.

 
Top of section

Closing your server session

When your client is done accessing the SilverStream server, it should explicitly close the server session. To do that, call the close() method of the AgrServerSession object.

For example:

  session.close();

It's best to code close() where you're certain it will execute (such as in the finally block of a try/catch/finally statement). Remember that a session won't time out automatically (because of the heartbeat feature of the AgrServerSession object).

    For more information, see Starting the client heartbeat.

 
Top of page

Developing the features for your client

To this point, you've learned mostly about the mechanics of connecting your external Java client to a SilverStream server. Now it's time to use the capabilities of that server to do some real application work. Possibilities include:

 
Top of section

Accessing data

An external Java client can retrieve and update rows of data from a data source object (DSO) on a SilverStream server. To implement this access, you use the com.sssw.rt.util.AgrData class in your client to represent the cache of rows to work with.

Using AgrData involves:

  1. Setting up the row cache (an instance of AgrData)

  2. Either of the following:

    To see some complete client classes that perform all of these steps, go to Application Techniques>Java Client Techniques in the help system:

    To learn about the various kinds of DSOs and how to create them, see Using Data Source Business Objects.

NOTE   DSO access requires an HTTP connection to your SilverStream server (RMI-IIOP does not support it). For more information on connections, see Connecting to a SilverStream server.

Setting up the row cache

To set up your client's row cache and enable it to access the appropriate DSO:

  1. Create an instance of AgrData.

      AgrData appdata = new AgrData();
    
  2. Call the init() method of the AgrData object to initialize it with the appropriate SilverStream server session (AgrServerSession object).

      appdata.init(session);
    
  3. Call the setDataSource() method of the AgrData object to specify the location and name (database:package.object) of the DSO to access.

      appdata.setDataSource("mydb:com.myorg.data.dsoMyData");
    
  4. Call the invokeQuery() method of the AgrData object to start accessing that DSO.

      appdata.invokeQuery(null);
    

Now the row cache (AgrData object) is ready to work with rows from the DSO.

Retrieving rows

You can use the query and data navigation methods of the AgrData object to:

    For more information on using these kinds of AgrData methods, see Data Access Basics.

Updating rows

You can use the data manipulation and update methods of the AgrData object to:

    For more information on using these kinds of AgrData methods, see Data Access Basics.

Providing rows to a table model

You can access the rows of your client's cache in controls (such as JTables) that use a table model. To do that, use the com.sssw.rt.util.AgoRowCursorTableModel class (which is based on javax.swing.table.AbstractTableModel):

  1. Create an instance of AgoRowCursorTableModel that uses the appropriate AgrData object.

      AgoRowCursorTableModel agmodel;
      agmodel = new AgoRowCursorTableModel(appdata);
    
  2. Create the control and bind that model (AgoRowCursorTableModel object) to it.

      JTable table = new JTable(agmodel);
    

AgoRowCursorTableModel supports both retrieval and update of rows from the control.

 
Top of section

Calling EJBs

An external Java client can call Enterprise JavaBeans (EJBs) that have been deployed on a SilverStream server. This involves:

  1. Accessing the bean you want from the server

  2. Calling methods of that bean

    To see a complete client class that performs these steps, go to Application Techniques>Java Client Techniques in the help system: Calling EJB Session Beans from External Java Clients.

    To learn about the various kinds of Enterprise JavaBeans and how to create them, see Using EJBs with SilverStream Applications.

Setting up your development environment

Before compiling a client that uses EJBs, make sure that:

    To learn how to get the remote JAR file for a bean, see Calling EJBs.

    To learn about other (general) setup requirements for your external Java development environment, see Coding Java for SilverStream Applications.

Preparing to access a secured bean

An EJB deployed on the SilverStream server may be secured so that an IIOP over SSL connection is automatically used when a client tries to access it. To support this kind of connection, your external Java client needs to take care of some housekeeping before performing the access steps.

Providing the agrootca.jar file   First, you must make sure that when the client is later deployed to user machines, the following JAR file of CA (Certificate Authority) certificates is provided as well: agrootca.jar. You can copy this file from a development machine that has the SilverStream server installed (it's located in the SilverStream lib directory). You can store it anywhere on a user machine (typically in the same location as the other SilverStream JAR and ZIP files you deploy).

If you need to use a CA certificate that isn't in this file, you must add it. Use the JAR editing tool of your choice (such as the Sun JAR utility or WinZip).

Specifying the location of agrootca.jar   Because the agrootca.jar file can be located anywhere on a user machine, you need to tell your external Java client where to find it. You can do that by including the following command-line argument when starting the client:

  -DAGROOTCA=path

This lets you assign the path of agrootca.jar to the system property AGROOTCA. For example:

  java -DAGROOTCA=c:\sssw\lib\agrootca.jar mypackage.myApplication

In your client's code, you can check to make sure AGROOTCA has a value assigned:

  class mycls
  {
    void func()
    {
      String agrootcaJar = System.getProperty("AGROOTCA");
      if (agrootcaJar == null)
        System.out.println("agrootca.jar file not specified");
      ...
    }
  }

An alternative to the command line argument is to use the System.setProperty() method in your client's code to assign the path of agrootca.jar to the system property AGROOTCA.

    For more information on secured connections to EJBs, see the chapter on setting up security in the Administrator's Guide of the server's Core Help.

Accessing the bean

Before your client can call any methods of an EJB, it must gain access to that bean on the appropriate SilverStream server. To do this, you can connect to that server (as described earlier in the chapter), then perform the steps below. If you want to avoid using SilverStream API code in these steps, first see Access without an explicit connection.

  1. Get the host name and port for the server by calling the getServerHostName() and getServerPort() methods of the AgrServerSession object.

      String servername = session.getServerHostName();
      int portnum = session.getServerPort();
      if (portnum != -1) {
        servername += ":" + Integer.toString(portnum);
      }
    
  2. Specify the JNDI name under which the bean is registered (JNDI is the Java Naming and Directory Interface).

      String jndiname = "MyBean";
    
  3. Do a JNDI lookup of the bean on that server by creating an instance of the javax.naming.InitialContext class

      InitialContext context = new InitialContext();
    

    and by calling the lookup() method of the InitialContext object to return the bean's home interface as an Object.

      Object sbobj = context.lookup("sssw://" + 
                                    servername + 
                                    "/RMI/" + 
                                    jndiname);
    

    Note that a couple parts of the address (sssw://.../RMI/...) are the same for any EJB deployed on a SilverStream server.

  4. Call the narrow() method of the javax.rmi.PortableRemoteObject class to check that the Object returned by the lookup can be cast to the appropriate type (the class of the bean's home interface)

      sbobj = PortableRemoteObject.narrow(sbobj,
                                          MyBeanHome.class);
    

    then cast the Object to that class.

      MyBeanHome sbhome = (MyBeanHome)sbobj;
    
  5. Call the create() method or a finder method of the resulting home object to get an instance of the bean's remote interface.

      MyBeanRemote sbremote = sbhome.create();
    

Your client now has the remote object for the bean and is ready to use it.

Access without an explicit connection   If you're concerned with the portability of your client, you can access EJBs (or other JNDI objects) from a SilverStream server without using any SilverStream API classes. Instead of explicitly coding AgRuntime and AgrServerSession to connect to the server and establish a session, you can skip directly to creating the InitialContext object and pass it information about the server (in a Properties argument). This information consists of the following strings:

For example:

  Properties p = new Properties();
  
  p.put(Context.INITIAL_CONTEXT_FACTORY,
        "com.sssw.rt.jndi.AgInitCtxFactory");
  p.put(Context.PROVIDER_URL, "sssw://myserver:8080");
  p.put(Context.SECURITY_PRINCIPAL, usernameString);
  p.put(Context.SECURITY_CREDENTIALS, passwordString);
  
  InitialContext context = new InitialContext(p);

This approach implicitly handles initialization for the client and establishes an RMI connection to the specified SilverStream server. It returns an InitialContext that you can then use to look up the appropriate bean on that server.

When using this approach, make sure you don't also code the SilverStream API approach (using AgRuntime and AgrServerSession to initialize and connect) in the same client. That's because AgRuntime automatically sets the InitialContext factory and overrides any factory you try to pass in the Properties argument.

Calling bean methods

Once your client has a bean's remote object, it can call the business methods of that bean (specifically, the methods exposed by the bean's remote interface). For example:

  result = sbremote.getTotal();

It can also call any other lifecycle methods of the bean's home interface that it needs to.

 
Top of section

Invoking business objects

An external Java client can invoke triggered business objects on a SilverStream server. This involves:

  1. Knowing the location and name (database:package.object) of the triggered business object to invoke

      String bo = "mydb:com.myorg.busobj.boMyBusinessObject";
    

    This business object must have an invoked trigger defined along with an invoked event handler.

  2. Calling the invokeBusinessObject() method of the AgrServerSession object to perform the processing defined by that business object (in its invoked event handler)

      Object result;
      result = session.invokeBusinessObject(bo);
    

    The result returned from the business object by the invokeBusinessObject() method can be any Serializable object. (There's also a variation of this method that passes a Serializable object to the business object.)

    To see a complete client class that performs these steps, go to Application Techniques>Java Client Techniques in the help system: Invoking Business Objects from External Java Clients.

    To learn about creating triggered business objects you can invoke, see Using Invoked Business Objects.

 
Top of section

Administering the server

An external Java client can perform administrative operations on a SilverStream server. This involves using the Server Administration API (the administration portion of the SilverStream API) to:

  1. Get an administration-enabled reference to the server by calling the getServer() method of the com.sssw.rts.adminclient.AgAdmin class, passing the AgrServerSession object as an argument

      AgiAdmServer admserver = AgAdmin.getServer(session);
    

    This method returns an object that implements the com.sssw.rts.adminapi.AgiAdmServer interface, representing the server for the purpose of administration.

  2. Call appropriate methods of the AgiAdmServer object (and related objects) to

    For example

      // Get a reference to the directory of users in the Silver 
      // Security realm
      AgiAdmDirectory userdir;
      userdir = (AgiAdmDirectory)admserver.getElement(
                                 AgiAdmDirectory.SILVERUSERS,
                                 AgiAdmDirectory.SILVERUSERS,
                                 null);
      
      // Get a sorted list of the users in that directory
      Enumeration users;
      users = userdir.getChildren(
              AgiAdmContainer.GET_CHILDREN_SORTED);
      .
      .
      .
    

    To see a complete client class that performs these steps, go to Application Techniques>Java Client Techniques in the help system: Administering the Server from External Java Clients.

    To learn more about the administrative operations you can perform on a SilverStream server, see the chapter on using the Server Administration API in the Administrator's Guide of the server's Core Help.

NOTE   Use of the Server Administration API requires an HTTP connection to your SilverStream server (RMI-IIOP does not support it). For more information on connections, see Connecting to a SilverStream server.

 
Top of page

Deploying your client

Once your external Java client is compiled and tested, you can deploy it to user machines. Deployment involves setting up each user machine to access all the files needed to run the client successfully. This includes:

 
Top of section

Installing the runtime environment

Instructions for installing the runtime environment depend on the platform you're using (Windows, UNIX, or Linux).

Installing on Windows

In Windows, each user machine must have appropriate versions of the following runtime components:

To install these, use the SilverStream installation (Setup) program.

    For details, see the chapter about installing SilverStream on Windows in the Installation Guide of the server's Core Help.

Coexisting with another runtime environment   Sometimes user machines may already have another JRE that you want to keep as the default instead of the one provided by SilverStream. In that case, follow these steps rather than using the SilverStream installation program:

  1. Create a new directory on the user machine for SilverStream files.

  2. Copy the jre directory from the SilverStream CD into that new directory.

  3. At runtime, temporarily set the PATH environment variable to reference the SilverStream JRE bin directory ahead of any other JRE bin directory.

    For example:

      PATH=c:\SilverStream\jre\bin;c:\Program Files\
      JavaSoft\JRE\1.2\bin;c:\WINNT\system32;c:\WINNT
    

    External Java clients that run in this context will be able to access SilverStream servers and their objects (including EJBs). Clients running outside of this context will continue to use whatever JRE they did previously.

Installing on UNIX or Linux

In UNIX or Linux, each user machine must have appropriate versions of the following runtime components:

To install these on a supported UNIX or Linux platform:

  1. Go to the directory in which you want the JRE and jBroker installed. For example:

      cd /export/home/sam/SilverApps
    
  2. Mount the SilverStream CD (to the /cdrom mount point) and enter this command:

      zcat /cdrom/SilverStream/jre.tar.Z | tar xvf -
    

    This creates jre and jbroker subdirectories in your current directory and copies the appropriate files into them.

    For detailed information about UNIX or Linux platform support, see the Application Server Release Notes.

 
Top of section

Installing your files

Provide each user machine access to the files you've developed for your client, including:

For EJB clients   If your client calls Enterprise JavaBeans, you must also provide:

    To learn how to get the remote JAR file for a bean, see Calling EJBs.

 
Top of section

Installing SilverStream files

Each user machine must have access to several ZIP and JAR files from SilverStream that contain:

The recommended way to get these files is to copy them from a development machine that has the SilverStream server installed. The next sections list the names of the files you need.

    For instructions on installing the SilverStream server, see the Installation Guide of the server's Core Help.

SilverStream ZIP and JAR files

The following table shows which SilverStream ZIP and JAR files to install, depending on the kinds of client classes you're deploying.

If you're deploying

Install this file

Typical location (may be different on your system)

Any client classes that will access the SilverStream server

SilverRuntime.zip

C:\SilverStream\lib

SilverClientObjectEra_Jbroker.zip

C:\SilverStream\Resources\Orbs

Any client classes that will use SSL (Secure Sockets Layer) to access the domestic (U.S.) version of the SilverStream server

SilverDomestic.zip

C:\SilverStream\lib

Any client classes that will administer the SilverStream server

SilverAdmin.jar

C:\SilverStream\lib

For secured EJB clients   If you're deploying any client classes that will access secured EJBs, you'll need to install this additional SilverStream JAR file: agrootca.jar.

    For details, see Preparing to access a secured bean.

Other ZIP and JAR files

This table shows the other supporting (Java and third-party) ZIP and JAR files to install. It's recommended that you always provide all of these.

Category

Functional area

File name

Typical location (may be different on your system)

Java

EJB

ejb.jar

C:\SilverStream\lib

JavaBeans activation

activation.jar

C:\SilverStream\lib

JavaMail

mail.jar

C:\SilverStream\lib

pop3.jar

C:\SilverStream\lib

JNDI and RMI

ldap.jar

C:\SilverStream\lib

nisplus.jar

C:\SilverStream\lib

cosnaming.jar

C:\SilverStream\jre\lib\ext

jndi.jar

C:\SilverStream\jre\lib\ext

providerutil.jar

C:\SilverStream\jre\lib\ext

rmiregistry.jar

C:\SilverStream\jre\lib\ext

Transactions

javax_trans.zip

C:\SilverStream\lib

Third-party

CORBA and RMI-IIOP

jbroker-rt.jar

C:\SilverStream\jre\lib\ext

jbroker-ssl.jar

C:\SilverStream\jre\lib\ext

 
Top of section

Setting the classpath

Once you've installed the required files, you need to make sure the Java runtime environment can find them. You can do that by setting the classpath to list these files (such as with the CLASSPATH environment variable).

The classpath on each user machine should include:


Programmer's Guide

Copyright © 2001, SilverStream Software, Inc. All rights reserved.