Most writers of wsadmin Jython scripts eventually reach a point where they have some routines that they want to reuse. If you are one of them, the good news is that there are a number of different ways to do this, with each technique having its own advantages, disadvantages, and challenges. The bad news is that the information about these different techniques is often difficult to find. To help you out, this article presents a collection of information on different ways you can reuse Jython objects, and things to consider when you are deciding which technique to use.
The information presented here is intended to assist you in becoming better able to prepare and define your IBM® WebSphere® Application Server scripting environment. As such, you should be familiar with the wsadmin scripting utility that is provided with the WebSphere Application Server, as well as the syntax and semantics of either the Python programming language, or (better yet) the Java™ implementation of this language called Jython. If you need more details, the WebSphere Application Server Information Center online documentation and the IBM Press book WebSphere Application Server Administration Using Jython are particularly helpful, and both were important sources for some of the material in this article.
One of the challenges for Jython programmers in a wsadmin environment is the fact that when you first start the wsadmin scripting utility, it comes with a lot of things defined for your convenience. How do you know this? Well, if you start wsadmin, you can use the dir() built-in function to display the contents of the current namespace. Listing 1 shows an interactive wsadmin session to demonstrate just this. Table A, which follows, explains each part of the interactive wsadmin session shown in the listing. (To help explain and clarify script code and command session examples, this listing/table pairing convention is used throughout the article.)
Listing 1: Initial (default) namespace
1|C:\IBM\WebSphere\AppServer80\bin>wsadmin -lang jython 2|WASX7209I: Connected to process "dmgr" on node ragweedCellManager03 3|using SOAP connector; The type of process is: DeploymentManager 4|WASX7031I: For help, enter: "print Help.help()" | 5|wsadmin>dir() | 6|['AdminApp', 'AdminApplication', 'AdminAuthorizations', 'AdminBLA', 7|'AdminClusterManagement', 'AdminConfig', 'AdminControl', 'AdminJ2C', 'AdminJDBC', 8|'AdminJMS', 'AdminLibHelp', 'AdminNodeGroupManagement', 'AdminNodeManagement', 9|'AdminResources', 'AdminServerManagement', 'AdminTask', 'AdminUtilities', 10|'ApplyPerfTuning', 'Help', 'LTPA_LDAPSecurityOff', 'LTPA_LDAPSecurityOn', 'TypedProxy', 11|'__builtin__', '__doc__', '__name__', 'bsf', 'cellName', 'checkuserpw', 12|'doAuthenticationMechanism', 'doGlobalSecurity', 'doGlobalSecurityDisable', 13|'doLDAPUserRegistry', 'domainHostname', 'exportLTPAKey', 'flag', 'forceSync', 14|'generateLTPAKeys', 'getLDAPUserRegistryId', 'getLTPAId', 'getSecId', 15|'getSecurityAdminMbean', 'imp', 'java', 'ldapPassword', 'ldapPort', 'ldapServer', 16|'ldapServerId', 'ldapUserRegistryId', 'lineSeparator', 'ltpaId', 'main', 'nodeName', 17|'osgiApplicationConsole', 'secMbean', 'securityId', 'securityoff', 'securityon', 18|'sleep', 'sys', 'whatEnv'] | 19|wsadmin>print len( dir() ) | 20|60 |
Table A. Description of Listing 1
| Lines | Description and comments |
|---|---|
| 1 | wsadmin command invocation - specifying jython as the language to be used. |
| 2-3 | WASX7209I Informational message, showing that wsadmin is successfully connected to a DeploymentManager. |
| 4 | WASX7031I Informational message showing how to use the Help wsadmin scripting object to obtain information about using the wsadmin scripting objects. |
| 5 | wsadmin interactive command prompt "wsadmin>" followed by the user specified command (that is, "dir()") |
| 6-18 | The output of the dir() command showing the names of all of the objects (for example, variables and functions) defined in the local namespace. |
| 19 | wsadmin interactive command prompt followed by the user specified command (that is, "print len( dir() )", which displays the length of the list of names returned by dir(), (that is, the number of names in the list). |
| 20 | The number of names in the dir() list; that is, 60. |
Unfortunately, it is not immediately obvious what all of these things are, or how and why they were added to the initial environment. To make the reuse techniques discussed here easier to understand, let’s start by removing these extra items from the initial namespace. This will make it is easier to see the effect of the changes you will be making to the wsadmin environment.
Cleaning up (shortening) the namespace
Some of the frequently asked questions about this initial list of object names include:
- Do I really need all of this stuff?
It depends upon what you want (and need) to do. There are circumstances in which some of these objects might be useful, but for the majority of users and situations, there are usually very few times when these objects appear to be used. Although still general, a more accurate answer to this question is, “rarely.”
- Is there any way to get rid of the stuff that I don't want or need?
Certainly. To get rid of the “extra” stuff and reduce the list of object names to an absolute minimum, you begin by renaming the <WAS_HOME>/scriptLibraries directory. You'll see what’s in this directory structure shortly, but for now, just rename the directory and restart wsadmin to see what this does to the list of object names in the default namespace. Listing 2 shows this using another interactive wsadmin session.
Listing 2. Namespace after renaming the scriptLibraries directory
1|wsadmin>dir() | 2|['AdminApp', 'AdminConfig', 'AdminControl', 'AdminTask', 'Help', 3|'LTPA_LDAPSecurityOff', 'LTPA_LDAPSecurityOn', 'TypedProxy', '__builtin__', '__doc__', 4|'__name__', 'bsf', 'cellName', 'checkuserpw', 'doAuthenticationMechanism', 5|'doGlobalSecurity', 'doGlobalSecurityDisable', 'doLDAPUserRegistry', 'domainHostname', 6|'exportLTPAKey', 'flag', 'forceSync', 'generateLTPAKeys', 'getLDAPUserRegistryId', 7|'getLTPAId', 'getSecId', 'getSecurityAdminMbean', 'imp', 'java', 'ldapPassword', 8|'ldapPort', 'ldapServer', 'ldapServerId', 'ldapUserRegistryId', 'lineSeparator', 9|'ltpaId', 'main', 'nodeName', 'secMbean', 'securityId', 'securityoff', 'securityon', 10|'sleep', 'sys', 'whatEnv'] 11|wsadmin>print len( dir() ) | 13|45 |
Table B. Description of Listing 2
| Lines | Description and comments |
|---|---|
| 1 | Interactive command prompt, and user command: dir() |
| 2-10 | The output of the dir() command showing the names of all of the objects (for example, variables and functions) defined in the local namespace. |
| 11 | wsadmin interactive command prompt followed by the user specified command (i.e., "print len( dir() )", which displays the length of the list of names returned by dir(), (that is, the number of names in the list). |
| 12 | The number of names in the (shortened) dir() list; that is, 45. |
As you can see in Table B, the listing shows that by renaming the scriptLibraries directory, you have removed 15 entries from the list of local scope object names. The number of items in the namespace, therefore, has been reduced by 25%, which is a reasonable start.
One of the things that occurs during the initialization of wsadmin is that the appropriate wsadmin.properties file is read and used to configure or initialize the wsadmin environment.
For example, if you use the -profileName command line option when you start wsadmin, or
if you start the wsadmin utility under a particular profile directory (such as,
C:\IBM\WebSphere\AppServer\profiles\AppSrv01\bin), then the wsadmin.properties file for that profile will be used. On the other hand, if you are in the <WAS_HOME>/bin directory (for example, C:\IBM\WebSphere\AppServer\bin) and do not specify the
-profileName option on the wsadmin command line, then the wsadmin.properties file for the default profile will be used. To determine the default profile name, use the command:
manageprofiles -getDefaultName
A wsadmin.properties file for a given profile is generally located in the properties directory under the specific profile (for example, C:\IBM\WebSphere\AppServer\profiles\Dmgr01\properties\wsadmin.properties).
Only a few of the directives in the wsadmin.properties file are discussed in this article, but for the moment we are only interested in the directive used to identify a list of profile files to be executed and processed before any user commands, or scripts. Initially the directive looks something like this (for the purpose of this article, this line was shortened using ellipses (…) to show where the <WAS_HOME> path would normally appear):
com.ibm.ws.scripting.profiles=.../securityProcs.jacl;.../LTPA_LDAPSecurityProcs.jacl
Does the .jacl file extension mean that these profile scripts aren't executed when the language is Jython? Yes and no. If the profile directive identifies one or more Jacl profile files, and the language is specified as Jython (either on the command line or on the com.ibm.ws.scripting.defaultLang directive of the wsadmin.properties file), then wsadmin will attempt to locate and execute the Jython versions of the specified profile files. Simply put, this means that instead of trying to execute securityProcs.jacl and LTPA_LDAPSecurityProcs.jacl, wsadmin will look for securityProcs.py and LTPA_LDAPSecurityProcs.py (in the specified directories) when the language is Jython. (Opening these Jython files in a text editor enables you to see where most of the named objects in the initial wsadmin namespace originate.) That being said, it is probably a good idea to have the file extensions of the profile files match the default language specified in the wsadmin.properties file.
Edit the appropriate wsadmin.properties file to comment out the profiles directive using an octothorpe (that is the "#" character) at the start of the line:
# com.ibm.ws.scripting.profiles=...
How much does that change the initial wsadmin environment? Listing 3 shows the effect of this change.
Listing 3. Minimum wsadmin namespace
1|wsadmin>dir() | 2|['AdminApp', 'AdminConfig', 'AdminControl', 'AdminTask', 'Help', 'TypedProxy', 3|'__builtin__', '__doc__', '__name__', 'bsf', 'imp', 'main', 'sys'] | 4|wsadmin>print len( dir() ) | 5|13 |
You've reduced the number of named objects in the local namespace by almost 80%, which is significantly shorter than the original list of 60 names. This is what it means to start with a “clean” environment.
Now that you’ve minimized the initial wsadmin environment namespace, you will be able to more easily understand how each reuse technique affects the scripting environment.
Techniques inherited from Python
Of the techniques that will be discussed in this article, the only ones that are inherited from the Python language are:
- Script files
- Modules
- Packages
Because you’re reading this article, you’re probably already familiar with wsadmin
script files and how to execute wsadmin scripts. Generally, a wsadmin script is a
collection of Jython statements in a file that can be executed by the wsadmin
utility. The name of the script file to be executed is specified as a wsadmin
command line option after the -f flag.
Scripts frequently make use of existing or built-in modules by using an import statement. To make any of the various built-in objects available to your scripts, you need to use a variation of the import statement, listed in Table C. (See Resources if you are unfamiliar with these variants.)
Table C. Import statement variations
| Variation number | Variant syntax |
|---|---|
| 1 | import moduleName |
| 2 | import moduleName as aliasName |
| 3 | from moduleName import objectName |
| 4 | from moduleName import objectName as objectAlias |
| 5 | from moduleName import * |
Before discussing these variations, or variants, you need to know how a module is located and executed when an import statement is processed. Jython looks in each of the directories specified in the sys.path list for a given moduleName by searching for a file named moduleName.py. Listing 4 shows the contents of sys.path before you rename the scriptLibraries directory, and Listing 5 shows the contents after this directory is renamed.
Listing 4. Default sys.path
1|wsadmin>for d in sys.path : print d 2|wsadmin> 3|. 4|C:\IBM\WebSphere\AppServer80\optionalLibraries\jython\Lib 5|C:/IBM/WebSphere/AppServer80/scriptLibraries/application/V70 6|C:/IBM/WebSphere/AppServer80/scriptLibraries/osgi 7|C:/IBM/WebSphere/AppServer80/scriptLibraries/perfTuning/V70 8|C:/IBM/WebSphere/AppServer80/scriptLibraries/resources/J2C/V70 9|C:/IBM/WebSphere/AppServer80/scriptLibraries/resources/JDBC/V70 10|C:/IBM/WebSphere/AppServer80/scriptLibraries/resources/JMS/V70 11|C:/IBM/WebSphere/AppServer80/scriptLibraries/resources/Provider/V70 12|C:/IBM/WebSphere/AppServer80/scriptLibraries/security/V70 13|C:/IBM/WebSphere/AppServer80/scriptLibraries/servers/V70 14|C:/IBM/WebSphere/AppServer80/scriptLibraries/system/V70 15|C:/IBM/WebSphere/AppServer80/scriptLibraries/utilities/V70 16|wsadmin> |
The empty line shown on line 2 in Listing 4 tells the Jython interpreter that the for statement started on line 1 is complete.
Also in Listing 4, notice how the “current working directory” (represented by "." on line 3) is first in the list. This means that when an import moduleName statement is executed, Jython will first look in the current working directory to see if moduleName.py exists and try to execute it. If the file does not exist in this directory, each directory in the sys.path list will be checked, in order, until either the specified moduleName.py file is located and executed, or the list of directories is exhausted. If the specified module, or object, can’t be located, an ImportError exception is raised.
Listing 5. sys.path when scriptLibraries directory doesn’t exist
1|C:\IBM\WebSphere\AppServer80\bin>wsadmin –conntype none 2|... 3| wsadmin>for d in sys.path : print d 4| wsadmin> 5|. 6| C:\IBM\WebSphere\AppServer80\optionalLibraries\jython\Lib 7| wsadmin> |
Understanding the import statement variants
Now that you understand how Jython tries to load a module, it is import that you understand the different import statement variations listed in Table C. Let’s discuss them in reverse order.
- Variant 5 acts as though the statements within the module file were entered by hand. This means that all of the definitions and assignment statements found in the file will directly affect the local scope namespace; existing objects of the same name can be modified, or even removed. The fact that every new object in this module will be added to the local namespace means that you can easily encounter something called namespace clutter, meaning that the local namespace can quickly fill up with object names and it is unlikely that you will know or remember from where these objects originated. Therefore, use of this variant is strongly discouraged.
- Variants 3 and 4 are used to selectively add objects from a module to the local namespace. Since they are selective, they are much less likely to be as dangerous as variant 5, but they still could cause harm. Consider the situation where the objectName, or objectAlias, imported from a module already exists in the local namespace. The existing object will be replaced by the imported object, which might not be what you intended. Using variant 3 or 4, you could unwittingly overwrite an existing object, which could make your script fail in a way that is difficult to debug or diagnose.
- Variants 3 through 5 will add items from the specified module to the local namespace. Once this has been done, you can simply use an object name to access the specific object. This is not the case when you use either variant 1 or 2, unless of course an object already exists in the local namespace with the name of the moduleName or aliasName that you intend to import. This might be nothing new to you. When you use import moduleName, the only addition to the local namespace will be moduleName, as shown in Listing 6.
Listing 6. Using variant 1: import moduleName
1|C:\IBM\WebSphere\AppServer80\bin>type something.py 2|print "dir():", dir() | 3|C:\IBM\WebSphere\AppServer80\bin>wsadmin -conntype none 4|... 5|wsadmin>dir() 6|['AdminApp', 'AdminConfig', 'AdminControl', 'AdminTask', 'Help', 'TypedProxy', 7|'__builtin__', '__doc__', '__name__', 'bsf', 'imp', 'main', 'sys'] | 8|wsadmin>import something 9|dir(): ['__doc__', '__file__', '__name__'] | 10|wsadmin>dir() 11|['AdminApp', 'AdminConfig', 'AdminControl', 'AdminTask', 'Help', 'TypedProxy', 12|'__builtin__', '__doc__', '__name__', 'bsf', 'imp', 'main', 'something', 'sys'] | 13|wsadmin>dir( something ) 14|['__doc__', '__file__', '__name__'] | 15|wsadmin>print something.__file__ 16|C:\IBM\WebSphere\AppServer80\bin\.\something.py 17|wsadmin> |
Table D. Description of Listing 6
| Lines | Description and comments |
|---|---|
| 1 | Operating system command to display the contents of something.py, a trivial module. |
| 2 | The contents of something.py. |
| 3 | Command used to invoke the wsadmin utility in local mode. |
| 4 | Ellipses used to show that the wsadmin generated output is not being displayed. |
| 5 | Interactive command prompt, and the import statement to be executed; that is, dir() |
| 6-7 | Generated output showing the current namespace contents. |
| 8 | Interactive prompt and our (variant 1) import statement. |
| 9 | Output generated by the execution of the module script file (that is, the module namespace). |
| 10 | Another instance of the dir() command to show the modified namespace. |
| 11-12 | Generated output showing that the only new namespace entry is that of the imported module (that is, "something"). |
| 13 | Another instance of the dir() command, this time used to display the namespace of the imported module. |
| 14 | Generated output showing that the module namespace has not changed (see line 9). |
| 15 | Print statement used to display the value of the __file__ variable within the something module. Note the use of the dot operator to identify the module object. |
The information above demonstrates some of the most important characteristics of modules, specifically:
- Importing a module (using either variant 1 or 2) provides access to all of the module objects without cluttering the local namespace.
- By using the dot notation to identify the object being referenced, you can easily see where the actual object exists (that is, within the specified module).
Modules and wsadmin scripting objects
By wsadmin scripting objects, we’re referring to the five objects that exist within the wsadmin environment to manipulate or interact with WebSphere Application Server: AdminApp, AdminConfig, AdminControl, AdminTask, and Help.
At one time (before WebSphere Application Server V7.0), modules had some challenges with doing this. In fact, both the WebSphere Application Server Administration Using Jython book and Using the full potential of Jython to build compact and maintainable wsadmin scripts article (see Resources) describe techniques that can be used to overcome this limitation. However, WebSphere Application Server V7.0 and later no longer have this issue, which means that all a module needs to do to access a wsadmin scripting object is to include a "global" statement for the object in question. For example, then, if a module needs to access the AdminConfig scripting object, it only needs to include a statement like global AdminConfig. You’ll see a little more of this later in the discussion on scriptLibraries.
Packages are the last of the reuse techniques that originated with Python. Packages are a way of organizing modules in a hierarchy and using the dot operator to indicate the relationship. For example, looking back at the directives in the wsadmin.properties files, you find directives like com.ibm.ws.scripting.defaultLang, which is analogous to the way that package naming works. Each name (for example, “com” and “ibm”) in this dotted list is sort of like a directory in a package hierarchy.
Why would you want or need this kind of nested module naming? Consider the situation where a collection of packages is being designed by a team of developers. Just as modules can be used to isolate a collection of objects together in a single namespace, packages can and should be used to collect and organize related modules together.
An Introduction to Python by Guido van Rossum and Fred L. Drake, Jr. (see Resources) has a good example in Section 6.4 that provides excellent information about packages. From it, we learn that:
- As with simple modules, any of the import statement variants described above can be used to make a module’s objects available.
- As shown above in Listings 4 and 5, the directories in sys.path will be used to find a module. The main difference between a simple module and a package is the way in which each package directory contains a special file (such as, __init__.py) that is used to tell Jython to treat the directory as containing a package. However, only the directory containing the first package (for example, the “com” above) needs to be in sys.path.
To understand what this means, take a look back at the default contents of the
sys.path list, where each directory in the scriptLibraries hierarchy containing a
*.py file is listed in sys.path. What does this do for you? For one thing, it
simplifies the import statement (if one were actually needed) to be something
like: import moduleName.
If the scriptLibraries were packages, then you would only need to have one entry in sys.path, such as, <WAS_HOME>/scriptLibraries. Additionally, each level of the directory structure would contain a (potentially empty) __init__.py file. Importing the AdminBLA module would require an import statement of the form shown in Listing 7.
Listing 7. Importing AdminBLA as a package
import application.V70.AdminBLA or from application.V70 import AdminBLA |
In fact, if you were to use the latter variation (which corresponds to variant 3 in Table C), this would simply add the moduleName (in this case, AdminBLA) to the namespace, just like what you would normally see with the scriptLibraries, which will be discussed shortly.
However, in order to make use of packages, you need to include the appropriate __init__.py file at each level of the directory structure.
Reuse techniques unique to wsadmin
The last of the reuse techniques described here are not part of Python and are only available for the wsadmin environment. They are:
- Profiles
- scriptLibraries
A profile file is a script file that is executed as part of the initialization phase of the wsadmin utility that can be used to add objects to, or remove objects from, the local namespace. This means that a profile script can be used to manipulate the wsadmin scripting environment before either a specified user script file is executed, or the interactive command prompt is displayed.
This should sound familiar because it is very similar to what was described earlier in reference to the most dangerous of the import variants. In fact, at the beginning of the article, a directive was commented out in the wsadmin.properties file so that the specified files would not be executed as profiles; if these profiles had been executed, 30 objects would have been added to the local namespace.
So, what's the difference between executing a file and executing a profile?
- Command line syntax
To execute a file, you specify the name of the file after the
-fwsadmin command line option; for example,-f myFile.py. To execute a profile script file, you would do use one of these techniques:- The
-profilewsadmin command line option can be specified; for example,wsadmin -profile myFile.py. - You can edit the appropriate wsadmin.properties file and profile script files to be executed can be added to the (uncommented) profile directive, as shown earlier.
- The
- Subsequent action taken after the profile or file script is executed
After all of the profile script files have been executed, wsadmin will either run the user specified script file (if there is one) or display an interactive prompt for user input if no script file is specified. (Unlike profile script files, only the last script file will be invoked if multiple occurrences of the
-f filename.pycommand line option exists. So, for a command likewsadmin –conntype none –f a.py –f b.pyonlyb.pywill be executed.)If a user specified script file is to be executed, then the wsadmin utility will remain active until the script is complete, at which time the wsadmin utility terminates.
One question that might come up relates to the fact that profile script files can be specified by either using the wsadmin command line option or by adding the script file name to the profile directive in the wadmin.properties file. Since profile files can be specified in multiple places, it is not immediately obvious the order in which they will be run.
To address the question of run sequence, two similar script files are shown in Listing 8, bob.py and Robert.py. The first, bob.py, is specified in wsadmin.properties, and the second, Robert.py is specified using the wsadmin command line option.
Listing 8. Profile execution order example
1|C:\IBM\WebSphere\AppServer80\bin>type bob.py 2|File = 'bob.py' 3|print 'File: %s __name__ = "%s"' % ( File, __name__ ) 4|print 'dir():\n%s' % dir() | 5|C:\IBM\WebSphere\AppServer80\bin>type Robert.py 6|File = 'Robert.py' 7|print 'File: %s __name__ = "%s"' % ( File, __name__ ) 8|print 'dir():\n%s' % dir() | 9|C:\IBM\WebSphere\AppServer80\bin>wsadmin -profile Robert.py 10|WASX7209I: Connected to process "dmgr" on node ... 11|File: bob.py __name__ = "__main__" 12|dir(): 13|['AdminApp', 'AdminConfig', 'AdminControl', 'AdminTask', 'File', 'Help', 'TypedProxy', 14|'__builtin__', '__doc__', '__name__', 'bsf', 'imp', 'main', 'sys'] 15|File: Robert.py __name__ = "__main__" 16|dir(): 17|['AdminApp', 'AdminConfig', 'AdminControl', 'AdminTask', 'File', 'Help', 'TypedProxy', 18|'__builtin__', '__doc__', '__name__', 'bsf', 'imp', 'main', 'sys'] 19|WASX7031I: For help, enter: "print Help.help()" | 20|wsadmin>print File | 21|Robert.py |
Table E. Description of Listing 8
| Lines | Description and comments |
|---|---|
| 1 | Operating system command to display the contents of bob.py. |
| 2-4 | The contents of bob.py |
| 5 | Operating system command to display the contents of Robert.py. |
| 6-8 | The contents of Robert.py, which are nearly identical to bob.py (lines 2-4). |
| 9 | Command used to start the wsadmin utility, and specify Robert. |
| 10 | Truncated message generated by wsadmin showing that it is connected to a deployment manager. |
| 11-14 | Output generated by bob.py (which was specified in wsadmin.properties file), showing that the wsadmin.properties file profiles are executed first. |
| 15-18 | Output generated by Robert.py, showing that command line profile are executed after the ones specified in wsadmin.properties. |
| 19 | Message generated by wsadmin utility for an interactive session. |
| 20 | wsadmin command prompt and print statement to display the contents of the File variable. |
| 21 | Output generated by the print statement showing the value of the File variable. The value shows how assignment statements within a profile can modify namespace values. |
If you were to run these script files, you would learn:
- The profile files specified in the wsadmin.properties file are executed first. In fact, additional testing shows that the profile files specified in the wsadmin.properties file are executed in the order listed (that is, left to right).
- The profile files specified on the wsadmin command line are executed next, and are
also executed in the order specified (if multiple
-profilecommand line directives are specified). - Statements in every profile file affect the local scope namespace, meaning that all definitions, assignments, modifications, and deletions made in any profile file change the values of objects in the local namespace. Did you notice how the value of the File variable initialized by bob.py was overwritten by the assignment statement in Robert.py?
Based upon this last fact, it would seem prudent to use profile files with caution, and sparingly. If you do create any profile files, be sure they result in a minimum number of namespace changes.
That’s not to say that you should never use profiles, but they should be used with caution. There are situations where using a profile to change the wsadmin environment for all wsadmin scripts makes sense. For example, Chapter 7 of the book mentioned earlier discusses some things that can be done in a profile file that make life much easier for wsadmin script users.
In addition, there are some things that are best done with profiles. These include:
- Executing import statements that should not be forgotten
For example, see the import statement in line 1 of Listing 9 (see Chapter 5 of the book). You might also want to import the original profile scripts (the ones that you removed from the wsadmin.properties file) as modules. An example of this is shown in lines 3 and 4 in Listing 9. Another kind of import statement that you might choose to include in a profile script could be one where a module is imported as an alias, as shown line 12.
- Adding directories to sys.path
Many people gather routines and modules into a specific directory for easy reuse. A profile script can be used to ensure that this directory is available in the sys.path by having statements in a profile script to check for the existence of the directory, and, if the directory exists, add it to the sys.path list in a desired location in the list. An example of this can be seen in lines 6 through 9 of Listing 9.
Listing 9. Possible profile example
1|from __future__ import nested_scopes 2| 3|import securityProcs 4|import LTPA_LDAPSecurityProcs 5| 6|import os 7|if 'wsadminModules' in os.listdir( r'C:\temp' ) : 8| sys.path.append( r'C:\temp' + os.sep + 'wsadminModules' ) 9|del( os ) # Remove os from the namespace to minimize clutter 10| 11|try : 12| import wsadmin_Jython_utilities as Util 13|except ImportError, e : 14| print '\n*** WARNING *** Module not found: %s\n' % str( e ).split( ' ' )[ -1 ] 15| del( e ) # Remove e from the namespace to minimize clutter |
One thing these examples do is help you clean up and organize your namespace. Consider how the profile script customizes your environment and makes your script files easier to understand. Instead of your profile adding all of the securityProcs objects to your namespace, Listing 10 shows your profile being imported as a module. You can now use the dot operator notation discussed earlier to access any of the objects within the module; you can see this in line 4 of Listing 10.
Listing 10. Using a profile imported module
1|wsadmin>dir( securityProcs ) 2|['__doc__', '__file__', '__name__', 'checkuserpw', 'securityoff', 'securityon'] 3|wsadmin> 4|wsadmin>securityProcs.securityoff() 5|LOCAL OS security is off now but you need to restart the connected server ... |
One of the first things that you did at the beginning of this article was to rename
the scriptLibraries directory that was created as part of the product
installation. In so doing, the name of each object was removed from the
namespace. Now that we have discussed script files, profiles, modules, and
packages, it shouldn't take much to realize that script library files are, in
fact, modules. To verify this, you can restore the scriptLibraries directory
(which you can do because you renamed them rather than deleted them) and start the
wsadmin utility. Use the dir() command to see what
happens to the local namespace. Listing 11 shows one way that this can be done.
(This is a slightly more complex example in order to make the generated output a little easier to read. Table F explains the important details.)
Listing 11. Minimum wsadmin namespace + scriptLibraries
1|C:\IBM\WebSphere\AppServer80\bin>wsadmin 2|WASX7209I: Connected to process "dmgr" on node ... 3|WASX7031I: For help, enter: "print Help.help()" | 4|wsadmin>def namesInColumns( names ) : 5|wsadmin> x, width = 0, max( [ len( x ) for x in names ] ) 6|wsadmin> for name in names : 7|wsadmin> if name != 'namesInColumns' : 8|wsadmin> print '%*s' % ( -width, name ), 9|wsadmin> x += 1 10|wsadmin> if ( x + 1 ) * ( width + 1 ) > 80 : 11|wsadmin> print 12|wsadmin> x = 0 13|wsadmin> print 14|wsadmin> | 15|wsadmin>namesInColumns( dir() ) | 16|AdminApp AdminApplication AdminAuthorizations 17|AdminBLA AdminClusterManagement AdminConfig 18|AdminControl AdminJ2C AdminJDBC 19|AdminJMS AdminLibHelp AdminNodeGroupManagement 20|AdminNodeManagement AdminResources AdminServerManagement 21|AdminTask AdminUtilities ApplyPerfTuning 22|Help TypedProxy __builtin__ 23|__doc__ __name__ bsf 24|imp main osgiApplicationConsole 25|sys | 26|wsadmin>namesInColumns( dir( AdminBLA ) ) | 27|AdminUtilities __doc__ __file__ __name__ addCompUnit 28|bundleName createEmptyBLA deleteAsset deleteBLA deleteCompUnit 29|editAsset editCompUnit exportAsset help importAsset 30|java listAssets listBLAs listCompUnits resourceBundle 31|startBLA stopBLA sys viewAsset viewCompUnit | 32|wsadmin>print AdminBLA.__file__ | 33|C:\IBM\WebSphere\AppServer80\scriptLibraries\application\V70\AdminBLA.py | 34|wsadmin>print AdminBLA.__name__ | 35|AdminBLA |
Table F. Description of Listing 11
| Lines | Description and comments |
|---|---|
| 1 | Command used to start the wsadmin utility. |
| 2-3 | Output generated during wsadmin initialization. |
| 4-13 | Statements to define a function to display the specified names in columns. |
| 15 | Call to namesInColumns() function to display the namespace contents in columns. |
| 16-25 | Generated output, showing the 28 names in the list of values returned by calling the built in dir() function. |
| 26 | Call to namesInColumns() function to display the namespace of the AdminBLA module. |
| 27-31 | Generated output, showing the 25 names in the module namespace. |
| 32 | Print statement to display the value of the __file__ object in module AdminBLA. |
| 33 | The generated output showing the fully qualified path to the file from which the module was loaded. |
| 34 | Print statement to display the value of the __name__ object in module AdminBLA. |
| 35 | The generated output showing the value of AdminBLA.__name__. |
The main difference between a module and any of the scriptLibraries modules is that you don't have to explicitly “import” the scriptLibraries modules – and that’s basically it. Remember, though, that in order for a module import statement to succeed, the directory containing the module must be present in the sys.path list.
Listing 4 shows that when the interactive wsadmin session begins, the contents of sys.path includes the directories containing the scriptLibraries directories containing Jython files (that is, files having an extension of .py).
You can verify that only directories containing *.py files are added to sys.path by renaming the *.py files in the scriptLibraries directory to some other extension (for example, *.py.tx), and starting wsadmin. Displaying the contents of sys.path will show that none of the scriptLibraries directories will be listed.
Are scriptLibraries modules usable by profile scripts?
If you have some profile code that depends upon one or more of the scriptLibraries modules, then these modules must be available before any profile script is executed. It’s easy enough to verify this; you can display the local namespace during the execution of the profile (Listing 12).
Listing 12. Which comes first: a profile or the scriptLibraries
1|C:\IBM\WebSphere\AppServer80\bin>wsadmin | 2|WASX7209I: Connected to process "dmgr" on node ... 3|File: bob.py __name__ = "__main__" 4|dir(): 5|['AdminApp', 'AdminApplication', 'AdminAuthorizations', 'AdminBLA', 6|'AdminClusterManagement', 'AdminConfig', 'AdminControl', 'AdminJ2C', 'AdminJDBC', 7|'AdminJMS', 'AdminLibHelp', 'AdminNodeGroupManagement', 'AdminNodeManagement', 8|'AdminResources', 'AdminServerManagement', 'AdminTask', 'AdminUtilities', 9|'ApplyPerfTuning', 'File', 'Help', 'TypedProxy', '__builtin__', '__doc__', 10|'__name__', 'bsf', 'imp', 'main', 'osgiApplicationConsole', 'sys'] 11|bob.py executed. 12|WASX7031I: For help, enter: "print Help.help()" 13|wsadmin> |
The good news is that Listing 12 shows that the modules in the scriptLibraries directories are already available when the profile is executed, even for the profile files specified in the wsadmin.properties file. Remember that you saw earlier that profile files identified in the wsadmin.properties file are executed before any profile files identified by the wsadmin command line -profile option.
The bad news is that if you were hoping to have a profile script do something to sys.path so that the scriptLibraries modules wouldn’t get loaded, then, you’re out of luck.
The scriptLibraries directory isn't the only script library you can use. To specify another or a different scriptLibrary directory, you need the syntax shown in line 4 of Listing 13.
Listing 13. Specifying additional scriptLibraries
1|C:\IBM\WebSphere\AppServer80\bin>type C:\temp\BobLibraries\trivialModule.py 2|print '\n%s executed.\n' % __file__ 3| 4|C:\IBM\WebSphere\AppServer80\bin>wsadmin -conntype none -javaoption |"-Dwsadmin.script.libraries=C:\temp\BobLibraries" | 5|WASX7357I: By request, this scripting client is not connected ... 6| 7|c:\temp\BobLibraries\trivialModule.py executed. 7 9|WASX7031I: For help, enter: "print Help.help()" | 10|wsadmin>for d in sys.path : print d 11|wsadmin> | 12|. 13|C:\IBM\WebSphere\AppServer80\optionalLibraries\jython\Lib 14|c:/temp/BobLibraries |
Table G. Description of Listing 13
| Lines | Description and comments |
|---|---|
| 1 | Command used to display the contents of the only *.py file in our scriptLibrary. |
| 2 | The contents of the specified module file. |
| 4 | wsadmin invocation, note the new command line option (that is, "-javaoption …"), and the fact that the line is so long that it is shown on multipple lines in the listing. |
| 5 | Truncated message generated by wsadmin. |
| 7 | Output generated by the trivialModule.py file in specified scriptLibraries directory. |
| 9 | Message generated by wsadmin for an interactive session. |
| 10 | Statements used to display the contents of the sys.path variable. |
| 12-14 | Generated output showing that directory specified on the wsadmin command line is now part of the sys.path variable. |
To understand what happens with this command line option, you need to realize that
wsadmin is, in fact, a command file (a shell script), hence the extension of .bat
or .sh on the executed wsadmin file. This command file will process the command
line options, and then launch a Java Virtual Machine (JVM), specifying the
appropriate options and class name so that the Java class for the wsadmin utility
will be run. The presence of -javaoption on the command line indicates that the parameter immediately following should be part of the options specified to the JVM, and not to the wsadmin utility.
There are a few important things to know about the –Dwsadmin.script.libraries option:
- It MUST be immediately preceded by
-javaoptionwhich is a special prefix that tells the wsadmin command file to take what follows as an option for the JVM. If-javaoptionis not specified, the value will be passed to the wsadmin utility as a parameter for the user script file. - To avoid common problems associated with using a backslash (\), the WebSphere Application Server product documentation encourages the use of a forward slash (/) as a directory delimiter, even in Windows environments.
In Windows environments, the complete -Dwsadmin.script.libraries value must be surrounded by double quotes because of the presence of the equal sign (=), as documented in Using the wsadmin scripting tool, which states:
"On Windows operating systems, if the option contains an equal sign (=) or a semicolon (;), you must put double-quotation marks (") around the option; for example:
wsadmin -javaoption "-Da.b.c=3"
Windows operating systems treat the equal sign (=) or the semicolon (;) in command-line arguments as a blank space. The wsadmin tool requires arguments that have a blank space to be enclosed in double-quotation marks."
As you have seen with profile files, it might be important to understand the order in which things get done. You know that the default scriptLibraries are executed before profile script files, but you don't know if they are executed (and therefore available) for your user specified script libraries. To figure this out, you can create a simple script library that will display information about the local namespace when it is executed. You can also have it display the contents of sys.path while you're at it. Listing 14 does this for you.
Listing 14. Simple user script library
1|C:\IBM\WebSphere\AppServer80\bin>type C:\temp\BobLibraries\myModule.py 2|print "Enter:", __file__ 3|print '-' * 60 4|print dir() 5|print '-' * 60 6|import sys 7|for d in sys.path : print d 8|print '-' * 60 9|print " Exit:", __file__ 10| 11|C:\IBM\WebSphere\AppServer80\bin>wsadmin -javaoption |"-Dwsadmin.script.libraries=C:\temp\BobLibraries" 12|WASX7209I: Connected to process "dmgr" on node ... 13|Enter: C:\temp\BobLibraries\myModule.py 14|------------------------------------------------------------ 15|['__doc__', '__file__', '__name__'] 16|------------------------------------------------------------ 17|. 18|C:\IBM\WebSphere\AppServer80\optionalLibraries\jython\Lib 19|C:/temp/BobLibraries 20|C:/IBM/WebSphere/AppServer80/scriptLibraries/application/V70 21|C:/IBM/WebSphere/AppServer80/scriptLibraries/osgi 22|C:/IBM/WebSphere/AppServer80/scriptLibraries/perfTuning/V70 23|C:/IBM/WebSphere/AppServer80/scriptLibraries/resources/J2C/V70 24|C:/IBM/WebSphere/AppServer80/scriptLibraries/resources/JDBC/V70 25|C:/IBM/WebSphere/AppServer80/scriptLibraries/resources/JMS/V70 26|C:/IBM/WebSphere/AppServer80/scriptLibraries/resources/Provider/V70 27|C:/IBM/WebSphere/AppServer80/scriptLibraries/security/V70 28|C:/IBM/WebSphere/AppServer80/scriptLibraries/servers/V70 29|C:/IBM/WebSphere/AppServer80/scriptLibraries/system/V70 30|C:/IBM/WebSphere/AppServer80/scriptLibraries/utilities/V70 31|------------------------------------------------------------ 32| Exit: C:\temp\BobLibraries\myModule.py 33|WASX7031I: For help, enter: "print Help.help()" 34|wsadmin> |
Table H. Description of Listing 14
| Lines | Description and comments |
|---|---|
| 1 | Operating system command to display the contents of our simple script library file (myModule.py). |
| 2-9 | Contents of myModule.py. |
| 11 | wsadmin command line used to specify our script library directory. Note: Due to the line length, it is shown on multiple lines in the listing. |
| 12 | Truncated message generated by wsadmin showing that a connection to a Deployment Manager server has been made. |
| 13 | Output generated by our library module showing the name of the module being processed. |
| 14-16 | Output generated by our library module showing the namespace contents. Note the lack of wsadmin scripting objects (for example, AdminApp, AdminConfig, and so on). |
| 17-30 | Output generated by our library module showing the contents of sys.path. |
| 32 | Output generated by our library module showing execution is complete. |
| 33 | Message generated by wsadmin for an interactive session showing how to get help for the wsadmin environment. |
What your scriptLibraries can do
Because user scriptLibraries are executed before the default scriptLibraries, you might wonder if you could have your script library module remove the default scriptLibraries directories from the sys.path list, thus keeping the default scriptLibraries from being processed and added to the namespace. This would provide you with an alternative method of ignoring the default scriptLibraries. The interactive session showing this is in Listing 15.
Listing 15. Disabling the default scriptLibraries processing
1|C:\IBM\WebSphere\AppServer80\bin>type C:\temp\BobLibraries\*.py 2| 3|C:\temp\BobLibraries\noDefaultScriptLibraries.py 4| 5| 6|import sys 7|sys.path = [ x for x in sys.path if x.find( 'scriptLibraries' ) < 0 ] 8| 9|C:\IBM\WebSphere\AppServer80\bin>wsadmin -javaoption \ 10|"-Dwsadmin.script.libraries=C:\temp\BobLibraries" | 11|WASX7209I: Connected to process "dmgr" on node ... 12|WASX7031I: For help, enter: "print Help.help()" | 13|wsadmin>dir() | 14|['AdminApp', 'AdminConfig', 'AdminControl', 'AdminTask', 'Help', 'TypedProxy', 15|'__builtin__', '__doc__', '__name__', 'bsf', 'imp', 'main', 16|'noDefaultScriptLibraries', 'sys'] | 17|wsadmin>for d in sys.path : print d 18|wsadmin> | 19|. 20|C:\IBM\WebSphere\AppServer80\optionalLibraries\jython\Lib 21|C:/temp/BobLibraries 22|wsadmin> |
Table I. Description of Listing 15
| Lines | Description and comments |
|---|---|
| 1 | Operating system command to display the contents of all *.py files in your scriptLibraries directory. |
| 3 | The name of the only *.py file found. |
| 6-7 | The contents of noDefaultScriptLibraries.py file. |
| 9-10 | wsadmin command, specifying our scriptLibraries directory. |
| 11-12 | Output generated by wsadmin showing connection to Deployment Manager, and message for interactive sessions. |
| 13 | Command prompt and statement to display current namespace contents. |
| 14-16 | Contents of current namespace. |
| 17 | Statements used to display the current values in sys.path list. |
| 19-21 | Contents of sys.path, showing that the default scriptLibraries entries are no longer present. |
Could there be problems with removing script library entries? It depends on what you call a problem. If you dynamically remove the default scriptLibraries values from sys.path in any of your scriptLibrary modules, and you have wsadmin tracing enabled (see the com.ibm.ws.scripting.traceString directive in wsadmin.properties), then the traceFile (see the com.ibm.ws.scripting.traceFile directive in wsadmin.properties) will contain an ImportError for each of the scriptLibraries modules. This might lead you to believe that wsadmin builds the list of default scriptLibary files to be processed before executing the user scriptLibary modules. And this makes sense if you think about it. The processing of the scriptLibraries directory determines which directories to add to the sys.path by traversing the directory hierarchy, and only adds entries to sys.path when a directory contains files with an extension of .py. Later, import statements for each of these modules are executed. Apparently, execution of the user specified scriptLibraries modules occurs between these two steps.
But that’s not all you need to know about the default scriptLibraries. If you plan
on creating and using your own script libraries, you need to heed this warning: A
scriptLibraries directory must exist under the WebSphere Application Server
installation directory for the -Dwsadmin.script.libraries option to function.
Take a look at the interactive session in Listing 16 to understand what this is about.
Listing 16. When scriptLibraries directory is missing...
1|C:\IBM\WebSphere\AppServer80\bin>type \temp\BobLibraries\trivialModule.py 2|print __file__, 'executed.' 3| 4|C:\IBM\WebSphere\AppServer80\bin>wsadmin -javaoption |"-Dwsadmin.script.libraries=C:\temp\BobLibraries" | 5|WASX7209I: Connected to process "dmgr" on node ... 6|C:\temp\BobLibraries\trivialModule.py executed. 7|WASX7031I: For help, enter: "print Help.help()" | 8|wsadmin>quit 9| 10|C:\IBM\WebSphere\AppServer80\bin>ren ..\scriptLibraries scriptLibraries.old 11| 12|C:\IBM\WebSphere\AppServer80\bin>wsadmin -javaoption \ |"-Dwsadmin.script.libraries=C:\temp\BobLibraries" | 13|WASX7209I: Connected to process "dmgr" on node ... 14|WASX7031I: For help, enter: "print Help.help()" | 15|wsadmin>dir() | 16|['AdminApp', 'AdminConfig', 'AdminControl', 'AdminTask', 'Help', 'TypedProxy', 17|'__builtin__', '__doc__', '__name__', 'bsf', 'imp', 'main', 'sys'] 18|wsadmin>quit |
Table J. Description of Listing 16
| Lines | Description and comments |
|---|---|
| 1 | Operating system command to display our trivial scriptLibrary module. |
| 2 | Contents of trivialModule.py. |
| 4 | wsadmin invocation, specifying our scriptLibraries directory. |
| 5 | Truncated output generated by wsadmin showing that a connection to the deployment manager exists. |
| 6 | Message generated by our trivialModule.py script showing that it executed. |
| 7 | Message generated by wsadmin for an interactive session. |
| 8 | wsadmin prompt, and command used to exit the interactive session. |
| 10 | Operating system command to rename the scriptLibraries directory. |
| 12 | wsadmin invocation, specifying the same scriptLibraries directory. |
| 13-14 | Messages generated by wsadmin, note how no message is generated by your scriptLibrary module! |
| 15 | wsadmin prompt, and command used to display the namespace contents. |
| 16-17 | Output showing the namespace contents. Note: Your scriptLibrary module is not listed. |
| 18 | wsadmin prompt, and command used to exit the interactive session. |
If you intend to use scriptLibraries, then a (possibly empty) directory of that name must exist in the <WAS_HOME> directory.
Advantages and disadvantages of scriptLibraries
In order to determine whether or not you should use scriptLibraries (either the IBM supplied ones or ones that you might want to create), you need to understand the advantages and disadvantages of this reuse technique.
Advantages
- Explicit import statements are not required; all scriptLibrary modules are automatically made available.
- Additional effort to add the scriptLibrary directories to the sys.path variable is not necessary. Once a scriptLibrary directory is identified, the wsadmin initialization or startup code automatically traverses the directory structure, adding each directory that contains files ending in .py to the sys.path variable.
- Each moduleName is automatically imported, thus providing you with the separation of code and minimizing the change of collision in the wsadmin namespace.
Disadvantages
- All modules in the scriptLibrary directory structure are automatically added to the namespace, regardless of whether or not they are actually used.
- Execution of the module files in the scriptLibrary directories requires additional processing, which slows the wsadmin initialization time.
- Adding a
–javaoption “-Dwsadmin.script.libraries=…”command line option significantly lengthens the command line, thus making it more difficult to read and understand. - Removing or renaming the scriptLibraries directory structure could complicate or introduce product update issues or challenges. (If you rename any of the scriptLibraries directories, be sure to delete all of the “*$py.class” files, or they will not be recompiled, and the value of any contained __file__ variable will be wrong.)
- To determine the location of the file from which a scriptLibrary module has been loaded, you need to display the value of its __file__ variable.
Ultimately, you must determine if wsadmin scriptLibraries are suitable for your environment.
Earlier, you saw how you could use a Jython statement to add a directory to the sys.path variable in Listing 9. Another javaoption exists that lets you to do this on the wsadmin command line. The interactive wsadmin session in Listing 17 demonstrates this.
Listing 17. -Dpython.path javaoption
1|C:\IBM\WebSphere\AppServer80\bin>wsadmin -javaoption |"-Dpython.path=C:/temp/BobLibraries;C:/temp/myModules" 2|WASX7209I: Connected to process "dmgr" on node ... 3|WASX7031I: For help, enter: "print Help.help()" | 4|wsadmin>for d in sys.path : print d 5|wsadmin> 6|. 7|C:\IBM\WebSphere\AppServer80\optionalLibraries\jython\Lib 8|C:/temp/BobLibraries 9|C:/temp/myModules 10| 11|wsadmin> |
Table K. Description of Listing 17
| Lines | Description and comments |
|---|---|
| 1 | wsadmin command invocation showing the use of –Dpython.path javaoption. |
| 2-3 | Messages generated by wsadmin for an interactive session. |
| 4-5 | Statements used to display the value of sys.path |
| 6-9 | Current value of sys.path, not the presence of the 2 directories specified by the –Dpython.path javaoption. |
New wsadmin.properties directives
One of the frustrating things about the -javaoptions for python.path and wsadmin.script.libraries is the fact that they are so very long, thus making the wsadmin command line difficult to read. If you’d like to put these directives in some kind of properties file you can try adding these directives to the appropriate wsadmin.properties file. It works! (Listing 18)
Listing 18. New directives example
1|C:\IBM\WebSphere\AppServer80\bin>type ..\profiles\Dmgr01\properties\wsadmin.properties 2|#------------------------------------------------------------------------- 3|# Properties file for scripting client 4|# Cell Manager version 5|#------------------------------------------------------------------------- 6|# 7|... 8|wsadmin.script.libraries=C:/temp/BobLibraries 9|python.path=C:/temp 10| 11|C:\IBM\WebSphere\AppServer80\bin>wsadmin | 12|WASX7209I: Connected to process "dmgr" on node ... 13| 14|c:\temp\BobLibraries\trivialModule.py executed. 15| 16|WASX7031I: For help, enter: "print Help.help()" | 17|wsadmin>for d in sys.path : print d 18|wsadmin> | 19|. 20|C:\IBM\WebSphere\AppServer80\optionalLibraries\jython\Lib 21|C:/temp 22|C:/temp/BobLibraries 23|wsadmin> |
Table L. Description of Listing 18
| Lines | Description and comments |
|---|---|
| 1 | Operating system command to display the wsadmin.properties file |
| 2-10 | Truncated output, showing the first and last few lines of wsadmin.properties. Note the new directives at the end of the file. |
| 11 | Trivial wsadmin command line. |
| 12 | Output generated by wsadmin showing that it is connected to a Deployment Manager. |
| 13-15 | Output generated by our trivial scriptLibraries module. |
| 16 | Message generated by wsadmin for an interactive session. |
| 17 | Statements used to display the contents of sys.path |
| 19-22 | Contents of sys.path. Note: For this example, the scriptLibraries directory was present, but empty. |
To make the best choice for how you should reuse your Jython code in your environment, you need to ask yourself some questions:
- How often are you going to use the objects or routines in question?
If you have some “highly specialized” code that will rarely be needed, then it might be best to place this code in a module that can be imported into your scripts as needed. The main reason for using a module instead of one of the other options is that by forcing a script writer to include one of the import variations, it is more obvious from where the code is being accessed.
- Are their times when you should simply duplicate code in your script?
Not really. The only time when it makes sense to copy and paste objects and routines to your script is when the code being used is trivial so you can demonstrate a programming technique. Otherwise, you fall into the trap of having code duplicated in multiple places that can easily get out of synch. If the code is useful and you want to reuse it, put it in a module, package, or one of the other reuse techniques mentioned here.
- When does it make sense to use a profile script file?
It is generally a bad idea to put lots of objects in a profile file, as you saw earlier, so it is unlikely that a profile script containing objects and routines will be of great benefit for your situation. However, it is quite conceivable that a profile script that customizes the wsadmin environment would be of immense value. For example, if you have some utility module that you would like to have available for all of your Jython scripts, a profile script that is referenced by the wsadmin.properties file might be exactly the right place for one of the import statement variations mentioned earlier.
- Are scriptLibraries right for your environment?
You are the best judge of this question. Do you want all of the script library modules to be automatically imported by every script that is executed? Initialization and processing time are required by every script that is executed in order to make these script library modules available. So, you have to determine if this overhead is worthwhile for your environment. If you do decide on using a scriptLibrary, then you will probably want to add a wsadmin.script.libraries directive to your wsadmin.properties file.
For many people, a combination of these techniques is appropriate. I tend to have a profile script to initialize my environment and make certain that my utility module is automatically imported. This means that the routines that I use all of the time are readily available whenever they are needed.
Using this article, you should be able to:
- Clean up and better organize your wsadmin environment.
- Minimize the wsadmin initialization time by limiting the code that needs to be processed during this time.
- Organize and improve (for example, better isolate and more fully document) the code that you write for your wsadmin scripting environment.
Hopefully you have found the information presented here useful. I also hope that you found the time required to read this to be time well spent.
-
WebSphere Application Server Administration Using Jython
-
IBM WebSphere Application Server V8.0 Network Deployment Information Center
-
IBM WebSphere Application Server V7 Network Deployment Information Center
-
Adding Jython modules to the classpath
-
Python Documentation
-
Current Jython Documentation
-
Scripting from scratch: Creating a Jython administrative script for IBM WebSphere Application Server
-
Using the full potential of Jython to build compact and maintainable wsadmin scripts
-
Using
the script library to automate the application serving environment using wsadmin scripting
-
Using the wsadmin scripting tool
-
An Introduction to Python - Section 6.4 Packages
-
IBM developerWorks
WebSphere

Bob Gibson is an Advisory Software Engineer who has over a quarter century of experience in numerous software related roles at IBM, including: Application Programmer, Architect, Developer, Instructor, Technical Support Analyst, and Tester. He is currently a team leader for the technical support group responsible for IBM WebSphere Distributed Application Server. He holds both a Bachelor of Science degree in Engineering Science and a Master of Science degree in Computer Science from the University of Virginia.




