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 as displayed in the Enterprise Manager's BBj Services > Java > Classpath display. A parent SSCP will be expanded in place to a list of its JAR files.

  • SSCPs can include other SSCPs by adding them through the Enterprise Manager.

  • 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. By default, it contains only the bbj_internal classpath.

  • 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.

For more information on the updates to SSCPs in BBj 19.10, see the Knowledge Base article Migrating to BBj 19.10.

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 bbj_internal, 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 an 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 an 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().

In BBj 19.10 and higher, it is possible for separate SSCPs to share object and variable definitions if they inherit the definition from the same parent SSCP.

Dependence on bbj_internal

Prior to BBj 19.10, all BBj interpreter sessions, including those that specified an SSCP, inherited the classpath that BBj used internally by default. Now, BBj’s JAR dependencies are captured in the bbj_internal SSCP. The bbj_internal SSCP identifies the BASIS JARs that BBj requires. It also captures BBj’s third-party dependencies by including the BBjIndex.jar and ExtIndex.jar files.

Some SSCPs created before 19.10 may now require explicit inclusion of JARs found in the bbj_internal SSCP. For these SSCPs to continue to function as expected, it may suffice for you to manually set the bbj_internal SSCP as the parent SSCP. This will allow your classpath to continue inheriting all of the JARs used by BBj.

However, it is strongly recommended that you determine the specific JARs that your SSCP depends on and include them separately, in order to avoid any direct dependence on bbj_internal. The bbj_internal SSCP can change without warning as BASIS updates, removes, or adds JAR files as necessary for internal use.

Using bbj_default

The bbj_default SSCP is the default classpath used when no classpath is specified and is entirely configurable and customizable. By default, its value is set to bbj_internal as the first and only entry so that it inherits the JARs from bbj_internal as its parent. This is purely a convenience for backward compatibility, and it is not necessary to continue to use bbj_internal within the bbj_default definition if you do not rely on it.

If you work with different SSCPs for different applications, bbj_default may serve as a convenience during development by allowing you to change its value on-demand depending on which SSCP you are currently working with. In such a case, it is easiest to maintain separate custom SSCPs and to simply set the parent of bbj_default to the SSCP you are working with, so that bbj_default is a copy of that SSCP. This method allows you to change the default SSCP quickly.

If you only need or use a single SSCP, bbj_default can also be edited directly to include the JARs you need without creating any other SSCPs.

Using a Different Version of a JAR

You may wish to use the JARs from bbj_internal (or another custom SSCP) but change one or more of them to use a different version. In a case like this, it is important to know that SSCPs are loaded sequentially in such a way that the first occurrence of a JAR will take precedence over any later ones. This means that you may first include the JAR file you wish to use, and then include bbj_internal after it. The JAR file you specified will overrule the one specified within bbj_internal, and the rest of the JARs will still be included.

However, note that since bbj_internal is not the first entry, it will no longer be the parent of this SSCP, which can cause namespace issues if you are attempting to share objects or functions between programs that use separate SSCPs.

Superseded: SSCPs Before 19.10

Pre 19.10: 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.

Pre 19.10: 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.