Adding Mbo records to a MboSet

In this blog I will show you in detail how to add new Mbo records to a MboSet.

The easy pattern

To do so we will directly start with a simple code example:

woset = session.getMboSet('WORKORDER')
wo = woset.add()
if wo is not None:
    wo.setValue("DESCRIPTION","New Testworkorder")
    wo.setValue("WOPRIORITY", 10)
 
    # Only save if necessary (e.g. Script executed via RMI)
    woset.save()

This is the simplest form of adding a record. At the beginning we need to have a MboSet object stored to the woset variable.
By using the add method woset.add() a new record will be added to an existing MboSet. The record is added at the beginning of the MboSet. If you would like to add the new record to the end of the existing set you can use the woset.addAtEnd() method.

Very important is line 3 to check if we really have created a new object instance. Without that check our wo.setValue(..) method calls would result in Null Pointer exceptions. The wo.setValue method is quite easy to use to set the individual fields in the MboSet. The good thing at this method is that it does not differentiate between datatypes.

The woset.save() method call is a bit special and need some explanation. Depending on the way you run your script you should or should not save the MboSet at the end:

  • In general no saving on object & attribute launchpoints
  • In general no saving in workflow actions
  • In general save in RMI Scripting, in direct invocation or when you act on a dialog button.

But as you can imagine there is no rule without exceptions and you eventually have to trial and error to find the correct usage.

Add Mbo records to multiple MboSet’s using transactions

In the previous example we just added a single record to a single Mbo. What if we wan’t to a add an additional Worklog entry to the new Workorder. What about transaction processing. We only want to create the Workorder together with the worklog entry or fail both. The following script shows such an example:

woset = session.getMboSet('WORKORDER')
wo = woset.add()
if wo is not None:
    wo.setValue("DESCRIPTION","New Testworkorder 3")
    wo.setValue("WOPRIORITY", 10)
 
    worklogset = wo.getMboSet("WORKLOGAPPT")
    worklog = worklogset.add()
    if worklog is not None:
        worklog.setValue("DESCRIPTION", "WLOG Descr.")
        woset.save()
        print "Workorder " + wo.getString("WONUM")  + " created !"

This example is quite similar to the first one. The difference is that we navigate from our newly created workorder Mbo to a Worklog MboSet via a predefined relationship. Using a relationship at this point automatically holds together the two MboSets via a transaction. There is nothing else via have to do to create this kind of dependency! Cool, isn’t it?

The next line to mention is the woset.save() statement. You could ask: “Why do we do not save the Workorder object?” My answer is: “Save the object you want! Since both MboSet objects are linked by a relationship it doesn’t matter which object you save. The result is the same!”

Jython Introduction

Jython is an implementation of the Python programming language designed to run on the Java Virtual Machine (JVM) and can be used for Maximo / ICD scripting development. The syntax of Jython is based on Python but Java libraries can be included and used in Jython. This is a major benefit when we use Jython for Maximo / ICD Development because on the one hand side you will find a lot of documentation especially for the Python language on the other hand side you can include all Java libraries used in Maximo / ICD. One of the most commonly used libraries is the businessobjects.jar file, which contains most of the business logic included in the product.

In Maximo and ICD up to release 7.6, there is a relatively old version 2.5.2 of Jython in use. If you develop your scripts you should keep this in mind as there is already Jython 2.7 available today which has some new features included. With Maximo & ICD 7.6.1 you will have Jython 2.7 available

In this blog, I will not provide a dedicated introduction into the Jython language since there is some very good stuff available on the internet. I will give you some links at this point:

  1. Official Jython Homepage – with references and tutorials
  2. The Definitive Guide to Jython – Very good book!
  3. Intro to Jython, Part 1: Java programming made easier – IBM Developer Works article
  4. The Jython Wiki

Navigate to different MboSet using Relationships

In this blog I will show you a way to navigate from a given Mbo to a different, related MboSet. The easiest way to perform such a navigation is to use a predefined relationship as it is defined in the database configuration of a table. For our example lets assume we are starting from the WORKORDER MboSet. We would like to print out all workorder activities for the first workorder we read.

The following script can be technical combined with the RMI introduction to get a quick result since it requires a valid session object.

woset = session.getMboSet('WORKORDER')
wo = woset.moveFirst();

if wo is not None:
    print "Workorder ",wo.getString("WONUM")    

    workActSet = wo.getMboSet("WOACTIVITY")
    workAct = workActSet.moveFirst()

    while (workAct != None):
        print "Workorder activity: ", workAct.getString("DESCRIPTION")
        workAct = workActSet.moveNext()

Some of the important commands in this example are:

  • if wo is not None: Very important! Check if we have found a workorder Mbo. If you do not do this check the next access like wo.getString(..) could lead to a null pointer exception.
  • worklogset = wo.getMboSet(“WORKLOGAPPT“) gets a reference to a different MboSet based on the current MBO in wo and the existing relationship “WORKLOGAPPT“
  • while (workAct != None) the loop construct to loop on all workorder actions. Have a look here to loop on MboSet’s.

Setting up Eclipse for Maximo / ICD Jython development

Introduction

When you start developing Jython scripts in context of Maximo & ICD the first question is where to edit the scripts. The provided editor in the Web-interface of the product can only be seen as a “Paste-In” area, since it absolutely lacks any needed development features. Better alternatives at this point can be the usage of more professional editors like UltraEdit or Notepad++. If you only want to develop a small set of short Jython scripts this can be a starting point for you. If you plan to do a bit more development I would highly encourage the usage of a professional development environment. In this article I would like to show you how you can set up the Eclipse platform to perfectly act as a Maximo & ICD development environment. I will guarantee you that the benefits of this platform over time are major, even if it is a bit work to setup at the beginning.

Required Software

So before we start let’s figure out, which software is needed for the installation:

  • Eclipse Luna (Download) (64 Bit)
  • Java JRE or SDK V1.7 or V1.8 (64 Bit) *** please see notices below
  • Jython Interpreter V2.5.2 (Download) – Even it is quit old – this is the used Version in the product.

Notices on Java:
For the development of Jython scripts the used JRE or SDK is really important. For Maximo/SCCD 7.5.x (TPAE 7.5) you need at least a JRE Level of Version 1.6 for Maximo 7.6 (TPAE 7.6) you need at least a JRE Level Version 1.7. I personally always try to use the IBM Java in the version 1.7 and set the JRE Compliance level to 1.6 if needed. I will show you later on how to set this – don’t care for the moment.

The download of the IBM Java is a bit tricky to find. The base download page is can be found here. For Windows you need to download the complete “IBM Development Package for Eclipse”, extract it and take out the JRE directory. You should use Version 5.0 64-bit which includes Java 7.1 (1.7).

Installing the Prerequisites

The installation of the software is described in this section.

  1. Eclipse installation

For Eclipse no special installation is required. It basically only needs to be extracted to a folder of your choose. On the first start you can select the folder where you would like to store your eclipse workspace (data-directory).

  1. Java JRE (optional – you may use your system JRE)

Depending on the Java Version you have to either run a setup program or just copy some files. The installed Java does not have to be the system Java! This is important to know if you use different software on your computer which requires a certain version of Java.

If you use the “IBM Development Package for Eclipse” just extract the “ibm_sdk71” subfolder to a folder on your local harddisk for later usage.

  1. Jython 2.5.2 Installation

Jython Installation is quit straight forward using the setup program. During installation you are asked for the Java Home directory where you should be careful to select the one provided by the Java JRE Installation.

 

Configuration of the Java Environment (optional)

At this point we need to set up the correct Java Environment Eclipse should use.

  1. In Eclipse go to “Window –> Preferences”.
  2. In the left navigation pane go to “Java –> Installed JRE’s”. In the window on the right you should see the currently installed JRE selected. If you have installed an additional JRE and want to make this the default JRE select the Add button on the right.
  3. Select “Standard VM” and “Next…”
  4. The next screen requires the definition of the new JRE. If you select the correct installation directory for your JRE home the rest of the Fields should be filled in automatically:
    eclipsejre1
  5. After selecting “Finish” a new SDK is available. The SDK which is checked and bold is the default SDK.

At the end the right Java compiler must be selected:

  • Maximo 6: Java 1.4
  • Maximo 7: Java 1.5
  • Maximo 7.5.x: Java 1.6
  • Maximo 7.6: Java 1.7

Set it in Eclipse preferences: Windows –> Preferences –> Java –> Compiler  –> Compile compliance level.

eclipsejre2

Installing the maximo.ear

The maximo.ear contains most of the Java method’s to operate on all kinds of Mbo’s and MboSet’s within TPAE. One of the best features of using Eclipse in comparison to a simple text editor is, that we can include the businessobjects JAR file from your Maximo/ICD installation and that we have some syntax checking and input features for these classes. I will show you in a later post how we can utilize these features to make our life easier.

The best way to make the JAR file available is to create an own project in Eclipse for the referenced Java libraries.

  • Select “File –> New –> Java Project” in the Eclipse Workbench with the name “MaximoLibs”.
  • Copy [SMPDIR]\maximo\deployment\default\maximo.ear from your admin workstation into the new project.
  • Extract the following files from the maximo.ear file:
    • jar
    • war and extract the content to a directory named maximouiweb
    • lib/*.jar files to a directory lib
  • Refresh the project tree in Eclipse (F5). Your project should now looks like follow:
    eclipsejre3

Installing the PyDev Plug-In in Eclipse

After the initial start of Eclipse and the selection of a workspace directory you find yourself in the Welcome screen, which should be closed using the “Workbench” symbol in the upper right corner.

To install PyDev select the Menu “Help à Install new Software…”

  1. Enter the text http://pydev.org/updates into the Work with text box.
  2. Select only the PyDev checkbox
    pydev1
  3. Press the Next Button…
  4. You get the Installation Details displayed where you also can press “Next”
  5. Accept the License and press “Finish”. The installation starts.
  6. At the end of the installation you are asked to restart Eclipse. Please answer with “Yes”.

Configuring PyDev in Eclipse

To configure PyDev perform the following steps:

  1. After Restart, click Window and then click Preferences.
  2. Find the entry “Jython Interpreter” as shown in the picture and select “New…”
    pydev2
  1. Enter “Jython 2.5.2” as the Interpreter Name and find the jython.jar file from your previous Jython installation. Select “OK”.
    pydev3
  2. The configuration starts. Select OK in the dialog which appears.

At the End your Jython Interpreter Configuration should look similar to this one:

pydev4

Create a new PyDev project

Now create a new PyDev project where you can store you Jython sources.

  • Select: File –> New –> Project
  • Select the wizard PyDev Project and select Next
  • Enter a project Name and select the correct Project Type Jython and the Grammar Version 2.5 with your defined Interpreter.
    eclipsejre4
  • Press Finish.

You get a question if the associated PyDev perspective should be opened. Select Yes.

Congratulations you have your first Python/Jython project. There is still one little piece missing…

Referencing the Maximo Java libraries

In a previous step we have extracted the Maximo related Java libraries. To use them in our Jython project we need to reference them.

  • Right click to your new project in the PyDev Package Explorer window and select properties.
  • In the property window select the option “PyDev – PYTHONPATH”
  • Select the tab “External Libraries”.
  • Using the “Add zip/jar/egg” button you can add all required libraries from the referenced project. At least the businessobjects.jar file should be added, but all other jar files could be added in addition. At the end your configuration looks like this:
    pydev5

Creating your first Jython Script

To create the first Jython script right click on your newly created project and select New –> File in the Popup Menu. Select a filename of your choose with the extension “.py” and click on Finish.

You are asked for the Default Eclipse preferences for PyDev. Just click ok.

You are now ready to create your first Jython script, but this is a story for another post.

Output fields from a Mbo with different data types

TPAE supports nearly twenty different data types for it’s fields which can be used during database configuration. Commonly used types are ALN, DATE, INT, UPPER, YORN just to mention some of them. A full list of available datatypes can be found on the support webpage.

When we read records using a script we have to be very carefully to always use the correct command which is related to the data type of the field. Some important commands are:

  • wo.getString(“<FIELD>”) – returns a String value
  • wo.getInt(“<FIELD>”) – returns a Integer value
  • wo.getLong(“<FIELD>”) – returns a BigInteger value
  • wo.getDouble(“<FIELD>” – returns a Double/Decimal value (better than getFloat()).
  • wo.getDate(“<FIELD>”) – returns a Date value
  • wo.getBoolean(“<FIELD>”) – returns Boolean Value from a YORN Field (True / False)
Attention: It is a common mistake to use the getString method to read numeric values which will work without errors. The issue you will fall into is that numbers are represented  with thousands separators so a number 1000 is represented as a string “1.000”.

In context of the workorder MboSet a code sample could be the following one, which reads different fields with different data types:

 woset = session.getMboSet('WORKORDER')
    wo = woset.moveFirst()

    while (wo != None):
        # Read out values
        print "Workorder ",wo.getString("WONUM")
        print "Priority ",wo.getInt("WOPRIORITY")
        print "StartDate ", wo.getDate("TARGSTARTDATE")
        print "WorkorderID ", wo.getLong("WORKORDERID")
        # get next Workorder
        wo = woset.moveNext()

Loop MboSet and output Mbo content

A very common programming pattern is to loop on a MboSet and read information from the included Mbo’s. This example can be technical combined with the RMI introduction to get a quick result since it requires a valid session object.

In this example I would like to show how to loop on all existing workorders in the system. Later on we will see how to select specific records from a MboSet, but for now let’s start with all workorders in the system. The following pattern can be used to achieve that objective and print out the workorder numbers:

woset = session.getMboSet('WORKORDER')

for i in range(0,woset.count()):

    # get one Workorder Mbo
    wo = woset.getMbo(i)

    # Read out a value
    print "Workorder ",wo.getString("WONUM")

Some of the important commands in this example are:

  • woset = session.getMboSet(‘WORKORDER’) – method to get a MboSet and stores this in the variable woset – in that case based on the session object
  • woset.count() – returns the number of records in woset
  • woset.getMbo(i) – gets the Mbo with index i
  • wo.getString(“WONUM”) – returns the string from DB Field WONUM from the Workorder Object

As always in programming there are often different ways to achieve the same goal and so I would like to introduce a different way on how it is possible to loop on a MboSet:

woset = session.getMboSet('WORKORDER')
wo = woset.moveFirst()

while (wo):
    # Read out a value
    print "Workorder ",wo.getString("WONUM")

    # get one Workorder
    wo = woset.moveNext()

In that case we use the methods of the MboSet object to navigate around using some simple commands:

  • wo = woset.moveFirst() – gets the first record from the woset
  • woset.moveNext() – moves the pointer to the next record in woset
  • while (wo != None) – loops as long as wo has a valid record (not at the end)