Introduction to Jython
January 9th, 2006
- Ian Maurer: http://www.itmaurer.com/
- Xteric Technology Group: http://www.xteric.com/
- Cleveland Area Python Interest Group: http://www.clepy.org/
What is Jython?
Jython is an implementation of the high-level, dynamic, object-oriented language Python written
in 100% Pure Java, and seamlessly integrated with the Java platform. It thus allows you to run
Python on any Java platform.
Jython is an excellent dynamic counterpart to Java's static language. Jython provides a
developer a very high level method for prototyping, scripting, and testing Java components.
- Jython: http://www.jython.org
Why Jython?
While there are numerous language implementations on the JVM, the following separate Jython from the rest:
- Dynamic compilation to Java bytecodes - highest possible performance without sacrificing interactivity.
- Ability to extend existing Java classes in Jython
- Optional static compilation - for creation of applets, servlets, etc.
- Bean Properties - make use of Java packages much easier.
- Python Language - combines remarkable power with very clear syntax. It also supports a full
object-oriented programming model which makes it a natural fit for Java's OO design.
- Original Wiki Document: http://wiki.python.org/jython/WhyJython
What does Jython do Well?
- Java Library Investigation with the Jython Interpreter
- Protyping Java Components and Libraries
- Glue together libraries already written in Java
- Embedded scripting language
- Original Wiki Document: http://wiki.python.org/jython/WhyJython
Beginning of Jython
Jim Hugunin
began Jython during a one-week experiment back in 1997
after discovering:
- That the static Java and dynamic Python languages complemented each other well, while still being
similar enough to work together.
- Python programs could be translated into Java bytecode without significant performance loss.
- The java.reflect package made it possible to load and use arbitrary Java libraries from Python
without having to write any glue code
Jim handed off the project in 1999 and is now working for Microsoft on a version of Python for the .NET and
Mono platforms called
IronPython.
- Story of Python: http://hugunin.net/story_of_jython.html
- IronPython: http://www.ironpython.com/
CPython
In the strict sense, "Python" is just a programming language. A set of keywords and syntax rules that
is defined by the
Python Reference Manual. A programming
language that has gone through
several revisions
over the years.
Most people, most of the time, also refer to the implementation of the Python interpreter written in
the C language as "Python". Its also the name of the program that runs the C interpreter.
However, when people speak about the "Jython" interpreter, then they usually use the name "CPython"
to refer back to the original C implementation.
- Python Reference: http://www.python.org/doc/versions.html
- Python Documentation by Version: http://www.python.org/doc/versions.html
Differences between CPython and Jython
- Differences between CPython and Jython: http://www.jython.org/docs/differences.html
- Differences (Brian Zimmer's Presentation): http://www.ziclix.com/jython/chipy20050113/slide-05.html
Peformance Differences
The
startup time of the JVM makes
Jython's startup time 10-20x slower than CPython's startup time. This makes Jython a very poor choice for
any situation where numerous processes need to be started and finished quickly, such as straight CGI programming.
Jython does benefit from the advantages that Java itself has over CPython. For instance, Java supports multiple
threads while CPython does not, due to the
Global Interpreter Lock.
- Startup Time: http://www.ziclix.com/jython/chipy20050113/slide-27.html
- Global Interpreter Lock: http://docs.python.org/api/threads.html
Current Status (January 9th, 2006)
Development of Jython has always lagged the CPython version with regards to new functionality and changes
to the language. But, while it lags in features to it's C counterpart, it still is a very reliable and
stable programming environment.
The current stable and recommended version of Jython is 2.1. There is also an alpha release of Jython 2.2.
The latest builds can always be found here:
- SourceForge Jython Download: http://sourceforge.net/project/showfiles.php?group_id=12867&release_id=342904
Installing Jython
Jython is distributed in a self-extracting .class file. To install it, simply run it in the java
interpreter from the command line:
java jython-21
Notice that you do not include the .class extension. If you run into problems check the
following links:
- Jython.org Installation Guide: http://www.jython.org/install.html
- Jython FAQ: Installation and Setup: http://wiki.python.org/jython/JythonFaq/InstallingJython
Jython Registry
Jython aquires it's namespace for variables (such as python.path and python.security.respectJavaAccessibility)
from the following sources (in ascending priority):
- Java system (JVM) properties
- System-wide jython "registry" file
- User-specific jython "registry" file
- Jython command line options
For more information see this link:
- Jython.org: The Jython Registry: http://www.jython.org/docs/registry.html
Jython Interpreter
The Jython Interpreter is very useful for testing out Java APIs.
C:\> jython
Jython 2.1 on java1.5.0_04 (JIT: null)
Type "copyright", "credits" or "license" for more information.
>>> import java
>>> m = java.util.HashMap()
>>> m.put("hello", "world")
>>> m.get("hello")
world
Jylluminate Module
The
Jylluminate module
makes interrogating Java objects from Jython easier.
>>> import java, jylluminate
>>> v = java.util.Vector()
>>> print jylluminate.methods(v)
methods implemented by the java.util.Vector class
addElement
capacity
copyInto
elementAt
elements
ensureCapacity
firstElement
insertElementAt
lastElement
removeAllElements
removeElement
removeElementAt
setElementAt
setSize
trimToSize
- Jylluminate module: http://home.earthlink.net/~kip.lehman/jython/jylluminate.py
Jylluminate Module (Continued)
>>> print jylluminate.lineage(java.util.Vector())
class: java.util.Vector
superclass hierarchy (excluding Object):
java.util.AbstractList
java.util.List (interface)
java.util.RandomAccess (interface)
java.lang.Cloneable (interface)
java.io.Serializable (interface)
java.util.Vector
methods defined in interfaces/implemented in superclasses (minus Object):
java.util.AbstractList
iterator
listIterator
listIterator
- Jylluminate module: http://home.earthlink.net/~kip.lehman/jython/jylluminate.py
Jylluminate Module (Continued)
java.util.List (interface)
add
addAll
get
indexOf
lastIndexOf
listIterator
remove
set
subList
toArray
- Jylluminate module: http://home.earthlink.net/~kip.lehman/jython/jylluminate.py
JavaBean Properties
Setting a property using a Java-style method call:
b = awt.Button()
b.setEnabled(0)
Using a property as an attribute:
b = awt.Button()
b.enabled = 0
Setting a property using keyword argument at instantiation:
b = awt.Button(enabled=0)
- Jyton.org Properties Page: http://www.jython.org/docs/properties.html
Event Listener
Java-style (Class-based) Event Listener:
class action(awt.event.ActionListener):
def actionPerformed(self,event):
java.lang.System.exit(0)
button = awt.Button("Close Me!")
button.addActionListener(action())
Python-style (Function-based) Event Listener:
def exit(event):
java.lang.System.exit(0)
button = awt.Button("Close Me!", actionPerformed=exit)
- Jyton.org Properties Page: http://www.jython.org/docs/properties.html
Java Arrays in Jython
The "jarray" module provides 2 methods for creating Java arrays:
array(sequence, type)
zeros(length, type)
The type argument is either a java class or a 1 letter code for a java
primitive type:
z: boolean c: char
b: byte h: short
i: int l: long
f: float d: double
Java Arrays in Jython (Examples)
The below example shows how to create an empty byte array
for use with a InputStream read:
buffer = jarray.zeros(bufferSize, "b")
readsize = stream.read(buf)
The 2nd example shows to make an array of Integers from
0 to 4 and an array of Doubles from 0.0 to 4.0:
# array([0, 1, 2, 3, 4], java.lang.Integer)
jarray.array(range(5), java.lang.Integer)
# array([0.0, 1.0, 2.0, 3.0, 4.0], java.lang.Double)
jarray.array(range(5), java.lang.Double)
Database Connectivity (JDBC)
When connecting to a JDBC datasource, you can use the Java classes directly. However, for those
wishing to use a Python DB API, then you can use the zxJDBC library that comes with Jython.
The following pages show how to print out a row of data in Java, Jython using the Java APIs,
and Jython using the zxJDBC library. For more information about JDBC, please check these
links:
- Database Connectivity in Jython: http://www.jython.org/docs/zxjdbc.html
- Brian Zimmer's JDBC Examples: http://www.ziclix.com/jython/chipy20050113/slide-19.html
JDBC (Java Example)
import java.sql.*;
import java.util.*;
public class JDBCExample {
public static void main(String[] args) throws Exception {
Class.forName("org.postgresql.Driver");
Connection db = DriverManager.getConnection("jdbc:postgresql://localhost/racing/", "bzimmer", null);
Statement c = db.createStatement();
ResultSet rs = c.executeQuery("select * from bz");
while (rs.next()) {
List row = new ArrayList();
ResultSetMetaData meta = rs.getMetaData();
for(int i=0;i<meta.getColumnCount();i++) {
int col = i+1;
int datatype = meta.getColumnType(col);
if (datatype == Types.INTEGER) {
row.add(new Integer(rs.getInt(col)));
} else if (datatype == Types.FLOAT) {
row.add(new Float(rs.getFloat(col)));
} else {
row.add(rs.getString(col));
}
}
System.out.println(row);
}
rs.close();
c.close();
db.close();
}
}
JDBC (Jython Example)
from java.sql import *
from java.lang import *
Class.forName("org.postgresql.Driver")
db = DriverManager.getConnection("jdbc:postgresql://localhost/racing/", "bzimmer", None)
c = db.createStatement()
rs = c.executeQuery("select * from bz")
_types = {Types.INTEGER:rs.getInt, Types.FLOAT:rs.getFloat}
while rs.next():
row = []
meta = rs.getMetaData()
for i in range(meta.getColumnCount()):
col = i + 1
datatype = meta.getColumnType(col)
v = _types.get(datatype, rs.getString)(col)
row.append(v)
print tuple(row)
rs.close()
c.close()
db.close()
JDBC (zxJDBC Example)
from com.ziclix.python.sql import zxJDBC
db = zxJDBC.connect("jdbc:postgresql://localhost/racing/", "bzimmer", None, "org.postgresql.Driver")
c = db.cursor()
c.execute("select * from bz")
for row in c:
print row
c.close()
db.close()
Jython Compiler
In order to build a real Java class from a Python class, you can use the "jythonc" script. Some tips:
For more information about the jythonc options:
- Compiling Python Source to Real Java Classes: http://www.jython.org/docs/jythonc.html
Compiling Jython Example
Foo.py
import java
class Foo(java.util.Date):
def __init__(self):
self.count = 0
def bar(self, incr=1):
"""@sig void bar(int incr)"""
self.count += incr
return self.count
def toString(self):
cnt = self.bar()
return "Foo[" + java.util.Date.toString(self) + " " + `cnt` + "]"
Compiling Jython Example (Continued)
Compiling Jython Class
C:\foo>jythonc Foo.py
processing Foo
Required packages:
java.util
Creating adapters:
Creating .java files:
Foo module
Foo extends java.util.Date
Compiling .java to .class...
Compiling with args: ['javac', '-classpath', 'C:\\Jython21\\jython.jar;...',
'.\\jpywork\\Foo.java']
Compiling Jython Example (Continued)
FooTest.java
import Foo;
public class FooTest {
public static void main(String[] args) {
Foo foo = new Foo();
System.out.println(foo);
foo.bar();
foo.bar(43);
System.out.println(foo);
}
}
Compiling Jython Example (Continued)
Running FooTest
C:\foo>java -cp ".;jpywork;C:\Jython21\jython.jar" FooTest
Foo[Mon Jan 09 19:00:00 EST 2006 1]
Foo[Mon Jan 09 19:00:00 EST 2006 46]
Creating a JAR
The 'jythonc' script can be used to create Java Archive files (JARs) through it's options. Below is
an example for creating the Applet demos on the Jython.org website:
jythonc --core --deep --jar appletdemo.jar *.py
Applet Demo
from java import awt, applet
class ButtonDemo(applet.Applet):
def init(self):
self.b1 = awt.Button('Disable middle button', actionPerformed=self.disable)
self.b2 = awt.Button('Middle button')
self.b3 = awt.Button('Enable middle button', enabled=0, actionPerformed=self.enable)
self.add(self.b1)
self.add(self.b2)
self.add(self.b3)
def enable(self, event):
self.b1.enabled = self.b2.enabled = 1
self.b3.enabled = 0
def disable(self, event):
self.b1.enabled = self.b2.enabled = 0
self.b3.enabled = 1
See Demo
IDE Support
To go along with the Python specific editors and IDEs, there are 3 main projects that
focus on Jython and (in the case of Coyote) other JVM scripting languages:
- NetBeans IDE Coyote Project: https://coyote.dev.java.net/
More Information
For more information, check out these links: