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

Some V2.1 library modules were deprecated or rewritten for Jython V2.7. So if your Jython V2.7 script imports them, you receive an ImportError like so:
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.
Deprecated Jython library modules:
  • 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)   
	nodes
	'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.

For example:

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.

The custom.py is automatically loaded when you run test.py such as:
wsadmin -f c:/test.py
If custom.py is placed in other location such as c:\customscripts directory, you need to specify -profile <profile_module> to import the custom module such as:
wsadmin -profile c:/customscripts/custom.py -f c:/test.py
If you need to import multiple modules located in different locations, for example:
  • test1.py is in the profile_root/profile_name directory
  • test2.py is in the profile_root/ directory
You can add modules through multiple -profile <profile_module> commands such as:
wsadmin -profile <profile_root/profile_name/test1.py> -profile <profile_root/test2.py> -f c:/test.py
Or you can add the modules path through the Jython system property python.path and it appends the paths to the property python.path when Jython is loaded such as:
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, Admin objects no longer register in the global name space so you need to retrieve it from system local name space instead.

For example, if custom.py contains the function print1(), which invokes the wsadmin AdminConfig.list() command:
def print1():
           print "I am custom"
           nodes = AdminConfig.list('Node')
           print "Nodes: " + nodes
When you run test.py, you can receive the error:
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
To resolve the NameError, you need to add the following Jython commands in front of your importing module script (not the calling script):
#custom.py:

import sys

# Retrieve scripting objects from system local name space 
AdminConfig = sys._getframe(1).f_locals['AdminConfig']
You can retrieve other Admin objects too if your script invokes other Admin commands:
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.

For example:

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

Icon that indicates the type of topic Concept topic



Timestamp icon Last updated: March 5, 2017 17:27
File name: rxml_jython27.html