Session-Specific Classpath (SSCP)

Overview

A Session-Specific Classpath (SSCP) is an alternate classpath that a BBj session can use. They provide the administrator with the ability to make different libraries available to different interpreters based on specific application requirements. A unique name identifies the SSCP and can be defined either in the Enterprise Manager or by invoking methods on BBjAPI. Simply specify the name of the SSCP when starting a new BBj session, either from the command line (with "-CP<SSCP_Name>") or using BBjCommandLineObject.setClasspathName().

Introduction

BBj 9.0 introduced Session-Specific Classpaths (SSCPs) to allow a BBj session to use Java classes that are not found in the BBjServices classpath. Prior to BBj 9.0, all BBj sessions shared the classpath of BBjServices, which meant that it was not possible to add a class to a BBj session without restarting BBjServices.

BBj 19.10 introduced an updated ClassLoader, which brought with it the following updates and improvements to SSCPs:

  • SSCPs can specify a single parent SSCP, allowing them to have a hierarchical structure. A parent must be the first entry in an SSCP definition, and is specified as the SSCP name enclosed in parentheses, like so: (<parent_sscp_name>). This will be expanded in place to include the definition of the parent SSCP.

  • SSCPs can include other SSCPs with the same syntax used for defining a parent (the SSCP name enclosed in parentheses), if the entry is not the first entry.

  • SSCPs can include wildcard syntax in their definitions. An asterisk (*) will match all .jar or .JAR files within the specified directory (including hidden files beginning with '.'). Files in subdirectories will not be included, so each subdirectory must be specified separately. The order of the files is not specified or guaranteed; if a specific order is needed then the files should be listed individually. Class files will not be included in the wildcard expansion, but can be included as a separate entry by specifying the directory name without the wildcard character.

  • The bbj_default SSCP is the SSCP used by default, when the -CP<SSCP> argument is not specified when running the BBj Interpreter. This special SSCP is fully configurable. Its default value is (bbj_internal).

  • The bbj_internal SSCP contains the classpath used by BBj internally. It is not configurable by the user, but may be included in other classpaths to easily add the bundle of JARs defined within it.

Use Cases for an SSCP

SSCPs can be used for the following use cases:

  • When developing user-defined Java classes, SSCPs make it possible to modify those classes and test the modifications without restarting BBjServices.

  • SSCPs allow for two BBjSessions to run with different versions of user-defined Java classes.

  • For the libraries provided by the ExtIndex.jar, it is possible for a particular BBjSession to use a different version of that library than the version that is provided by the BBj install.

Creating or Modifying an SSCP

Using Enterprise Manager in Eclipse

For information on how to create and/or modify an SSCP, go to the 'Java Classpath Settings' section in BBj Services - Java Settings.

To enable/disable 'Recheck Session Classpath', go to the Thin Client Performance section in BBjServices - Settings.

Using BBjAPI

The following is an example of creating an SSCP within the BBjAPI:

admin! = BBjAPI().getAdmin(adminName$, adminPassword$)
env! = admin!.getEnvironment()
vec! = BBjAPI().makeVector()
vec!.add("/dev/testSSCP/AFoo.jar")
vec!.add("/dev/testSSCP/BFoo.jar")
env!.setClasspath("test", vec!)
print env!.getClasspath("test")

Using an SSCP at the Command Line

In BBj 9.0 and later, the command line option -CP<classpathName> specifies which SSCP to use when starting a BBj session. To run the program ATest.bbj using the SSCP whose name is test, use the command line:

bbj –CPtest Atest.bbj

Using an SSCP with BBjAPI::newBBjSession()

An SSCP is used within the BBjAPI by using code similar to the following:

config! = BBjAPI().getConfig()
cmd! = config!.getCommandLineObject()
cmd!.setClasspathName("t")
x = BBjAPI().newBBjSession(cmd!)

Using Enterprise Manager in Java GUI (Deprecated)

Create and/or modify an SSCP from the Classpath tab of the Server Information section of Enterprise Manager. To create a new classpath, click the "plus" next to the "Classpath Names" list. Type a new name in dialog and press [OK]. To modify a classpath, add, remove or change the order of the Classpath entries in the "Classpath Entries" list using the buttons on the right. Click the [Save] button at the bottom of the Enterprise Manager window to save the new or modified SSCP. For more information, see the  Enterprise Manager - Server Information.

Using an SSCP with BBjCpl

To compile and type-check programs that refer to jar files in a SSCP, BBjCpl also accepts a -CPclasspathName option. BBjCpl will use the SSCP configured via either BBjAPI or Enterprise Manager to search for Java class names when compiling and type-checking BBj programs. The following example will type-check the program Atest.bbj without producing any output:

bbjcpl -CPtest -N -X Atest.bbj

Modifying an Existing SSCP

Once a BBj session is started with a particular SSCP, then any changes made to that SSCP will not affect the running BBj session. This is illustrated in the following code that defines an SSCP named test, then starts a BBj session. After starting the BBj session, the SSCP changes, but the BBj session that has already started will not see the changes.

admin! = BBjAPI().getAdmin("admin","admin123")
config! = BBjAPI().getConfig()
env! = admin!.getEnvironment()
rem set the test SSCP
vec! = BBjAPI().makeVector()
vec!.add("/dev/testSSCP/AFoo.jar")
vec!.add("/dev/testSSCP/BFoo.jar")
env!.setClasspath("test", vec!)
rem retrieve a CommandLineObject and set its SSCP
cmd! = config!.getCommandLineObject()
cmd!.setClasspathName("TEST")
rem start a new BBjSession with the TEST SSCP
x = BBjAPI().newBBjSession(cmd!)
rem ==================================
rem modify the tests SSCP
rem the changes in test do NOT affect the program
rem that has already been started
rem ==================================
vec!.add("/dev/testSSCP/CFoo.jar")
env!.setClasspath("test", vec!)

Modifying Jar Files and Reloading an SSCP

If a jar file named foo.jar is contained in an SSCP named test and foo.jar is modified on disk then there are several factors that determine whether a BBjSession that is using the test SSCP will recognize the changes in foo.jar (i.e. whether files will be loaded from the old foo.jar or the newly modified foo.jar).

These factors include:

  • Whether a program calls BBjEnvironment::reloadClasspath(“test”)

  • How the ‘recheck session classpath’ performance setting in Enterprise Manager was set

  • If the BBj session was started before or after the change was made

If any program invokes the method BBjEnvironment::reloadClasspath("test"), then all subsequent BBj processes that use the test SSCP will load classes from the modified jar. It is best to call this method after modifying any jar file that is on any SSCP.

If Recheck Session Classpath is set to “development,” then BBj checks the date of each file on the SSCP every time a new BBj process is started with that SSCP. This means that any new BBj process that use the test SSCP will load classes from the modified jar.

The behavior of BBj sessions that were already running prior to changing foo.jar is system dependent. We recommend that jar files not be modified until all BBj processes that are using a SSCP that includes that jar file are terminated.

SSCP and Static Variables

In Java, a static variable is shared across all instances of a given class. In most cases there is only one class for any given class name within the entire JVM so a static variable is shared across the entire JVM. When using SSCP, this is not always the case. If Foobar.class is found in foo.jar, and foo.jar appears in two different SSCPs named testA and testB, then each SSCP will load a different class object for Foobar. This means that the code running within a BBj session with testA SSCP will have a different class object for Foobar than the code running in a BBj session with testB SSCP. Those BBj sessions will see a different value for any static variable that is in Foobar.

Similarly, if a call is made to BBjEnvironment::reloadClasspath("testA"), then any new BBj sessions that use the testA SSCP will see a different static variable than any BBj sessions that were started with the testA SSCP before the call to reloadClasspath().

SSCP and BASIS Jars

BBj ships with a number of jar files, some of which BBjServices require and some the various demo programs use. The jars that BBjServices require cannot be overridden by jars in an SSCP. These jars are included in the BBjIndex.jar which is included on BBjServices’ classpath. Any class found in a jar on an SSCP will not be loaded if it shares its class name with another class that is found in a jar that BBj requires.

SSCP and the BBjServices Classpath

Classes that are found in jars on an SSCP will override classes that are found in the other jars on the BBjServices classpath, including those indexed with ExtIndex.jar but not those indexed with BBjIndex.jar. This means that if a class found in a jar on the SSCP has the same class name as a class found in a non-required jar that is on the BBjServices classpath, then BBj will use the class from the SSCP.

NOTE: Some third party jars used by BBj cannot be overridden in a session-specific classpath. These jars are indexed with BBjIndex.jar.

Identifying Jars/Classes that are not overridable with SSCP

The classes in the jars indexed by BBjIndex.jar are not overridable with SSCP. To see a list of these jars and the packages they contain, extract the META-INF/INDEX.LIST from the BBjIndex.jar. The following command can be used to extract this file:

> jar xf ${BBjHome}/lib/BBjIndex.jar META-INF/INDEX.LIST

After running the command, the extracted META-INF/INDEX.LIST has entries that look like this:

BasisCharsetProvider.jar
META-INF
META-INF/services
com
com/basis
com/basis/util

Each jar listed is followed by the packages contained within that jar. To see more details on the classes in the jar, use the following command:

> jar tf ${BBjHome}/lib/BasisCharsetProvider.jar
META-INF/MANIFEST.MF
META-INF/
com/
com/basis/
com/basis/util/
com/basis/util/BasisCharsetProvider$BasisCharset.class
com/basis/util/BasisCharsetProvider$BasisCharsetDecoder.class
com/basis/util/BasisCharsetProvider$BasisCharsetEncoder.class
com/basis/util/BasisCharsetProvider.class
META-INF/services/
META-INF/services/java.nio.charset.spi.CharsetProvider
META-INF/BASIS.KEY

This command lists all the classes included in the jar.



______________________________________________________________________________________

Copyright BASIS International Ltd. BBj®, Visual PRO/5®, PRO/5®, and BBx® are registered trademarks.