Thanks for your elaborate reply on my post.
I was hoping for someone to reply and adress the shortcomings of the proposed solution / improve the proposed solution.
Original Message:
Sent: 03-26-2025 11:50
From: Jason VenHuizen
Subject: Yet another way to define functions that can be used in another automationscript...
Erwin,
I think you have over complicated this. Here is an example of the same approach, where I have another scripted called EXAMPLE_SCRIPT_NAME and it has a function called example_function_name that takes an integer parameter and returns some value that I am printing. That is all you need to do. You do not need to import sys or the PythonInterpreter, at least in the MAS 9 system I tested this with.
from com.ibm.tivoli.maximo.script import ScriptCachefrom com.ibm.tivoli.maximo.script import JSR223ScriptDriver# Note the use of "snake_case" for variable names as is the PEP8 naming convention standard for Pythondef get_auto_script(auto_script_name): # Use the ScriptCache to get the script source so you are not making a database call, which is otherwise expensive scriptInfo = ScriptCache.getInstance().getScriptInfo(auto_script_name) # Make sure that the script is Jython / Python. Note that we are comparing the engine name because both Jython and Python use the same engine. # Also note that getScriptLanguge() is the correct method name and Language is misspelled in the Maximo API if JSR223ScriptDriver.getSupportedScriptEngineInfo(scriptInfo.getScriptLanguge()).getEngineName() == "jython": return scriptInfo.getScriptSource()exec(get_auto_script("EXAMPLE_SCRIPT_NAME"))print(str(example_function_name(1)))
Also note there are a few mistakes you are making in your approach.
- In Python the semicolon is not used as a line terminator
- Use the PEP 8 style guide, which states that snake_case should be used for variable and function names
- Hungarian notation (putting type in front of variables e.g. strVar or intVar) is not part of the Python style conventions
- Try to avoid using the System UserInfo object as this never terminates and will leak memory if you do not properly close MboSets opened by this user
- Put MboSet close and cleanup functions in a try: finally: block so they get called even if there is an error: https://www.sharptree.io/blog/2021/2021-11-22-close-things/
- There is a method for getting the System UserInfo object directly from the MXServer object with MXServer.getMXServer().getSystemUserInfo()
- If you want to get a reference to the MicService you should use the lookup method on MXServer, MXServer.getMXServer().lookup("MIC") will return the MicService class. You should not create a new instance of the service classes.
- The getNewUserInfo method on the MicService class returns the user defined by the mxe.int.dfltuser system property and probably does not, or should not, have the rights needed to perform lookups on the AUTOSCRIPT table.
Regards,
Jason
------------------------------
Jason VenHuizen
Sharptree
Original Message:
Sent: 03-25-2025 03:03
From: Erwin Hebing
Subject: Yet another way to define functions that can be used in another automationscript...
Disclaimer: Use the described method at your own risk...
Why did we look for another option to define jython functions that can be used in another automationscript?
We found the other methods complex
What did we come up with:
Define re-usable functions in an automationscript that can then be called from another automationscript
And yes there are other ways but we find this method simple to use
What do we need to make this functionality work?
1. An automationscript with a function that retrieves an automationscript and return the SOURCE-field (see function def GetAutoscript(strAutoscriptName) in the script below)
2. An automationscript containing a function that we want to use in another automationscript:
Lets say you want to perform some simple calculations in a function called iIncrease that has one parameter iIncreaseMe
if iIncreaseMe == 1 you want to add 1
if iInCreaseMe == 2 you want to add 2
otherwise you want to add 10
Writing a jython function for this would look something like:
def iIncrease(iIncreaseMe):
print "Function:iIncrease(" + str(iIncreaseMe) + ") - Start";
if (iIncreaseMe == 1):
iReturnValue = iIncreaseMe + 1;
elif (iIncreaseMe == 2):
iReturnValue = iIncreaseMe + 2;
else:
iReturnValue = iIncreaseMe + 10;
print "Function:iIncrease(" + str(iIncreaseMe) + ") - End - Returning:[" + str(iReturnValue) + "]";
return iReturnValue;
And we defined an automationscript called EH_FUNCTION_01 containing the function as depicted above.
In order to use our function in an automationscript we have to:
1. Read the (source-field of the) automationscript that contains the function we want to use in another automationscript
2. Put the function into memory
3. Use the function
We have therefore defined following automationscript:
----- Script START ----------
import sys
from psdi.server import MXServer
from psdi.security import UserInfo
from psdi.iface.mic import MicService
from org.python.util import PythonInterpreter
ICDServer = MXServer.getMXServer()
svcIntegration = MicService(ICDServer)
svcIntegration.init()
ICDUser = svcIntegration.getNewUserInfo()
# Function:
def GetAutoscript(strAutoscriptName):
strReturnValue = ""
try:
setAUTOSCRIPT = ICDServer.getMboSet("AUTOSCRIPT", ICDUser)
strFWhereClause = "AUTOSCRIPT = '" + strAutoscriptName + "' "
setAUTOSCRIPT.setWhere(strFWhereClause)
recAUTOSCRIPT = setAUTOSCRIPT.moveFirst()
if (recAUTOSCRIPT):
strReturnValue = recAUTOSCRIPT.getString("SOURCE")
setAUTOSCRIPT.close()
setAUTOSCRIPT.cleanup()
except:
strErrorMessage = "Error: " + str(sys.exc_info()[0]) + " - Message: " + str(sys.exc_info()[1])
print "Function:GetAutoscript(" + strAutoscriptName + ") - Failed with: [" + strErrorMessage + "]"
return strReturnValue
print "============================================(1)"
print "Read autoscript EH_FUNCTION_01"
strFunction = GetAutoscript("EH_FUNCTION_01")
print "============================================(2)"
print "strFunction:"
print strFunction
print "============================================(3)"
print "Performing Exec - Read Function into memory"
exec(strFunction)
print "============================================(4)"
print "Use Read Function - by executing iValue = iIncrease(1)"
iValue = iIncrease(1)
print "iValue:"
print str(iValue)
print "============================================(5)"
print "Use Read Function - by executing iValue = iIncrease(2)"
iValue = iIncrease(2)
print "iValue:"
print str(iValue)
print "============================================(6)"
print "Use Read Function - by executing iValue = iIncrease(10)"
iValue = iIncrease(10)
print "iValue:"
print str(iValue)
----- Script END ----------
And when we execute the script by pressing (the re-introdued) run script button we see the following output:
----- Output START ----------
============================================(1)
Read autoscript EH_FUNCTION_01
============================================(2)
strFunction:
def iIncrease(iIncreaseMe):
print "Function:iIncrease(" + str(iIncreaseMe) + ") - Start";
if (iIncreaseMe == 1):
iReturnValue = iIncreaseMe + 1;
elif (iIncreaseMe == 2):
iReturnValue = iIncreaseMe + 2;
else:
iReturnValue = iIncreaseMe + 10;
print "Function:iIncrease(" + str(iIncreaseMe) + ") - End - Returning:[" + str(iReturnValue) + "]";
return iReturnValue;
============================================(3)
Performing Exec - Read Function into memory
============================================(4)
Use Read Function - by executing iValue = iIncrease(1)
Function:iIncrease(1) - Start
Function:iIncrease(1) - End - Returning:[2]
iValue:
2
============================================(5)
Use Read Function - by executing iValue = iIncrease(2)
Function:iIncrease(2) - Start
Function:iIncrease(2) - End - Returning:[4]
iValue:
4
============================================(6)
Use Read Function - by executing iValue = iIncrease(10)
Function:iIncrease(10) - Start
Function:iIncrease(10) - End - Returning:[20]
iValue:
20
============================================(7)
----- Output END ----------
Note: We are using the function exec() to read the function into memory, the exec()-function becomes available by including "from org.python.util import PythonInterpreter"
Let us know what you think...!
#Customizations
------------------------------
Kind Regards,
Erwin Hebing
------------------------------