0% found this document useful (0 votes)
78 views55 pages

Monty Jy Thon

This document provides an overview of using the Jython scripting language within IBM WebSphere Application Server (WAS) 6.1. It begins with objectives and a brief history of Jython. It then describes the Jython programming features within the WAS 6.1 Application Server Toolkit, including the Jython editor, debugger, command assistance, and Jacl to Jython conversion tool. The document also covers Jython language essentials such as statements, exceptions, data types, strings, tuples, lists, dictionaries and functions. It demonstrates Jython concepts like list comprehensions. The overall purpose is to explain how to use Jython effectively for WAS scripting.
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
78 views55 pages

Monty Jy Thon

This document provides an overview of using the Jython scripting language within IBM WebSphere Application Server (WAS) 6.1. It begins with objectives and a brief history of Jython. It then describes the Jython programming features within the WAS 6.1 Application Server Toolkit, including the Jython editor, debugger, command assistance, and Jacl to Jython conversion tool. The document also covers Jython language essentials such as statements, exceptions, data types, strings, tuples, lists, dictionaries and functions. It demonstrates Jython concepts like list comprehensions. The overall purpose is to explain how to use Jython effectively for WAS scripting.
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 55

W eb Sp he re

2007 WebSphere User Group


September 11, 2007 Edinburgh

ce en r fe

2007

r Se s ce vi T e ch ni ca l

on

Monty Jython's Scripting Circus

(ISSW UKISA, Andrew Simms/UK/IBM, simmsa@uk.ibm.com)

Andrew Simms

Objectives
Our Holy Grail: To work out some recommended practices for using Jython in WAS scripting How we're going to get there:
Quick look at what's in the WAS 6.1 Application Server Toolkit (AST) Describe the essentials of the Jython language Look at some more advanced Jython features Pick out some key things as we proceed Demonstrate bit and pieces of Jython Suggest some guidelines for what scripts should look like

2007 WebSphere User Group

It's: A short history of Jython


Python invented by Guido van Rossum in 1991
Operating system-independent Object-oriented Based on a language called ABC Designed to be readable Named after the TV programme Small language core with extensive libraries

Jython is a Java implementation of Python


WAS 6.1's Jython is version 2.1
Latest Jython is 2.2, Python 2.5

2007 WebSphere User Group

Jython programming in the AST Purpose:


To greatly ease wsadmin scripting
by simplifying the development of Jython scripts
using the Jython Editor

by simplifying debugging Jython scripts


using the Jython Debugger

by generating scriptlets
using the Admin Console Command Assist feature

by converting existing Jacl scripts to Jython


using the Jacl2Jython conversion tool

2007 WebSphere User Group

Jython editor in the AST


Text editing (find, replace, indent, undo, etc) Syntax colouring wsadmin keyword & method assistance
Keyword & method syntax detection and colouring Keyword & method code completion (including parameters) Keyword & method context assistance and flyover help

Outline view (classes & methods & loops) Provides integration with Jython Debugger Has self-evident usage (Eclipse consistent) NO compiler parse errors, NO parameter type checks
2007 WebSphere User Group 5

Jython debugger in the AST Uses local server runtime(s) for wsadmin execution
Can target (compatible) remote servers (using -host -port)

Can run Jacl and Jython scripts But debugging is Jython only
Local v6.1 Breakpoints, step-over etc Variables view (cannot change variable contents) Stack frame view (variables reflect current level)
2007 WebSphere User Group 6

Command assistance in the AST


Command Assist View in AST can receive configuration changes made via the Admin Console
Some (not all) actions result in Jython commands being generated Limited in 6.1 maybe 10% Expect more in later releases

Insert generated code into a script using the Jython Editor script
Will need further editing

2007 WebSphere User Group

Jacl2Jython utility from the AST


Takes your Jacl scripts and converts them to Jython
Typically does 95-98% code conversion Inserts problem warnings into the converted code

The developer must then:


Manually verify all of the preliminary conversion Modify some code to make it function as originally intended Thoroughly test the resulting script

Does it produce Jython code in a style you would use if writing from scratch?
Not if you want to use the OO features
2007 WebSphere User Group 8

Jython: Language essentials

Indentation and comments Statements Trapping exceptions Data types Strings, tuples and lists Dictionaries Functions (classless methods) Built-in functions

2007 WebSphere User Group

Indentation and comments It's an indented language


No curly brackets Colon and indentation instead
Beware mixing tabs and spaces

Comments: use # and anonymous string In interactive wsadmin you can't cut and literals: paste comments that spread over two or
more lines. Not a problem for the AST. # This is a comment 'This is a comment' """This is a comment that spreads across many lines between triple-quotes. So a good way to comment out code is to use triple-quotes"""

2007 WebSphere User Group

10

Statements
Much more like Java than Jacl (Tcl) Statement syntax is Java-like:
for x in (1, 2, 3): "else" here is a misnomer print "x=", x always executed unless you use "break" to exit from the for loop else: print "Counter-intuitive that this gets executed"
1

for z in (range(45, 55)): In interactive wsadmin make sure you if z == 50: type the indentation correctly, and you break may need a blank line at the end of blocks. Not a problem for the AST. else: print z else: print "Broke out so this won't get printed"

2007 WebSphere User Group

11

Statements
Multiple assignments (Fibonacci series):
a, b = 0, 1 while b < 1000000: print b a, b = b, a+b This is actually a tuple assignment as we shall see later
2

Some other things:


del a,b x = 1 x += 1 # No x++ assert x == 2 pass # no-op

2007 WebSphere User Group

12

try except else finally


Try/except/else:
try: v = 1 / 0 except ArithmeticError: print "You can't do that!" except: print "This is a catch-all" else: print "value = ", v

"else" here: if you go to the exceptions then the else doesn't get executed; if you don't go to the exceptions then it does get executed

Try/finally:
try: doStuff finally: doCleanUpStuff finally: always gets executed and any exception re-raised after it executes

Use raise to raise exceptions


2007 WebSphere User Group

13

Jython data classes


All data classes are dynamic:
s = "hi there" ; v = 42 type(v) # -> <jclass org.python.core.PyInteger at 658253628>

Numeric types:
Integer, long, float, complex Numeric objects are immutable:
id(v) # -> 791424812 v += 1 id(v) # -> 791818034

Types are detected syntactically:


vi vl vf vc = = = = 42 42L 42.1234 42+43j # # # # -> -> -> -> Integer Long Float Complex Can use lower-case el but don't (indistinguishable from the number one) Probably not much use in WAS scripting!
14

2007 WebSphere User Group

Sequences: Strings, tuples and lists


Type Strings Contents Character data only Any kind of object Any kind of object Mutable? No Delimiter Examples Quotes s = "one two three four" s[5] # indexing -> 'w' s[5:9] # slicing -> 'wo t' t = ("one", "two", "three", "four") t[1] # -> 'two' t[:2] # -> ('one', 'two') l = ["one", "two", "three", "four"] l[-1] # -> "four" l[1:-2] # -> ['two'] l[0::2] # -> ['one', 'three']

Tuples

No

Round brackets Square brackets

Lists

Yes

Think of a tuple as a constant list, but you can still change any mutable element it may have

len() tells you the sequence length Use empty paired delimiters to get an empty sequence, e.g. L=[]
2007 WebSphere User Group

Slicing and indexing apply to all sequences

15

Sequence mutability
Strings are immutable:
s = "one two three four" s[8:-1] = "buckle my shoe" # fails

Tuples are immutable:


t = ("one", "two", "three", "four") t[2:] = "buckle my shoe" # fails

But lists are mutable:


l = ["one", "two", "three", "four"] l[-2:] = "buckle my shoe" print l # probably not what you wanted l = ["one", "two", "three", "four"] l[-2:] = ["buckle", "my", "shoe"] print l # better
3

2007 WebSphere User Group

16

Sequences: Strings
Use single, double or triple quotes Reverse quotes (equivalent to the repr() function):
v = 42 s = `v / 6` type(s) # s is the string '7' not the integer 7 s = int(s) type(s) # now it is

Some useful PyString methods:


capitalize(), endswith(), find(), isxxx(), join(), lower(), rfind(), split(), splitlines(), startswith(), strip(), upper()

join() converts a sequence to a string:


s1 = ":" s2 = s1.join(["join", "with", "colons"]) # 'join:with:colons'

split() converts a string to a list:


s2.split("i") # -> ['jo', 'n:w', 'th:colons']
2007 WebSphere User Group 17

Sequences: Tuples
Contains references to any object type Those objects can be mutable but the tuple itself is immutable No methods available for tuples Represented by round brackets but you don't have to specify them
t = "one", "two", "three", "four" t = ("one", "two", "three", "four") t = (("one", "two", "three", "four")) But do so for clarity

Objects can be of different types:


t = ("one", 2, 3L, 4.0+5.0j)
2007 WebSphere User Group

Beware: t=("one") is a string You need a trailing comma: t=("one",)


18

Sequences: Lists
Contains references to any object type The only sequence type that is mutable Represented by square brackets
l = ["one", 2, 3L, 4.0+5.0j] Convert a list to a tuple with list(seq)) and vice versa with tuple(seq)

PyList methods:
append(), count(), extend(), index(), insert(), pop(), remove(), reverse(), sort()

Examples:
l.append(6.0E7) l.count(60000000) l.extend([7, "eight"]) l.index(4+5j) l.insert(3, 2.5) l.pop(1) l.remove(4+5j) l.reverse() l.sort() # # # # # # # # # appends one object to the list 1 (how often does the value occur) appends a list to the list 3 (the index of this value) inserts 2.5 in index 3 2 (and removes it from the list) removes this value from the list reverses the list order sorts the list (in some way)
19

2007 WebSphere User Group

List comprehension A syntax that allows you to create one list from another by applying a function or expression to each member:
[expr for var1 in seq1 if test1 for var2 in seq2 if test2 . . .]

Exploit this to set heap sizes for all of your app servers in one line!
None of the Admin* functions return a true Jython list. [AdminConfig.modify(x, [["initialHeapSize", 64], ["maximumHeapSize", 128]]) for x in 5 AdminConfig.list("JavaVirtualMachine").splitlines() if 14 x.find("nodeagent") == -1 and x.find("dmgr") == -1]
14

2007 WebSphere User Group

20

Dictionaries (mapping objects)


Dictionaries are very useful as we will see later

Connects a set of immutable keys to a set of objects Enclose with curly brackets and colon- and commaseparated values:
chineseLanguages = ["Mandarin Chinese", "Cantonese"] indianLanguages = ["Hindi", "Urdu", "Gujarati"] china = ["Beijing", 1316E6, chineseLanguages] india = ["New Delhi", 1110E6, indianLanguages] cdict = {"China": china, "India": india}

# -> {'China': ['Beijing', 1.316E9, ['Mandarin Chinese', 'Cantonese']], 'India': ['New Delhi', 1.11E9, ['Hindi', 'Urdu', 'Gujarati']]}

2007 WebSphere User Group

21

Dictionaries (mapping objects)


PyDictionary methods:
clear(), copy(), get(), has_key(), items(), keys(), popitem(), setdefault(), update(), values()

Examples:
cdict("England") = ["London", 4.8E7, ["Cockney", "Geordie", "Sassenach"]] cdict.update({"Scotland": ["Edinburgh", 1.0E7, ["English"]]}) cdict.get("India") cdict.has_key("Egypt") cdict.keys() cdict.items() cdict.popitem() cdict.setdefault("Egypt") cdict.values() copy=cdict.copy() del cdict["Egypt"] cdict.clear() # # # # # # # # # # returns value if present 0 (not present) ['India', 'China', 'England'] returns a list of tuples pops an item as a tuple appends a key pair if not present returns a list of values performs a shallow copy deletes an entry empties the dictionary

2007 WebSphere User Group

22

Functions
Functions are methods defined outside a class
def myFunction(p1, p2, p3): doSomeStuff return whatever Function names: Don't use underscores as these have special meanings Don't use built-in function names This is really useful not restricted to returning a single value

Can return multiple values


A tuple is constructed

Functions can be nested Functions can have attributes as well as variables:


def myFunction(): myFunction.attr1 = "bonjour" attr2 = "hello"
7

myFunction() myFunction.attr2 = "g'day"

attr2 is a local variable but attr1 is available externally This is a new attribute assigned externally
23

2007 WebSphere User Group

Right room for an argument Positional, default values, variable args:


def myFunction(p1, p2="def", *p3, **p4): print vars() Varargs: extra positional args are passed as a tuple Varargs: extra key-value args are passed as a dictionary

myFunction("abc") myFunction("abc", "ghi", "jkl", "mno") myFunction(p2="xyz", p1="uvw") myFunction("a", "b", "c", "d", id1="e", id2="f")

This is a great way of keeping a function's signature constant yet allowing arbitrary parameters to be passed to it
2007 WebSphere User Group 24

Doc strings Place an anonymous string literal after a function definition. Its content becomes that functions doc string. Print its documentation using
<name>.__doc__

def someFunction(): """someFunction does something or other""" pass A Jython library becomes self-documenting. Can see this using the AST. someFunction.__doc__ # -> someFunction does something or other

2007 WebSphere User Group

25

Built-in functions
type() type of an object: id() identity of an object: Numeric functions:
hex(), oct(), abs(), ...

Type conversions:
int(3.14159), tuple("abcd"), ...

File handling:
open("/tmp/myFile", "r")

Sequence generators:
range(3, 17, 2) xrange(3, 1234567, 2)

Class attributes:
dot notation also: hasattr(), delattr(), getattr(), setattr()

Many more
2007 WebSphere User Group 26

Jython: Classes and other advanced features

Namespaces Functional programming Regular expressions Threads Modules and packages Classes Using Java in Jython

2007 WebSphere User Group

27

Namespaces: Bruces and new Bruces


Static and statically nested (lexical) scoping Static scoping:
Two namespaces: locals and globals
bruce = 1 def changeBruce(): # global bruce # bruce = 10 bruce += 1 print bruce changeBruce() print bruce Without the global and without the assignment Jython treats this as a new bruce. Error: bruce isn't defined when incremented.

With this assignment but without the global, Jython sees this bruce as a new bruce
2007 WebSphere User Group

With the global we only have one bruce


28

Namespaces: Nested functions Statically nested scoping:


Names used in outer functions are not visible in the inner function without a special import
from __future__ import nested_scopes def outer(x, y): def inner(z): if z > 0: print z, y inner(z-1) inner(x) outer(3, "bruce") Jython's way of introducing new features

2007 WebSphere User Group

29

Functional programming
Create anonymous functions using lambda forms which have expressions but no statements:
isLeapYear = lambda year: not (year % 400 and (year % 4 or not year % 100)) Note that this print "2000 - ", isLeapYear(2000) returns a function print "2007 - ", isLeapYear(2007) print "2008 - ", isLeapYear(2008) print "2100 - ", isLeapYear(2100)

map iterates over sequences calling a function on each member:


map(lambda x: x*x, range(10)) map(lambda x,y: x>y and x-y or y-x, [1, 5, 8], [3, 1, 7]) # -> [2, 4, 1]

2007 WebSphere User Group

30

Functional programming
filter iterates over a sequence returning a subset of its values where the called function returns true:
set1 = range(0, 200, 7) set2 = range(0, 200, 3) filter(lambda x: x in set1, set2) # -> [0, 21, 42, 63, 84, 105, 126, 147, 168, 189]

reduce computes a single value by applying a twoarg function recursively:


reduce(lambda x, y: x+y, range(11))

2007 WebSphere User Group

31

Three ways of doing recursion


Ordinary functions can be recursive:
def fact(x): x = long(x) if x == 0: return 1 return x * fact(long(x-1)) Ultimately breaks with stack overflow, e.g. fact(1712)

Ditto

You can use an anonymous function:


fact = lambda num: num == 1 or num * fact(long(num-1))

You can use the reduce() function, which eats a sequence applying a recursive function to it:
Doesn't break fact = lambda num: num > 0 and reduce(lambda x, y: long(x)*long(y), range(1, num + 1)) or 0

2007 WebSphere User Group

32

Functional programming examples using AdminConfig (1) Test whether a name is a valid configurable object:
isValidType = lambda x: x in AdminConfig.types().splitlines() isValidType("JavaVirtualMachine") # -> 1 isValidType("Garbage") # -> 0

Set heap sizes for all of your app servers in one line (as earlier):
map(lambda x: AdminConfig.modify(x, [["initialHeapSize", 64], ["maximumHeapSize", 128]]), 14 filter(lambda x: 10 x.find("nodeagent") == -1 and x.find("dmgr") == -1, 14 AdminConfig.list("JavaVirtualMachine").splitlines()))

2007 WebSphere User Group

33

Functional programming examples using AdminConfig (2)


Test whether some configurable type has a named attribute:
isAttribute = lambda x, type: Each entry is a string in the isValidType(type) and x in format attrName-space-attrType map(lambda z: z.split()[0], AdminConfig.attributes(type).splitlines()) isAttribute("systemProperties", "JavaVirtualMachine") # -> 1 isAttribute("garbage", "JavaVirtualMachine") # -> 0

Store attributes of a configurable type in a Jython dictionary:


from __future__ import nested_scopes The attrType may contain attsToDict = lambda type, dict: spaces map(lambda x: dict(x[0:x.index(" ")]) = x[x.index(" ") + 1:] , AdminConfig.attributes(type).splitlines()) jvmatts = {} attsToDict("JavaVirtualMachine", jvmatts) jvmatts.has_key("systemProperties") jvmatts.get("systemProperties") Builds dictionary of all atts including those whose values are references to other types
34

2007 WebSphere User Group

Functional programming examples using AdminConfig (3) Store just the simple attribute names and append the type name to each:
from __future__ import nested_scopes Contains entries such as: attsToDict = lambda type, dict: {initialHeapSize_JavaVirtualMachine int} map(lambda x: dict(x[0:x.index(" ")] + "_" + type) = x[x.index(" ") + 1:], \ filter(lambda x: x.endswith("*") == 0 and x.endswith("@") == 0, \ AdminConfig.attributes(type).splitlines()))

Build a Jython dictionary of all simple attribute names of all object types:
11 bigDict = {} map(lambda x: attsToDict(x, bigDict), AdminConfig.types().splitlines())

2007 WebSphere User Group

35

Functional programming examples using AdminConfig (4)


Use the dictionary to validate and set values:
One generic function serving most update needs

15

def setValues(baseType, simpleName, qualifier=None, **setThese): objid = AdminConfig.getid("/" + baseType + ":" + simpleName + "/") for attrUndType, value in setThese.items(): undPos = attrUndType.find("_") if bigDict.has_key(attrUndType): attrName = attrUndType[:undPos] ; attrType = attrUndType[undPos+1:] attrTypeIdList = AdminConfig.list(attrType, objid).splitlines() if qualifier: for listItem in attrTypeIdList: Error checking if listItem.startswith(qualifier): removed to keep this attrTypeId = listItem example simple break else: if len(attrTypeIdList) == 1: attrTypeId = attrTypeIdList[0] AdminConfig.modify(attrTypeId, [[attrName, value]])

2007 WebSphere User Group

36

Functional programming examples using AdminConfig (4)


Use the dictionary to validate and set values:
setValues("Server", "engine1", initialHeapSize_JavaVirtualMachine = 1024, maxInMemorySessionCount_TuningParams = 200, setValues() works for parallelStartEnabled_Server = "false") setValues("Server", "engine1", description_ThreadPool="some description", minimumSize_ThreadPool=2, maximumSize_ThreadPool = 17, qualifier="WebContainer")

16

simple changes. Doesn't create or delete objects. Doesn't add or delete attributes to existing objects (e.g. custom properties)

2007 WebSphere User Group

37

Regular expressions Similar to regexp in other languages Can get unreadable use raw strings (introduced by "r") Produce a more readable list of application servers:
import re for appserv in AdminConfig.list("ApplicationServer").splitlines(): print re.sub(r".*\(cells/.+/nodes/(.+)/servers/(.+)\|.+\)", r"\2 on \1", appserv)

12

2007 WebSphere User Group

38

Threads Run an object and arg tuple in a new thread:


import thread mynode = "appServNode" def startAServer(server): print "I'm: ", server AdminControl.startServer(server, mynode) print "I'm done: ", server Starts application servers in parallel threads. Note the tuple passed as an argument to the function

for server in "server1", "server2": thread.start_new_thread(startAServer, (server,))

2007 WebSphere User Group

39

Modules and packages


Module: a .py file containing Jython code
Can reload modules you're working on using reload()

Package: Hierarchy of modules in a directory tree


Is a package if there's a file called __init__.py in the directory

Use the import statement to load them


import A.B.C implies A and B are packages, C is a module or package

Special variables: __name__, __doc__, __file__, __all__ dir(A.B.C), dir(A.B.C.someFunction) tell you what's available
2007 WebSphere User Group 40

Importing modules and packages

Four types of import:


Import everything in a hierarchy:
import sys
Can import WebSphere classes too

Import a subset of a hierarchy:


from java import util

Import a hierarchy but give it a new name:


import os as myOS

Import a subset but give it a new name:


from sys import packageManager as pm

2007 WebSphere User Group

41

Using AdminConfig etc from packages


Suppose A.B.C.py contains this:
def listServers(): AdminConfig.list("Servers")

and you invoke it from D.py:


import A.B.C as C C.listServers() # -> NameError

Not even placing global AdminConfig in C.py works. Global in Jython is not the same as in Jacl

Could change D.py to call execfile("<path>/C.py"), but this collapses everything to a single module you might get name clashes. Would then call listServers() not C.listServers(). Instead you could change C.py and retain the hierarchy:
import com.ibm.ws.scripting.AdminConfigClient as Scripting AdminConfig = Scripting.getInstance() def listServers(): AdminConfig.list("Servers")

Clearly this is WAS-version specific so isn't a great solution

2007 WebSphere User Group

42

Some useful Jython libraries


Need to import these libraries to use them Java platform (e.g. 1.5) Useful things in sys:
argv, modules, path, platform, version, exc_info() Jython version (e.g. 2.1)

Use os for platform-independence


Use glob for file pattern matching Use re for regular expressions Unit testing with PyUnit

os.linesep, os.pathsep, os.mkdir(), os.stat(), os.listdir(), os.path.join(), os.path.isfile(), os.path.isdir(), os.path.dirname(), . . . For really robust admin scripts:
import unittest <body of module> if __name__ == '__main__': <test cases>
2007 WebSphere User Group 43

Classes No explicit private, protected, public tags


Implicit name prefixes:
One underscore => private Two underscores => very private But can always access via the full name

Defining a class:
class class_name[(inheritance)]: <code> class Myclass: """documentation""" <class-level attributes> <method 1>: <instance-level attributes>

Note: no class-level (static) methods

Can dynamically create attributes

Create class-level attributes within a method by prefixing with the class name
2007 WebSphere User Group 44

Instance methods and constructors


Use the __init__ method as a constructor Instance method definitions require an identifier as the first parameter (conventionally "self"):
class JVM: def __init__(self, server = "server1"): serverId = AdminConfig.getid("/Server:"+server) stringJvmIds = AdminConfig.list("JavaVirtualMachine", serverId) listJvmIds = stringJvmIds.split() if len(listJvmIds) != 1: raise "JVMIdException" self.jvmString = listJvmIds[0] def getHeapSizes(self): minHeap = AdminConfig.showAttribute(self.jvmString, "initialHeapSize") maxHeap = AdminConfig.showAttribute(self.jvmString, "maximumHeapSize") return (minHeap, maxHeap) jvmid = JVM("controller") minHeap, maxHeap = jvmid.getHeapSizes() print minHeap, maxHeap

13

2007 WebSphere User Group

45

Class Inheritance Can inherit from multiple classes:


class OrderItem(Cust, Stock): def __init__(self, custref, stockref, qty): self.custref = custref self.stockref = stockref if stockref.qty qty >= 0: self.qty = qty stockref.qty -= qty else: print "Not enough in stock" def showQty(self): print self.custref.id, ":", self.custref.name, ":", self.stockref.code, ":", self.qty myitem = orderItem(alphaOrg, stock1, 14) myitem.showQty()
2007 WebSphere User Group 46

Java from Jython A Jython class can only inherit from one Java class, but many Jython classes A Jython subclass cannot access a Java class's:
protected static methods and fields protected instance fields package-protected members

Just import the Java classes and off you go:


from java.lang import System from java.lang import String x = String("Spamalot") if x.startsWith("Spam"): System.out.println("Spam spam spam spam")

2007 WebSphere User Group

47

And now for something completely different

Making wsadmin scripts more readable, robust, maintainable, extendable Making interactive administration a more friendly experience Suggested conventions

2007 WebSphere User Group

48

Scripts should be environment-independent Scripts must be independent of the target environment


Don't edit the scripts as you move from environment to environment Externalise in properties files Could split into "definitely unique per environment" and "common but seems sensible to externalise" Choice:
Make the property values Jython sequences Make them more human-readable

Choice:
Use execfile() to execute those properties files Use the p option on the wsadmin command line
2007 WebSphere User Group 49

Scripts should be modularised

EITHER:
Develop a common.py Develop individual .py files that wrap up a bunch of AdminConfig, AdminApp objects
e.g. jdbc.py, appserver.py, cluster.py

execfile() them all and have a single namespace for your entire scripts

OR:
Use Jython packages, modules and classes to structure it in an OO fashion import these and have separate namespaces
2007 WebSphere User Group 50

Good practices Strive for platform independence Never make N calls from a shell script to wsadmin each passing a separate c option
Each involves connecting to WAS Make those N calls from within a wsadmin script

Script the entire configuration build


Tear down and rebuild

Simplify the wsadmin complexity:


Hide the verbose naming convention
Work in WAS scopes Display simple names, work out the verbose ones

Hide the navigation hierarchy


2007 WebSphere User Group 51

More good practices


You probably don't need to dive into Java from Jython
Many (most?) administrators are not Java programmers

Don't just provide create, modify and delete functions


List and show are also useful Build a script library a library of functions and/or classes & methods

Move away from positional parameters on functions


Allow keywords or dictionaries to be passed in

Make it possible to use your library easily interactively


This is hardly the case with out-of-the-box wsadmin

Conventions:
Class names have upper case first char Method and function names in camelCase Spaces around operators and parameters No space before colon in dictionaries Indent consistently either 2 or 4 spaces
2007 WebSphere User Group 52

Summary
Dj vu:
We've seen there are excellent Jython productivity tools in the WAS 6.1 AST We've looked at the basic and some advanced features of the Jython language We've established some recommended practices for Jython scripting

2007 WebSphere User Group

53

References Jython Essentials, Samuele Pedroni & Noel Rappin (O'Reilly) Jython for Java Programmers, Robert Bill (New Riders)

2007 WebSphere User Group

54

Spanish Inquisition Nobody expects . . .

2007 WebSphere User Group

55

You might also like