Getting started with Jython

Getting started with Jython

Submitted by Christian Crawford on Mon, 01/12/2015 - 15:54
jython logo

As you can guess from the name Jython is an amalgamation of the Python and Java programming languages. It is one of three implementations of the Python language, the other two being CPython and IronPython (.Net). Jython is one of the most mature JVM languages that is available on the Java platform. The language was created in 1997 to replace the C language with Java for performance-intensive code accessed by python programs. The language provides many benefits from both of the languages including java byte code utilization, reusability of java classes and interfaces, Python’s simplified syntax, and many more. Since it is a JVM language it can maintain Java’s “Compile once, run anywhere” slogan and also has access to thousands of Java’s API libraries. The language can be written as standalone python files or they can be integrated into java classes themselves, with a bit of work. Knowledge of the Python language is not necessary to understand this article, as long as you are familiar with some programming language since the basic concept are pretty universal.

In order to use the language you need to go download Jython. You can download the latest release from jython.org. Once you’ve downloaded the jar you can navigate to where you downloaded it and double-click it. An installation wizard will then guide you through the process. After you have finished installing you should add the jython.sh to your PATH variable.

Now we can begin writing our code. We’ll begin our introduction with the most basic of all programs, a Hello World. You can create a file called hello.py and add the following line to the program

print “Hello World!”

Save the file and open your terminal shell. Navigate to where you’ve saved the file and run jython hello.py

If you’ve done everything right so far you should see “Hello World!” on the screen.

Next we will show a simple bill calculator example which uses variables, functions, and formatted strings:

def calc_bill(amount): 
  tax = amount * 0.07
  tip = (tax + amount) * 0.15
  total = amount + tax + tip 
  print “Tax: %f Tip: %f” % (tax, tip) 
  print “Total after tax and tip %f” % total

calc_bill(24.83)

All functions in python (and therefore Jython) begin with “def” followed by name, the parameters, and a colon. Variables in Python are typeless so you don’t need to provide one. Formatted strings look similar to they do any many other languages (d for integer, f for float, s for string, etc).  Whitespace is extremely important in the language. While there is no standard number of spaces, you must maintain the same spacing conventions for the entire block otherwise the interpreter will throw errors.

One important data structure in Jython is the list. Lists are just like arrays in any language. They are index addressed and can be appended to or sliced apart. The following code shows a method that takes in some number and returns the squared values

num_list = [2,3,4,5,6,7,8,9]

def squareNum(num_list):
  squares = []
  for num in num_list:
    squares.append(num ** 2)
  return squares

print squareNum(num_list)

As you can see the list is created with some values and then later on the square function is called with the list as the parameter. To add an item to a list you use the append method. Raising a number to a given power is denoted by double asterisk (number ** exponent). Along with lists there are structures called dictionaries in Python. These are addressed with key, value pairs as opposed to number indexes and are denoted with curly brackets.

Now that we’ve got a basic foundation in the language we can move onto a more real world example, connecting to a database and accessing the records. When it comes to connecting to your database there are several options available, two of which will be covered today. The first is Jython’s DBI implementation zxJDBC, which is good for simple one-off scripts where portability is not a huge concern. The other option covered is using Java’s JDBC. As you will see there is a considerably less code needed to perform the same operations between the pure java implementations and the Jython versions:

Java:

import java.sql.*;
import java.util.*;

public class JDBCExample {
 public static void main(String[] args) throws Exception {
   Class.forName("com.mysql.jdbc.Driver");
   Connection db = DriverManager.getConnection("jdbc:mysql://localhost/(dbName)/", "dbUserName", "dbPassword");
   Statement c = db.createStatement();
   ResultSet rs = c.executeQuery("select * from events");
   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 {
         row.add(rs.getString(col));
       }
     }
     System.out.println(row);
   }
   rs.close();
   c.close();
   db.close();
 }

If you are familiar with Java this code should look quite familiar. The code connects to the database, makes a select query, and prints out the data


Jython (JDBC):

from java.lang import Class
from java.sql import DriverManager, SQLException

 DriverManager.registerDriver(Class.forName(com.mysql.jdbc.Driver).newInstance())
 conn=DriverManager.getConnection(“jdbc:mysql://localhost/dbName”, “username”, “password”)
 stmt=conn.createStatement()
 sql="select title from tix_section"
 results=stmt.executeQuery(sql)
 _types = {Types.INTEGER:rs:getInt, Types.FLOAT:rs.getFloat}

 while results.next():
   row = []
   meta = results.getMetaData()
   for i in range(meta.getColumnCount()):
     col += 1
     datatype = meta.getColumnType(col)
     value = _types(datatype, results.getString)(col)
     row.append.value
     print tuple(row)

 statement.close()
 conn.close()

The code looks fairly similar to the plain Java. In Jython the keyword "range" provides a way to iterate the loops until it reaches the range.


Jython (zxJDBC):

from com.ziclix.python.sql import zxJDBC

db = zxJDBC.connect("jdbc:mysql://localhost/dbName/", "userName", “passowrd”, "com.mysql.jdbc.Driver")
c = db.cursor()
c.execute("select * from events")
for row in c:
 print row
c.close()
db.close()


The first line connects to the database with the given parameters.

The next line creates a cursor. Cursors wrap JDBC statements and resultsSet objects and make it easy for store and manipulate the resulting data in the pythonic way. There are two kinds of cursors, static and dynamic. Static cursors, the default, perform an iteration over the entire resultSet, whereas dynamic cursors iterate through on an as-needed basis.

We will conclude by showing how to use your java code in your Jython program and vise versa.

Beach.java

public class Beach {

    private String name;
    private String city;


    public Beach(String name, String city){
        this.name = name;
        this.city = city;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }
}


pythBeach.py

import Beach
beach = Beach("South Beach", "Miami")
print beach.getName() +", " + beach.getCity()

When you launch the program ("jython beach.py") you should see the values that you assigned to the name and city.


Using Jython modules (classes) in you Java programs involves a bit more work since the Python object must be coerced into a Java object. The most common way to doing this is to create object factories which convert them into something that Java can easily use. There are two main ways of going about the factory process, one involves making a factory for each object, and other other involves a more loosely coupled factory that can generically handle all of the objects.

Creating a factory for each object has the advantage of being able to maintain complete awareness of the Jython object, meaning that you can pass in arguments directly into the constructor method and makes it very clear what is going on in the program for anyone to see. A disadvantage of this method is that it creates a lot of boilerplate code and this can become an issue if you start to have large numbers of Jython objects that need to be converted. The steps involved include creating the Jython object file with just some getter methods, a java interface to implement those getters, the java factory, which passes the Python object through the interpreter and converts it into a java object

The loosely coupled factory can be generalized enough that it can be used with any Jython object, thus eliminating the large boilerplate coding portions from the one-to-one factory and also allows you to separate out the factory logic to do with it as you please. The coding process is similar to how it was for the previous implementation except for a few changes. In the python file you now need to add setters as well as getters, the interface file is still the same, and the factory once again passes the Jython object to the interpreter for coercion. Examples of these can be found here.

If you would like to see more about J/Python basics or see more examples you can read through the free "Definitive Guide to Jython" found here. The books covers everything from the basics of the language to creating Swing UI driven application to web applications using servlets like Tomcat and Glassfish.

Christian Crawford

Profile picture for user Christian Crawford
Senior Engineering Manager & Lead Software Developer
  • Drupal site building, module development, theming (since Drupal 7)
  • Cloud Infrastructure (AWS, Azure, Google)
  • Docker & Kubernetes
  • SQL (MySQL and Oracle), NoSQL (MongoDB)
  • ReactJS, Svelte, jQuery, NodeJS
  • HTML, CSS, SASS/LESS
  • Nginx and Apache Stacks