Jython V2.7 行为更改
发现您移植 Jython V2.1 脚本以使用 Jython V2.7 时需要了解的内容。
下列是 V2.7 中的已知 Jython 行为更改。如果您的脚本无法正常地与 Jython V2.7 配合工作,请使用下列建议来更新脚本或继续使用旧的 Jython V2.1:
Jython V2.7 中不推荐使用的库模块
WASX7017E: 运行文件“c:/test.py”时接收到异常;异常信息:com.ibm.bsf.BSFException:来自 Jython 的异常:
回溯(最近的调用显示在最后):
文件“<string>”,第 1 行,在 <module> 中
ImportError:没有名为 jreload 的模块
您必须重新编写 Jython 脚本以使用 V2.7 中提供的最新 Jython 库函数,或者,如果您不想更新脚本,请继续使用旧的 Jython V2.1。- dospath
- gopherlib
- javaos
- jreload
- reconvert
- tzparse
- whrandom
javaos 模块已替换为 os。在 V2.7 中,大部分 jreload 函数包含在 ihooks 中。
String 行为更改
在 V2.7 中,String 处理行为使用缺省字符串类型 Unicode。它不会影响现有的 WebSphere Application Server 函数,但它使用在开头附加 u 的字符串字面值(例如 u'string)将返回的字符串显示为 Jython Unicode 字符串。用户可指定 print 命令以显示常规字符串,或者调用 str() 命令以将 Jython Unicode 字符串转换为常规字符串,例如:
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)'
对 sys.exit() 函数的更改
sys.exit() 会引发 SystemExit 异常,因此它应该捕获 SystemExit 异常。在 V2.1 中,它不需要引发 SystemExit 异常,但如果在 V2.7 中不捕获 SystemExit 异常,那么脚本可能会因 SystemExit 错误而失败:
请参阅示例代码 test.py,它演示了这种行为:
test.py:
a = 5
b = 6
if (a > b):
print "a > b"
sys.exit(1)
else:
print " a < b"
sys.exit(0)
发生以下异常:
WASX7017E: 运行文件“c:/q.py”时接收到异常;异常信息:com.ibm.bsf.BSFException:来自 Jython 的异常:
回溯(最近的调用显示在最后):
文件“<string>”,第 12 行,在 <module> 中
SystemExit:0
可以使用下列任何一种解决方案来避免此问题:
- 如果您不想引发 SystemExit 异常,请注释掉 sys.exit()。
- 如果您不想触发异常,请使用 os._exit() 函数来代替 sys.exit()。
test.py: import os a = 5 b = 6 if (a > b): print "a > b" os._exit(1) else: print "a < b" os._exit(0)
- 如果您想检测 SystemExit 错误并引发异常,请捕获 SystemExit 异常。
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"
对导入模块的更改
如果 Jython 脚本需要导入模块,那么可以将该模块放在 wsadmin 工作目录中,也可以将其放在另一位置。
例如:
test.py 包含下面这一行:
import custom
custom.py 可以放在运行 wsadmin 的 wsadmin 工作目录中,例如 c:\WebSphere\AppServer\profiles\dmgr01\bin。
wsadmin -f c:/test.py
wsadmin -profile c:/customscripts/custom.py -f c:/test.py
- test1.py 在 profile_root/profile_name 目录中
- test2.py 在 profile_root/ 目录中
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
如果导入模块调用 wsadmin Admin 命令,那么您可能会接收到以下错误消息:NameError:全局名称“AdminConfig”未定义。此问题也可能是其他 Admin 对象(例如 AdminControl、AdminApp、AdminTask 或 Help)所致。对于 Jython 2.7,全局名称空间和 Admin 对象不再于全局名称空间中进行注册,因此您需要改为从系统局部名称空间中进行检索。
def print1():
print "I am custom"
nodes = AdminConfig.list('Node')
print "Nodes: " + nodes
WASX7017E: 运行文件“c:/test.py”时接收到异常;异常信息:com.ibm.bsf.BSFException:来自 Jython 的异常:
回溯(最近的调用显示在最后):
文件“<string>”,第 15 行,在 <module> 中
文件“<string>”,第 9 行,在 print2 中
文件“c:\custom.py”,第 21 行,在 print1 中
cell = AdminConfig.list('Cell')
NameError:全局名称“AdminConfig”未定义
#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
如何引发字符串异常
Jython V2.7 不允许引发字符串异常,因此您需要引发 ValueError、AttributeError 或 TypeError 之类的异常或错误,或者在 Jython 类中创建自己的错误类型。
例如:
test.py:
nodeName = "testNode1"
if (nodeName != "testNode2"):
raise "Could not find node name '%s'" % (nodeName)
它可以与 Jython 2.1 配合工作,但是您会在 Jython V2.7 中接收到以下 TypeError:
WASX7017E: 运行文件“c:/p.py”时接收到异常;异常信息:com.ibm.bsf.BSFException:来自 Jython 的异常:
回溯(最近的调用显示在最后):
文件“<string>”,第 5 行,在 <module> 中
TypeError:异常必须是旧样式的类或者从 BaseException 派生,而不能是 str
您需要重新编写脚本,以引发异常或 ValueError/TypeError/AttributeError。
- 引发异常:
if (nodeName != "testNode2"): raise Exception("Could not find node name '%s'" % (nodeName))
- 引发 ValueError:
if (nodeName != "testNode2"): raise ValueError("Could not find node name '%s'" % (nodeName))
- 在 Jython 类中创建您自己的错误类型:
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))
数字类型更改
在 Jython V2.1 中,numeric 类型为 Py 对象(例如 PyInteger 或 PyFloat),因此具有 toString() 之类的方法。在 Jython V2.7 中,numeric 类型更像是 native 类型,而没有这些基本 Object 方法。将整数传递到 Jython 函数并使用 toString() 方法来输出它的值时,可以发现这种差别。
在 Jython V2.7 中,使用以下样本代码:
foo = 3.1415
print "foo =", foo.toString()
foo =
将产生以下错误:
WASX7015E: 运行以下命令时发生异常:“"foo =", foo.toString()”;异常信息:
com.ibm.bsf.BSFException: 来自 Jython 的异常:
回溯(最近的调用显示在最后):
文件“<input>”,第 1 行,在 <module> 中
AttributeError:“float”对象没有“toString”属性
您可使用以下命令来显示 numeric 类型:
print "foo = %f" % foo
foo = 3.141500