Best practices for converting wsadmin scripts from Jacl to Jython

Explore strategies for manual and automated conversion

This article describes best practices for manual and automatic conversion of Jacl script to Jython. Jacl and Jython are types of WebSphere®Administration Scripting (wsadmin scripts), which is the preferred way to manage servers and applications on WebSphere Application Server. Of the two types of wsadmin scripts, Jython is the preferred scripting method since WebSphere Application Server V7. Future investment will focus on Jython as development on Jacl stabilizes. Thus, to ease future maintenance, convert your wsadmin scripts from Jacl to Jython.

Share:

Zheng You Zhou (zyouzhou@cn.ibm.com), Software Engineer, IBM

zhou zhengyou's photoZheng You joined IBM WebSphere Commerce as a Software Engineer in July 2010. Zheng You mainly works on WebSphere Commerce migration development but is also interested in Java Technologies that are based on WebSphere Application Server, such as Apache Ant, Eclipse plug-in, and Java Platform, Enterprise Edition.



Xi Ying Zhou (zhouxiy@cn.ibm.com), Software Engineer, IBM

zhou xiying's photoXi Ying joined IBM WebSphere Commerce as a Software Engineer in 2004. Xi Ying currently serves as Team Lead for WebSphere Commerce migration development.



13 December 2013

Introduction

The number of applications that are based on WebSphere Application Server grows each day. WebSpere Application Server provides four ways to manage these applications:

  • web-based administration console (manual)
  • command line utilities (manual)
  • API calling (automatic)
  • wsadmin scripting (automatic)

Automatic processes are more usable and efficient than manual operations and for these reasons, are a better management method. Of the two automated processes, wsadmin script is the easiest to maintain and is now considered the best way to manage WebSphere Application Server applications. WebSphere Application Server provides two forms of wsadmin scripts: Jacl and Jython. Starting in WebSphere Application Server V7, Jython is the preferred scripting approach. Future investment will focus on Jython. To support this change and ease future maintenance, you can convert wsadmin scripts from Jacl to Jython. The following sections in the article describe wsadmin scripts, reasons for converting to Jython, and suggested practices when you convert to Jython.


Manage servers and applications in WebSphere Application Server with wsadmin scripting

The WebSphere Administration Scripting (wsadmin scripting) tool is an ideal lightweight tool for the management of servers and applications in WebSphere Application Server. Using wsadmin scripts has several advantages over other methods that are used to manage servers and applications in WebSphere Application Server. For example, wsadmin scripting is useful when you want to implement some complex configurations that are repetitive and time consuming. Each of the following methods has limitations.

  • Web-based administrative integrated console is sufficient for tasks that are simple, short, and non-repetitive. However, the console is not automatic.
  • Command utility tasks are sometimes predefined but have limitations that do not meet all administration requirements.
  • Java™ APIs must be called in Java classes, which you must compile.

The wsadmin scripting framework

The wsadmin scripting is an interface that is based on the Bean Scripting Framework (BSF). BSF is an open source project to implement an architecture for incorporating scripting into Java applications. The BSF architecture works as an interface between Java applications and scripting languages. Because wsadmin script is based on BSF, it can make various Java objects available through specific language interfaces to scripts. Figure 1 shows the major components that are contained in the wsadmin scripting framework.

Figure 1. Components of the wsadmin scripting framework
An image to show the framework of wsadmin scripting

WebSphere Application Server properties are stored in the configuration repository as resources, as shown in Figure 1. Scripting language defines some objects that manage these resources and runs these objects through configuration component service operating on Managed Beans (Mbeans), such as servers or applications. Five management objects are supported by wsadmin scripting. You can use these objects to manage WebSphere Application Server. Two programming languages are used to write wsadmin scripts: Jython and Jacl. In WebSphere Application Server V7, Jacl is stabilized. Jython is a strategic script. Jacl is an alternative implementation of Tool Command Language (TCL) and is written in Java, and Jython is an alternative implementation of Python and is written in Java.

Five management objects

As shown in Figure 1, five management objects are supported by both scripting languages. These administrative objects provide server configuration and management capabilities.

Help
When you're scripting, refer to the Help Object to quickly find information about methods, operations, and attributes.
AdminConfig
Use the AdminConfig object to manage the configuration information that is stored in the repository. This object communicates with the WebSphere Application Server configuration service component to make configuration inquires and changes. You can use it to query existing configuration objects, create configuration objects, modify existing objects, and remove configuration objects.
AdminControl
Use the AdminControl object for operational control. It communicates with Mbeans that represent live objects running a WebSphere server process. It includes commands to query existing running objects and their attributes and runs operations on the objects.
AdminApp
Use the AdminApp object to update application metadata, map virtual hosts to web modules, and map servers to modules for installed applications.
AdminTask
Use the AdminTask object to access a set of task-oriented administrative commands that provide an alternative way to access configuration commands and running object management commands. AdminTask helps you perform more complex tasks and write less code.

Convert Jacl to Jython

Currently, the preferred scripting language for applications in WebSphere Application Server is Jython. In WebSphere Application Server V5.1 and later, wsadmin supported both the Jacl and Jython scripting languages. However, in WebSphere Application Server V7, Jacl became stabilized and Jython became the focused script. Enhancements to Jython continue.

Many enterprise applications are built on the WebSphere Application Server. Some of these applications are large-scale and require automated administration tasks because manual administration is too cumbersome. Also, automation can save on resources and increase efficiency. Because Jython is the preferred scripting language, some existing scripts for applications that are written in Jacl must be converted to Jython.

To convert Jacl to Jython, choose from these methods:


Automatically convert Jacl to Jython with the Jacl2Jython assistant

You can use the IBM® Jacl to Jython Conversion Assistant (Jacl2Jython) to convert Jacl wsadmin scripts to Jython wsadmin scripts. This tool is provided by WebSphere Application Server. In most cases, it can automatically convert wsadmin script in Jacl to the equivalent Jython syntax wsadmin script. You can obtain the tool from the IBM support website or from Rational® Application Developer.

To automatically convert Jacl to Jython with the assistant tool, follow these steps.

  1. Open a command line and change to the directory where the executable Jacl2Jython program is located.
  2. Run the following command
    Jacl2Jython{.bat|.sh} {jacl_script}
    where {jacl_script} represents the full, qualified name for the Jacl script, such as D:\temp\myScript.jacl.
  3. If the command runs successfully, the tool generates a corresponding Jython script. You can find the Jython script in the same directory as the Jacl script. For example, D:\temp\myScript.py.

Disadvantages of the tool

If Jacl2Jython encounters parse errors in the Jacl script, Jython script is not generated. Additionally, some differences between the Jacl and Jython scripting languages make it difficult for the Jacl2Jython tool to convert some lines from Jacl script to Jython. In most cases, the preliminary converted lines of script are flagged #?PROBLEM?. For areas with problems, you must manually verify or alter the script to ensure that the intended runtime results are maintained. Moreover, you must manually verify the converted content line-by-line.

In most cases, you must perform some manual conversion tasks after you run the Jacl2Jython assistant. For information about manual conversion, refer to Manually convert Jacl to Jython.


Manually convert Jacl to Jython

If you understand the similarities between Jacl and Jython syntax and some commonly-used conversion rules, you can make your manual conversion of wsadmin scripts from Jacl to Jython run smoothly.

The rules focus mainly on the differences between Jacl and Jython. An example of each rule is provided, which includes information about the Jacl processes and Jython processes. Additionally, information about conversion is provided. Some rules are a bit complicated - for example, rules about how to handle the returned result from wsadmin script management objects, such as AdminConfig. Also, rules about how to handle regular expression can be complicated because regular expression is different in Jacl and Jython.

For information about rules and syntax, see the following sections.

Best practices for Jacl and Jython scripting

Jacl and Jython are different programming languages. However, as scripting languages, Jacl and Jython use similar syntax in some locations. When you convert Jacl to Jython, you do not need to change instances of syntax that are the same in Jacl and Jython. These instances are listed.

Comments in the code

Both Jacl and Jython use # to mark one sentence as a comment.

Listing 1. Comment is started with #
#  This is a comment

The declaration of global variables

Both Jacl and Jython use the global identifier to declare that a variable is global.

Listing 2. Global variable is declared by the global identifier
Global AdminConfig

The entry point of program

For both Jacl and Jython, the program runs from the first statement that is outside any function. The statement cannot be an import statement for Jython.

The denotation of a string

Both Jacl and Jython use double quotation marks “” to denote a string. However, a Jython string can be enclosed with two single quotation marks '', and a Jacl string can exist without any quotation marks at all.

Standard output statement

To print a string or other contents, use puts in Jacl. In Jython, use print and sys.stdout.write().

Listing 3. Standard output statement example
Jacl:
puts stdout "This is a Jacl string to screen"
puts "print this string to predefined log file"

Jython:
sys.stdout.write("This is a Jacl string to screen")
print "print this string to predefined log file"

Best practices for standard output statements

  • Change all puts stdout to sys.stdout.write.
  • Change all single puts to print.

Code block definition

Jacl uses a pair of brackets {} to define a code block in which there is no format requirement for each line. Jython uses a single colon :. However, there is an obvious difference between these definitions. In Jython, code in the same block can have the same indent for each line, which is a requirement. Otherwise, this block is not recognized by the Jython interpreter.

Listing 4. Code block definition example
Jacl:
if {[llength $argv] < 5} {
    puts "The number of arguments is less than 5."
}

Jython:
if len(argv) < 5:
    print "The number of arguments is less than 5."

Best practices for code block definitions

  • Delete brackets {} in Jacl and use :.
  • Keep the same indention in same block.

Variable definition

To define a variable in Jacl, use set. To use the variable, use $ as the prefix to the variable name. Jython is similar to Java; use an equal sign = to assign a value to the variable.

Listing 5. Variable definition example
Jacl:
set name "Jack"
puts Hello $person

Jython:
name = "Jack"
print "Hello" + person

Best practices for variable definitions

  • To set a value to a variable, delete set and ensure that the equal sign = is located between the value and the variable.
  • To use the variable, delete the $ prefix.

Indention

In Jacl, strict indention is not required. Statements can have any indentions. However, you must adhere to strict indention rules in Jython. All statements in a code block and all statements outside of a code block must use the same indention. Also, statements at the same hierarchy must have the same indention. Otherwise, programs cannot run as you want or successfully compile.

Listing 6. Indention example
Jacl:
set person "Tom"
if { $person == "Tom" } {
    puts Hello $person
puts "This is Jerry" 
}

Jython:
person = "Tom"
if person == "Tom":
    print "Hello" + person
    print "This is Jerry"

Best practices for indention

Use the same indention for all statements in the same codeblock.

List data access

Jacl uses lindex to access each element in a list. In Jython, accessing list data is similar to accessing an array in other advanced programming language, such as Java.

Listing 7. List data access example
Jacl:
set element [lindex $aList 0]

Jython:
element = aList[0]

Best practices for list data access

Change the array index to an exact number.

Logical operators process

Jacl uses the same logical operators as other advanced programming language, such as C or Java. Use || to indicate a logical or relationship and use & & to indicate a logical and relationship. Jython uses the or and and keywords.

Listing 8. Logical operators process example
Jacl:
set str1 "hello"
set str2 "world2"
if { $str1 == "hello" || $str2 == "world" } {
}
if { $str1 == "hello" && $str2 == "world" } {
}

Jython:
str1 = "hello"
str2 = "world"
if str1 == "hello" or str2 == "world":
if str1 == "hello" and str2 == "world":

Best practices for logical operators processes

  • Change "||" to or.
  • Change "&&" to and.

Parsing arguments that are passed into the main function

Jacl stores all arguments that are passed into the main function in the argv global variable, which is a list. Jython stores all arguments in the sys.argv system attribute, which is also a list. To parse arguments, follow the method described in List Data Access. The parsed arguments can then be used correctly by other statements. Typically in wsadmin scripts, programs parse arguments first. The following example shows three arguments.

Listing 9. Parsing arguments that are passed into the main function example
Jacl:
set arg1 [lindex $argv 0]
set arg2 [lindex $argv 1]
set arg3 [lindex $argv 2]

Jython:
argv = sys.argv
arg1 = argv[0]
arg2 = argv[1]
arg3 = argv[2]

Best practices for parsing arguments that are passed into the main function

Write a argv = sys.argv line for every Jython file.

Function definition and invocation

Jacl uses proc to define a function. Jython uses def to define a function. Both Jacl and Jython use the code block that is described earlier in the article to define a function.

Listing 10. Function definition and invocation example
Jacl:
proc subFunction {argv1 argv2 argv3} {
    # function body
}

Jython:
def subFunction(argv1, argv2, argv3):
    # function body

Best practices for function definitions

  • Change proc to def.
  • Change {} for parameters to ().
  • Change the code block {} to single colon :.

Switch statement

Jacl uses the switch keyword to define switch statements; however, Jython does not use switch keywords. If you require the switch function in Jython, you must implement it yourself. Listing 11 shows an example of a switch statement in Jacl and two conversion implementations in Jython. Method 1 shows an if/else statement. Method 2 shows a dictionary data structure and some defined functions. In the second implementation, one function is defined for each case, and a dictionary stores all the cases. Then, when a case argument is passed to the dictionary, a specific case is the result.

Listing 11. Example of a switch statement
Jacl:
Switch –exact -- $var {
val1 {
    # code for the case that the value of var is val1
}

val2 {
    # code for the case that the value of var is val2
}

default {
    # code for the default case that the value of var does not match 
    # any of the above two cases
}
}

Jython:
Method 1 – implemented by if-elif-else
if var == "var1":
    # code for the case that the value of var is val1
elif var == "var2":
    # code for the case that the value of var is val2
else:
    # code for the default case that the value of var does not match 
    # any of the above two cases

Method2 – implemented by a dictionary and functions
def caseForVar1():
    # code for the case that the value of var is val1

def caseForVar2():
    # code for the case that the value of var is val2

def caseForDefault():
    # code for the default case that the value of var does not match
    # any of the above two cases

cases = {"var1":caseForVar1, "var2":caseForVar2}
cases.get(var, caseForDefault)();

Best practices for switch statements

If you compare the implementation methods, you discover that using If/Else in Jython is the simplest way to replace switch statements. Maintenance is easier too.

Process the returned result from the wsadmin management objects

The wsadmin script language defines five types of management objects, such as AdminConfig. Some methods of these management objects retrieve the specified resources. The returned resources can be handled for a specific purpose. For example, AdminConfig contains getId method, which returns the corresponding resources with the passed URI string. Jacl and Jython adopt different ways to deal with the returned resources. In most cases, the returned resource represents a list of objects that are split by a space or line separator. In Jacl, the delimiter is handled automatically so that the returned resources look like a list. However, in Jython, the delimiter is handled explicitly. Jython splits the returned resource string and retrieves a list. Then, you can perform some operations on the list. The following example shows how to use the returned resource to convert wsadmin script from Jacl to Jython.

Listing 12. The getId method of AdminConfig example
Jacl:
set HostAliasList [$AdminConfig getid /VirtualHost:$VirtualHostName/HostAlias:/]

foreach HostAlias $HostAliasList {
    # handle each host alias in the host alias list
}

Jython:
HostAliasList = AdminConfig.getid('/VirtualHost:' + VirtualHostName + '/HostAlias:/')
# Split the HostAliasList by line separator before handle it
for HostAlias in HostAliasList.splitlines():
    # handle each host alias in the host alias list
Listing 13. The method list of AdminApp example
Jacl:
foreach TmpAppName [$AdminApp list] {
    # handle each application
}

Jython:
for TmpAppName in AdminApp.list().splitlines():
    # handle each application

Best practices for processing returned results from wsadmin management objects

  • For the AdminConfig.getid() method and the AdminApp.list() method, use splitlines() to split the returned result to array. For the AdminConfig.showAttribute() method, use the modules [1:len(modules) - 1].split(' ') to split the value to array.
  • For other methods, if you are not sure about splitlines or split(' '), print the result and determine which method is used to split.

Regular expressions process

Jacl uses the regexp keyword to handle regular expressions. Regexp is easy to use because it retrieves the substring that directly matches the pattern. Regexp statements satisfy most requirements for regular expressions in Jacl. However, regular expressions are more complicated in Jython. For example, you need to know the APIs that handle regular expressions in Jython, such as the module re and the model re methods. The article briefly describes some methods in re. You can use the compile method to initialize regular expressions. The compile method returns a pattern that can be used to search the substring from a specified string. This method is often used to convert wsadmin script from Jacl to Jython. You can use the search method to retrieve the substrings from the working string for matching patterns. This method returns a group in which the substrings are stored. You can get the substring per the pattern order in the regular expression. The following example shows the difference between how Jacl and Jython process regular expressions. In the example, the JDBC driver path and JDBC driver JAR file are retrieved from the JDBCDriver variable.

Listing 14. Regular expressions process example
Jacl:
#split the JDBCDriver into two parts:  path, JAR file
regexp {(.*)/([^/]+)$} $JDBCDriver count JDBCDriverPath JDBCDriverJar

Jython:
import re # In Jython, the module re should be imported firstly
#split the JDBCDriver into two parts:  path, jar file
pattern = re.compile('(.*)/([^/]+)$')
JDBCDriverPath = pattern.search(JDBCDriver).groups()[0]
JDBCDriverJar = pattern.search(JDBCDriver).groups()[1]

Best practices for regular expressions

To change the Jacl expression to Jython expression, define the pattern and then use the pattern search method to generate the pattern values.

Exception handling process

Jacl uses the catch keyword to handle exceptions. However, Jython uses a more common method that is typically used by advanced programming languages. To process the exception during the program execution, Jython uses two keywords, try and except. The Jacl handling mechanism is different from the Jython handling mechanisms. If an exception occurs in Jacl, the exception message is directly returned in a variable that is defined in the catch expression. However, in Jython, the exception message is retrieved from the sys.exc_info() method. The following example shows how to stop a running application with the AdminConfig management object. Because an error can be thrown when you stop an application, the exception is caught with a process.

Listing 15. Exception handling process example
Jacl:
catch {$AdminControl invoke $appMgt stopApplication $AppName} error
if { $error != "" } {
    puts "Failed to stop application $AppName: $error"
} else {
    puts "$AppName on node $node with process $process stopped"
}

Jython:
try:
    AdminControl.invoke(appMgt, 'stopApplication', AppName)
    print AppName + ' on node ' + node + ' with process ' + process + ' stopped'
except:
    print 'Failed to stop application ' + AppName + ': ' + sys.exc_info()

Best practices for exception handling

Use Jython exception format.

Dynamic variable process

In the most advanced programming languages, you must declare and initialize variables before you use them. Also, you must explicitly specify the variable name to match the previously declared literal string. However, you can use other scripting languages to retrieve a value for a variable. To retrieve a value, reference another variable that is dynamically seen as a group of declared variables. The group of variables is used per actual case. As script languages, both Jacl and Jython support dynamic variables; however, they handle dynamic variables differently. In Jacl, if you add the $ prefix to the dynamic variable name, you can use the variable the same way as you use other common variables. In Jython, the $ prefix retrieves the variable's value. Jython requires you to use the eval function to retrieve variable values.

Listing 16. Dynamic variable process example
In Jacl:
set var01 "value01"
set var02 "value01"
set var10 "value10"

set var ""
if {$i < 10} {
    append var $ "var0" $i
} else {
    append var $ "var" $i
}

puts $var

In Jython:
var01 = "value01"
var02 = "value02"
var10 = "value10"

var = ""
if i < 10:
    var = var + "var0" + str(i)
else:
    var = var + "var" + str(i)

print eval(var)

Best practices for dynamic variables

In Jython, the eval method is used to obtain the value of a dynamic variable.

Call Java objects

Jacl is a TCL script language that is implemented by Java. Also, Jython is a Python script language that is implemented by Java. It is easy for both Jacl and Jython to call Java directly. However, they start Java APIs differently. For example, you import classes and start a new instance for a class differently in Jacl and Jython, as shown in the following example.

Listing 17. Call Java objects example
Jacl:
java::import java.io.FileInputStream
java::import java.util.Properties
set fileprop [java::new Properties]
set fileStream [java::new FileInputStream $propFileName]
$fileprop load $fileStream

Jython:
from java.io import FileInputStream
from java.util import Properties
fileprop = Properties()
fileStream = FileInputStream(propFileName)
fileprop.load(fileStream)

Best practices for calling Java objects

Use Jython Java calling format when converting from Jacl.


Test the Jython script that is converted from Jacl

When you finish converting a wsadmin script from Jacl to Jython, you can test it in the WebSphere Application Server run environment. By default, the server is started first because the Simple Object Access Protocol (SOAP) connection is used for the wsadmin script. Also, you can change it. All wsadmin running parameters are stored in the wsadmin.properties file, which is in the properties directory under a WebSphere Application Server profile. To test Jython script, follow these steps:

  1. Start the application server from the command line
    {profileDir}/bin/startServer{.bat|.sh} serverName
  2. Run the wsadmin command with the script file as arguments
    {profileDir}/bin/ wsadmin -lang jython -f '/temp/script/test1.jy'

You can find the wsadmin script trace in the wsadmin.traceout file in the {profileDir}/logs directory. If there is a problem with the converted Jython script, the error messages are written into this trace file. Use the error message to determine the cause of the error and where the error occurred.


Conclusion

This article describes best practices for converting wsadmin scripts from Jacl to Jython, including the automatic conversion process and specifically the Jacl2Jython assistant tool. You also learned about the rules and syntax that you must understand before you can manually convert Jacl to Jython. These best practices should ensure your conversion runs smoothly. Additionally, refer to the article for troubleshooting information about using the Jacl2Jython assistant tool.

Resources

Learn

Get products and technologies

  • Evaluate IBM products in the way that suits you best: Download a product trial, try a product online, use a product in a cloud environment.

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Commerce on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Commerce, WebSphere
ArticleID=957018
ArticleTitle=Best practices for converting wsadmin scripts from Jacl to Jython
publish-date=12132013