Variable Initialization in IBM BPM Coaches: Heritage vs. Client-Side

Follow

Several clients have reported finding bugs seemingly related to coach controls automatically initializing variables that were intentionally left uninitialized (null). These cases are actually due to ongoing changes in IBM policy with regard to how BPM itself handles variables bound to coach views and are not arising from the coach view controls themselves.

Background

If you work exclusively with only Heritage Human Services (HHS) or only Client-Side Human Services (CSHS) you are less likely to have noticed any unusual behaviors because these two types of services are (mostly) internally consistent. However, there are differences in behavior when you compare HHS to CSHS: In HHS, variables that are left uninitialized remain null while in CSHS, String, number, and Objects variables that are bound to coach views are automatically initialized as appropriate for their variable type.

Therefore, if you have been working with an IBM BPM system that has been upgraded over time or have recently made a switch from creating HHS to CSHS (or converting older HHS to newer CSHS) then you may have stumbled upon the variable initialization "problem" when a previous approach that relies on null values no longer works as expected.

IBM Policy and Known Issues

Regardless of the desired behaviors, current IBM policy on this issue can be summarized as such:

  1. All variables should be initialized. CSHS will automatically initialize String (""), number (0 or 0.0), and Complex Objects ({}) associated with coach views as appropriate. However, IBM does note that even with this automatic initialization:
    For correct coach modeling, it is recommended that you do not rely on the coach initialization of variables. Instead, you should explicitly initialize all the variables that are bound to the coaches to the appropriate default values. Alternatively, you can make adjustments for the fact that variables might not be initialized after the coach step in the human service.

    To be clear, uninitialized variables used strictly in client-side scripts and not associated with coach view controls will remain undefined.
  2. HHS, while not fitting the above paradigm, will remain unchanged and variables will not be automatically initialized:
    ...[V]ariable initialization used by Coaches in HHS and CSHS ... are as designed. There is [sic] currently no plans to change these behaviors since both have been in place for many releases.

 There are, however, a couple of known issues:

  • Version 8.5.0.2 of IBM BPM shows automatic initialization of variables in HHS. This is not the case for v.8.5.0.1 or any releases after v.8.5.0.2 (so 8.5.6 through 8.5.7 CF201703, as of the time of this writing). This is likely due to JR48321. IBM has no plans to alter this version as other upgrade points are available.
  • CSHS will initialize almost all variables except for lists of Complex Business Objects. The String and number fields of a singular Complex BO will initialize automatically, as do lists of simple variables, but the fields in Complex BO list do not. As the designer, you can, of course, follow IBM's guidelines and explicitly initialize these.

Use Cases for Nulls

An uninitialized variable will be null. In HHS, input fields bound to uninitialized variables will display empty controls (note, examples are shown using stock IBM controls, not Brazos UI controls):

NullBindingsHHS.PNG

However, the same setup in a CSHS shows that numeric values are initialized to zero:

InitializedBindingsCSHS.PNG

What can't be seen in this comparison is that the string value in the HHS is null while it is an empty string ("") in the CSHS. You can run coaches in debug mode or use logging to verify this behavior as well.

There are two main use cases in which this difference has been utilized:

  1. A developer can check if a user has entered any value in addition to any validation against the specific value. This is usually more of an issue with numeric values but may have use cases involving strings as well.
    • When null values are allowed (HHS), a null check can be used to determine if a user purposefully entered a given value (binding is no longer null) or if they skipped a required field (binding is still null).
    • With CSHS, where values are automatically initialized, the value will never be null. If a zero-value is valid input, then the developer has no immediate method for knowing if a user intentionally entered a zero or if the system simply initialized it to zero.
  2. Zero-values and empty-strings are not programmatically equivalent to nulls, but they may also not be meaningfully equivalent either. This is acknowledged by IBM in iFix JR51185 and has the following example:
    This issue is a problem if these properties
    directly correlate with identity values from a DB2 database.
    
    If you have an optional foreign-key relationship, null values
    are replaced with non-null values when returning data to the
    database. For example, if you have a table (EMPLOYEES) with a
    primary key of EMPLOYEE_ID (INTEGER) that you retrieve data from
    and that table has an optional foreign key to EMPLOYEES
    MANAGER_EMPLOYEE_ID (INTEGER), a null value for
    MANAGER_EMPLOYEE_ID is very different from a MANAGER_EMPLOYEE_ID
    of 0.

Recommendations and Requests for Enhancement

We recommend against relying on any "unstable" behavior or one that could be considered an unintended side effect. Therefore, we broadly support the position of IBM that values should be initialized and recommend that designers explicitly initialize variables in CSHS to avoid potentially confusing outcomes.

However, we do understand that pain-points exist when having to rework existing application logic. With that in mind, there are some strategies that can be employed when dealing with the change in behavior between HHS and CSHS.

Whether you pursue a process/service redesign or a short-term workaround, we recommend that you focus on the use case and end goal of the data to make sure your approach is appropriate for the actual problem.

Example Workarounds for Testing User Inputs

A generalized use case where a designer may run into issues is with expected but optional inputs. For example, it could be possible to have a customer that has no salary but still has other income. In that case, it may be unusual to have zero salary and so the designer may want to have confidence that rare, zero-value responses are intended and not simply user oversight.

As indicated above, null-checks can fill this role. Ideally, the designer would not rely on these, however, and would design a system for monitoring changes to these input fields (e.g. flags that are toggled when inputs are changed or maybe even when a control gains and looses focus) or to explicitly verify with users unexpected values (e.g. a dialog box with "You entered no salary, please confirm or cancel and correct.").

In cases where an existing application cannot be easily redesigned, a null-check can't be perfectly mimicked, but there are some options. Examples:

  1. If there are invalid numbers, they could be used in place of a null. For example, if negative numbers are not valid inputs, then initialize a default number value to -1 (Integer) or -1.0 (Decimal). User input can then be verified for any value that is >= 0. 
  2. If immediate and direct client-side calculations are not required for a number value, a String could be used to hold number inputs. The default empty string can then be used for checking if a user has entered a value (string != ""). This user experience can be improved in some situations by using the Input Mask configuration options on the Brazos UI Input String control to limit user inputs to numeric values. Of course, if the associated value needs to be an actual number you may want to convert it for later use or data persistence.
  3. A placeholder value can be used for Strings. Typically placeholder text in an input control is "background" text and is not stored in the actual binding. However, a default binding could be used in the string (e.g "Enter value here") which can then be checked against (string != "Enter value here"). This has a slightly awkward user experience, however, since the existing value needs to be manually overridden by the user. 

We have submitted two RFEs with IBM. The first is to ensure consistency in CSHS automatic initialization of coach-vew-associated variables. The second RFE technically goes against IBM and BP3's recommendations but would allow for a "designer beware" parity with HHS when using CSHS. Please feel free to upvote if one or both fit your needs:

Additional Notes

  • Building Coaches (IBM Knowledge Center) references how variables are initialized and the recommendation that they should be explicitly initialized.
  • Booleans associated with coach views are also are automatically initialized in CSHS (to 'false'). However, this is likely to go unnoticed because undefined Boolean values in HHS evaluate to 'false'. We would still recommend that you initialize Booleans as well, so as not to rely on this questionable behavior.
Have more questions? Submit a request

Comments

Powered by Zendesk