Jython V2.7 での動作の変更

Jython V2.1 スクリプトを移植して Jython V2.7 を使用する場合に知っておく必要のあることについて説明します。

V2.7 では、Jython の動作が以下のように変更になっています。 作成したスクリプトが Jython V2.7 で正常に動作しない場合、提案されている以下の手順を使用してスクリプトを更新するか、引き続き古い Jython V2.1 を使用してください。

Jython V2.7 で推奨されないライブラリー・モジュール

一部の V2.1 ライブラリー・モジュールは、非推奨となったか、または Jython V2.7 用に書き直されました。 そのため、Jython V2.7 スクリプトでそれらをインポートすると、次のような ImportError を受け取ります。
WASX7017E: ファイル "c:/test.py" の実行中に例外を受け取りました。例外情報: com.ibm.bsf.BSFException: Jython からの例外:
Traceback (most recent call last):
File "<string>", line 1, in <module>
ImportError: No module named jreload
V2.7 で利用可能な最新の Jython ライブラリー関数を使用するように Jython スクリプトを書き換える必要があります。 スクリプトを更新することが望ましくない場合は、引き続き古い Jython V2.1 を使用してください。
非推奨の Jython ライブラリー・モジュールを以下に示します。
  • dospath
  • gopherlib
  • javaos
  • jreload
  • reconvert
  • tzparse
  • whrandom

javaos モジュールは、os に置き換えられました。 jreload の関数の大部分は、V2.7 の ihooks に含まれています。

String の動作の変更

V2.7 における String 処理の動作では、デフォルトの Unicode ストリング・タイプが使用されます。 これは、既存のアプリケーション・サーバーの機能には影響しませんが、戻されるストリングは、ストリング・リテラル u を先頭に追加された Jython ユニコード・ストリングとして表示されます。 例えば、通常の string は、Unicode u'string として戻されます。 戻されたストリング値を wsadmin コマンドの変数として使用する場合は、そのストリング値に Unicode ストリングが含まれていないことを確認してください。 ストリング値に Unicode ストリングが含まれている場合は、 val1wsadmin コマンドに渡す前に str(va1) を使用します。 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例外。 以下の値を上げる必要はありません。SystemExitv2.1では例外が発生しますが、スクリプトは以下の原因で失敗する可能性があります。SystemExit収集しない場合はエラーが発生します。SystemExitv2.7:

この動作を例示するサンプル・コード 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 からの例外:
	Traceback (most recent call last):
           	File "<string>", line 12, in <module>
	SystemExit: 0

この問題は、以下の解決方法うちいずれか 1 つを使用することにより回避できます。

  • 以下を上げたくない場合は、 sys.exit() をコメント化します。SystemExit例外。
  • 以下の代わりに 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 など) に配置できます。

custom.py は、次のようにして test.py を実行する際に自動的にロードされます。
wsadmin -f c:/test.py
custom.pyc:\customscripts ディレクトリーなどの他の場所に配置されている場合は、 -profile <profile_module> を指定して、以下のようなカスタム・モジュールをインポートする必要があります。
wsadmin -profile c:/customscripts/custom.py -f c:/test.py
異なる複数の場所にある複数のモジュールをインポートする必要がある場合には以下のようにします。例えば次の例を考えます。
  • test1.pyprofile_root/profile_name ディレクトリーにある
  • test2.pyprofile_root/ ディレクトリーにある
この場合、次のようにして複数の -profile <profile_module> コマンドを使ってモジュールを追加できます。
wsadmin -profile <profile_root/profile_name/test1.py> -profile <profile_root/test2.py> -f c:/test.py
あるいは、次のように Jython のシステム・プロパティー python.path を使ってモジュールのパスを追加することもできます。 それらのパスは、Jython のロード時にプロパティー python.path に追加されます。
wsadmin.sh -lang jython -javaoption "-Dpython.path=<profile_root/profile_name>;< profile_root>" -f c:/test.py

インポート・モジュールが wsadmin Admin コマンドを呼び出すと、以下を受け取ることができます。NameError: global name 'AdminConfig' is not definedエラー・メッセージ。 AdminControlAdminAppAdminTaskHelp など、他の Admin オブジェクトに関してもエラー・メッセージが出る場合があります。 Jython 2.7 で、Admin オブジェクトはグローバル名前空間で登録されなくなったため、代わりにシステムのローカル名前空間からそれを取得する必要があります。

例えば、custom.py に関数 print1() が含まれていて、そこから次のように wsadmin AdminConfig.list() コマンドが呼び出されるとします。
def print1():
           print "I am custom"
           nodes = AdminConfig.list('Node')
           print "Nodes: " + nodes
この場合、test.py を実行すると、次のエラーを受け取ることがあります。
WASX7017E: ファイル "c:/test.py" の実行中に例外を受け取りました。例外情報: com.ibm.bsf.BSFException: 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
以下を解決するには、NameErrorインポート・モジュール・スクリプト (呼び出しスクリプトではない) の前に、以下の Jython コマンドを追加する必要があります。
#custom.py:

import sys

# Retrieve scripting objects from system local name space 
AdminConfig = sys._getframe(1).f_locals['AdminConfig']
スクリプトで Admin の他のコマンドを呼び出す場合、Admin の他のオブジェクトも取得する必要があります。
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,TypeErrorJython クラスに独自のエラー・タイプを作成することもできます。

例:

test.py:

	nodeName = "testNode1"
	if (nodeName != "testNode2"):
     	      raise "Could not find node name '%s'" % (nodeName)

これは Jython 2.1で機能しますが、以下を受け取ります。TypeErrorJython V2.7:

WASX7017E: ファイル "c:/p.py" の実行中に例外を受け取りました。例外情報: com.ibm.bsf.BSFException: 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

例外または例外として発生するようにスクリプトを再作成する必要があります。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 タイプは PyIntegerPyFloat などの Py オブジェクトであり、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 からの例外:
	Traceback (most recent call last):
  	File "<input>", line 1, in <module>
	AttributeError: 'float' object has no attribute 'toString'

numeric タイプを表示するには、次のコマンドを使用できます。

print "foo = %f" % foo
	foo = 3.141500

Windows オペレーティング・システムでの英語以外のロケール

Windows オペレーティング・システムで Jython V2.7 を使用する場合、エンコード方式の処理方法が原因で Unicode 文字の処理が影響を受けます。 Jython V2.7 の動作は、UTF-8 エンコードを前提としています。 UNIX オペレーティング・システムでは、文字の処理と表示は正しく行われます。 Windows オペレーティング・システムの場合、Jython V2.7 プロセスは、Windows コマンド・プロンプトで文字の表示を中断します。これは、Windows コマンド・コンソールが UTF-8 をサポートしておらず、Unicode 文字を誤って解釈するためです。

この問題を回避するには、wsadmin.bat ファイルを更新して、-Dfile.encoding=UTF-8 ステートメントを追加します。 以下の例は、このスクリプトの調整を示しています。
%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 %*

-useJython21 オプションの使用

行継続文字 "\" を指定して実装された Jython スクリプトは、 WebSphere Application Server バージョン 8.0 とバージョン 8.5.5 では適切に実行されますが、 バージョン 9.0 では正しく実行されません。 バージョン 9.0 の場合、同じスクリプトでも com.ibm.bsf.BSFException: exception from Jython: "no viable alternative at input".. で失敗します。

この例外に対しては次の 2 つの解決策が考えられます。
  1. 継続文字を削除し、スクリプトを長い 1 行にします。 この方法は Jython27 を使用する V9.0 に有効です。
  2. (行継続文字を使用した状態で) スクリプトをそのままにします。ただし、-useJython21 option をスクリプトに追加します。
この状態を示すスクリプト例を以下に示します。
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 \
....

スクリプト・オブジェクトの名前空間に対する変更

Jython 2.7 の場合、スクリプト・オブジェクトは、グローバル名前空間に登録されるのではなく、システムのローカル名前空間から取得されます。 スクリプト・オブジェクトは、AdminApp、AdminConfig、AdminTask、AdminControl、および Help です。

カスタム・スクリプトをスクリプト・ライブラリーにインポートする際に、そのカスタム・スクリプトが AdminUtilities および Micromanagement などの wsadmin スクリプト・ライブラリーを実行すると、NameError エラーを受け取る可能性があります。 このエラーが発生するのは、wsadmin スクリプト・ライブラリーが、システムのローカル名前空間で指定されていないスクリプト・オブジェクトを使用する場合です。 以下に test1 カスタム・スクリプトの例を示します。

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
以下の例では、test1 カスタム・スクリプトが NameError エラーを受け取ります。
D:&#xa5;WebSphere&#xa5;AppServer&#xa5;profiles&#xa5;Dmgr01&#xa5;bin>wsadmin -conntype none -javaoption "-Dwsadmin.script.libraries=c:&#xa5;testscript" -c "test1.disableAdminAuthCache('abc')"
WASX7357I: 要求により、このスクリプト・クライアントはどのサーバー・プロセスにも接続されていません。 特定の構成とアプリケーションの操作がローカル・モードで使用可能です。
WASX7015E: コマンド "test1.disableAdminAuthCache('abc')" を実行中に例外が発生しました。例外情報:
com.ibm.bsf.BSFException: Jython からの例外:
Traceback (most recent call last):
  File "<input>", line 1, in <module>
NameError: name 'test1' is not defined
NameError エラーを解決するには、スクリプト・オブジェクトをカスタム・スクリプトに追加します。
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']
-usejython21 オプションを使用してカスタム・スクリプトを Jython V2.1 として実行し、カスタム・スクリプトが wsadmin スクリプト・ライブラリーを実行する場合は、カスタム・スクリプト内のスクリプト・オブジェクトをコメント化します。 以下の例では、スクリプト・ライブラリーがコメント化されています。
$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']

test.py という名前のカスタム・スクリプトは許可されない

カスタム・スクリプトの実行時に AttributeError エラーを回避するには、カスタム・スクリプトに test.py という名前を付けないでください。これは、Jython ライブラリー・モジュールで test の用語が使用されているためです。 以下の例は、AttributeError エラーを示しています。
D:&#xa5;WebSphere&#xa5;AppServer&#xa5;profiles&#xa5;Dmgr01&#xa5;bin>wsadmin -conntype none -javaoption "-Dwsadmin.script.libraries=c:&#xa5;testscript" -c "test.disableAdminAuthCache('abc')"
WASX7357I: 要求により、このスクリプト・クライアントはどのサーバー・プロセスにも接続されていません。 特定の構成とアプリケーションの操作がローカル・モードで使用可能です。
WASX7015E: コマンド ""test.disableAdminAuthCache('AMYLIN8Cell43')" を実行中に例外が発生しました。例外情報:
com.ibm.bsf.BSFException: Jython からの例外:
Traceback (most recent call last):
  File "<input>", line 1, in <module>
AttributeError:「module」オブジェクトに属性「disableAdminAuthCache」がありません。