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
- Non-English locale on the Windows operating system
- Using the -useJython21 option
- Changes to the name space for scripting objects
- Custom script named test.py not allowed
Deprecated library modules in Jython V2.7
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 jreloadYou 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 application server functions, but it displays the returned string as
Jython Unicode string with a string literal u
added to the beginning of the string.
For example, it returns the regular string
as Unicode u'string
.
When you use the returned string value as a variable for the wsadmin command,
check to make sure that the string value does not contain Unicode string. If the string value
contains Unicode string, then use str(va1)
before you pass val1
to
the wsadmin command. You can specify the print command to
display the regular string. Alternatively, you can call the 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.
wsadmin -f c:/test.py
-profile
<profile_module>
to import the custom module such
as: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
-profile <profile_module>
commands
such
as:wsadmin -profile <profile_root/profile_name/test1.py> -profile <profile_root/test2.py> -f c:/test.py
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.
print1()
,
which invokes the wsadmin AdminConfig.list()
command: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']
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
Non-English locale on the Windows operating system
When you use Jython V2.7 on a Windows operating system, the processing of Unicode characters is affected because of how encoding is handled. The Jython V2.7 behavior assumes UTF-8 encoding. On the UNIX operating system, the processing and display of characters is correct. For the Windows operating system, the Jython V2.7 process breaks the display of characters on the Windows command prompt because the Windows command console does not support UTF-8 and misinterprets the Unicode characters.
-Dfile.encoding=UTF-8
statement to avoid this issue. The following example
demonstrates this script
adjustment.%JAVA_EXE% -Dfile.encoding=UTF-8
-Djava.ext.dirs="%WAS_JAVA_EXT_DIRS%"
-Djava.endorsed.dirs="%WAS_ENDORSED_DIRS%"
-Dcmd.properties.file=%TMPJAVAPROPFILE% %PERFJAVAOPTION%
%WAS_LOGGING% %CONSOLE_ENCODING%
%WAS_DEBUG% "%CLIENTSOAP%"
"%JAASSOAP%" "%CLIENTSAS%"
"%CLIENTSSL%"
%WSADMIN_PROPERTIES_PROP%
%WORKSPACE_PROPERTIES% "
-Duser.install.root=%USER_INSTALL_ROOT%"
"-Dwas.install.root=%WAS_HOME%
" %javaoption%
com.ibm.wsspi.bootstrap.WSPreLauncher -nosplash -application
com.ibm.ws.bootstrap.WSLauncher
com.ibm.ws.admin.services.WsAdmin %*
Using the -useJython21 option
Jython scripts that are implemented with a line continuation character "\"
execute properly on WebSphere Application Server Version 8.0 and Version 8.5.5 but not on Version
9.0. For Version 9.0, these same scripts fail with a com.ibm.bsf.BSFException: exception
from Jython: "no viable alternative at input"..
.
- Remove the continuation character and string the script out into a long single line. This approach works for V9.0 using Jython27.
- Keep your script as is (with the line continuation character), but add the -useJython21 option to the script.
def updateEAR(input_appName, input_appname_path,
input_MapModulesToServers):
#print "input_appName : " + input_appName
#print "input_appname_path : " + input_appname_path
#print "input_MapModulesToServers : " +
input_MapModulesToServers
AdminApp.update(input_appName, \
'app',
'[ -operation update \
-contents ' + input_appname_path + ' \
-nopreCompileJSPs \
-distributeApp \
-nouseMetaDataFromBinary \
-nodeployejb \
-createMBeansForResources \
....
Changes to the name space for scripting objects
For Jython 2.7, the scripting objects are retrieved from the system local name space instead of being registered in the global name space. The scripting objects are AdminApp, AdminConfig, AdminTask, AdminControl, and Help.
When you import a custom script to the scripting library, if the custom script runs wsadmin scripting libraries such as AdminUtilities and Micromanagement, the custom script might receive a NameError error. The error occurs when the wsadmin scripting libraries use scripting objects that are not specified in the system local name space. The following example is the test1 custom script:
test1.py: (invoke AdminUtilities script library function)
import AdminUtilities,AdminClusterManagement,AdminServerManagement
bundleName = "com.ibm.ws.scripting.resources.scriptLibraryMessage"
resourceBundle = AdminUtilities.getResourceBundle(bundleName)
# 1: Remove Cell Custom Property
def disableAdminAuthCache(cellName):
try:
# Get a handle to the JVM object...
AdminUtilities.infoNotice("Cell name supplied to disableAdminAuthCache: " + cellName)
propertyId = AdminConfig.getid("/Cell:"+cellName+"/Property:enableAdminAuthorizationCache/")
AdminUtilities.infoNotice("Property to remove is: " + propertyId)
# Get the current args set
if (propertyId != ""):
AdminConfig.remove(propertyId)
AdminUtilities.infoNotice("enableAdminAuthorizationCache property is now removed")
except:
AdminUtilities.infoNotice("There was an issue removing the enableAdminAuthorizationCache property")
raise
#endTry
#endDef
D:\WebSphere\AppServer\profiles\Dmgr01\bin>wsadmin -conntype none -javaoption "-Dwsadmin.script.libraries=c:\testscript" -c "test1.disableAdminAuthCache('abc')" WASX7357I: By request, this scripting client is not connected to any server process. Certain configuration and application operations will be available in local mode. WASX7015E: Exception running command: "test1.disableAdminAuthCache('abc')"; exception information: com.ibm.bsf.BSFException: exception from Jython: Traceback (most recent call last): File "<input>", line 1, in <module> NameError: name 'test1' is not defined
import sys
# Retrieve scripting objects from 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']
$WAS_HOME/scriptLibraries/servers/V70/AdminServerManagement.py
# Retrieve scripting objects from 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']
Custom script named test.py not allowed
test.py
because the test
term is used in Jython library modules.
The following example illustrates the AttributeError
error:D:\WebSphere\AppServer\profiles\Dmgr01\bin>wsadmin -conntype none -javaoption "-Dwsadmin.script.libraries=c:\testscript" -c "test.disableAdminAuthCache('abc')" WASX7357I: By request, this scripting client is not connected to any server process. Certain configuration and application operations will be available in local mode. WASX7015E: Exception running command: "test.disableAdminAuthCache('AMYLIN8Cell43')"; exception information: com.ibm.bsf.BSFException: exception from Jython: Traceback (most recent call last): File "<input>", line 1, in <module> AttributeError: 'module' object has no attribute 'disableAdminAuthCache'