Jython V2.7 behavior changes
Discover what you need to know when porting Jython V2.1 scripts to use Jython V2.7.
The following are known Jython behavioral changes in V2.7. If your script does not work properly with Jython V2.7, update your script by using the following suggestions or stay with the older Jython V2.1:
- Deprecated library modules in Jython V2.7
- String behavior changes
- Changes to sys.exit() function
- Changes to importing modules
- How to raise a string exception
- Numeric type changes
Deprecated library modules in Jython V2.7
WASX7017E: Exception received while running file "c:/test.py"; exception information: com.ibm.bsf.BSFException: exception from Jython:
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: No module named jreload
You
need to rewrite your Jython script to use the most recent Jython library functions available in V2.7
or continue to use the older Jython V2.1 if you do not want to update your script.- dospath
- gopherlib
- javaos
- jreload
- reconvert
- tzparse
- whrandom
The javaos module was replaced with os. Most of the jreload functions are contained within ihooks in V2.7.
String behavior changes
The String handling behavior uses a default string type of Unicode in V2.7. It does not impact the existing WebSphere Application Server functions, but it displays the returned string as Jython Unicode string with a string literal u prepended for example, u'string. The user can specify print command to display the regular string or call str() command to convert Jython Unicode string to a regular string such as:
AdminConfig.list('Node')
u'TestCellManager(cells/TestCell/nodes/TestCellManager|node.xml#Node_1)\r\nTestNode(cells/TestCell/nodes/TestNode|node.xml#Node_1)'
# use print command to display regular string
print AdminConfig.list('Node')
TestCellManager(cells/TestCell/nodes/TestCellManager|node.xml#Node_1)
TestNode(cells/TestCell/nodes/TestNode|node.xml#Node_1)
nodes = AdminConfig.list('Node')
u'TestCellManager(cells/TestCell/nodes/TestCellManager|node.xml#Node_1)\r\nTestNode(cells/TestCell/nodes/TestNode|node.xml#Node_1)'
print nodes
TestCellManager(cells/TestCell/nodes/TestCellManager|node.xml#Node_1)
TestNode(cells/TestCell/nodes/TestNode|node.xml#Node_1)
# Call str() command to convert unicode string to regular string
nodes = str(nodes)
noeuds
'TestCellManager(cells/TestCell/nodes/TestCellManager|node.xml#Node_1)\r\nTestNode(cells/TestCell/nodes/TestNode|node.xml#Node_1)'
Changes to sys.exit() function
The sys.exit() raises a SystemExit exception, so it expects to capture the SystemExit exception. It does not need to raise the SystemExit exception in v2.1, but your script can fail with the SystemExit error if you do not capture the SystemExit exception in v2.7:
See example code test.py, which demonstrates this behavior:
test.py:
a = 5
b = 6
if (a > b):
print "a > b"
sys.exit(1)
else:
print " a < b"
sys.exit(0)
The following exception occurs:
WASX7017E: Exception received while running file "c:/q.py"; exception information: com.ibm.bsf.BSFException: exception from Jython:
Traceback (most recent call last):
File "<string>", line 12, in <module>
SystemExit: 0
The problem can be avoided by using any one of the following solutions:
- Comment out sys.exit() if you don't want to raise the SystemExit exception.
- Use os._exit() function instead of sys.exit() if you don't want
to trigger an
exception.
test.py: import os a = 5 b = 6 if (a > b): print "a > b" os._exit(1) else: print "a < b" os._exit(0)
- Capture the SystemExit exception if you want to detect the
SystemExit error and raise an
exception.
test.py: a = 5 b = 6 try: if (a > b): print "a > b" sys.exit(1) else: print "a < b" sys.exit(0) except SystemExit: print "sys.exit() worked as expected" except: print "Something went wrong"
Changes to importing modules
If your Jython script needs to import a module, the module can be placed in the wsadmin working directory or it can be placed in another location.
Exemple :
test.py contains the following line:
import custom
The custom.py can be placed in the wsadmin working directory such as c:\WebSphere\AppServer\profiles\dmgr01\bin where wsadmin is run.
wsadmin -f c:/test.py
wsadmin -profile c:/customscripts/custom.py -f c:/test.py
- test1.py is in the profile_root/profile_name directory
- test2.py is in the profile_root/ directory
wsadmin -profile <profile_root/profile_name/test1.py> -profile <profile_root/test2.py> -f c:/test.py
wsadmin.sh -lang jython -javaoption "-Dpython.path=<profile_root/profile_name>;< profile_root>" -f c:/test.py
If your importing module invokes wsadmin Admin commands, you can receive the NameError: global name 'AdminConfig' is not defined error message. It can complain about other Admin objects such as AdminControl, AdminApp, AdminTask, or Help as well. With Jython 2.7, the global name space and Admin objects no longer register in the global name space so you need to retrieve it from system local name space instead.
def print1():
print "I am custom"
nodes = AdminConfig.list('Node')
print "Nodes: " + nodes
WASX7017E: Exception received while running file "c:/test.py"; exception information: com.ibm.bsf.BSFException: exception from Jython:
Traceback (most recent call last):
File "<string>", line 15, in <module>
File "<string>", line 9, in print2
File "c:\custom.py", line 21, in print1
cell = AdminConfig.list('Cell')
NameError: global name 'AdminConfig' is not defined
#custom.py:
import sys
# Retrieve scripting objects from system local name space
AdminConfig = sys._getframe(1).f_locals['AdminConfig']
AdminApp = sys._getframe(1).f_locals['AdminApp']
AdminControl = sys._getframe(1).f_locals['AdminControl']
AdminTask = sys._getframe(1).f_locals['AdminTask']
Help = sys._getframe(1).f_locals['Help']
def print1():
print "I am custom"
nodes = AdminConfig.list('Node')
print "Nodes: " + nodes
How to raise a string exception
Jython V2.7 does not allow raising a string exception, so you need to either raise an exception or error such as ValueError, AttributeError, TypeError, or create your own error type in a Jython class.
Exemple :
test.py:
nodeName = "testNode1"
if (nodeName != "testNode2"):
raise "Could not find node name '%s'" % (nodeName)
It works with Jython 2.1, but you receive the following TypeError in Jython V2.7:
WASX7017E: Exception received while running file "c:/p.py"; exception information: com.ibm.bsf.BSFException: exception from Jython:
Traceback (most recent call last):
File "<string>", line 5, in <module>
TypeError: exceptions must be old-style classes or derived from BaseException, not str
You need to rewrite your script to raise as an exception or a ValueError/TypeError/AttributeError.
- Raise an
exception:
if (nodeName != "testNode2"): raise Exception("Could not find node name '%s'" % (nodeName))
- Raise a
ValueError:
if (nodeName != "testNode2"): raise ValueError("Could not find node name '%s'" % (nodeName))
- Create your own error type in a Jython
class:
class MyError(Exception): '''raise this when there's an error from my command''' if nodeName != "testNode2": raise MyError("Could not find node name '%s'" % (nodeName))
Numeric type changes
In Jython V2.1, numeric types were Py objects like PyInteger or PyFloat and as such had methods like toString(). In Jython V2.7, numeric types are more like native types and do not have these basic Object methods available. The difference was discovered when an integer is passed into a Jython function and its value is printed by using the toString() method.
In Jython V2.7, using this sample code:
foo = 3.1415
print "foo =", foo.toString()
foo =
Results in the following error:
WASX7015E: Exception running command: ""foo =", foo.toString()"; exception information:
com.ibm.bsf.BSFException: exception from Jython:
Traceback (most recent call last):
File "<input>", line 1, in <module>
AttributeError: 'float' object has no attribute 'toString'
You can use the following command to display the numeric type:
print "foo = %f" % foo
foo = 3.141500