Differences between revisions 2 and 18 (spanning 16 versions)
Revision 2 as of 2005-02-07 19:11:42
Size: 6060
Editor: BillDehora
Comment:
Revision 18 as of 2015-05-01 01:56:57
Size: 5053
Editor: JimBaker
Comment: Update to 2.7
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
[:../:FAQ Home] = Programming Jython =
Line 3: Line 3:
= Programming Jython =
JythonFaq

<<TableOfContents>>
Line 7: Line 10:
'''Why can't I multiply inherit from two Java classes?''' == Why can't I multiply inherit from two or more Java classes? ==
Line 9: Line 12:
In earlier versions of JPython, you actually could. This was deliberately disabled in 1.1 for a variety of good reasons. For a detailed discussion on this issue see the following archive messages: In earlier versions of JPython, you actually could. This was deliberately disabled in 1.1 for a variety of good reasons.  For one, multiply
inheriting from t
wo Java classes breaks the single inheritance contract that is assumed when developing Java classes.
Line 11: Line 15:
  http://www.python.org/pipermail/jpython-interest/1998-April/000213.html
  http://www.python.org/pipermail/jpython-interest/1999-June/001874.html

Note that you can still multiply inherit from any number of Python classes.
Note that you can still multiply inherit from any number of Python classes, and you can inherit from any number of Java interfaces.
Line 18: Line 19:
'''Why does dir(someJavaObject) return the empty list?'''

Because the built-in dir() function returns a list of names called from the object's __dict__, __methods__, and __members__ attributes. In Python, an instance's methods live in the instance's class's dictionary, so dir(someJavaObject.__class__) would return a list of the method names (although only for the direct class, not for any base classes).

----

'''I'm trying to execute a 'protected' or 'private' Java Instance Method or attribute in a Java package. How can I get access?'''
== I'm trying to execute a 'protected' or 'private' Java Instance Method or attribute in a Java package. How can I get access? ==
Line 36: Line 31:
'''Can I reload a java class as is possible for python modules?'''
Line 38: Line 32:
The support for reloading java classes through reload(java-class), is disabled. The reload(java-class) only worked when the java class was a standalone class without any dependencies on other java classes (except the system class). When there was more than one class involved, the simple reload(java-class) no longer worked. == How can I access Java protected (static) members from a Jython subclass? ==
Line 40: Line 34:
Now on the other hand Jython 2.0 comes with some alternative (experimental) user-level support for java classes reloading ("jreload" module).

See: http://www.jython.org/docs/jreload.html

Further Jython 2.0 internal changes enable the expert user to play with reloading and class-loaders as he would from native java.

----

'''How can I access Java protected (static) members from a Jython subclass?'''

The short answer: you can't. At least not without setting the registry option python.security.respectJavaAccessibility to false.
The short answer: you can't. At least not without setting the registry option ``python.security.respectJavaAccessibility`` to ``false``.
Line 68: Line 52:
 
'''
How can I use a Java null value in Jython?'''
 
A java null is turned into a Python None value.

==
How can I use a Java null value in Jython? ==

A Java ``null`` is turned into a Python ``None`` value.
Line 79: Line 63:
  ... print "null returned" 
  ... 
  null returned 
  >>>    
  ... print "null returned"
  ...
  null returned
  >>>
Line 87: Line 71:
'''Where's the -O switch?''' == Where's the -O switch? ==
Line 89: Line 73:
Jython 2.0 does not have a -O command-line switch. Jython does not have a -O command-line switch.
Line 91: Line 75:
Assigning __debug__=0 has been used to get -O behavior from things like "assert", but such assignments to __debug__ are considered an error, and in the future, will raise an exception. __debug__ is supposed to be a read-only variable.  Assigning __debug__=0 has been used to get -O behavior from things like "assert", but such assignments to __debug__ are considered an error, and in the future, will raise an exception. __debug__ is supposed to be a read-only variable.
Line 95: Line 79:
''When I write to a file, it's empty. Why?''' == When I write to a file, it's empty. Why? ==
Line 97: Line 81:
The addition of buffering to the org.python.core.PyFile class in the 2.1 development cycle changed the autoflushing of Jython file objects. In Jython 2.1x, you must explicitly flush() and/or close() a file object opened for writing or appending before any data will actually be saved. You need to close the file (or flush the buffer). You can ensure this happens by using ``finally`` or the ``with`` statement:
Line 99: Line 83:
This reflects the current status and is not meant to imply this will always be the case for Jython (but it may be for certain java versions).

Currently, For example:
Line 103: Line 84:
    f = open("myFile", "w")
    # if the program terminates here, the file is empty
    f.flush() # or f.close()
    # If the program terminates here ,the file has data
    from __future__ import with_statement
    # some code...
    with open("myFile", "w") as f:
        f.write("some data")
Line 108: Line 89:
Another example:
{{{#!python
    open("myFile", "w").write("some data")
}}}
This will create an empty file, but note that the standard lib does not use write on anonymouse file objects as it is considered poor practice anyway.
Line 116: Line 92:
'''The Jython's os module is missing some functions, why?''' == The Jython's os module is missing some functions, why? ==
Line 118: Line 94:
Python's and Jython's os modules differ necessarily because of differences Java imposes on natvie system access. For example, Java does not have a chdir equivalent, so it does not exist in Jython's os.

There is an alternative os module that does provide additional functionality, and it is the jnios module found at:

    http://sourceforge.net/projects/jnios

The jnios module replaces the default os module with a Java/JNI implementation of Python's os and posix modules.

Jython CVS also has more functions in the os module (like system and the popen* functions). See ''The Jython's os module is missing some functions, why?'' below.
For Posix and Windows, Jython implements most of the os module seen in CPython (excluding most notably ``fork``). Under certain sandbox settings, it's not possible to run the necessary Java Native Runtime code for this (using JNI), so instead a pure Java version is substituted. This is also what is available when running under other OS's, such as zOS.
Line 130: Line 98:
'''The Jython's os module is missing some functions, why?''' == How can I manipulate a java.util.Date object in Jython? ==
Line 132: Line 100:
Use the os.system or os.popen* functions from Jython CVS. {{{java.util.Date.getTime()}}} gives the milliseconds since the epoch while Jython (just like CPython) gives seconds since the epoch. So you need to divide the values given from {{{java.util.Date}}} by 1000.
Line 134: Line 102:
To use these functions, you'll need javaos.py, javashell.py, and popen2.py: Example:
{{{#!python
>>> from java.util import Date
>>> import time
>>> times=(float(Date().time)/1000,time.time())
>>> times[0]-times[1]
0.0
}}}
Line 136: Line 111:
    http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/jython/jython/Lib/ ----
Line 138: Line 113:
You'll need to delete the 'from __future__ import division' line from javaos.py (this is a Python 2.2 feature not supported in Jython 2.1) == jythonc ==
Line 140: Line 115:
Alternatively, you could use java.lang.Runtime.exec() directly, but the os functions handle a lot of complexity for you. jythonc is no longer available as of 2.5.
Line 142: Line 117:
---
-
for more info on jythonc see http://www.jython.org/Project/jythonc.html

----

== How can catch a Java exception thrown from within Jython? ==
How do I distinguish between different Java exceptions thrown
from within jython if the `interp.exec` method only throws a `PyException` ?

{{{
 PythonInterpreter interp = new PythonInterpreter();
 String jythonCodeString = "from com.example import MyJavaException\n" +
   "raise MyJavaException('special condition occurred.')";

 try {
      interp.exec(jythonCodeString);
    } catch (org.python.core.PyException e) {
      if (e.value instanceof PyJavaInstance) {
        Object javaError = e.value.__tojava__(Throwable.class);
        if (javaError != null && javaError != jy.NoConversion) {
          if (javaError instanceof MyJavaException ){
            throw (MyJavaException)javaError;
          }
        }
      }

      if (Py.matchException(e, Py.KeyboardInterrupt)) {
        throw new InterruptedException(
            "Interupted while executing Jython script.");
      }
      throw e;
    }
}}}

Programming Jython

JythonFaq


Why can't I multiply inherit from two or more Java classes?

In earlier versions of JPython, you actually could. This was deliberately disabled in 1.1 for a variety of good reasons. For one, multiply inheriting from two Java classes breaks the single inheritance contract that is assumed when developing Java classes.

Note that you can still multiply inherit from any number of Python classes, and you can inherit from any number of Java interfaces.


I'm trying to execute a 'protected' or 'private' Java Instance Method or attribute in a Java package. How can I get access?

By default, as in Java, these methods are protected from external access, but there may be reasons, such as test scaffolding scripts, that this feature is not wanted. In the [jython home]/registry file:

  # Setting this to false will allow Jython to provide access to
  # non-public fields, methods, and constructors of Java objects.
  python.security.respectJavaAccessibility = false


How can I access Java protected (static) members from a Jython subclass?

The short answer: you can't. At least not without setting the registry option python.security.respectJavaAccessibility to false.

It is difficult to add in a nice manner. The problem is a bit like this:

A normal (public) static method is from jython called on the parent java class:

  • javaclass.method()

Such a call does not originate from the subclass, but from internal reflection code in jython. If we want to add support for calling protected static methods from a jython subclass, the call will have to originate from the subclass (ie. the proxy class), so we will have to generate a referring method in subclass proxy like:

   1   public static void method() {
   2      javaclass.method()
   3   }

(with the right return type and throws clauses) and the jython subclass will have to call the method on its own class, not the java class.


How can I use a Java null value in Jython?

A Java null is turned into a Python None value.

  import java
  >>> h = java.util.Hashtable()
  >>> print h.get("abc")
  None
  >>> if h.get("abc") is None:
  ...   print "null returned"
  ...
  null returned
  >>>


Where's the -O switch?

Jython does not have a -O command-line switch.

Assigning debug=0 has been used to get -O behavior from things like "assert", but such assignments to debug are considered an error, and in the future, will raise an exception. debug is supposed to be a read-only variable.


When I write to a file, it's empty. Why?

You need to close the file (or flush the buffer). You can ensure this happens by using finally or the with statement:

   1     from __future__ import with_statement
   2     # some code...
   3     with open("myFile", "w") as f:
   4         f.write("some data")


The Jython's os module is missing some functions, why?

For Posix and Windows, Jython implements most of the os module seen in CPython (excluding most notably fork). Under certain sandbox settings, it's not possible to run the necessary Java Native Runtime code for this (using JNI), so instead a pure Java version is substituted. This is also what is available when running under other OS's, such as zOS.


How can I manipulate a java.util.Date object in Jython?

java.util.Date.getTime() gives the milliseconds since the epoch while Jython (just like CPython) gives seconds since the epoch. So you need to divide the values given from java.util.Date by 1000.

Example:

   1 >>> from java.util import Date
   2 >>> import time
   3 >>> times=(float(Date().time)/1000,time.time())
   4 >>> times[0]-times[1]
   5 0.0


jythonc

jythonc is no longer available as of 2.5.

for more info on jythonc see http://www.jython.org/Project/jythonc.html


How can catch a Java exception thrown from within Jython?

How do I distinguish between different Java exceptions thrown from within jython if the interp.exec method only throws a PyException ?

 PythonInterpreter interp = new PythonInterpreter();
 String jythonCodeString = "from com.example import MyJavaException\n" +
   "raise MyJavaException('special condition occurred.')"; 

 try {
      interp.exec(jythonCodeString);
    } catch (org.python.core.PyException e) {
      if (e.value instanceof PyJavaInstance) {
        Object javaError = e.value.__tojava__(Throwable.class);
        if (javaError != null && javaError != jy.NoConversion) {
          if (javaError instanceof MyJavaException ){
            throw (MyJavaException)javaError;
          }
        }
      }

      if (Py.matchException(e, Py.KeyboardInterrupt)) {
        throw new InterruptedException(
            "Interupted while executing Jython script.");
      }
      throw e;
    } 

JythonFaq/ProgrammingJython (last edited 2015-05-01 01:56:57 by JimBaker)