Archive for August, 2008

Ant Jython Tasks (PAnt Tasks)

Posted on 08/20/2008 , Alexander Ananiev, 11 Comments ( Add )

PAnt build tool comes with several Ant tasks to facilitate the use of Jython/Python from Ant.

PAnt tasks have a number of advantages over built-in <script language="jython"> way of invoking Jython from Ant:

  • More graceful exception handling. Jython code invoked using "script" generates long error stack that contains full stack trace of the "script" task itself. Sifting through the traces and trying to distinguish Java trace from Python trace is quite painful. PAnt "jython" task produces brief readable python-only error stack.
  • You can use Ant properties as parameters ("jython" task makes them available in the local namespace of the calling script).
  • Convenience "import" attribute.
  • "jythonInit" task allows for setting python.path using Ant path structure.
  • Jython interpreter is initialized once per Ant project. All scripts invoked from the same Ant project reuse the same built-in namespace. So you can define variables and imports in one call and use them in a subsequent call.
  • Task name ( the name that prefixes all console output from Ant for a given task) is generated automatically based on the supplied Python code.
  • "verbose.jython" property triggers verbose output for jython-related tasks only. This is much easier than trying to scan through hundreds of lines of general "ant -v" verbose log.

Example:

Ant code:


<jythonInit pythonPathRef="python.path" />
<property name="testProp" value="testVal" />

<jython>
print "Property from ant:", testProp
# define a var that we can use in other scripts
s="test"
</jython>

<jython>
print "Var created earlier: ",s
</jython>

<jython  import="from testmodule import *" exec="test(testProp)"  />

"testmodule" python code:


from pant.pant import project 
def test (prop):
    print "Passed parameter: ",prop
    print "Test property: ", project.properties["testProp"]

Please refer to this build.xml file for more examples.

The tasks can be used independently of PAnt python code.

PAnt Ant Tasks Reference

Getting Started

Download PAnt, extract pant.jar and create "taskdef" as described here

"jythonInit" Task

The tasks initializes jython interpreter. Because of the overhead, the interpreter is initialized only once even if jythonInit is invoked multiple times. The repeating calls are simply ignored.
jythonInit automatically adds pant.pant module to PYTHONPATH.

Attributes:

  • pythonPathRef - PYTHONPATH (python.path) to use, given as reference to a PATH defined elsewhere. Required if "pythonPath" nested element was not provided.
  • pythonHome - location of python distribution (optional). If provided,jythonInit will set python.home system property and will automatically add ${python.home}/Lib to the python path if ${python.home}/Lib exists.
  • cacheDir - location of jython cachedir used for caching packages (optional). Defaults to ${java.io.tmpdir}/jython_cache (note-- this is different from default jython behavior).

Nested elements:

pythonPath - python.path to use defined using Ant path-like structure. Required if "pythonPathRef" attribute was not provided.

Special properties:

log.python.path - if set to "true", jythonInit will print python path to Ant log. Default: false.

"jython" Task

Invokes python code.
Note: by default, jython does not print python stack trace in case of an exception. To see the trace, run Ant in verbose mode using "-v" or use "-Dverbose.jython=true" property.

Attributes:

  • exec - Python code snippet to execute. Typically, this is a function from a module available from python.path. This has to be a single line, e.g., mod.fun() although you could combine multiple statements separated by ";". Required if "execfile" was not provided.
  • import - a convenience attribute for providing "import" statement. Its only purpose is to make the task invocation more readable. Alternatively, you can have "import" as part of the"exec",e.g., exec="import mod;mod.fun()". Optional.
  • execfile - path to a python script file. Required if "exec" was not provided.

Nested elements:

Inline text with python code.

Special properties:

verbose.jython - if set to "true", jython will print additional information about executing python code to Ant log. Default: false.

pimport Task

Creates Ant targets from a python module. Functions that will be used as targets have to be marked using "@target" decorator as described here.
Python module name is used as Ant project name. Target overriding works the same way with Ant import task. In other words, targets defined using pimport will override targets previously defined using "import" or "pimport" tasks.

Attributes:
module - python module to create targets from. The module has to be available from python.path specified using jythonInit.

WebSphere 7 Supports Properties-Based Configuration

Posted on 08/20/2008 , Alexander Ananiev, 1 Comment ( Add )

IBM WebSphere 7 (currently in beta) comes a property-file based configuration tool that provides a "human-consumable" interface to the currently XML-based configuration repository of the application server. This is another proof that XML is simply not the right mechanism for managing configuration of complex software products.

From the release notes:


Properties (name/value pairs) files are more consumable for human administrators than a mix of XML and other formats spread across multiple configuration directories.

Kudos to IBM for recognizing that.

It is still not clear though how hierarchical relationships between configuration objects will be supported.

Back in WAS 6 world, I've been using a simple jython script that converts python named parameters into wsadmin format. This is an example of a resource described in this format:


 WASConfig.DataSource(parent="testJDBCProvider", name="testDS", jndiName="jdbc/testDS",
                              description="Test DataSource", propertySet=dict(
                              resourceProperties=[
                                  dict(name="dbName", value="testDB", type="java.lang.String" ),
                                  dict(name="connectionAttribute",value="", type="java.lang.String")
                               ]))


I think that a slightly more streamlined python-based format will be superior to properties.

Jython in WebSphere Portal

Posted on 08/10/2008 , Alexander Ananiev, No Comments ( Add )

Most developers and administrators working with WebSphere Application Server (WAS) know that both JACL and Jython languages can be used for various WAS administration and configuration tasks. However, JACL has always been a preferred choice, simply because this is the default language used by the product's admin tool (wsadmin) and also because JACL examples and documentation are more complete.

Using JACL might have been a valid option just a few years back (when WAS just came out) given the uncertainty surrounding the Jython project. Today, however, jython is clearly alive and well; alpha version supporting Python 2.5 was announced recently. Therefore there is really no point in using JACL any longer, except may be for shops with a large collection of existing JACL scripts. JACL syntax is quite arcane compared with Python and the language is clearly not as widely used.

IBM confirmed this view by releasing JACL to Jython converter a couple years back.

Unfortunately, up until recently, jython was not officially supported in another IBM product, WebSphere Portal, which comes with wpsript tool for managing pages, deployable modules and other portal artifacts.

But since portal scripting relies on wsadmin's shell, jython is in fact fully supported by the product, it's just not documented.
All that you need to do to switch to jython is to invoke wsadmin with "-lang jython" and "-wsadmin_classpath " followed by the list of portal jars (you can copy the classpath from SCRPATH variable definition in wpscript.sh).

As an example, I put together a simple Jython script for cleaning up a portal page hierarchy. Removing pages before applying an XMLAccess script with page definitions allows to start portal configuration from a clean "known" state. Very often, especially in a development environment, an application's page hierarchy gets polluted with various "test" pages created by developers. The script gets rid of them.

In WebSphere Portal 6.1 Jython is finally made a first-class citizen. The product's documentation proclaims that JACL support will be phased out and that jython is the way to go. Surprisingly, though, all examples still use good old JACL. I assume it's just a matter of time before they are converted.