Browse DevX
Sign up for e-mail newsletters from DevX


Use Jython to Exercise Java APIs Without Compiling : Page 2

Save development time and effort by using Jython to test code syntax prior to writing your Java classes.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Getting Down to Business
I'll start by looking at how to test the syntax of a core Java API class, java.lang.String. Jython relies upon the system classpath to know where to find and load Java class files. Therefore, to get at any of the core libraries requires a simple one-line import statement. In the code snippet below you'll see the import statement and also likely notice that to instantiate a String object in Jython doesn't require the use of the 'new' operator. I'm always in favor of less typing, however, this might trip you up initially if you're coding in Java on auto-pilot mode. Also, note that if the Jython interpreter likes what you've entered, it silently returns to the command prompt. If it doesn't like it, an error message will specify where you went wrong.

>>> from java.lang import String >>> s=String("hello world Jython") >>> from java.util import Kollections Traceback (innermost last): File "<console>", line 1, in ? ImportError: cannot import name Kollections >>> from java.util import Collections >>>

To take this a step further you need to test your new String object. The String class' substring( ) method requires the starting and ending position to break out, but are these arguments inclusive or exclusive? You can use Jython to test this out (shown in the next code snippet).

First, remind yourself of the value of the starting String object. In Jython simply typing the name of the variable pulls back its value—no need for System.out.println( ). To extract the word 'world' from the String I count the letters to the initial 'w' and then to the end of the word and use them as my arguments to the substring() method. Again, no class file or compile cycle is required—in two seconds I see my results and know that my guess—that the substring starting point was inclusive—was incorrect. I make the adjustment and confirm the proper syntax for this method.

>>> s hello world Jython >>> s.substring() Traceback (innermost last): File "<console>", line 1, in ? TypeError: substring(): expected 1-2 args; got 0 >>> s.substring(7,11) 'orld' >>> s.substring(6,11) 'world' >>>

If you've got a good memory and are very familiar with the core APIs, that probably didn't impress you very much, so now I'll move on to a more challenging third-party library. Recently, I had to do a little regular expression pattern matching and made use of the Jakarta-Oro library. For those using JDK 1.4 day-to-day, pattern matching for regular expressions is available in the core API; for those of us using older SDKs, the Jakarta-Oro library works very well. It is worth mentioning that regular expressions are part of the core Python distribution in the re module but I needed to write the code for this project in Java.

To gain access to the class files in the jakarta-oro.jar file I have to make the Jython interpreter aware of its existence. As in Java, the .jar file must be added to the classpath, however, I'll use Python syntax as a shortcut for doing this in the Jython environment. The Python sys library contains the "path" class that is used to add .jar files to the runtime environment.

>>> import sys >>> sys.path.append(r'C:\Documents and Settings\doug\javalib\jakarta-struts-1.1 \lib\jakarta-oro.jar')

Next I verify that the path is updated by querying its contents. Note that no print statement is required. Simply typing the variable returns its value.

>>> sys.path ['', 'C:\\jython-2.1b1\\.', 'C:\\jython-2.1b1\\Lib', 'c:\\jython-2.1b1\\jython-2 .1b1lib', 'C:\\jython-2.1b1', 'C:\\Documents and Settings\\doug\\javalib\\jakarta-struts -1.1\\lib\\jakarta-oro.jar']

Now that I know that my .jar file is on the path, I can access its classes just as I accessed the core library String class earlier.

>>> from org.apache.oro.text.regex import Pattern *sys-package-mgr*: processing new jar, 'C:\Documents and Settings\gidat\javalib\ jakarta-struts-1.1\lib\jakarta-oro.jar'

Note that Jython very helpfully informs me that it is opening a new .jar file to comply with my import request. I need some other imports so I'll specify those next.

>>> from org.apache.oro.text.regex import PatternCompiler >>> from org.apache.oro.text.regex import PatternMatcher >>> from org.apache.oro.text.regex import Perl5Compiler >>> from org.apache.oro.text.regex import Perl5Matcher

Now I'm ready to start instantiating my objects so I can test out my regular expressions. In the snippet below I obtain a compiler object and as you can see from the class name, it is going to be compliant with the way the Perl 5 regex engine evaluates expressions. Next, I set up the pattern that I'll use for the matching. I'm looking for an ID that is six digits. The regex shorthand for a digit is \d and I escape the backslash in the string with another backslash so it is evaluated correctly. The {6} specifies that I'm looking for exactly six digits—no more, no less. (For more information about the somewhat arcane syntax of regular expressions see Related Resources in the left column.)

>>> c=Perl5Compiler() >>> p=c.compile("\\d{6}")

What I'm looking to do is fairly simple as regular expressions go, but I want to make sure I've got it right before I start coding my class. I get a little impatient though and type:

>>> p.match("777777") Traceback (innermost last): File "<console>", line 1, in ? AttributeError: match

Not only do I have the incorrect method name but I am also attempting to use a method on the Pattern object that really exists in the Perl5Matcher class. I'll take another shot at it:

>>> s="777777" >>> m=Perl5Matcher() >>> m.match(s,p) Traceback (innermost last): File "<console>", line 1, in ? TypeError: call of non-function ('None' object)

I'm getting closer but it appears that I have the method name wrong; a quick peek at the Javadoc sets me straight and I get a successful match.

>>> m.matches(s,p) 1

Jython returns a 1 value for 'true' and 0 for 'false'. Because the regular expression pattern I compiled is for exactly six consecutive digits, the code above evaluated to a match. Compare my successful matching effort to the lines below after I reassign variable s to a non-numeric string.

>>> s="aaaaaa" >>> m.matches(s,p) 0

That's all there is to it: I can play around with my pattern matching without ever needing to compile a class or write a main( ) method. I've used this technique with disparate libraries such as Alta Vista and Lotus Notes Java APIs among others and it has saved me countless hours of work.

Despite Jython's slight lag with the C Python implementation and current JDK, it is a robust and stable language for working with Java libraries. Jython's command line interactive interpreter can save you time when figuring out or testing an unfamiliar API and the interactive interpreter provides instantaneous feedback. Other open source tools such as Groovy or the new 'Scrap Page' feature in Eclipse 3.14 offer similar capabilities and are worth investigating too, but if you're familiar with Python, Jython offers substantial other functionality that ought to put it at the top of your tools list.

Doug Tillman is a veteran Java and Python developer turned Scrum Master.
Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date