Sie sind auf Seite 1von 16

Jython and the JLI

Table of Contents
1. Introduction................................................................................................................. 3
1.1.
Overview............................................................................................................. 3
2. Before You Begin ........................................................................................................ 4
3. Linux and UNIX Installations ................................................................................... 4
3.1.
Installing JLI on the Application Server............................................................. 4
3.1.1.
Installing Jython.......................................................................................... 4
3.1.2.
Installing JLI Files ...................................................................................... 5
3.2.
Using the JLI....................................................................................................... 5
4. Windows Installations ................................................................................................ 5
4.1.
Installing JLI on a Windows Application Server................................................ 5
4.1.1.
Installing Jython.......................................................................................... 5
4.1.2.
Installing JLI Files ...................................................................................... 6
4.2.
Using the JLI....................................................................................................... 6
5. Instantiating and Executing the JLI ......................................................................... 7
6. Basic Jython Programming Principles...................................................................... 7
6.1.
Importing Native/Custom Modules .................................................................... 7
6.1.1.
Import Search Path...................................................................................... 8
6.2.
Suites................................................................................................................... 9
6.3.
Documenting....................................................................................................... 9
7. Examining Common JLI or Jython Examples....................................................... 10
7.1.
Setting Server Properties................................................................................... 10
7.1.1.
update_server_status.jli............................................................................. 10
7.1.2.
populate_server_hardware_properties.jli.................................................. 12
7.2.
Java via Jython and the execv module ........................................................... 15
7.2.1.
execv.py .................................................................................................... 15
8. Debugging Jython ..................................................................................................... 16
8.1.
pdb..................................................................................................................... 16

2 of 16
2005 BladeLogic, Inc. All rights reserved.

Confidential and Proprietary

1. Introduction
1.1. Overview
The scope of this document concerns the installation of Jython to leverage the
BladeLogic JLI as well as examples of common uses of the JLI. Jython, the
open-source Java based version of Python, offers a native scripting interface with
Java classes. Leveraging this ability, the JLI acts as a Jython bridge to the
BLCLI. Therefore, by instantiating a single JLI connection to the BLCLI, a script
maintains BLCLI context from one command to another, requiring a single
occurrence of the Java Virtual Machine as well as a single authentication with the
BladeLogic Application Server.
The document below discusses the installation of Jython with instructions to
configure Jython on a machine to utilize the JLI modules. This document focuses
on installation and configuration of the JLI on the BladeLogic Application Server,
though the same configuration principles may be applied to installations on
workstation machines. This document further discusses common uses of the JLI
and examines specific examples of Jython code using the JLI. While this
document shall, from time to time, explain details of the Jython language, one
should not expect a full course in Jython within this document. While little
literature exists on Jython specifically, one wishing to learn more about Jython
should seek material focusing on Python. Specically, for a decent first or
refresher course in Python, one may want to download and read a free e-book,
Dive Into Python, available for download in multiple formats or for purchase in
physical form at http://www.diveintopython.org.
*One should take special note of the execv.py example in Section 7.2 document.
This Jython module offers an excellent example of how to utilize Jythons native
interface to Java classes. The execv.py module creates a way to execute OS level
system calls via Jython and retrieving results and result codes by utilizing native
Java classes.

3 of 16
2005 BladeLogic, Inc. All rights reserved.

Confidential and Proprietary

2. Before You Begin


From jython.org, download the latest version of jython-XX.class where XX
refers to the Jython version number.

3. Linux and UNIX Installations


3.1. Installing JLI on the Application Server
3.1.1. Installing Jython
- Copy jython-XX.class to /usr/nsh
- Change to the /usr/nsh directory
- Run command: java jython-XX
*One must execute this command from within a GUI session.

- Jython Install Directory: /usr/nsh/jython/


chown R bladmin:bladmin /usr/nsh/jython
- JLI directory, with Jython/BLCLI modules: /usr/nsh/jli
- $HOME for user bladmin: /usr/nsh/br
- .profile updated for user bladmin:
/usr/nsh/br/.profile
PATH=${PATH}:/usr/nsh/jython
export PATH

*appserver restart required for this change to effect scripts in CM

- .jython file created in bladmin $HOME:


/usr/nsh/br/.jython
python.path = /usr/nsh/jli

- Modified /usr/nsh/jython/jython to include BladeLogic paths and classpath:


/usr/nsh/jython/jython
#!/bin/sh
##########
#
BLADELOGIC_HOME=/usr/nsh
JAVA_HOME=/usr/nsh/br/java
BLDEPLOY=$BLADELOGIC_HOME/br
STDLIB=$BLDEPLOY/stdlib
CLASSPATH=$BLADELOGIC_HOME/br:$BLADELOGIC_HOME/br/bladelogic.ja
r:$JAVA_HOME/jre/lib/rt.jar:$STDLIB:$STDLIB/activation.jar:$STD
LIB/jaxp.jar:$STDLIB/log4j-1.2.4.jar:$STDLIB/looks1.1.2.jar:$STDLIB/mailapi.jar:$STDLIB/msbase.jar:$STDLIB/mssqls
erver.jar:$STDLIB/msutil.jar:$STDLIB/mysql.jar:$STDLIB/oracle.j
ar:$STDLIB/parser.jar:$STDLIB/smtp.jar:$STDLIB/xerces.jar:$STDL
IB/xml-writer.jar
$JAVA_HOME/bin/java -Dpython.home="/usr/nsh/jython" -classpath
"/usr/nsh/jython/jython.jar:$CLASSPATH"
"org.python.util.jython" "$@"

- Using BladeLogic Java Runtime Environment: /usr/nsh/br/java/bin/java


- Set python.path line in Jython registry file:
/usr/nsh/jython/registry
python.path = /usr/nsh/jython/Lib

4 of 16
2005 BladeLogic, Inc. All rights reserved.

Confidential and Proprietary

3.1.2. Installing JLI Files


- JLI files copied to /usr/nsh/jli:
ls -1RA /usr/nsh/jli/
/usr/nsh/jli:
bladelogic
/usr/nsh/jli/bladelogic:
cli
cli.py
__init__.py
/usr/nsh/jli/bladelogic/cli:
__init__.py

Modify __init__.py in /usr/nsh/bladelogic/cli. If you have installed this


on the application server, then you will only need to change lines 42 and 43 to
point to the proper directories. If installed on a different server, line 36 needs to
reference the BladeLogic application server.

3.2. Using the JLI


After all changes in Section 3.1 are complete, Jython scripts may be added to the
depot as an NSH Script depot object, then executed as an NSH Script Job. The
first line of the script, specifying the interpreter, must read:
#! /usr/bin/env jython

4. Windows Installations
4.1. Installing JLI on a Windows Application Server
4.1.1. Installing Jython
- Copy jython-XX.class to c:\tmp
- Change to the c:\tmp directory
- Run command: java jython-XX
- Choose the Jython Install Directory: e.g.: c:\bladelogic\jython
- JLI directory, with Jython/BLCLI modules: c:\bladelogic\jli
- $HOME for user LocalSystem: c:\
- .jython file created in $HOME
c:\.jython
Python.path = C:\\bladelogic\\jli

5 of 16
2005 BladeLogic, Inc. All rights reserved.

Confidential and Proprietary

- Create c:\WINDOWS\system32\jython.bat
c:\WINDOWS\system32\jython.bat
@echo off
set JAVA_HOME=" c:\Progra~1\BladeLogic\OM\jre\bin\java"
set STDLIB=C:\Progra~1\BladeLogic\OM\br\stdlib
set BRDIR=C:\Progra~1\BladeLogic\OM\br
set JYTHON=C:\bladelogic\jython
set JREDIR=C:\Program Files\BladeLogic\OM\jre\lib
SET CLASSPATH=%JYTHON%\jython.jar;%JREDIR%\rt.jar;%STDLIB%;
%STDLIB%\log4j-1.2.4.jar;
%STDLIB%\activation.jar;%STDLIB%\jaxp.jar;%STDLIB%\mailapi.jar;
%STDLIB%\parser.jar;%STDLIB%\mysql.jar;%STDLIB%\xerces.jar;
%STDLIB%\xml-writer.jar;%STDLIB%\oracle.jar;%STDLIB%\msbase.jar;
%STDLIB%\mssqlserver.jar;%STDLIB%\msutil.jar;%STDLIB%\smtp.jar;
%BRDIR%;%BRDIR%\bladelogic.jar;%STDLIB%\looks-1.1.2.jar;
C:\Progra~1\BladeLogic\OM\bin;%STDLIB%\rbachelp.jar
set ARGS=
:loop
if [%1] == [] goto end
set ARGS=%ARGS% %1
shift
goto loop
:end
java -Dpython.home=%JYTHON% -classpath %CLASSPATH%
org.python.util.jython %ARGS%

- Using the BladeLogic Java Runtime Environment:


c:\Progra~1\BladeLogic\OM\jre\bin\java
- Set python.path line in Jython registry file:
~/jython/registry
Python.path = c:\\bladelogic\\jython\\Lib

4.1.2. Installing JLI Files


- JLI files copied to /c/bladelogic/jli
ls -1RA /c/bladelogic/jli/
/c/bladelogic/jli:
bladelogic
/c/bladelogic/jli/bladelogic:
cli
cli.py
__init__.py
/c/bladelogic/jli/bladelogic/cli:
__init__.py

Modify __init__.py in /c/bladelogic/jli/bladelogic/cli. If you have


installed this on the application server, then you will only need to change lines 42
and 43 to point to the proper directories. If installed on a different server, line 36
needs to reference the BladeLogic application server.

4.2. Using the JLI


After all changes in Section 4.1 are complete, Jython scripts may be run from
within the CM by calling jython /path/to/script/scriptName.jli from
within an NSH Script Job.

6 of 16
2005 BladeLogic, Inc. All rights reserved.

Confidential and Proprietary

5. Instantiating and Executing the JLI


01
02
03
04
05
05
06
07
08
09
10
11

#!/usr/bin/env jython
from bladelogic.cli import CLI
jli = CLI()
jli.initialize()
cmd = [NameSpace,blcliCmd,Arg1,,ArgN]
returnObject = jli.run(cmd)
# returnObject has various methods and properties.
# The following if statement demonstrates the important three.
if(returnObject.success()):
print returnObject.returnValue
else:
print returnObject.getError()
*see Section 6 for more information about the following analysis

Line 1: Import the CLI class from the bladelogic.cli module.


Line 2: Create an instance of the CLI class named jli.
Line 3: Initialize the JLI. This line calls the same authentication classes that
cause latency starting the BLCLI.
Line 4: The JLI accepts BLCLI commands as arrays (lists). This line
demonstrates a pseudo-command in the JLI.
Line 5: The jli.run(cmd) statement accepts the array variable cmd and returns
a BLCLI return object to the returnObject variable.
Line 6 & 7: Comments.
Line 8: Test for the successful execution of the JLI command processor. If the
command executed successfully, returnObject.success() returns 1; if
unsuccessful, returnObject.success() returns 0.
Line 9: If .success() equals 1, this line executes, printing the return value of
the executed command.
Line 10: If .success() equals 0, this line begins the else suite of the ifelse
clause.
Line 11: If .success() equals 0, executing the else suite, this line prints the
error retrieved from the unsuccessful execution of the JLI processor.
*Despite the BLCLI API indicating that some commands accept an integer, the JLI requires a
script to pass all commands as string. Therefore, a script must cast all non-string values to a
string before passing their values in an array to the JLI processor. This includes numbers and DB
keys.

6. Basic Jython Programming Principles


This section addresses basic Jython language and programming principles, aiming
to give the reader a brief introduction to some concepts used in Section 6,
Examining Common Jython or JLI Examples.

6.1. Importing Native/Custom Modules


Maintaining all code in a single file is often impractical, especially for large
projects. Additionally, one may desire to create code modules or classes easily
shared with other applications. The Jython command import loads these external
code modules into the current script.

7 of 16
2005 BladeLogic, Inc. All rights reserved.

Confidential and Proprietary

On import, an external file is compiled and processed, executing any code not in a
function. Scripts contain import statements on the first lines of a script. Import
statements take the following forms:
import bladelogic.cli as blcli
from bladelogic.cli import CLI
Exhibit 5.1

The first line in Exhibit 5.1 imports the bladelogic.cli module, naming the
imported object blcli. The second line does not import the entire
bladelogic.cli module. Instead, the second import statement imports only the
CLI class from within the bladelogic.cli module. If an external module
contains more than one class, function, variable or other such Jython object, the
from <module> import <object>, does not load the entire module, but rather
only the specific external object.
Using the second line from Exhibit 5.1, one may now access (instantiate) the CLI
class directly as a global variable within the script.

6.1.1. Import Search Path


When an import line tries to import a Jython module, it searches a specific search
path. The python.path variable in the Jython registry and .jython files,
mentioned in Sections 3.1.1 and 4.1.1 append values to the default Jython import
search path, the current directory .. The sys module makes this path available
as a variable of type list via sys.path. One may add extra values to this path
via the Jython append command: sys.path.append(/new/path).
Obviously, the directory containing the bladelogic/cli directories must exist
within the sys.path variable for import into a JLI script. If this directory does
not exist within the sys.path, copy the directories and files to the directory
declared as Python.path in the Jython registry file.

8 of 16
2005 BladeLogic, Inc. All rights reserved.

Confidential and Proprietary

6.2. Suites
Anyone accustomed to other high-level programming or scripting languages such
as C/C++, Java, or PERL may find the lack of function and class delimiters
somewhat disconcerting. Rather than the normal squiggly brackets used to
indicate the beginning and end of a function or class, if or for statement, Jython
breaks its control structures into suites. A suite consists of a series of lines with
similar levels of indentation. See Exhibit 5.2 for more information.
def toggle(y):
if(y==0):
y = 1
elif(y==1):
y = 0
else:
y = -1
return y
if(x==1):
x = toggle(x)
print Hello World!
print x
Exhibit 5.2

The first suite in Exhibit 5.2 defines a function named toggle that takes an
argument y. Notice the indented if, elif (else if), and else control structures.
The statements within the toggle function indent 1 level, and the statements
within each control structure indent yet another level. The final line in the
function, the return statement, lies outside of the ifelse control structure and
therefore has the same level (1) of indentation.
Each of the if statements in the toggle function has 1 line within its suite. The
if(x==1) statement in Exhibit 5.2 demonstrates a multi-line suite with no other
indentations, unlike the multi-line, multi-suite toggle function.
Notice the : at the end of the first line of the if suite and toggle function
definition. This colon indicates the beginning of a suite. The Jython interpreter
will throw an error during compilation if it finds the next line not indented one
more than the beginning of the suite. Notice the lack of a syntactical indication of
the end of a suite. A suite ends when the compiler finds a line of the same
indentation level as the beginning line of the suite.
While the reader may find the concept of a suite somewhat non-intuitive, over
time the reader may discover that the suite methodology employed by Jython
remains logical and lends to more readable code.

6.3. Documenting
Jython allows for both single line code documentation and multiple line code
documentation. Single line documentation has no restrictions and one may place
the comments wherever one pleases by simple prefixing the comment with a #.
This # comments out the all text to the right of it, allowing one to temporarily
remove the execution of a line of code or to make a note to explain the purpose of
a particular line of code.
9 of 16
2005 BladeLogic, Inc. All rights reserved.

Confidential and Proprietary

Multiple line documentation, aside from its obvious benefits, offers a special
functionality as well. Multiple line documentation, when used as the initial lines
of a function, class, or module, become available at runtime as
<functionName>.__doc__. One uses triple quotation marks to denote multiple
line documentation. One may use multiple line documentation anywhere, though
one restriction exists. Multiple line documentation must retain the same level of
indentation as the suite it documents.
function foo(bar):
This function prints the value of bar.
This is a test.
print bar
Exhibit 6.3

Importing a library with the function foo in Exhibit 6.3 allows one to access the
documentation via <module name>.foo.__doc__.

7. Examining Common JLI or Jython Examples


7.1. Setting Server Properties
7.1.1. update_server_status.jli
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

import sys
import os
import string as s
import re
from bladelogic.cli import CLI
jli = CLI()
jli.initialize()
CR=os.linesep
serverList = jli.run(['Server','listAllServers']).returnValue
serverList = s.rstrip(serverList)
serverArray = re.split('\n',serverList)
for serverName in serverArray:
cmd = []
NameSpace = Utility
blcliCmd = updateServersStatus
cmd.append(NameSpace)
cmd.append(blcliCmd)
cmd.append(serverName)
cmd.append(1)
cmd.append(2000)
cmd.append(true)
try:
update = jli.run(cmd)
assert update.success(), update.getError()
print 'Success for: '+serverName
except AssertionError,e:
print e
print 'All available servers updated.'
sys.exit(0)

*Note: A bug currently exists using the Utility updateServersStatus command in


Jython. Each execution of the command opens and maintains a file descriptor for
the life of the script. This becomes a problem when run against >900 servers.
Ensure that this script runs against less than 900 servers at a time.
Line 1: Import sys, the Jython module with methods handling system operation.
10 of 16
2005 BladeLogic, Inc. All rights reserved.

Confidential and Proprietary

Line 2: Import os, the Jython module handling OS specific methods.


Line 3: Import string as an object named s. The string module handles
simple string operations.
Line 4: Import re, the Jython module handling Regular Expressions.
Lines 5-8: See Section 5.
Line 9: Set CR (carriage return) as the OS specific character to separate lines.
Line 11: Execute the Server listAllServers BLCLI command. Assign the
returnValue of the command to serverList.
Line 12: Because command from Line 10 returns a value in the string format of:
Server1\nServer2\n\nServerX\n, we must parse this string into an array so
that we may iterate through the array and operate on each server in the list. The
string.rstrip() function strips trailing white space from a given string,
including new lines (\n). This prevents an extra, empty array element resulting
from the following command.
Line 13: The re.split() function splits a string into an array based on the first
argument, an \n character in this case.
Line 15: This line begins a for loop, looping through all servers in
serverArray
Line 16: Initializes the cmd variable as an empty array.
Lines 17 - 18: Set NameSpace and blcliCmd variables.
Lines 19 24: Append values to the cmd array, building the BLCLI command.
Line 25: Begins a try suite, anagolous to the try clauses in Java. If an error
occurs within this suite, the code execution jumps immediately to the except
suite, though the script only traps for an AssertionError.
Line 26: Executes the compiled BLCLI command as the cmd variable, assigning
the return object to the update variable.
Line 27: Asserts that update.success() evaluates to true, 1 in this case. If an
assert statement evaluates to false, the execution of the code jumps to the
except suite, passing the text to the right of the comma as e (Line 30), in this
case: update.getError(), the error value returned by the BLCLI.
Line 28: If the assert statement evaluates to true, normal code execution
continues, printing Success for: the current server name to STDOUT.
Line 29: If the assertion on Line 27 evaluates to false, the script jumps to this line.
The assert statement on Line 27 passed an error, evaluated as the e in this
except suite.
Line 30: Within the except suite, this line prints the value of e, the error
passed from the assert statement.
Line 31: Lies outside of the for loop and executes when the for loop finishes,
printing the string in quotes to STDOUT.
Line 32: Calls the exit() function from the sys module, exiting the script
with an exit value of 0.

11 of 16
2005 BladeLogic, Inc. All rights reserved.

Confidential and Proprietary

7.1.2. populate_server_hardware_properties.jli
This script (Lines 47-51) reduces the time to update server properties by
leveraging the JLIs direct interface to the BLCLI, taking advantage of BLCLI
context. For more information on BLCLI context see the Best Practice for
Using the BLCLI [Internal] document in the BladeLogic Knowledge Base.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60

import sys
import string as s
import re
from execv import execv as e
from bladelogic.cli import CLI
jli = CLI()
jli.initialize()
serverFile = open(sys.argv[1],'r')
allServers = serverFile.readlines()
allServers.sort()
serverFile.close()
def getPropertyKey(propertyName):
propertyKey = ''
cmd = ['Property','propertyNameToDBKey']
cmd.append(propertyName)
propertyObject = jli.run(cmd)
if(propertyObject.success()):
propertyKey = propertyObject.returnValue
return str(propertyKey)
def setPropertyValue(propertyKey,propertyValue):
cmd = ['Server','putPropertyValue']
cmd.append(propertyKey)
cmd.append(str(propertyValue))
jli.run(cmd)
print 'Getting property keys.'
cpuNumKey = getPropertyKey('CPU_NUMBER')
cpuSpeedKey = getPropertyKey('CPU_SPEED')
memoryKey = getPropertyKey('MEMORY')
print 'Property keys retrieved. Processing server data.'
for server in allServers:
server = s.rstrip(server)
print 'Processing properties for '+server
noverOut = e('nover -c -H '+server).out
noverSubbed = re.sub('"','',noverOut)
noverStripped = s.rstrip(noverSubbed)
nover = re.split(',',noverSubbed)
if len(nover) > 1:
cpuNum = str(nover[3])
cpuSpeed = str(nover[4])
memory = str(nover[6])
try:
jli.run(['Server','findByName',server])
setPropertyValue(cpuNumKey,cpuNum)
setPropertyValue(cpuSpeedKey,cpuSpeed)
setPropertyValue(memoryKey,memory)
jli.run(['Server','save'])
except:
print 'ERROR:::Failure setting properties. '
continue
else:
print 'Finished for '+server+'.'
else:
print 'ERROR:::Timed out connecting to '+server+'.'
print 'Server property update completed.'
sys.exit(0)

Line 1: Import sys, the Jython module with method to handling system
operation.
12 of 16
2005 BladeLogic, Inc. All rights reserved.

Confidential and Proprietary

Line 2: Import string as an object named s. The string module handles


simple string operations.
Line 3: Import re, the Jython module handling Regular Expressions.
Line 4: Import execv class from execv module and name script object as e.
See Section 7.2.1 for more information about this class.
Line 5 - 8: See Section 5.
Line 9: Open file containing list of servers in read mode. Assign to file handle
serverFile. The NSH Script Job that executes this script builds a target host
list file and passes it to this script upon execution. The sys.argv array contains
arguments passed from command line upon execution of script, with element 0
having a value of the name of the script and element 1 having a value of the first
argument.
Line 10: Read all lines from open file and assign return value to array named
allServers.
Line 11: Perform alpha-numeric sorting of allServers array.
Line 12: Close file handle.
Line 14: Define function getPropertyKey, taking propertyName variable as
argument.
Line 15: Set the local variable propertyKey as empty string.
Line 16: Initialize cmd array with BLCLI commands.
Line 17: Append propertyName value to cmd array.
Line 18: Execute the JLI command with argument cmd. Assign return object to
propertyObject variable.
Line 19: Check successful execution of JLI command.
Line 20: If JLI successfully executes, assign returnValue to propertyKey.
Line 21: Cast propertyKey as a string (force value type to string) and return.
Line 23: Define setPropertyValue function, taking arguments propertyKey
and propertyValue.
Line 24: Initialize cmd array with BLCLI command.
Line 25: Append propertyKey value to cmd array.
Line 26: Append propertyValue value to cmd array.
Line 27: Execute JLI with command cmd. Ignore return object; assume success.
Line 29: Inform the user of script progress.
Lines 30 - 32: Set property key values for named properties.
Line 33: Inform the user of script progress.
Line 35: Begin for loop. For each iteration, set server variable equal to each
element of allServers array.
Line 36: Strip all white space from right side of server string, \n in this case.
Line 37: Inform the user of current server.
Line 38: Execute nover c H against remote server via execv class. Assign
output to noverOut.
Line 39: Remove double-quotes from nover output. Assign to noverSubbed.
Line 40: Remove any white space from the right side of the noverSubbed string.
Line 41: Split the noverSubbed string into an array at the commas.
Line 42: Check that the nover command returned good data, that the length of
the nover array has a greater length than 1.
Line 43: Assign the 4th element of the nover array to the cpuNum variable.
Line 44: Assign the 5th element of the nover array to the cpuSpeed variable.
Line 45: Assign the 7th element of the nover array to the memory variable.
13 of 16
2005 BladeLogic, Inc. All rights reserved.

Confidential and Proprietary

Line 46: Begin a try suite.


Line 47: Execute the Server findByName JLI command, loading the server into
BLCLI context.
Lines 48-50: Set specified property values on the server in context.
Line 53: Save the current server in context, saving all set properties to server.
Line 52: An except statement handles exceptions within the try suite.
Line 53: Handle exceptions by informing the user of an error.
Line 54: The continue statement here tells the script to continue executing
code, despite an exception.
Line 55: Where no error has occurred, execute this else suite.
Line 56: Inform the user that the script has finished setting properties for the
specified server.
Line 57: If nover did not return good data, execute this else suite.
Line 58: Inform the user that there may exist a problem with the agent on this
remote server.
Line 59: Inform the user that the script has completed.
Line 60: Calls the exit() function from the sys module, exiting the script
with an exit value of 0.

14 of 16
2005 BladeLogic, Inc. All rights reserved.

Confidential and Proprietary

7.2. Java via Jython and the execv module


7.2.1. execv.py
This library provides a class to execute system calls from Jython via Java,
something that Jython, as of version 2.1, lacks. While the code is written in
Jython, the classes used are native Java objects.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

from java.lang import Runtime


from java.io import BufferedInputStream
class execv:
out = None
err = None
exitVal = None
isErr = None
def __init__(self,cmd):
p = Runtime.getRuntime().exec(cmd)
self.exitVal = p.waitFor()
stream = BufferedInputStream(p.getInputStream())
e = []
if(self.exitVal!=0):
self.isErr = 1
stream = BufferedInputStream(p.getErrorStream())
r = stream.read()
while r != -1:
e.append(r)
r = stream.read()
retVal = "".join(map(chr, e))
if(self.isErr):
self.err = retVal
else:
self.out = retVal

Line 1: Import runtime class Runtime from java.lang, a native Java package.
Line 2: Import runtime class BufferedInputStream from java.io, a native
Java package.
Line 4: Define a Jython class named execv.
Lines 5 - 8: Set return values to None, the Jython Null value.
Line 10: When defining a class, the __init__ function acts as the class
initialization (or main) function. This function takes the assigns the passed
system call to the cmd variable. This function gets called when instantiating the
class. All class methods require self as their first argument.
Line 11: Execute a system call through the Java Runtime class, exec method.
Assign process to variable p.
Line 12: Call waitFor() method of process p. This method waits for the
process to finish, returning the executed commands return code to the exitVal
property of the execv class.
Line 13: This Java code gets the input stream, capturing STDOUT for the executed
command and buffers it to the variable stream.
Line 14: Initializes the variable e as a Jython array.
Line 15: If return code of executed command does not equal 0, the command
failed. Otherwise, execution jumps to Line 18.
Line 16: If the executed command failed, sets isErr property of execv property
to 1.
Line 17: Sets stream variable equal to error stream, capturing STDERR.
Line 18: Reads the first character of stream.
15 of 16
2005 BladeLogic, Inc. All rights reserved.

Confidential and Proprietary

Line 19: Begins a while loop until the value of r equals -1, building stream
output into the array e.
Line 20: Appends the value of r to the array e.
Line 21: Reads the next character of stream. The read() function returns -1
at the end of the stream.
Line 22: Joins the array e into a single string, assigning joined string to
retVal.
Line 23: If the isErr property, set on Line 16, of execv equals 1, otherwise
continue to the else statement on Line 25. Sets the relevant property of execv
to the retVal value.
Line 24: Sets the err property of execv to the value of retVal.
Line 26: Sets the out property of execv to the value of retVal.
Usage
from execv import execv as e
ls = e(ls la)
if(not ls.isErr):
print ls.out
else:

print ls.err

8. Debugging Jython
8.1. pdb
The Jython debugger (the p in pdb stands for Python, as Jython is just a Java
port of Jython) allows the line by line debugging of Jython scripts. To execute a
script in debug mode, one must import the pdb module and insert the
set_trace() function call near the beginning of the script or where one
suspects problems:
import pdb
pdb.set_trace()

Execute the script from the command line. The script will pause, expecting input,
when it reaches the pdb.set_trace() line in the scripts execution. One may use
the following commands to navigate the debugger.

n execute the next line of the script

l list 10 lines of script before and 10 lines above current position

s step into the function in the next line of the script

b b <line#> sets a breakpoint at the specific line number

c continue execution uninterrupted until the next breakpoint

r continue executing the function in current scope until it returns

p p <variable> prints the value of a variable in the current scope

16 of 16
2005 BladeLogic, Inc. All rights reserved.

Confidential and Proprietary

Das könnte Ihnen auch gefallen