Release Notes for JSDT 1.5

[Last updated 14th May 1999].


Contents

    Changes in JSDT 1.5
    Changes in JSDT 1.4
    Changes in JSDT 1.3
    Changes in JSDT 1.2
    Changes in JSDT 1.1
    Changes from JSDA
    Migrating from JSDT 1.4 to JSDT 1.5
    Getting JSDT to Work Through Firewalls
    JDK 1.2 Policy Files for the examples
    How to get the HotJava Browser
    How to get the LRMP Distribution
    How to make jsdt.jar smaller
    JSDT Interest Mailing List
    Trouble Shooting
    More Information on JSDT

Changes in JSDT 1.5

These are the changes between JSDT 1.4 and JSDT 1.5.
    New Features and Improvements.
    API Changes.
    Bugs Fixed.
    Changes to the User Guide.
    Changes to the Examples.

New Features and Improvements.

API Changes.

Bugs Fixed.

Changes to the User Guide.

Changes to the Examples.


Changes in JSDT 1.4

These are the major changes between JSDT 1.3 and JSDT 1.4.
  1. Added Manageable.getSession()
  2. Added a Client parameter to the ByteArray.setValue() methods.
  3. Added a new PortInUseException(). This can be thrown by:
  4. Internationalized all the text strings.
  5. Added a check for a hostname name of "localhost" in the JSDT URL Strings, and if found, resolved it to the real local host name before it gets bound in the Registry.
  6. Adjusted the JSDT User Guide to reflect these API changes.
  7. Expelling a Client from a Channel was not sending out the ChannelEvent.LEFT and ChannelEvent.CONSUMER_REMOVED events.
  8. Trying to release() a Token you hadn't grabbed or inhibited caused a NullPointerException.
  9. For the socket or LRMP implementations, if an exception is thrown inside any of the JSDT user callbacks, it is now caught, and an error message is printed out. These user callbacks are:
  10. It was possible for the Session.close() operation to hang waiting for a reply that was lost.
  11. Token.give() would fail with PermissionDeniedException due to incorrect security checking.
  12. Using the LRMP implementation sometimes gave a ClassCastException when creating a managed Session.
  13. Killing a Client that was grabbing a Token, was not causing the Token's status to be reset correctly.
  14. Due to a thread timing issue, it was possible to hang JSDT on a Windows platform doing two Session.createChannel() calls in a row to a managed Session, when everything was running in the same VM.
  15. Doing a Token.test() on a token that no longer existed resulted in a hang.

Changes in JSDT 1.3

These are the major changes between JSDT 1.2 and JSDT 1.3.
  1. Added Channel.listConsumerNames()
  2. Added Token.listHolderNames()
  3. Channel.receive() and Channel.dataAvailable() now take a Client parameter
  4. New ClientFactory class
  5. Authentication is now done with Java objects rather than String values
  6. SessionListener and SessionAdaptor did not have a sessionDestroyed() method
  7. Added an alternate SessionFactory.createSession() method
  8. Added Manageable.isManaged()
  9. Added Channel.receive(Client client, long timeout)
  10. Significant speedups to the socket implementation
  11. Various JSDT User Guide updates
  12. Error messages are now written to System.err
  13. Added extra checks on certain operations to prevent Client spoofing.
  14. With the socket implementation if you tried to set two or more consumers from a single channel proxy, it would not work correctly
  15. If a client left a channel and it was consuming that channel, then no CONSUMER_REMOVED channel event was ever sent
  16. The socket implementation (hopefully) no longer hangs under very heavy loads
  17. If a Client subclasses ClientAdaptor, it no longer gets a java.lang.ClassCastException when an attempt is made to send it a ClientEvent.
  18. With the socket implementation it was possible for multiple TCPSocketServer objects to be instantiated, each waiting for messages on the same port.
  19. Incorrectly specifying the JSDT Session URL could cause a NullPointerException
  20. If Data is sent on a Channel that is no longer valid (the Client has left the Session), there is no longer a NullPointerException. It now correctly throws a NoSuchClientException
  21. Inhibiting a token was not correctly sending a tokenGrabbed() event to token listeners

Changes in JSDT 1.2

These are the major changes between JSDT 1.1 and JSDT 1.2.
  1. Release includes a JSDT User Guide.
  2. JSDT API JavaDoc now generated using the new JDK1.2beta3 version of javadoc, which results in much nicer output.
  3. ChannelListeners can now be notified when ChannelConsumers are added or removed from a Channel.
  4. Added a new ConnectionException that gets thrown when some kind of network error has occured when two components within a JSDT collaboration have failed to communicate with each other. This affects most methods in the JSDT API.
  5. Channel.sendToClient() now also throws NoSuchConsumerException.
  6. SessionFactory.sessionExists() now also throws NoSuchHostException.
  7. By default, no error messages will be output. Added debugging flags for displaying these error messages and stack traces. See the FAQ for details of how to turn these on.
  8. With the LRMP implementation; if the proxy-side and server-side connections are in the same VM, then JSDT uses direct method calls (rather than an LRMP session), to talk between the two, yielding a vast speedup.
  9. Added a new getSession() method to the AuthenticationInfo class which will return the name of the Session associated with this authentication operation.
  10. Added more documentation of getting LRMP.
  11. Added better documentation to describe what the AuthenticationInfo class getName() method will return.
  12. Fixed NullPointerException with SessionFactory.sessionExists() if this method was called before a SessionFactory.createSession() call had been made.
  13. Much better cleanup when a JSDT application terminates.
  14. The Data.getChannel() method now returns the Channel value.
  15. The AuthenticationInfo.getType() method now returns the correct value.
  16. Removing a listener didn't work correctly if there was already more than one listener associated with that JSDT object.
  17. All the threads that JSDT creates are now explicitly named to aid in debugging.
  18. Fixed up all the deprecated methods.

Changes in JSDT 1.1

These are the major changes between JSDT 1.0 and JSDT 1.1.
  1. Release includes an LRMP (light-weight reliable multicast protocol) implementation of JSDT.
  2. Release includes an RMI (remote method invocation) implementation of JSDT.
  3. Naming.list() no longer throws NoSuchHostException.
  4. Naming.list() no longer throws a NullPointerException if there are no Sessions or Clients registered with the JSDT Registry.
  5. Added a DESTROY_SESSION action to AuthenticationInfo.java.
  6. Added a Session.close() method to allow a client to terminate their session connection.
  7. Implemented Session.destroy().
  8. With the socket implementation; if the proxy-side and server-side connections are in the same VM, then JSDT uses direct method calls (rather than a socket), to talk between the two, yielding a vast speedup.
  9. The Token grab() method also needed to throw PermissionDeniedException.
  10. The Manageable interface needed to extend Serializable.
  11. Added a RegistryFactory class to start/check the Registry, independent of implementation type.
  12. Added a new RegistryExistsException exception class.
  13. Added a SessionFactory.sessionExists(String url) method.
  14. Fixed NullPointerException problem if a Client used Channel.sendToClient() to send Data to a Client that did not have a Consumer for that Channel.
  15. Tested JSDT against JDK 1.2(beta3).

Changes from JSDA

JSDA was the predecessor to JSDT. These are the major differences between the last released version of JSDA and JSDT 1.0
  1. Package name is now com.sun.media.jsdt
  2. Session and Client URLS now start with jsdt: rather than coll:
  3. Rather than having a single Exception class, there is now a separate class for each type of JSDT Exception that can be thrown
  4. ByteArrays, Channels, Sessions and Tokens are now defined in interface files rather than classes, to separate the definition from the implementation
  5. The shared primitives (Boolean, Integer, Long, Float, Double, String) have been removed
  6. Observers are now Listeners
  7. Uses a JDK 1.1 event model. Events are in a separate com.sun.media.jsdt.event package. Event Listeners and Adaptors are provided for ByteArray, Channel, Client, Session and Token events
  8. ByteArrays are now extended from the Manageable class, and are peer objects to Channels and Tokens
  9. Users should implement Client and ClientListener if they want to receive ClientEvents for notification of invitation to and expulsion from ByteArrays, Channels, Sessions and Tokens
  10. When you create an unmanaged ByteArray, Channel or Token you have the option to automatically join it
  11. New methods in the Session class allow you to determine if a ByteArray, Channel or Token exists, and which ByteArrays, Channels and Tokens you have already joined
  12. The various uniformSend methods have been removed from the Channel class. The state of the reliable and ordered flags when the Channel is created indicate whether Data sent over the Channel with be uniformly sent
  13. Rather than having destroyChannel and destroyToken methods on the Session class, there is now a destroy method on the Manageable class that works for ByteArrays, Channels, Sessions and Tokens

Migrating from JSDT 1.4 to JSDT 1.5

JSDT 1.5 has introduced several new methods, and deprecated several others. This section is provided to help you adjust your code to use these new methods.

    The URLString class.
    New Exceptions.
    Creation of ByteArrays.
    Getting and Setting Values in Data and ByteArray Objects.
    New Functionality.
    Configurable Options.

Note that you should just be able to run your JSDT 1.4 applications and applets against JSDT 1.5, but when you go to recompile, you will notice that some of the methods you are using have been deprecated. Over time, you should adjust your code to use the non-deprecated methods. The deprecated methods will probably be removed from a future JSDT release.

These API changes are not gratuitous. They've been done to:

The URLString class.

This new class has been provided to encapsulate the way a JSDT URL String is created.

The JSDT 1.4 approach was something like:

    String  url = "jsdt://stard.eng.sun.com:7777/socket/Session/chatSession";
    Session session = SessionFactory.createSession(client, url, true);
    

The simplest JSDT 1.5 approach would be:

    String  url = "jsdt://stard.eng.sun.com:7777/socket/Session/chatSession"; 
    Session session = SessionFactory.createSession(client, new URLString(url), true);
    

Typically the URL String is made up of several parts. A static method on the URLString class is providing to make construction of one of these URLStrings easier.

The JSDT 1.4 approach was something like:

    String  url = "jsdt://" + host + ":" + port + "/" + type + "/Session/" + name;
    Session session = SessionFactory.createSession(client, url, true);
    

Now with JSDT 1.5, you would do:

    URLString urlString = URLString.createSession(host, port, type, name);
    

Methods in SessionFactory, ClientFactory and the Naming classes have been provided to use URLString.

New Exceptions.

Two new exceptions have been introduced: These new exceptions are thrown by most methods in the JSDT API.

If you typically have something like:

        try {
	    ... JSDT method call ...
        } catch (JSDTException e) {
	    ... handle exception ...
        }
        

then you should not have to make any changes to your code. If on the other hand, you individually catch each exception that a method can throw, then you will have to add in catch clauses for these new exceptions.

The exceptions are there to help you, so there might be some specific action you now would like to do if these new exceptions are thrown.

Creation of ByteArrays.

The way ByteArrays are created has been changed in JSDT 1.5 to be consistent with the way Channels and Tokens are created. It's now a two step process; you create the bytearray, then set the value.

In JSDT 1.4, you would have had something like:

        try {
            byteArray = session.createByteArray(client, name, value, true);
        } catch (JSDTException e) {
            ... handle exception ...
        }
        

In JSDT 1.5, this is now:

        try { 
            byteArray = session.createByteArray(client, name, true);
	    byteArray.setValue(value);
        } catch (JSDTException e) { 
            ... handle exception ...
        }
        

If there was no ByteArray with this name already created, then it is initially created with a zero-filled byte array of length 1. If the ByteArray did exist, the proxy is returned the current value (as with JSDT 1.4), which can be then be retrieved with one of the new ByteArray getValueXXX() methods.

Getting and Setting Values in Data and ByteArray Objects.

Methods have been added to the Data and ByteArray classes, to make it easier to handle Strings and Java objects.

In JSDT 1.4, for converting a Java object into serialized form, and storing as a byte array within a Data object, you would have done:

    Object object = ... some Java object ...;

    try {
        ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
        ObjectOutputStream    oos  = new ObjectOutputStream(baos);

        oos.writeObject(object);

        Data data = new Data(bos.toByteArray());
    } catch (Exception e) {
        ... handle exception ...
    }
    

In JSDT 1.5, to achieve the same result, you would do:

    Object object = ... some Java object ...;
 
    try {
        Data data = new Data(object);
    } catch (Exception e) { 
        ... handle exception ... 
    }
    

After being sent over a Channel, with JSDT 1.4, you could unmarshall the byte array stored in the Data object, back into a Java object with:

    try {
        Data                 data;
        ByteArrayInputStream bais   = new ByteArrayInputStream(data.getData());
        ObjectInputStream    ois    = new ObjectInputStream(bais);
        Object               object = ois.readObject();
        ois.close();
	bais.close();
    } catch (Exception e) { 
        ... handle exception ... 
    }
    

The equivalent JSDT 1.5 code is now:

    try { 
        Data   data;
	Object object = data.getDataAsObject();
    } catch (Exception e) {  
        ... handle exception ...  
    }
    

A similar approach can now be used for setting and getting Java objects to/from ByteArrays too.

New Functionality.

These are the completely new methods that have been introduced in JSDT 1.5.

Configurable Options.

The following variables are available to allow you to adjust the way each implementation operates. These variables are described more fully in the new Implementations chapter in the User Guide, including details of exactly which implementation each variable is applicable to. They should be set right at the beginning of your JSDT application.
/** Use for debugging purposes. Set to true to print a message when
 *  an unexpected exception occurs.
 */  
    public static boolean showMessage = false;


/** Use for debugging purposes. Set to true to print a stack trace when
 *  an unexpected exception occurs.
 */  
    public static boolean showStack = false;


/** The time to wait (in milliseconds) for Token give() operations. */
    public static int giveTime = 15000;


/** The number of milliseconds to wait for a reply from the server. */
    public static long timeoutPeriod = 15000;


/** The number of milliseconds to wait before pinging the server to see
 *  if there are any asynchronous messages buffered there which need to
 *  be retrieved. Used by the HTTP implementation.
 */  
    public static long pingPeriod = 500;


/** The number of seconds to attempt to try to start the Registry. */
    public static int registryTime = 60;


/** The maximum size of the message queue. */
    public static int maxQueueSize = 15;


/** The maximum thread pool size. */
    public static int maxThreadPoolSize = 5;


/** The time-to-live for LRMP packets. */
    public static int TTL = 15;


/** The factory class for creating sockets for the "socket" implementation
 *  of JSDT.
 *
 *  For TCP sockets, this should be set to:
 *  "com.sun.media.jsdt.socket.TCPSocketFactory"
 *
 *  For SSL sockets, this should be set to:
 *  "com.sun.media.jsdt.socket.SSLSocketFactory"
 */
    public static String socketFactoryClass =
                               "com.sun.media.jsdt.socket.TCPSocketFactory";


/** The cipher String to use with SSL sockets. */
    public static String SSLCipher = "SSL_DH_anon_WITH_RC4_128_MD5";


/** The port number the Registry should run on. */
    public static int registryPort = 4561;


/** The multicast Registry address to use with the LRMP implementation. */
    public static String registryAddress = "224.1.2.3";

/** The port number to use, to contact the HTTP proxy server. */
    public static int httpTunnelPort = 80;

Getting JSDT to Work Through Firewalls

Many intranets have firewalls which do not allow a direct connection to the Internet. If the JSDT HTTP implementation cannot establish a direct TCP socket connection, it provides two forms of HTTP-tunneling, tried in order:

In http-to-port tunneling, we attempt an HTTP POST request to a http: URL directed at the exact hostname and port number of the target server. The HTTP request contains a single JSDT request. If the HTTP proxy accepts this URL, it will forward the POST request to the listening JSDT server, which will recognise the request and unwrap it. The result of the call is wrapped in an HTTP reply, which is returned through the same proxy.

Often, HTTP proxies will refuse to proxy requests to unusual port numbers. In this case, we will fall back to http-to-cgi tunneling. The JSDT request is encapsulated in a HTTP POST request as before, but the request URL is of the form http://hostname:80/cgi-bin/java-jsdt.cgi?port=n (where hostname and n are the hostname and port number of the intended server). There must be an HTTP server listening on port 80 on the server host, which will run the java-jsdt.cgi script (supplied with the JSDT distribution), which will in turn forward the request to a JSDT server listening on port n. JSDT can unwrap a HTTP-tunneled request without help from a http server, CGI script, or any other external entity. So, if the client's HTTP proxy can connect directly to the server's port, then you don't need a java-jsdt.cgi script at all.

Note that you can set an alternate HTTP proxy port using the com.sun.media.jsdt.impl.JSDTObject.httpTunnelPort variable (see Section 8.6.2, of the JSDT User Guide for more information.

If you are running a web server that is capable of running Java servlets, then you can alias the "/cgi-bin/java-jsdt.cgi" script to a Java servlet class called com.sun.media.jsdt.http.ServletHandler which is also included with the JSDT distribution. This is much faster that a CGI script.

Note that the http-to-cgi method opens a dramatic security hole on the server side, since without modification it will redirect any incoming request to any port.

Configuring the CGI script.

The following two files from your JSDT distribution need to be put in the web servers cgi-bin directory: Make sure the java-jsdt.cgi script has execute permission by the web server.

Configuring the Java servlet.

These instructions are written under the assumption that you will be using JavaWebServer1.1.

To run the ServletHandler perform the following steps:

  1. Install the servlet class files:
  2. Configure the servlet using the webserver's administration utility:

JDK 1.2 Policy Files for the examples

JDK 1.2 contains substantial security features and enhancements. They include security policy files. The minimal policy files to run the examples included with the JSDT distribution are included here.

For a good tutorial on creating policy files, see: http://java.sun.com/docs/books/tutorial/security1.2/tour1/index.html

This is the policy file for the Chat example when run as an applet.

  grant {
      permission java.lang.RuntimePermission "modifyThread";
      permission java.lang.RuntimePermission "modifyThreadGroup";
      permission java.net.SocketPermission "*:1024-", "connect,accept";
  };
  

This is the policy file for the WhiteBoard and Stock examples when run as applets.

  grant {
      permission java.lang.RuntimePermission "modifyThreadGroup";
      permission java.lang.RuntimePermission "modifyThread";
      permission java.net.SocketPermission "*:1024-", "connect,accept";
      permission java.io.FilePermission "<>", "read";
  };
  

This is the policy file for the Sound example when run as an applet.

  grant {
      permission java.lang.RuntimePermission "modifyThreadGroup";
      permission java.lang.RuntimePermission "modifyThread";
      permission java.net.SocketPermission "*:1024-", "connect,accept";
      permission java.io.FilePermission "<>", "read";
      permission java.lang.RuntimePermission "accessClassInPackage.sun.audio";
  };
  

This is the policy file for the Ppong example when run as an applet.

  grant { 
      permission java.lang.RuntimePermission "modifyThreadGroup"; 
      permission java.lang.RuntimePermission "modifyThread"; 
      permission java.net.SocketPermission "*:1024-", "connect,accept";
      permission java.lang.RuntimePermission "accessClassInPackage.sun.audio"; 
  };
  

How to get the HotJava Browser

The top-level runme file launches HotJava to browse the JSDT setup html page. If you haven't already got HotJava, then you can download it from here.

How to get the LRMP Distribution

If you are going to use the LRMP implementation of JSDT, then you will need to get a copy of the Inria LRMP distribution, which can be downloaded from here.

How to make jsdt.jar smaller

With this release, the jsdt.jar file contains four implementations (socket, LRMP, RMI and HTTP). This has increased the size of the file quite dramatically. If you know you are only going to be using one implementation, then you might wish to unpack this file, remove the implementations you don't want, and jar it up again.

If you don't want the socket implementation, remove the com.sun.media.jsdt.socket directory.
If you don't want the LRMP implementation, remove the com.sun.media.jsdt.lrmp directory.
If you don't want the RMI implementation, remove the com.sun.media.jsdt.rmi directory.
If you don't want the HTTP implementation, remove the com.sun.media.jsdt.http directory.


JSDT Interest Mailing List

There is a mailing list for people interested in the JSDT. It is:
 
  jsdt-interest@Sun.COM

In order to subscribe to the jsdt-interest list now, you should send mail to
 
  javamedia-request@Sun.COM

with the message body (not the subject) containing:
 
  subscribe jsdt-interest

To unsubscribe, the body needs to read:
 
  unsubscribe jsdt-interest

Note this is javamedia-request@sun.com *NOT* jsdt-request@sun.com. This is in line with the other javamedia aliases.

The JSDT alias is now being managed by majordomo. For those of you not familiar with majordomo, here are a few notes:

The common commands you can give in the body of the email to javamedia-request@sun.com are:
 
  lists (gives you a list of aliases maintained by majordomo)
  info (returns information about the alias)
  subscribe
  unsubscribe
  help (help on the commands available)

New versions of the JSDT are announced on the mailing list, plus active discussion on problems with and ideas for enhancements to the JSDT.

The JSDT mailing list archives (in hypermail format) are available here.


Trouble Shooting

No DOS Environment Space Under Windows 95

Under Windows 95, you might need to increase the environment space to enable the example Run commands to work. There is an easy way to increase your DOS environment space for ALL DOS programs. Add or modify this line to your config.sys file (typically on c:\):
shell=c:\windows\command.com c:\windows /p /e:4096

Problems Running The LRMP Implementation

Running the LRMP implementation of JSDT requires that you have installed LRMP on your machine and have the LRMP lib/webcanal.jar file added to your CLASS_PATH. See an earlier entry in these Release Notes on how to get the LRMP distribution.

More Information on JSDT

There is a home page for JSDT at:
http://www.sun.com/software/jsdt.

A FAQ (Frequently Asked Questions) document can be found here.