# Organizing Program Compiled Objects

Updated: 10/19/2020, 10:24:56 AM
Created: 10/19/2020, 10:24:56 AM
Last Updated By: Daniel Klein
Read Time: 9 minute(s)

# Flexibility is a Dual-Edged Sword

jBASE is wonderful in the way that it allows the administrator to have a high-degree of control of his development and deployment scheme.  Unlike traditional MultiValue environments, jBASE really allows the system architect to layout the system structure any way he/she wishes.

But, as with all things flexible, care must be taken not to inadvertently back yourself into a corner.  For developers and administrators coming to jBASE from mainstream development environments, this article will be a yawner.  But if you come from a Pick background, you may be accustomed to working in a fenced environment where you don't have to worry about these structure issues.

# Where does the Compiled Object Go?

In traditional MultiValue systems, when you compile and catalog your programs, object code is placed into a location that is associated with your source code file.  For example, on legacy Pick systems, the compiled object for a source item is usually placed into the dictionary of the source code file.  On systems such as Universe, a directory named <sourceCodeFile>.O  (note the .O meaning object) is created by the uniVerse basic compiler and the object is placed there.    The developer usually does not need to know where the object is stored because the commands used to invoke (run) the program understands this structure and will automatically locate the object.

But this does complicate the process of sharing code because now, you must create pointers to all of the object repositories in each account where you wish to run the code.  Pick developers take this for granted but developers in the outside world usually pack their objects from many source repositories into single object stores that are shared via pathing.  This makes the distribution of software simpler.  jBASE prefers to use the modern method of object distribution but in doing so, it can be a little confusing at first to the Pick developer.  This article attempts to explain the basics of how jBASE creates and finds objects and it delves into the topic of what pitfalls the Pick programmer transition to jBASE may encounter.

# jBASE is Configured by Environment Variables

Two environment variables control most of what BASIC and CATALOG will do with resultant compiled code.

JBCDEV_BIN
JBCDEV_LIB
1
2

# The jBASE SYSTEM File

The two environment variables mentioned above are normally set to a bin and lib path that is appropriate for the account in which the code lives.  For example, if you have an account defined in the jBASE SYSTEM file called ACCOUNT-A, you might see entries within that SYSTEM record that define the value to be assigned to JBCDEV_BIN and JBCDEV_LIB.   When you execute a LOGTO, the SYSTEM file item for that account is read and a slew of environment variables are set.  More information on system file here.

 001 Type
 002 Absolute Account Path
 003 Reserved
 004 Reserved
 005 Reserved
 006 Reserved
 007 Encrypted Password (optional)
 008 Reserved
 009 Reserved
 010 Reserved
 011 Optional Parameters for LOGTO (use attributes 20 through 37 on jBASE 4 and jBASE 5)
 012 - 019 Reserved
 020 ESYSTEM_START
 021 JBCEMULATE
 022 HOME
 023 JBCDEV_BIN
 024 JBCDEV_LIB
 025 PATH
 026 JBCOBJECTLIST
 027 JEDIFILEPATH
 028 JEDIFILENAME_MD
 029 JBC_TCLRESTART
 030 JBC_ENDRESTART
 031 JBCRESTARTPROG
 032 JBCLOGINPROG
 033 Reserved
 034 JBASE_I18N
 035 JBCPORTNO (multi-valued range)
 036 OTHER ENVIRONMENT VARIABLES (multi-valued)
 037 ESYSTEM_END
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

Attributes 23 and 24 of the SYSTEM file entry for the account will contain the values that should be placed into these environment variables.

So, if you LOGTO ACCOUNT-A, then these environment variables will be set properly.

That means that when you compile/catalog code, the resulting bins and shared objects that are generated by that process will be placed into those two directories.  If we LOGTO to ACCOUNT-A and we have a BP file called BP, then we would do

CATALOG BP <programName>
1

and it would generate executables to the value of JBCDEV_BIN or JBCDEV_LIB defined in the SYSTEM record for that ACCOUNT.

# What if Profile scripts are used rather than Logto and System file?

Some jBASE installations don't use the SYSTEM file at all and they set all of their environment variables by using conventional profile scripts or configuration managers that are executed at login.  If you are one of those users, then remember that the basics of what we will discuss in this article are the same but the mechanism used for setting those environment variables may have nothing to do with the SYSTEM file.  The SYSTEM file in jBASE is really a helper to allow PICK administrators to more easily manage the unix-level environment variables.  However, at the end of the day, regardless of whether you use SYSTEM file or do it yourself using scripts, environment variables are set and these control the behavior of jBASE.

# Our Example Environment

For the purposes of our discussion, we'll assume a structure where we have two accounts called ACCOUNT-A and ACCOUNT-B.  We will have a source directory that lives in ACCOUNT-A on the path /dbms/ACCOUNT-A/BP.

Here are excerpts from the SYSTEM file for both of these accounts:

# Account-A

0023 /dbms/ACCOUNT-A/bin
0024 /dbms/ACCOUNT-A/lib
1
2

# Account-B

0023 /dbms/ACCOUNT-B/bin
0024 /dbms/ACCOUNT-B/lib
1
2

If we contrast what would happen in most Pick implementations vs. jBASE (using the above configuration), the behavioral differences will become apparent:

Let's also assume that we have a Q-POINTER in ACCOUNT-B called BP that points to the BP source directory in ACCOUNT-A.

Command What happens on Pick What happens on jBASE
LOGTO ACCOUNT-A Reads system file and initializes TCL on that account location Reads SYSTEM file and initializes environment variables based on values stored in the SYSTEM file record of that account name and cd's you to the account path.
BASIC BP TESTPROGRAMCATALOG BP TESTPROGRAM Reads the source item, runs it though the compiler, generates object in DICT BP or BP.O and places a record in MD or VOC for the program object Reads the source item, runs though transpile to C, invokes native C Compiler to produce object which is placed in path JBCDEV_BIN (/dbms/ACCOUNT-A/bin) and/or JBCDEV_LIB (/dbms/ACCOUNT-A/lib).  No record written to MD/VOC.
TESTPROGRAM Looks up record called TESTPROGRAM in VOC/MD, locates object, executes object. Scans PATH environment variable to find TESTPROGRAM in one of the directories named in PATH then execs that object.

In the above example, all is fine in ACCOUNT-A.  The objects are properly placed into /dbms/ACCOUNT-A/bin and /dbms/ACCOUNT-A/lib.

So, now you say "Well, I'd like to be able to run that program from Account-B".  You go about your normal Pick way of doing that by:

  • LOGTO ACCOUNT B
  • Setup a Q-pointer to ACCOUNT-A BP calling it BP
  • CATALOG BP TESTPROGRAM

And it works!  Or so it seems....

But look at what really happened:

Command What happens on Pick What happens on jBASE
LOGTO ACCOUNT-B Reads system file and initializes TCL on that account location Reads SYSTEM file and initializes environment variables based on values stored in the SYSTEM file record of that account name and cd's you to the account path.
CATALOG BP TESTPROGRAM Writes a MD/VOC item called TESTPROGRAM Produces object which is placed in path JBCDEV_BIN (/dbms/ACCOUNT-B/bin) and/or JBCDEV_LIB (/dbms/ACCOUNT-B/lib).  No record written to MD/VOC.
TESTPROGRAM Looks up record called TESTPROGRAM in VOC/MD, locates object, executes object. Scans PATH environment variable to find TESTPROGRAM in one of the directories named in PATH then execs that object.

# So what's the problem, it works doesn't it?

Well, yes it does.  But as you can see, we've generated additional duplicate objects in /dbms/ACCOUNT-B/bin and /dbms/ACCOUNT-B/lib.  The problem comes down the line when you go back and make a change to TESTPROGRAM while in ACCOUNT-A expecting (as it does on Pick) that the run program in ACCOUNT-B will automatically pickup the change you made in ACCOUNT-A.  Of course, this isn't going to happen until you LOGTO ACCOUNT-B and re-catalog the object to update ACCOUNT-B's copy of the object.

This has a number of issues:

  1. People will forget to update the OBJECT in ACCOUNT-B
  2. You get no benefits of shared code across accounts because you're running separate objects in each account
  3. It is primed for someone to make a collossal mess because there is no mechannism in place to ensure that the updates are properly pushed.

On the other hand, the benefits are that this might be desirable in a TEST account where you would be assured that compiling in the test account would not alter the production bins and libs.

If your organization wishes to keep with the "Pick" way of doing things then there are certain configuration best practices that should be followed.

# But how do we Make Code in Account-A run in Account-B?

The proper way to accomplish this is to simply update the PATH and JBCOBJECTLIST attributes in ACCOUNT-B's SYSTEM record adding the bin path

 025 PATH
 026 JBCOBJECTLIST
1
2

Example of ACCOUNT-B's SYSTEM entry BEFORE sharing ACCOUNT-A's bin and lib directories

 025 /dbms/ACCOUNT-B/bin
 026 /dbms/ACCOUNT-B/lib
1
2

Example of ACCOUNT-B's SYSTEM entry AFTER sharing ACCOUNT-A's bin and lib directories

# For Linux/UNIX Systems

 025 /dbms/ACCOUNT-B/bin:/dbms/ACCOUNT-A/bin
 026 /dbms/ACCOUNT-B/lib:/dbms/ACCOUNT-A/lib
1
2

# For Windows Systems

 025 /dbms/ACCOUNT-B/bin;/dbms/ACCOUNT-A/bin
 026 /dbms/ACCOUNT-B/lib;/dbms/ACCOUNT-A/lib
1
2

# Note

UNIX/Linux uses colon as a separator whereas Windows uses semi-colon

We have added a colon delimiter followed by the path to the bin (or lib) directory in ACCOUNT-A where our object in ACCOUNT-A.  So, there is no need to catalog anything in ACCOUNT-B, it will just automatically search the paths and find the objects.  So, the task is to modify the SYSTEM file entries so that other accounts have visibility to the objects of the account(s) where the code lives.  Pretty simple and a WHOLE lot easier and more flexible (but different) than how we have done things in Pick.  But the change is very worth while.

Back to Coding Corner