Read Maximo system properties in a Jython script

It is a good practise to store all properties like usernames, passwords, Url’s, etc in the Maximo System Properties. User defined properties can be defined in addition to all the tons of existing system properties. You will find the properties application under

System Configuration –> Plattform Configuration –> System Properties

To define a new property just click “New Row” in the Global Properties section:


The usage of these properties in a Jython script is quit easy. To read and print the new “custom.username” property the following script can be used:

from psdi.server import MXServer
configData = MXServer.getMXServer().getConfig();
maxProperty = configData.getProperty("custom.username");
print maxProperty


When tested in the Maximo Script editor the script should print out the username “bigadmin”. If you get a no output at StdOut or “None” you should verify if you made a live refresh of the property data.

Selecting specific Mbo’s using Relationships and Where Clauses

A very common scenario is that you would like to get an instance of a MboSet with not all records included, but only a subset. Spoken in SQL you would like to apply a where clause to limit the number of records you get as a result in a MboSet. In this article I will show you different ways on how you can achieve this.

  1. Usage of relationships

A very common pattern is to just use relationships when you initialize your MboSet. I have shown such a pattern in this article. You can easily define the where clause directly in the relationship and you will only get the records based on the where clause.

  1. Adding a Where-Clause to an existing MboSet

It is quit handy to add a Where-Clause to an existing MboSet. The following code example will show this scenario:

woset = session.getMboSet('WORKORDER')
woset.setWhere("WONUM = '2009'")
wo = woset.moveFirst()
if wo is not None:
    print "Workorder ",wo.getString("WONUM")

At the beginning you initialize a MboSet returning all Workorder’s in the system. In line 2 you append a Where-Clause to the result set. When you have used a relationship with an existing where clauses in it the new where clause will be appended. The woset.reset() method call in line 3 is required to “execute” the where clause and update the result set in woset. The rest of the script just shows the first record.

  1. Building a temporary relationship

This is one of my favorite patterns which can help you make life much easier. When you develop your script you will not always have the perfect relationship for navigation defined in the system. So you can either define a new relationship in database configuration or you can do this step directly from your Jython script. You define a new relationship just to be used temporarily in your script with no impact to the rest of the system.

The syntax based on the JavaDoc is:

public MboSetRemote getMboSet(java.lang.String name,
                              java.lang.String objectName,
                              java.lang.String relationship)
                    throws MXException, java.rmi.RemoteException

A real example statement to get all worklog entries for a specific workorder could look like this:

worklogset = wo.getMboSet("$TEMPREL1", "WORKLOG", "RECORDKEY='2009'")

$TEMPREL1 – An unique identifier for the relationship. It needs to be unique and for this reason it is good practice to start the name with a dollar sign.

WORKLOG – The database object which should be queried using any provided where clause.

RECORDKEY=’2009’ – The where clause to be applied to reset the MboSet of interest.

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)

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 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.")
        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 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!”