Run a Script interactively from ICD/Maximo

The Automation Script application provides the capability to directly run a script without having a launch point defined. This is useful to test some scripting capabilities or to run scripts performing maintenance tasks triggered by an user.

AttentionIf you are using Maximo or ICD in Version 7.6.x you might not find the “Launch Script” Action. In that case you should read this article to solve this issue first!

To test this behavior we will create a simple script without a launch point which lists all defined users from the ICD/Maximo system. Important is, that in this scenario no implicit variables are available and you have to initialize your MBO context manually based on the MXServer object. The scripts looks as follows:

#DESCRIPTION:Script to demonstrate usage of Run-Script function from GUI
from psdi.server import MXServer
from psdi.iface.mic import MicService

mxServer = MXServer.getMXServer()
micService = MicService(mxServer)
userInfo = micService.getNewUserInfo()

# Example: Loop over all Users....
userSet = mxServer.getMboSet('MAXUSER', userInfo)
userMbo = userSet.moveFirst()
while (userMbo != None):   
    print "User ",userMbo.getString("USERID")    
    userMbo = userSet.moveNext()

To run the script you should hit the following icon in the Taskbar of the Automation Script application:

The result should look as follows:

Use a Button to launch an action script

A very common usage of automation scripting is to develop the action logic when a button is pressed in an application. The concept I will describe in this blog is principal the same for the following three scenarios:

  • A button included in the application with the application designer (I will show this in this blog)
  • A Toolbar Menu entry (Icon Toolbar)
  • A Action Menu entry

So what are the steps to create a button and run the script on it?

  • Create a new Signature Option and assign it to the appropriate user group.
  • Create the new Button, Toolbar Menu or Action Menu in Application Designer.
  • Create a new Automation Script with an Action launchpoint.

I would like to take a demo scenario with very simple scripting so we can concentrate mainly on the other stuff. In the Item Master Application when a new item is created the Commodity Group and Commodity Code has to be selected for each item. Let’s say you are mostly entering new Laptop items and you would like to get a “Default Commodity” button to fill in these two fields with default values like this:


That’s basically all, so lets start.

Create a new Signature Option and assign it to the appropriate user group

To create a new Signature Option we need to go the the Application Designer:

  • Go To > System Configuration > Platform Configuration > Application Designer
  • Select the application ITEM (Item Master) in the List View.
  • Now you go the “Select Action” menu and select the “Add/Modify Signature Options” entry.


  • In the dialog which opens hit the “New Row” button to add a new Signature Option.
  • Create a new Option with a name and a comment like follows:


And now the important part!!! Did you recognized the “Advanced Signature Options” section which is closed by default? Open it and check the following point:


If you forget to check this entry your button will never work and your script will never run.

  • Click on OK to close the dialog.
  • Assign the new Signature Option to a Security Group where your user is in (e.G. MAXADMIN for testing). You will find the new signature Option in the ITEM Application section:Selection_033
  • Don’t forget to logoff / logon to the Server before you proceed.

Create the new Button in Application Designer

After a new logon proceed in the Application Designer:


  • Go To > System Configuration > Platform Configuration > Application Designer
  • Select the application ITEM (Item Master) in the List View.
  • In the Application design screen select the “Item” Tab from the application.
  • Open the Control Palette dialog in the Toolbar: Selection_034
  • From the Control Palette Drag and Drop the “Button Group” symbol to the “Commodity Group” Text. The button group should occur above the Commodity Group.
  • Right Click on the “pushbutton…” and select the properties Menu
  • Enter the following Values:
    • Label: “Default Commodity”
    • Event: “DEFCOMM” (This is the Name of the Action we will define later)
    • Signature Option (on page two): DEFCOMM (the one you created before)

That is basically all you need to do in Application Designer. Your Button should now look as follows:


Save your work.


Create and test the automation Script

The new script will be created in:

Go To > System Configuration > Plattform Configuration > Automation Scripts

In the Select “Select Action” box select “Create > Script with Action Launchpoint”.


Fill in the dialog as follows and press “Next” when done:


Interesting here is the Object field. This field is the MBO Object your are in and which your script will get as the implicit “mbo” Variable.

In the next dialog we need to fill in some more values. It is always good practise to name the action, launchpoint and script the same (unless you will have multiple launchpoints with different meanings for a script).


Press the “Next” button when filled in.

In the last dialog you will have to paste in the following script code:

itemMbo = mbo  # @UndefinedVariable
itemMbo.setValue("COMMODITYGROUP", "43211500")
itemMbo.setValue("COMMODITY", "43211503")

Press “Create” to create the automation script. The Action object will be automatically created in background. Don’t forget this when you need to transport your development to another system.

Test the new solution

To test your new button:

Go To > Inventory > Item Master

Create a new Item and press the new Button. The Commodity Group and Code should be automatically be filled in. Congratulations!



Download (all) Scripts from Maximo / ICD to your Eclipse Project

In one of my last blogs I showed a very nice way how to upload Jython scripts from Eclipse to your Maximo / ICD environment. Now what about the situation that you already have a Maximo / ICD environment with tons of scripts in it? In this blog I will show you a simple way how you can include all these scripts to your Eclipse project within 15 minutes. This will also include the first comment lines needed for the later upload.

To achieve our goal the following steps are needed:

  • Setup an application export in the Autoscript application
  • Download a XML File including all scripts
  • Run a Jython script to extract all the unique scripts

Setup an application export in the Autoscript application

The application export will be configured using the “Object Structures” application. Launch:

Go To > Integration > Object Structures

In the Object Structures application search for the “MXSCRIPT” Object Structure and open it.


After opening select an action:

Select Action > Add/Modify Application Export Support



In the dialog box create a new row in the table using the values shown here:


Press OK. The export support now has been created. Next step is to grant the security rights to the user group which should use the tool. In my example I will grant the rights to the maxadmin group. Goto the following Menu:

Go To > Security > Security Groups

Now perform the following steps:

  1. Search and open the security group you want to grant the rights to.
  2. Change to the “Applications” Tab.
  3. Filter for the Application “Automation Scripts” and select the record.
  4. In the Options for Automation Scripts section enable the option “Application Export”.Selection_022
  5. Save the Security Group.
  6. Logoff and Logon again to Maximo / ICD. Be sure that all your user sessions are successfully logged of – otherwise the settings will not be activated.

Download a XML File including all scripts

To download a XML File which includes all scripts in your system you have to go to the Automation Scripts application.

Go To > System Configuration > Plattform Configuration > Automation Scripts

If the previous step worked correctly you should now see a new Icon in the iconbar Selection_023for the application export. Before you press this button you have to search for the scripts to export. If all scripts should be exported just press enter in the search field. Now press the icon.

In the “Application Export” Dialog you just can take all settings and press “OK”.


The XML File now will be downloaded to the download directory of your browser on your local PC.

Run a Jython script to extract all the unique scripts

First of all you have to have a project setup in Eclipse where you would like to store your downloaded scripts. This chapter requires a complete project-setup using Eclipse, Jython and PyDev like described in this blog. Copy the downloaded XML file to this directory and name it scripts.xml.

Now create a Jython script with the following code:

#DESCRIPTION:Script to export all Jython Scripts on a Server

from import File
from org.jdom.input import SAXBuilder

xmlFile = File("scripts.xml")
builder = SAXBuilder()

document =
wrap = document.getRootElement()
ns = wrap.getNamespace()
rootNode = wrap.getChild("MXSCRIPTSet", ns)

liste = rootNode.getChildren("AUTOSCRIPT",ns)
for i in range(0,liste.size()):
    node = liste.get(i)
    scriptName = node.getChildText("AUTOSCRIPT",ns)
    scriptDesc = node.getChildText("DESCRIPTION",ns)
    scriptVersion = node.getChildText("VERSION",ns)
    scriptDebug = node.getChildText("LOGLEVEL",ns)
    scriptCode = node.getChildText("SOURCE",ns).encode('utf-8')
    scriptFile = open(scriptName + ".py","w")
    scriptFile.write("#AUTOSCRIPT: " + scriptName + "\n")
    scriptFile.write("#DESCRIPTION:" + scriptDesc + "\n")
    scriptFile.write("#VERSION:    " + scriptVersion + "\n")
    scriptFile.write("#LOGLEVEL:   " + scriptDebug + "\n")

This scripts requires the Java JDOM Class. Please ensure that the jdom.jar file is included in your PYTHONPATH. You can check this by right-click on your Eclipse project and select the “Properties” Menu. Check under “PyDev – PYTHONPATH” if jdom.jar is existent. If not use the “Add zip/jar/egg” Button to add it.


Remark: If you don’t have a local version of jdom.jar you can find one on your Maximo / ICD Server in the following directory: %WEBSPHERE _DIR%\AppServer\profiles\ctgAppSrv01\installedApps\ctgCell01\MAXIMO.ear\lib

Everything is prepared now. You can run the Script now from Eclipse using the Run Icon Arrow  Selection_009 and then the following menu:


Hopefully after a refresh of your project/folder (F5) you will see a bunch of new scripts! Congratulations!

Deleting Mbo’s

So far we know how to insert, update and view our Mbo records, so the next step is to delete a record.

You delete Mbo’s by calling the delete() method. This method removes the current Mbo from an MboSet. Basically the Mbo is not delete when you call the delete method it is more over marked for deletion. The real delete operation is executed when the transaction is commit to the database. In general this is the save operation on the MboSet.

Here comes an example which deletes a specifc Workorder from the Workorder MboSet:

    # Example: Delete a specific Mbo
    woset = session.getMboSet('WORKORDER')
    woset.setWhere("WONUM = '2009'")
    wo = woset.moveFirst()
    if wo is not None:   
        # Mark Mbo for deletion

        # Real delete is done at this point

Using field Flags to set attribute content

Each attribute in Maximo / ICD can have several Validation Java classes and Jython scripts associated which will trigger when a new value for an attribute is set. Field flags can control some of the conditions under which the attributes can be modified and prevent execution of that classes / scripts.

The following field Flags are commonly used:

  • NOACCESSCHECK is used to update the value even if the attribute is marked readonly
  • NOVALIDATION supressess checking of the value. Be sure you know what you do, because you will prevent the business logic from checking for a valid value.
  • DELAYVALIDATION does not perform any validation when the attribute is modified. The validation takes place on the save action. This can be useful if the validity of an attribute depends on other attributes.
  • NOACTION is used to bypass the execution of all business rules. Use it carefully!

Now how do we use these flags in Jython? They are used in the setValue() Method as a third parameter. So sometimes you will see scripts like this:

itemMbo.setValue(description", "Hello World!", 1L)

In this 1L stands for NOVALIDATION and it is bad practise to write it in a numeric format. How about this style?

from psdi.mbo import MboConstants
itemMbo.setValue("description", "Hello World!", MboConstants.NOVALIDATION)
companyMbo.setValue("company", "COM1", MboConstants.NOVALIDATION_AND_NOACTION)

If multiple field flags should be combined for a field they could be combined by a bitwise or operation. See this example:

from psdi.mbo import MboConstants
itemMbo.setValue("description", "Hello World!", MboConstants.NOVALIDATION | MboConstants.NOACCESSCHECK)

So far we always used the setValue method to directly manipulate the field flag while we are setting a value to a field. In some cases it is also useful to just set the field flag without applying a new value. This can be done with the setFieldFlag method. You can set and remove certain flags from a field. Mostly taken is this for the read only state:

from psdi.mbo import MboConstants
itemMbo.setFieldFlag("description", MboConstants.READONLY,False)
itemMbo.setValue("description", "Hello World!")
itemMbo.setFieldFlag("description", MboConstants.READONLY,True)

The setFieldFlag method can also take a list of fields as a parameter, if you would like to modify a bunch of fields:

from psdi.mbo import MboConstants
itemMbo.setFieldFlag(fields, MboConstants.READONLY,False)

Upload Jython Scripts from Eclipse to Maximo/ICD

In this post I would like to introduce a cool feature to upload your Jython scripts developed in Eclipse directly to Maximo/ICD without the need to jump to the scripting application and doing some copy/paste actions. To Archive this objective we will utilize the Integration Framework and will write a small Jython script to be called from Eclipse and utilizing this interface. I will show you step by step the different configuration steps.

This is a quit complex configuration to do and there are a lot of places to introduce errors so that the complete system will not work. Please post me your experiences with the configuration as a comment so I can improve this article over time.


What are the prerequisites for our project:

  1. An Eclipse Installation with PyDev integrated where you develop your Jython Scripts
  2. A local Jython 2.x installation (which should normally already be in place). Please consider that we need a full installation and it is not enough to just have a copy of the jython.jar file since we need some standard Jython libraries for our project.
  3. Access to a Maximo/ICD System

The solution currently only has been tested with local authorization. The Upload script might need slight modifications for LDAP authorization (comments welcome :-).

The solution currently only supports http protocol. If you are using https the upload script might need some modifications.

Preparations Integration Framework in Maximo/ICD

Create a new Object Structure

We need to create an own Object Structure based on the existing MXScript Structure.

  1. Go to menu Integration → Object Structure and search the MXScript Object Structure.
  2. Duplicate the Object Structure (Select Action → Duplicate Object Structure)
  3. The new Object Structure should be called JYSCRIPT unless you want to edit the upload script later on.
  4. Remove the Source Object „AUTOSCRIPT/VARSThe configuration for the duplicated Object Structure should now look like this:jyecli02
  5. Select Action → Exclude/Include Fields
    Exclude all fields except the following ones:
    • SOURCE

Create an Enterprise Service

A new Enterprise Service must be created.

  1. Go to menu Integration → Enterprise Services
  2. Create a new Record and fill in the following fields only:
  3. Save the Enterprise Services

Create an External System

A new External System must be created by the following steps:

  1. Go to menu Integration → External Systems
  2. Create a new Record and fill in the System Tab with the following values:
  3. Be sure all fields are filled in as shown
  4. Select the tab “Enterprise Services” and create a connection to the previously created Enterprise service. For this select the “New Row” button. Fill in the new line as follows:
  5. Be sure that the enabled box is checked.
  6. Save the External System. The configuration on the Maximo/ICD side is now finished.

 Configuration of the Eclipse Side

The configuration of Eclipse consist of two steps:

  • Prepare Upload Script
  • Create a “Run entry” in the Run configuration.

Prepare Upload Script

Take the following script and store it in a place of a Eclipse project. The project should have a valid Jython Runtime configured. Please have a look to this article for proper Eclipse setup if you are unsure.

# DESCRIPTION:        Script to upload Jython Scripts from
#                     Eclipse to Maximo / ICD
# AUTHOR:             Matthias Stroske
# Created             25.11.15
# VERSION:            1.0
# COPYRIGHT:          (c) Matthias Stroske
# MAXIMO/ICD Version: 7.5 and higher
# History of Changes
# Ver  Date      Name               Description
# 1.0  01.10.15  Matthias Stroske   Initial Version
# 1.1  25.11.15  Matthias Stroske   Improved Parameter Handling
import sys
import httplib
import base64
import string
import re
from xml.sax.saxutils import escape
def main():
    if len(sys.argv) < 5:
        print "USAGE: <inDatei> <host> <user> <password>"
    inDatei = sys.argv[1]
    host = sys.argv[2]
    user = sys.argv[3]
    password = sys.argv[4]
    # Set Defaults as far as possible
    scriptName = None
    scriptDescription = None
    logLevel = "ERROR"
    version = "1.0"
    httpUrl = "http://" + host + "/meaweb/es/JYSCRIPT/JYSCRIPT"
        f = open(inDatei)
        fileContent =
    except Exception,ex:
        print ("Error reading the input file!")
        print ("Exception:" + str(ex))
    firstLines = fileContent.split("\n", 15)
    for line in firstLines:
        matchObj = re.match(r'^#\s*DESCRIPTION:(.*)',line, re.I)
        if matchObj:
            scriptDescription =
        matchObj = re.match(r'^#\s*AUTOSCRIPT:(.*)', line, re.I)
        if matchObj:
            scriptName =
        matchObj = re.match(r'^#\s*LOGLEVEL:(.*)', line, re.I)
        if matchObj:
            logLevel =
        # Simple Style
        matchObj = re.match(r'^#\s*VERSION:(.*)', line, re.I)
        if matchObj:
            version =
        # CVS Style
        matchObj = re.match(r'^#\s*Revision:(.*)', line, re.I)
        if matchObj:
            version =
    if scriptName is None or scriptDescription is None:
        print "ScriptName and ScriptDescription have to be specified in first Script Lines!"
    print "Script Name       = " + scriptName.strip()
    print "DESCRIPTION       = " + scriptDescription.strip()
    print "LOGLEVEL          = " + logLevel.strip()
    print "VERSION           = " + version.strip()
    message = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
    message += "<SyncJYSCRIPT xmlns=\"\" xmlns:xsi=\"\">\n"
    message += "<JYSCRIPTSet>\n"
    message += "<AUTOSCRIPT>\n"
    message += "<AUTOSCRIPT>" + scriptName.strip() + "</AUTOSCRIPT>\n"
    message += "<DESCRIPTION>" + scriptDescription.strip() + "</DESCRIPTION>\n"
    message += "<LOGLEVEL>" + logLevel.strip() + "</LOGLEVEL>\n"
    message += "<SCRIPTLANGUAGE>jython</SCRIPTLANGUAGE>\n"
    message += "<VERSION>" + version.strip() + "</VERSION>\n"
    message += "<SOURCE>\n"
    message += escape(fileContent)
    #message += "pass\n"
    message += "</SOURCE>\n"
    message += "</AUTOSCRIPT>\n"
    message += "</JYSCRIPTSet>\n"
    message += "</SyncJYSCRIPT>\n"
    message += "\n"
    contentType = "application/soap+xml;charset=UTF-8;action=\"urn:processDocument\""
    auth = 'Basic ' + string.strip(base64.encodestring( user + ':' + password))
    webservice = httplib.HTTPConnection(host)
    headers = {"Content-type": contentType, "Content-Length": len(message), "Authorization": auth}
    webservice.request("POST", httpUrl, message, headers)
    # get the response
    res = webservice.getresponse()
    if res.status == 200:
        print "Script upload successful!"
        print "Script upload completed with RC = " + str(res.status)
if __name__ == "__main__":

Eclipse External Tools configuration

To run the script in context of Eclipse you need to do an additional configuration step in Eclipse.

Find the following Icon in the Eclipse iconbar:   Selection_004

Select the little arrow beside the icon to expand the menu and select “External Tools Configurations…”


In the following Window fill in the Head section with the Name of the configuration.

Continue to fill in the  Main tab with the following values:

  • Location: The location of your locally installed Jython interpreter.
  • Working Directory: should be ${workspace_loc:/<ProjectName}
  • Arguments: 5 Arguments for the Jython interpreter to run.
    1. Name of Jython Upload Script: e.G. ${workspace_log:/Blog/}
    2. Name of the Script to be uploaded: Best we can specify here is always: ${workspace_loc}${selected_resource_path}
    3. Maximo / ICD Host: IP Adress or Hostname of the Maximo Server
    4. Username in Maximo / ICD
    5. Password in Maximo / ICD  *** yes I know it is not good to store the PW in clear-text. With little modifications you could store it base64 encoded here if you modify the Jython script slightly.


Preparing your script and using the new tool

Preparing your script

To use the new tool your script must follow a little convention. The first 15 lines must include relevant information which are required to synchronize the script with Maximo/ICD.


This are fields which map to the appropriate fields in Maximo/ICD. The AUTOSCRIPT field is the Name of the Autoscript in Maximo/ICD. With the upload you can create new automation scripts, but you can not create or modify any launchpoints. When you change the DESCRIPTION,VERSION or LOGLEVEL field later on these fields are modified in Maximo/ICD.

I have created a base template for your code, which can be found in this blog.

Using the new Tool

To use the tool we assume, that you are now editing your custom Maximo/ICD Jython script with the information lines included and some Jython Code. From this place you just need to run the Upload Script by Clicking the Run external Symbol in the iconbar again. Selection_004 A script with the name you have chosen during configuration should appear in the drop down list.

After some second you will hopefully get a response “Script upload successful”  in the Console View of Eclipse. Otherwise you’ll get an error with the http Return Code.


I hope the solution will work in your environment!

Implicit launchpoint Variables

Implicit launchpoint variables are predefined if a script runs in the context of ICD (not if you are using the RMI Interface).

Overview of Implicit Variables

The following list describes the most commonly used variables:

Input Variables (incoming to the script):

mbo – The current Mbo in the context of the script execution. This is an object.
mboname – The name of the current Mbo in context of the script as a string.
app – Name of the ICD application which initiated the script execution
user – Name of the user whose action initiated the script execution.
interactive – Is true if script is executed interactive via UI and false if executed in background (e.g. scheduler, integration framework).
scriptName – name of the script
launchPoint – name of the launch point
action – Only for action launchpoints the name of the action that executed the script.
onAdd – Boolean variable. Is True if the Mbo in the script is added and a new Mbo (not yet saved). Very useful for conditional launchpoints, but may also be useful for Object and Attribute launchpoints.
onUpdate – Boolean variable indicating that related Mbo is being updated.
onDelete – Boolean variable indicating that related Mbo is marked for deletion.
wfinstance – Object of type psdi.workflow.WFInstance that indicates the current workflow from which the action was started. This is only valid for action launchpoints if the action is launched from a workflow.

Output Variables (Script provides them back to ICD)

errorkey – For throwing MXExceptions from the script
errorgroup – For throwing MXExceptions from the script
params – For throwing MXExceptions from the script. This is a Array of Strings
evalresult – evaluation result of the Condition Launch point

Usage patterns

When using implicit variables in your script you should first care about the fact that the variables are nowhere defined and therefor eclipse will throw you an error on the first usage. Please have a look to the “Undefined Variables” Section in this articel to solve the issue.

Perform different actions based on the Launchpoint executing the script

A Jython script could have more than one launchpoint to start its execution. Sometimes the script needs to perform different kind of actions depending on the launchpoint. Another use case for this pattern is to assign different values to variables based on the launchpoint to omit the usage of launchpoint variables. A sample for this is shown in the article “Tips for using Eclipse with Jython” in the section “Prevent Using Script In-/Out Variables”

Execute script actions only if running from GUI

It is sometimes a requirement that a script behaves differently if it is called from a User GUI Interaction or from a system interaction like a crontask, escalation or an Integration Framework call. The following pattern can solve this issue:

interactive = interactive # @UndefinedVariable

if interactive == True:
# Things to do if script is running in user Context
# Things to do if script is called by Crontask, MIF, ...

Execute different script actions depending on the ICD Application

Sometimes it is required that a script executes different paths depending on the Maximo application it is executed from. The code pattern is quit simple in that case:

app = app  # @UndefinedVariable

if app == "ASSET":
    # Do actions if called from asset Application
if app == "ITEM":
    # Do actions if called from item Application

Throwing an exception from a script

The usage of the errorkey/errorgroup/params variables is shown in this article.

Logging in Maximo Jython scripts

When you develop scripts with more than a couple of lines of code it is always useful to write some information to a log. Maximo has a very powerful logging engine based on the Apache log4j Java based logging utility.

In the first part of this Blog I will show you how the logging engine will be configured. In the second part we will discover the technics to utilize the logging system from our Jython scripts.

Preparation of Maximo Logging

The Logging configuration in Maximo can be found in the following menu:

Goto > System Configuration > Plattform Configuration > Logging

The first think we have to do is to create a new Appender. This is basically the definition of the logfile where the log is written to. You can either define a common customscript logfile or define different logs for larger scripts. From the Logging application select the Action „Manage Appenders“ and the following screen occurs:


By selecting „New Row“ you can add an additional Appender. Fill in the values as shown below and press OK at the end.


You are now back at the entry screen for logging. Go to the Filter bar an search for the „autoscript“ Root Logger entry.


As you can see there are no specific Loggers defined under this entry. You can now define your own Customscript Logger by pressing the „New Row“ button in the Loggers section. Fill in the following values:


Important is to select the „Appenders“ entry „customscript“. This is the additional appender for this Logger which will write to the customscript.log file.

To apply your new settings there is no save button. You have to select the Action „Apply Settings“ to enable the new Logger you just have defined.

Using the customscript Logger

To use the scripting engine you first have to initialize a new Logger. This can be done by the following statement:

myLogger = MXLoggerFactory.getLogger(„maximo.script.customscript")

After that the logger can be easily used:“<message>”) writes one line to the log with the selected message level. Only levels equals or higher then selected in the customscript logger are really written to the logfile.

A complete example looks like this:

from psdi.util.logging import MXLoggerFactory
myLogger = MXLoggerFactory.getLogger("maximo.script.customscript")
myLogger.debug(“This is a debug entry")“This is an info entry")
myLogger.warn(“This is a warning entry")
myLogger.error(“This is an error entry")
myLogger.fatal(“This is a fatal entry")

Tips for using Eclipse with Jython

After you hopefully read the article about setting up Eclipse for Maximo Jython development, there are some Tips & Tricks to get the best results from using Eclipse in combination with Jython. A short summary can be found here:

Undefined Variables

You often use so called implicit variables when you program in context of a launchpoint. The best known variable is mbo which is used quit often. If you use this variable in context of Eclipse it will throw an error in the GUI, because it has never been declared in context of the script.


My best practice is to assign these variables at the beginning of the script to another variable even using a more meaningful variable name (or even the same name) and using the @UndefinedVariable tag. The above sample would now looks like this and will not throw any error:

workorderMbo = mbo  # @UndefinedVariable

Prevent Using Script In-/Out Variables

Maximo provides you the opportunity to define In-/Out Variables in context of a launchpoint. Variables defined in that way can be accessed as regular variables in Jython but will seamlessly read/change the content of an MBO attribute. This looks very handy at the beginning, but will make reading of scripts much harder, because you can never be sure which attribute a variable is really bound to. In addition you get much more issues with Undefined Variables in eclipse. So in fact of clarity I am a big fan of not using In-/Out Variables. I will show you the programming alternative to this:


assetNum = mbo.getString(“ASSETNUM”)



Now you could say that the Maximo mechanism will provide you the benefit to assign different values to a variable based on its launchpoint. The situation can also be handled quit simple using some script code:

launchPoint = launchPoint  # @UndefinedVariable
if launchPoint == ‘MYLAUNCHPOINT1’:
    assetNum = mbo.getString(“ALTASSETNUM”)

So I hope you will not see any uncovered situations but your script has now all clarity at one place.

Let Eclipse organize your Imports

Have you ever seen a Jython script which starts like this:

from import *
from java.rmi import *
from psdi.mbo import *

This is really bad style because you will import the complete classes from which you only need a small piece. Much better:

from import files
from java.rmi import RemoteException
from psdi.mbo import MboConstants

But how can you easily maintain the shown list? Quit easy: Don’t care about – Eclipse will help you. Never define an Import manually!
Just write your code using an method from a class library. When you use an method not yet imported Eclipse will help you with an error. Just place your mouse over the error and you will get a hint like this:

Now press the CTRL-1 one key and Eclipse will show you how it might solve the issue:

By selecting the first option “Import MXServer (psdi.server)” Eclipse will create the import statement for you:

from psdi.server import MXServer

On the other hand side, when you no longer need an import Eclipse will show a warning on that import:


You can just delete the line. Even when you delete a line to much you now know an easy way to restore the imports.

Use a Revision Control System

I think it is agreed best practice to have a Revision Control System in place when you develop more than some small scripts. But sometimes you do not have a choose and there is no tool available in your environment. For that case there is a cool, but not well known function within Eclipse. The Team function provides a local history of your edits within the last 7 days. You do not have to activate it, it’s just there!

To get an older file version right click on the File and select Team > Show Local History…


You can now right click an entry and either open it directly or compare an old version with the current version. That is a very nice feature.

How about the 7 days? You may want a longer retention period for your files.

Select: Window > Preferences in the menu.

In the tabs on the left select: General > Workspace > Local History

In this configuration page you can either completely remove time limits for this function or extend the number of days and size for the history.


Display Maximo Messages in Jython

It is often useful to provide a user some visual feedback if a script runs ok or ends with an error message. Maximo provides a complex message system which can be found in its Database configuration. Using this message system you can create message boxes like the following one.


In this post I will show you step by step the usage of the message system.


The scenario we want to implement is to check the Priority field within a Workorder. If the Value is larger than 50 we would like to inform the user by a message and not allow to save the record.

The implementation needs the following elements:

  1. A message defined in Maximo
  2. A script with an Attribute Launchpoint

Preparation of Messages in Database Configuration

Start the Database Configuration by:

Goto –> System Configuration –> Platform Configuration –> Database Configuration

In the “Select Action” Menu select “Messages”. You will see an editor Window where you can edit all messages of the Maximo application.


To add new messages press the “New Row” button. A big input screen appears:


A couple of important fields in this screen need some clarification:

  • Message Group: Maximo has a couple of predefined Messages Groups for the different applications or other grouping characteristics. You can either add your message to an existing group or define your own group. An own group can specially help you if you have a couple of related messages for the same context.
  • Message Key: The unique Message Key is an important identifier to address a specific message from your script later on. Therefor it should be a short meaningful specification of what the message means. I prefer upper camel case conversion like “InvalidPrio”. The Message Key together with the Message Group uniquely identifies the message.
  • Display Method: Can be ‘MSGBOX’ or ‘STATUS’. The ‘MSGBOX’ display a standard popup window displaying the message and a set of customizable buttons. The ‘STATUS’ displays the text above the tool bar and does not require user intervention
  • Message ID Prefix: Should be “BMXZZ” which is the pre-defined message prefix  for all custom messages.
  • Message ID Suffix: Specification of the Severity:
    • I = Informational
    • W = Warning
    • E = Error
  • Display ID?: If checked the ID BMXZZ… will be shown in the Messagebox.
  • Value: The Message text. The message Text can include placeholders {0}, {1}, {2} and so on for replacement parameters. I will show you later how to script them.

After clicking OK the new message is immediately available. No Database configuration is required at this point.

Creating the Attribute Launchpoint and the Script

GoTo –> System Configuration –> Platform Configuration –> Automation Scripts

In the “Select Action” Menu select “Create –> Script with Attribute Launchpoint”.

Fill in the following dialog and press Next:


In the following dialog enter the script name and press next:


In the final configuration screen enter the following sample code:

woPriority = mbo.getInt("WOPRIORITY")
if woPriority > 50:
    # Raise an error using a message
    errorgroup = "workorder"
    errorkey = "invalidPrio"

Please notice, that I never use In/Out variables for my scripts, because they make scripts less readable and will cause more issues with undefined variables in Eclipse. As a result I need to get the woPriorty value in line 1.

The important code for the message handling is in lines 4 and 5. We only set the explicit variables errorgroup and errorkey to existing values in the Message Database and that’s all. But how do we show the message to the screen? There is no code for this? The answer is: Maximo will do this for us. We only have to set the two variables at the end of our script. As you see this is also one big limitation, since we can use messages usually only at the end of our script.

If you now save the script and test the Workorder application you should get a message if you enter a Workorder Priority higher than 50.


Sending a message with parameters

What is still missing how we can replace parameters in messages. Let’s assume we have the following message:

Workorder {0} could not be processed because invalid Priority {1} has been specified.

To address such an message from our script we need the following code:

woPriority = mbo.getInt("WOPRIORITY")
woNumber = mbo.getString("WONUM")
if woPriority > 50:
    # Raise an error using a message
    errorgroup = "workorder"
    errorkey = "invalidPrio2"
    params=[woNumber, str(woPriority)]

The trick is the params variable which is a list of replace values for {0} and {1}. The final result looks as follows:


Message boxes are displayed by throwing exceptions from Jython. If your script updates fields in a Mbo currently displayed the exception can have the effect that the fields in the applications are not updated on the screen. Please consider the Messagebox as the source of the issue if you see this behaviour!
1 2 3 4