Introduction
- Brian Zimmer (bzimmer@ziclix.com)
- ChiPy 2004-01-23
Jython, lest you do not know of it, is the most compelling weapon the Java platform has for its survival into the 21st century.
-Sean McGrath, CTO, Propylon
Topics
- What is Python or Jython?
- Some examples showing Python source and Java source.
- Discuss alternatives to Java & Python integration
- Walk through a simple runtime example
What Is Python?
- An interpreted, interactive, object-oriented programming language
- Dynamic typing & high level data structures
- Higher productivity and easier maintenance
- Fewer lines of code than comparable Java program
What Is Jython?
- The Java implementation of the Python programming language
- Dynamic compilation to JVM byte codes
- Seamless integration with Java libraries
- Interactive exploration and prototyping of all Java libraries
- History
- Original implementation by Jim Hugunin in 1997
- Handed off to many primary maintainers
Differences - Python & Jython
Python
- C
- Multi-platform
- Compiles to .pyc
- Extend with C
- GIL
- Python Garbage Collection
Jython
- 100% Java
- Any JVM (currently 1.1+)
- Compiles to .class
- Extend with Java
- Truly multi-threaded
- Java garbage collection
General Bits
-
del is not reliable because the Java garbage collector is used
-
Java only has Unicode strings
-
Cannot mix Python and Java classes in multiple inheritance
-
Java instances cannot have dynamic attributes
-
Boolean type difficult to address
public void do(int i); public void do(boolean b);
-
Jython changes with two fronts
- Keeping up with CPython language changes
- new-style classes
- list comprehensions
- generators
- Keeping up with Java language changes
- enum
- auto-boxing
- vargs
- generics (not necessary in Python)
- annotations
- StackTraceElement
- Keeping up with CPython language changes
Differences - Python & Java
- Python is dynamically typed; Java is statically typed
- Python has only unchecked exceptions; Java has both checked and unchecked
- Python uses whitespace for scoping
- In my experience, almost every Java program (not machine generated) does
- Python has no seperate compilation step
- Python has multiple, functional inheritance; Java has multiple hierarchical inheritance but singular functional inheritance
- Python has richer built-in data structures (lists, dicts, tuples, everything is an object)
- No operator overloading in Java (personal annoyance)
What Does Jython Do Well?
- Protyping
- Java investigation
>>> from java.util import Date >>> d = Date() >>> print d Sat Jan 08 16:26:16 CST 2005 >>> from java.util import Random >>> print dir(Random) ['__init__', 'nextBoolean', 'nextBytes', 'nextDouble', 'nextFloat', 'nextGaussian', 'nextInt', 'nextLong', 'seed', 'setSeed'] >>>
- Bean properties accesible
>>> print Date().time 1105500911121
- Glue together libraries already written in Java
- Excellent embedded scripting language
- Object Domain UML Tool
- PushToTest
- Drools
What Does Jython Not Do Well?
- Anything Java can’t do
- Access Python modules written in C
- C libraries without JNI
- COM libraries without JNI
- missing Unix-ish functionality without JNI
- os filesystem methods
- signals
What Java Libraries Are Superior To Python?
- Servlets
- JMS
- J2EE
- Javadoc
- Swing is often considered superior to other GUI toolkits - I have little experience
Jython’s Production Viability
- Used by BEA for managing Weblogic
- WebLogic Server Scripting Tool
- Propylon
- Numerous internal systems
- Financial services
- App support & operations
- Sun hosted a dynamic languages summit for languages targeting the JVM
Examples
- Differences in syntax and language features between Java and Python
Examples - Lists
-
Java
import java.util.List; import java.util.Iterator; import java.util.ArrayList; public class ExLists { public static void f(Object o) { System.out.println(o); } public static void main(String[] args) { List t = new ArrayList(); t.add(new Integer(1)); t.add(new Integer(2)); t.add(new Integer(3)); // loop the list for(Iterator i=t.iterator();i.hasNext();) { Object o = i.next(); ExLists.f(o); } } }
-
Jython
def f(x): print x [f(x) for x in T]
Examples - Dicts
-
Java
import java.util.Map; import java.util.HashMap; public class ExDicts { public static void main(String[] args) { Map m = new HashMap(); m.put("a", new Integer(1)); m.put("b", new Integer(2)); m.put("c", new Integer(3)); } }
-
Jython
d = {"a":1, "b":2, "c":3}
Examples - Reading files line by line
This one is not fair ;)
-
Java
import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.LineNumberReader; import java.io.FileNotFoundException; public class ExReadFile { public static void main(String[] args) { FileReader r = null; File f = new File("jython-presentation.py"); try { r = new FileReader(f); } catch (FileNotFoundException e) { return; } LineNumberReader lnr = new LineNumberReader(r); String line = null; do { try { line = lnr.readLine(); } catch (IOException e) { line = null; } if (line != null) { System.out.println(line); } } while(line != null); try { r.close(); } catch (IOException e) {} } }
-
Jython
fp = open("jython-presentation.py") try: for line in fp: print line, finally: fp.close()
Examples - Exception Handling
- Java
public class ExException { public static void main(String[] args) { try { int a = 1; int b = a/0; } catch (ArithmeticException e) { e.printStackTrace(); } catch (NullPointerException e) { e.printStackTrace(); } } }
- Jython
try: a = 1 b = a/0 except (ZeroDivisionError, ValueError, NameError), e: print e
Examples - Reflection
- Java
import java.util.ArrayList; import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; public class ExReflection { public static void main(String[] args) { List a = new ArrayList(); a.add(new Integer(1)); Method g = null; try { g = a.getClass().getMethod("get", new Class[] {Integer.TYPE}); } catch (NoSuchMethodException e) { e.printStackTrace(); } System.out.println(g); try { System.out.println(g.invoke(a, new Object[] {new Integer(0)})); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } }
- Jython
from java.util import ArrayList a = ArrayList() a.add(1) g = getattr(a, "get") print g print g(0) # alternatively g = a.get
Examples - Subclassing
- Simple subclassing example
Collections are proxied so
from java.util import ArrayList class CountingArrayList(ArrayList): def __init__(self): ArrayList.__init__(self) self.count = 0L def get(self, index): self.count += 1 return ArrayList.get(self, index) a = CountingArrayList() a.add(1) a.add(1) a.add(2) a.add(3) a.add(5) print "len says: %02d, size says: %02d" % (len(a), a.size()) a.get(0) a.get(4) print "accessed %02d times" % (a.count)
__len__
and other magic methods work as expected (most of the time).
Examples - Servlets
-
Java
import java.io.IOException; import java.io.PrintWriter; import java.util.Date; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class HelloWorldServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) { response.setContentType("text/html"); try { PrintWriter out = response.getWriter(); out.println( "<html>" + "<head><title>Hello World Servlet</title></head>" + "<body>Hello World Servlet at " + new Date() + "</body>" + "</html>" ); } catch (IOException e) { // now what? } } }
-
Jython
PyServlet (included with Jython) is registered to handle all requests for files with .py extension. The servlet loads the .py file and executes it. All code is written in Python.from javax.servlet.http import HttpServlet from java.util import Date class HelloWorldServlet(HttpServlet): def doGet(self, req, res): res.setContentType("text/html"); out = res.getOutputStream() print >> out, ("<html>" "<head><title>Hello World Servlet</title></head>" "<body>Hello World Servlet at %s<body>" "</html>" % Date()) out.close() return
Examples - Databases
-
Java
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(); } }
-
Python
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()
-
zxJDBC
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()
Examples - Embedding
-
Simple embedding example
import org.python.core.PyObject; import org.python.core.PyInteger; import org.python.core.PyException; import org.python.util.PythonInterpreter; public class Embedded { public static void main(String []args) throws PyException { System.setProperty("python.home", "/Users/bzimmer/Development/sourceforge/jython"); PythonInterpreter interp = new PythonInterpreter(); System.out.println("Hello, brave new world"); interp.exec("import sys"); interp.exec("print sys"); interp.set("a", new PyInteger(42)); interp.exec("print a"); interp.exec("x = 2+2"); PyObject x = interp.get("x"); System.out.println("x: "+x); System.out.println("Goodbye, cruel world"); } }
-
More complicated example (included with Jython)
package org.python.util; import java.io.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; import org.python.core.*; /** * This servlet is used to re-serve JPython servlets. It stores * bytecode for JPython servlets and re-uses it if the underlying .py * file has not changed. * <p> * Many people have been involved with this class: * <ul> * <li>Chris Gokey * <li>David Syer * <li>Finn Bock * </ul> * If somebody is missing from this list, let us know. * <p> * * e.g. http://localhost:8080/test/hello.py * <pre> * * from javax.servlet.http import HttpServlet * class hello(HttpServlet): * def doGet(self, req, res): * res.setContentType("text/html"); * out = res.getOutputStream() * print >>out, "<html>" * print >>out, "<head><title>Hello World, How are we?</title></head>" * print >>out, "<body>Hello World, how are we?" * print >>out, "</body>" * print >>out, "</html>" * out.close() * return * </pre> * * in web.xml for the PyServlet context: * <pre> * <web-app> * <servlet> * <servlet-name>PyServlet</servlet-name> * <servlet-class>org.python.util.PyServlet</servlet-class> * <init-param> * <param-name>python.home</param-name> * <param-value>/usr/home/jython-2.1</param-value> * </init-param> * </servlet> * <servlet-mapping> * <servlet-name>PyServlet</servlet-name> * <url-pattern>*.py</url-pattern> * </servlet-mapping> * </web-app> * * </pre> */ public class PyServlet extends HttpServlet { private PythonInterpreter interp; private Hashtable cache = new Hashtable(); private String rootPath; public void init() { rootPath = getServletContext().getRealPath("/"); if (!rootPath.endsWith(File.separator)) rootPath += File.separator; Properties props = new Properties(); // Context parameters ServletContext context = getServletContext(); Enumeration e = context.getInitParameterNames(); while (e.hasMoreElements()) { String name = (String) e.nextElement(); props.put(name, context.getInitParameter(name)); } // Config parameters e = getInitParameterNames(); while (e.hasMoreElements()) { String name = (String) e.nextElement(); props.put(name, getInitParameter(name)); } if (props.getProperty("python.home") == null && System.getProperty("python.home") == null) { props.put("python.home", rootPath + "WEB-INF" + File.separator + "lib"); } PythonInterpreter.initialize(System.getProperties(), props, new String[0]); reset(); PySystemState sys = Py.getSystemState(); sys.add_package("javax.servlet"); sys.add_package("javax.servlet.http"); sys.add_package("javax.servlet.jsp"); sys.add_package("javax.servlet.jsp.tagext"); sys.add_classdir(rootPath + "WEB-INF" + File.separator + "classes"); sys.add_extdir(rootPath + "WEB-INF" + File.separator + "lib", true); } /** * Implementation of the HttpServlet main method. * @param req the request parameter. * @param res the response parameter. * @exception ServletException * @exception IOException */ public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { req.setAttribute("pyservlet", this); String spath = (String)req.getAttribute( "javax.servlet.include.servlet_path"); if (spath == null) { spath = ((HttpServletRequest) req).getServletPath(); if (spath == null || spath.length() == 0) { // Servlet 2.1 puts the path of an extension-matched // servlet in PathInfo. spath = ((HttpServletRequest) req).getPathInfo(); } } String rpath = getServletContext().getRealPath(spath); interp.set("__file__", rpath); HttpServlet servlet = getServlet(rpath); if (servlet != null) servlet.service(req, res); else throw new ServletException("No python servlet found at:" + spath); } public void reset() { destroyCache(); interp = new PythonInterpreter(null, new PySystemState()); cache.clear(); PySystemState sys = Py.getSystemState(); sys.path.append(new PyString(rootPath)); String modulesDir = rootPath + "WEB-INF" + File.separator + "jython"; sys.path.append(new PyString(modulesDir)); } private synchronized HttpServlet getServlet(String path) throws ServletException, IOException { CacheEntry entry = (CacheEntry) cache.get(path); if (entry == null) return loadServlet(path); File file = new File(path); if (file.lastModified() > entry.date) return loadServlet(path); return entry.servlet; } private HttpServlet loadServlet(String path) throws ServletException, IOException { HttpServlet servlet = null; File file = new File(path); // Extract servlet name from path (strip "…/" and ".py") int start = path.lastIndexOf(File.separator); if (start < 0) start = 0; else start++; int end = path.lastIndexOf('.'); if ((end < 0) || (end <= start)) end = path.length(); String name = path.substring(start, end); try { interp.execfile(path); PyObject cls = interp.get(name); if (cls == null) throw new ServletException("No callable (class or function) "+ "named " + name + " in " + path); PyObject pyServlet = cls.__call__(); Object o = pyServlet.__tojava__(HttpServlet.class); if (o == Py.NoConversion) throw new ServletException("The value from " + name + "must extend HttpServlet"); servlet = (HttpServlet)o; servlet.init(getServletConfig()); } catch (PyException e) { throw new ServletException("Could not create "+ "Jython servlet" + e.toString()); } CacheEntry entry = new CacheEntry(servlet, file.lastModified()); cache.put(path, entry); return servlet; } public void destroy() { destroyCache(); } private void destroyCache() { for (Enumeration e = cache.elements(); e.hasMoreElements(); ) { CacheEntry entry = (CacheEntry) e.nextElement(); entry.servlet.destroy(); } } } class CacheEntry { public long date; public HttpServlet servlet; CacheEntry(HttpServlet servlet, long date) { this.servlet= servlet; this.date = date; } }
Alternatives
- Jython is not the only means for accessing Java libraries
- Numerous other 100% Java language implementations
- Several Python-Java integration efforts
Alternatives - 100% Java Languages
- Groovy
- Its a dynamically and/or statically typed language (i.e. static typing is optional, otherwise it defaults to dynamic typing) high level scripting language for the JVM which compiles down to bytecode either at run time or compile time. It features closures, neat List and Map syntax, integrated markup language and expression language, auto-boxing, operator overloading, mixins, AOP interceptors etc.
- BeanShell
- BeanShell is a small, free, embeddable, Java source interpreter with object scripting language features, written in Java. BeanShell executes standard Java statements and expressions, in addition to obvious scripting commands and syntax. BeanShell supports scripted objects as simple method closures like those in Perl and JavaScript(tm).
- JRuby
- A pure Java implementation of the Ruby interpreter
- A much longer list
Alternatives - JVM-PVM Integration
- Python
- JPype
- JPype is an effort to allow python programs full access to java class libraries. This is achieved not through re-implementing Python, as Jython/JPython has done, but rather through interfacing at the native level in both Virtual Machines.
- Actively developed
- JPE
- JPE is a seamless, complete, and efficient integration of Java and standard Python (C Python).
- Last cvs change in 2002
- JPype
- Independent compilation of Java
- GCJ
- GCJ is a portable, optimizing, ahead-of-time compiler for the Java Programming Language. It can compile:
- Java source code directly to native machine code
- Java source code to Java bytecode (class files)
- Java bytecode to native machine code.
- GCJ is a portable, optimizing, ahead-of-time compiler for the Java Programming Language. It can compile:
- Java -> compiled library; compiled library -> SWIG; SWIG + Python
- Actively developed
- GCJ
Alternatives - Distributed Objects
- Pickling
- CPython and Jython pickles are generally compatible
- Pyro
- Supports CPython-Jython communication
- SOAP
- CORBA
Alternatives - Which To Choose?
- Depends of course
- If 100% Java is important choose one of those.
- Which platform will see the most development?
Performance
- Java VM startup time does not rival CPython’s
- JVM ships with JIT; Python requires seperate download of Psyco (not available for OS X)
- Language backgrounds dictate where performance gains are realized
- Python’s scripting background addresses startup, file iteration
- Java focuses primarily on server processes with many threads
- Some optimizations
- PyIntegers cached
Performance - Startup
- startup.py
import sys print sys.version raise SystemExit()
- Python
$ time python startup.py 2.3 (#1, Sep 13 2003, 00:49:11) [GCC 3.3 20030304 (Apple Computer, Inc. build 1495)] real 0m0.147s user 0m0.010s sys 0m0.030s
- Jython
$ time jython startup.py 2.2a0 real 0m2.578s user 0m1.430s sys 0m0.250s
Performance - Iterate A File & Regular Expressions
- ex_re.py
Something to note, files are not automatically closed in Jython as they are in CPython.
import re import time s = time.time() c = re.compile("Slide.*-.*") for i in range(3): n = 0 fp = open("jython-presentation.py", "r") try: for line in fp: if c.search(line): n += 1 finally: fp.close() print "found %02d occurences" % (n) e = time.time() print e - s
- Python
$ python ex_re.py found 14 occurences found 14 occurences found 14 occurences 0.0106308460236
- Jython
$ jython ex_re.py found 14 occurences found 14 occurences found 14 occurences 0.29399991035461426
Getting Starting
- Download from http://www.jython.org
- Only version ~2.1 available
- Check out the current CVS head
- Uses CPython 2.2 Lib/
- Getting started documentation available on the site
- The mailing lists have active support from numerous individuals
Development Environment
- vim or SubEthaEdit for Python
- Eclipse or IntelliJ for Java
- ant for builds
- No support for distutils setup.py building Java source
- should be doable though
- Any OS with JVM support
How It Works
- Writing extension modules
- Looking at the runtime through byte code
How It Works - Writing Extension Modules
- Subclass PyObject
- Remember, Java has single implemenation inheritance (but multiple interface inheritance)
- If implementing a module, add to org.python.modules.Setup
- This might change
- Java<=>Python datatype mapping in both directions
- This is not really extensible right now unless you implement the class yourself.
- Sample code
public void __setattr__(String name, PyObject value) { if ("arraysize".equals(name)) { this.arraysize = value.__int__().getValue(); } else if ("softspace".equals(name)) { this.softspace = value.__int__().getValue(); } else if ("datahandler".equals(name)) { this.datahandler = (DataHandler)value.__tojava__(DataHandler.class); } else { super.__setattr__(name, value); } } /** * Gets the value of the attribute name. * * @param name * @return the attribute for the given name */ public PyObject __findattr__(String name) { if ("arraysize".equals(name)) { return Py.newInteger(arraysize); } else if ("softspace".equals(name)) { return Py.newInteger(softspace); } else if ("__methods__".equals(name)) { return __methods__; } else if ("__members__".equals(name)) { return __members__; } else if ("description".equals(name)) { return this.fetch.description; } else if ("rowcount".equals(name)) { return Py.newInteger(this.fetch.rowcount); } else if ("rownumber".equals(name)) { int rn = this.fetch.rownumber; return (rn < 0) ? Py.None : Py.newInteger(rn); } else if ("warnings".equals(name)) { return warnings; } else if ("lastrowid".equals(name)) { return lastrowid; } else if ("updatecount".equals(name)) { return updatecount; } else if ("datahandler".equals(name)) { return Py.java2py(this.datahandler); } else if ("dynamic".equals(name)) { return this.dynamicFetch ? Py.One : Py.Zero; } else if ("connection".equals(name)) { return this.connection; } else if ("closed".equals(name)) { return Py.newBoolean(closed); } else if ("callproc".equals(name)) { try { // dynamically decide on the the attribute based on the driver if (!getMetaData().supportsStoredProcedures()) { return null; } } catch (Throwable t) {} } return super.__findattr__(name); } /** * Returns an iteratable object. * * @return PyObject * * @since Jython 2.2, DB API 2.0+ */ public PyObject __iter__() { return this; } /** * Returns the next row from the currently executing SQL statement * using the same semantics as .fetchone(). A StopIteration * exception is raised when the result set is exhausted for Python * versions 2.2 and later. * * @return PyObject * * @since Jython 2.2, DB API 2.0+ */ public PyObject next() { PyObject row = __iternext__(); if (row == null) { throw Py.StopIteration(""); } return row; } /** * Return the next element of the sequence that this is an iterator * for. Returns null when the end of the sequence is reached. * * @since Jython 2.2 * * @return PyObject */ public PyObject __iternext__() { PyObject row = fetchone(); return row.__nonzero__() ? row : null; }
How It Works - Writing Extension Modules - Thoughts
- zxJDBC written as Java library
- JNumeric uses primitivies for performance
- Using Python is generally faster to implement
- Wrap up Java-centric library with more Pythonic approach
- PyObject subclassed object can grow dynamic attributes whereas Java instance cannot
- The more Python modules converted to C make more work for Jython developers
How It Works - Runtime
Not my area of expertise — yet
- First parsed by a JavaCC parser generated from grammar file
- AST compiled to Java byte code
- Extensive Java based runtime to support byte codes
- Both JVM and PVM are stack-based virtual machines
- Example python module
a = 1 + 1
- CPython bytecode
1 0 LOAD_CONST 1 (1) 3 LOAD_CONST 1 (1) 6 BINARY_ADD 7 STORE_FAST 0 (a)
How It Works - Runtime - Java
Remember, there is no operator overloading in Java
-
Java (using primitives)
public class ExRuntime { public static void main(String[] args) { int a = 1 + 1; } }
-
Decompiled
// Jad home page: http://www.geocities.com/kpdus/jad.html // Decompiler options: packimports(3) annotate // Source File Name: ExRuntime.java public class ExRuntime { public ExRuntime() { // 0 0:aload_0 // 1 1:invokespecial #1 <Method void Object()> // 2 4:return } public static void main(String args[]) { byte byte0 = 2; // 0 0:iconst_2 // 1 1:istore_1 // 2 2:return } }
-
Java (using Integers)
public class ExRuntime2 { public static void main(String[] args) { int a = new Integer(1).intValue() + new Integer(1).intValue(); } }
-
Decompiled
// Jad home page: http://www.geocities.com/kpdus/jad.html // Decompiler options: packimports(3) annotate // Source File Name: ExRuntime2.java public class ExRuntime2 { public ExRuntime2() { // 0 0:aload_0 // 1 1:invokespecial #1 <Method void Object()> // 2 4:return } public static void main(String args[]) { int i = (new Integer(1)).intValue() + (new Integer(1)).intValue(); // 0 0:new #2 <Class Integer> // 1 3:dup // 2 4:iconst_1 // 3 5:invokespecial #3 <Method void Integer(int)> // 4 8:invokevirtual #4 <Method int Integer.intValue()> // 5 11:new #2 <Class Integer> // 6 14:dup // 7 15:iconst_1 // 8 16:invokespecial #3 <Method void Integer(int)> // 9 19:invokevirtual #4 <Method int Integer.intValue()> // 10 22:iadd // 11 23:istore_1 // 12 24:return } }
How It Works - Runtime - Jython
-
Java source (using jython)
// Jad home page: http://www.geocities.com/kpdus/jad.html // Decompiler options: packimports(3) // Source File Name: /home/bzimmer/development/ziclix/jython-presentation/ex_runtime.py import org.python.core.*; public class e.PyObject extends PyFunctionTable implements PyRunnable { public PyObject f$0(PyFrame pyframe) { pyframe.setglobal("__file__", _0); pyframe.setline(1); PyObject pyobject = _1._add(_1); pyframe.setlocal("a", pyobject); pyobject = null; pyframe.f_lasti = -1; return Py.None; } public PyCode getMain() { return f$0; } public PyObject call_function(int i, PyFrame pyframe) { switch(i) { case 0: // '\0' return f$0(pyframe); } return null; } static final ng self; static final PyString _0 = Py.newString("/home/bzimmer/development/ziclix/jython-presentation/ex_runtime.py"); static final PyInteger _1 = Py.newInteger(1); static final PyCode f$0; static { self = new <init>(); String as[]; f$0 = Py.newCode(0, as = new String[0], "/home/bzimmer/development/ziclix/jython-presentation/ex_runtime.py", "?", 0, false, false, self, 0, null, null, 0, 0); } public e.PyObject() { } }
-
Java bytecode source (using jython)
// Jad home page: http://www.geocities.com/kpdus/jad.html // Decompiler options: packimports(3) disassembler // Source File Name: /home/bzimmer/development/ziclix/jython-presentation/ex_runtime.py import org.python.core.*; public class e.PyObject extends PyFunctionTable implements PyRunnable { public PyObject f$0(PyFrame pyframe) { // 0 0:aload_1 // 1 1:ldc1 #11 <String "__file__"> // 2 3:getstatic #17 <Field PyString _0> // 3 6:invokevirtual #9 <Method void PyFrame.setglobal(String, PyObject)> // 4 9:aload_1 // 5 10:iconst_1 // 6 11:invokevirtual #22 <Method void PyFrame.setline(int)> // 7 14:getstatic #26 <Field PyInteger _1> // 8 17:getstatic #26 <Field PyInteger _1> // 9 20:invokevirtual #32 <Method PyObject PyObject._add(PyObject)> // 10 23:astore_2 // 11 24:aload_1 // 12 25:ldc1 #34 <String "a"> // 13 27:aload_2 // 14 28:invokevirtual #37 <Method void PyFrame.setlocal(String, PyObject)> // 15 31:aconst_null // 16 32:astore_2 // 17 33:aload_1 // 18 34:iconst_m1 // 19 35:putfield #41 <Field int PyFrame.f_lasti> // 20 38:getstatic #47 <Field PyObject Py.None> // 21 41:areturn } public e.Py.None() { // 0 0:aload_0 // 1 1:invokespecial #53 <Method void PyFunctionTable()> // 2 4:return } public PyCode getMain() { // 0 0:getstatic #58 <Field PyCode f$0> // 1 3:areturn } static { // 0 0:new #13 <Class ex_runtime$py> // 1 3:dup // 2 4:invokespecial #62 <Method void ex_runtime$py()> // 3 7:putstatic #64 <Field ex_runtime$py self> // 4 10:ldc1 #66 <String "/home/bzimmer/development/ziclix/jython-presentation/ex_runtime.py"> // 5 12:invokestatic #70 <Method PyString Py.newString(String)> // 6 15:putstatic #17 <Field PyString _0> // 7 18:iconst_1 // 8 19:invokestatic #74 <Method PyInteger Py.newInteger(int)> // 9 22:putstatic #26 <Field PyInteger _1> // 10 25:iconst_0 // 11 26:iconst_0 // 12 27:anewarray String[] // 13 30:astore_0 // 14 31:aload_0 // 15 32:ldc1 #66 <String "/home/bzimmer/development/ziclix/jython-presentation/ex_runtime.py"> // 16 34:ldc1 #78 <String "?"> // 17 36:iconst_0 // 18 37:iconst_0 // 19 38:iconst_0 // 20 39:getstatic #64 <Field ex_runtime$py self> // 21 42:iconst_0 // 22 43:aconst_null // 23 44:aconst_null // 24 45:iconst_0 // 25 46:iconst_0 // 26 47:invokestatic #82 <Method PyCode Py.newCode(int, String[], String, String, int, boolean, boolean, PyFunctionTable, int, String[], String[], int, int)> // 27 50:putstatic #58 <Field PyCode f$0> // 28 53:return } public PyObject call_function(int i, PyFrame pyframe) { // 0 0:iload_1 // 1 1:tableswitch 0 0: default 26 // 0 20 // 2 20:aload_0 // 3 21:aload_2 // 4 22:invokevirtual #86 <Method PyObject f$0(PyFrame)> // 5 25:areturn // 6 26:aconst_null // 7 27:areturn } static final e.PyFrame self; static final PyString _0; static final PyInteger _1; static final PyCode f$0; }
Where Is Jython Going?
- Better Java Integration
- Drop JDK 1.1 support (to gain Collection framework support, simpler code, …)
>>> from java.util import ArrayList >>> a = ArrayList([1,2,3]) Traceback (innermost last): File "<console>", line 1, in ? TypeError: java.util.ArrayList(): 1st arg can't be coerced to java.util.Collection or int
- Drop JDK 1.1 support (to gain Collection framework support, simpler code, …)
- Changes required for new Java 1.5 updates
- enum
- assert
- Upgrade compatibility with Python 2.4
- Currently uses CPython 2.2 Lib/
- Implementation of new-style classes
- Coming very soon
- Implementation of popular missing modules
- sets
- select
- datetime
- Recently received one of three PSF grants for so development will continue