JPython: The Felicitous Union of Python and Java
Java has been misrepresented. Overoptimistically, Sun's marketing department presents Java as revolutionary, because a person can write code on one operating system and have it run on many others. Performance fanatics ridicule Java, because no Java program can match the speed of optimized C code. Both of those points of view are flawed—the marketers are wrong to claim that a revolutionary level of “write once, run anywhere” has been achieved, and the speed freaks ignore the fact that Java's performance is “good enough” for many tasks. In my view, Java is a well-designed, modern systems programming language which did not try to integrate well with others or be a performance leader. It's a fine language for writing medium to large, fairly static systems, especially if interoperability with Java libraries is desired and interoperability with non-Java “legacy” code is not needed. Under those conditions, all that's missing is a good scripting solution which allows the users to control the applications. And that's just what Jim Hugunin did when he rewrote the Python interpreter in Java and called it JPython.
That's right: JPython is a completely new implementation in Java of what Guido van Rossum did in C—7 years later and using a very different language. It's the same thing, and yet altogether different. I will describe what JPython is, how it works, and what it will let you do which “the original Python” can't. If you have any need for a scripting language which can interact with Java libraries such as the Swing GUI toolkit, you may find that JPython fills a significant gap. But first, a little history.
In 1990, Guido van Rossum chose a portable, well-established language to write his first version of Python. That language was C. Guido cares deeply about portability, and as a result, Python runs on just about anything with a C compiler. (I should know—I claim to be the first person to have run Python on both a Windows CE handheld and a Cray supercomputer.) History validated this choice; while C++ was available at the time, it was still immature. By 1997, Python had achieved all the portability Guido thought was reasonable—and then Java came along and upset everything. For a variety of reasons, the Java platform was designed to operate in a language vacuum—as a result, the interfaces between Java and other languages such as C and C++ are cumbersome. Furthermore, any Java system made to talk to “native” code using the Java Native Interface (JNI) loses several important features of a pure Java program, such as portability and security guarantees. Thus, Python couldn't, as written, run on the “Java Platform”.
There were three possible ways of solving that problem. The first, to have Python talk to Java via the JNI, was attempted by a few teams, but didn't provide a complete solution and did not allow the development of a 100% Java solution. A second alternative considered was to convert Python virtual machine bytecodes to Java virtual machine bytecodes. While this sounds simple in theory, it wasn't practical. Python's bytecodes are very high level and manipulate complex objects, while Java's bytecodes are more akin to assembly language. The third approach was the “right” one, but it was also the most ambitious: to convert Python source files directly to Java bytecodes. Because of Python's dynamic nature, this meant re-implementing the Python parser and interpreter in Java. Luckily for us, Jim Hugunin, a longtime fan of Python and the main author of the Numeric Python extensions, undertook that project.
Soon, Jim Hugunin was so engrossed with JPython that he quit his Ph.D. work at MIT and went to work full-time for the Corporation for National Research Initiatives. There he joined Guido and other Python hackers to finish JPython. Jim released JPython 1.0 in July 1998 and started work on JPython 1.1, a major revision. Jim's success with JPython led to an offer he couldn't resist from Xerox PARC (the folks who invented the laser printer, the mouse, the desktop metaphor, Ethernet, etc.), and in mid-1999, Jim was off to Palo Alto to work on other Java-related projects. Luckily for the rest of us, Barry Warsaw, another of Guido's esteemed colleagues, took over the maintenance and development of JPython. As of this writing, Barry remains the current “flag-bearer” for JPython. If you're itching to install JPython at this point, see the “Installation Issues” sidebar.
JPython is a Python interpreter and compiler written in and for Java. The fact that JPython is an interpreter means you can type jpython at a command-line shell and get the familiar >>> prompt. As we will see, most Python code written for CPython (what the original Python implementation is called when contrasted with JPython) runs fine in JPython. The fact that JPython is a Python compiler for Java means you can take a Python program and compile it to Java .class files, which in turn can be used by other Java programs in myriad ways. Finally, the fact that it is written in and for Java means JPython allows the Python programmer absolutely seamless access to any and all Java libraries, and that is, as we'll see, its “killer feature”.
As a teaser, consider the program calc.py, shown in Listing 1.
A few things are worth noting about this program, which I adapted from one written by Guido van Rossum. If you're a Java programmer, you may notice that calc.py is a useful program which doesn't define a single class. This is one of the ways in which Python (here JPython) provides a simple scripting solution, whereas Java requires the programmer to know about classes, inheritance, public vs. private members, etc. The second aspect of calc.py, which Java programmers might notice, is that the code is more compact than the equivalent Java code, and yet its purpose remains clear. This is one of Python's most valued strengths, and JPython builds on it in several ways. Python programmers will probably first notice they can read the code and it “feels” like good old Python; and second, the parts of the code they don't immediately understand refer to objects like JPanel, BorderLayout, JTextField, etc. These are defined in Java's Swing GUI. We won't describe Swing in detail here, but see the Swing sidebar for some discussion on what Python programmers should know about Swing.
- Bruce Nikkel's Practical Forensic Imaging (No Starch Press)
- Transitioning to Python 3
- Progress on Privacy
- Stepping into Science
- Linux Journal December 2016
- Radio Free Linux
- The Tiny Internet Project, Part II
- CORSAIR's Carbide Air 740
- FutureVault Inc.'s FutureVault
- A Better Raspberry Pi Streaming Solution