Using __tojava__ - where is the class code running ?

View: New views
4 Messages — Rating Filter:   Alert me  

Using __tojava__ - where is the class code running ?

by David Griffin :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I have a java abstract class "uiscript".  It has an abstract method "display"
At runtime I create an interpreter and read some Jython text from
somewhere (myJythonClass.py)
This text contains a class definition for a class that overrides
"uiscript" and which implements the  display() method.
I execute this Jython text then I get a class object, and execute that
to instantiate an object of this class.  Using __tojava__  I get an
object representing an instance of the class.

In Java I can now treat this object as an instance of   uiscript   and
execute the display() method.

Here's the question.

What is this Java class (of which this object is an instance) exactly
?  Is it a java wrapper round a class whose method code is in Jython ?
 Or have I now got an instance of a fully compiled java class,
compiled on the fly as part of the __tojava__ process ?   Put another
way, is the Jython code in the display() method (and any other Jython
methods it calls) going to be executed by the interpreter or as Java
byte code ?

Could the interpreter go out of scope while I still have a valid
reference to this new object in Java ?

I suspect that when I fully understand what is happening here I will
realise the question is the wrong question but I only learn by
asking...

One other question. If I create many many class definitions in my
interpreter in a given session
- are they just in memory ?  Or is there any disk usage related to this
- how do I remove a definition of a class I don't intend to use any
more to free up some resources ?


TIA

David Griffin

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Jython-users mailing list
Jython-users@...
https://lists.sourceforge.net/lists/listinfo/jython-users

Parent Message unknown Fwd: Using __tojava__ - where is the class code running ?

by Tobias Ivarsson :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Yeah, that's right, forgot that this list doesn't have reply-to headers set to the list...

---------- Forwarded message ----------
From: Tobias Ivarsson <thobes@...>
Date: Mon, Aug 11, 2008 at 1:17 PM
Subject: Re: [Jython-users] Using __tojava__ - where is the class code running ?
To: David Griffin <gripfin@...>




On Mon, Aug 11, 2008 at 8:40 AM, David Griffin <gripfin@...> wrote:
I have a java abstract class "uiscript".  It has an abstract method "display"
At runtime I create an interpreter and read some Jython text from
somewhere (myJythonClass.py)
This text contains a class definition for a class that overrides
"uiscript" and which implements the  display() method.
I execute this Jython text then I get a class object, and execute that
to instantiate an object of this class.  Using __tojava__  I get an
object representing an instance of the class.

In Java I can now treat this object as an instance of   uiscript   and
execute the display() method.

Here's the question.

What is this Java class (of which this object is an instance) exactly
?  Is it a java wrapper round a class whose method code is in Jython ?
 Or have I now got an instance of a fully compiled java class,
compiled on the fly as part of the __tojava__ process ?   Put another
way, is the Jython code in the display() method (and any other Jython
methods it calls) going to be executed by the interpreter or as Java
byte code ?

All code executed by Jython is always compiled to Java bytecode.

When Jython first encounters your code (for example when you import your module) Jython will compile all the code to Java bytecode. That means that all the code bodies will be compiled to Java bytecode. A class definition in Python is just a code body that defines a bunch of bindings in a locals dictionary followed by a call to some makeClass system level method. In Jython when the class definition is executed this makeClass method will look at the bases you have defined, identify the Java interfaces you have defined there and create a Java class with the apropriate methods. These methods will, when invoked, lookup the apropriate name from the Jython object and invoke that function. The __tojava__ method will simply return an instance of this Java class.


Could the interpreter go out of scope while I still have a valid
reference to this new object in Java ? 


I suspect that when I fully understand what is happening here I will
realise the question is the wrong question but I only learn by
asking...

It was a good question, thank you for asking! I hope my answer clarified things somewhat for you.


One other question. If I create many many class definitions in my
interpreter in a given session
- are they just in memory ?  Or is there any disk usage related to this
 
If Jython has a writable cache area Jython will store the java bytecode for the code bodies that you have defined, kinda like CPython stores pyc-files.


- how do I remove a definition of a class I don't intend to use any
more to free up some resources ?

I am not sure on this one... does someone else have an idea?


/Tobias



-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Jython-users mailing list
Jython-users@...
https://lists.sourceforge.net/lists/listinfo/jython-users

Re: Using __tojava__ - where is the class code running ?

by Nicholas Riley :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

In article
<76e0d22a0808102340i1e2e4179sfcdae018bc767ac6@...>,
 "David Griffin" <gripfin@...> wrote:

> One other question. If I create many many class definitions in my
> interpreter in a given session
> - are they just in memory ?  Or is there any disk usage related to this

If the class is generated from a .py file on disk then the class file
will be cached on disk too; if not, it'll be in memory.

> - how do I remove a definition of a class I don't intend to use any
> more to free up some resources ?

Just delete it from within Python.  If you want to track interactive
Java class generation, put a print statement in Py.compile_flags such as:

        System.out.println(filename + " => " + name);

With this in place, you'll still have to wait for the classes to get
garbage collected, which you can see most easily by switching to the
serial GC and turning on GC verbosity:

% jython -J-verbose:gc -J-XX:+UseSerialGC -Dpython.verbose=comment
[...]
>>> from gc import collect
<stdin> => org.python.pycode._pyx1
import: 'gc' as org.python.modules.gc in builtin modules
>>> collect()
<stdin> => org.python.pycode._pyx2
[Full GC[Unloading class org.python.pycode._pyx0]
[Unloading class org.python.pycode._pyx1]
 12387K->10739K(24040K), 0.0665128 secs]
>>> import foo
<stdin> => org.python.pycode._pyx3
import: 'foo' as foo.py
0
>>> import sys
<stdin> => org.python.pycode._pyx4
>>> del sys.modules['foo']
<stdin> => org.python.pycode._pyx5
>>> del foo            
<stdin> => org.python.pycode._pyx6
>>> collect()    
<stdin> => org.python.pycode._pyx7
[Full GC[Unloading class org.python.pycode._pyx5]
[Unloading class org.python.pycode._pyx2]
[Unloading class org.python.pycode._pyx4]
[Unloading class org.python.pycode._pyx3]
[Unloading class org.python.pycode._pyx6]
[Unloading class foo$py]
 13297K->10245K(25772K), 0.0852887 secs]

A class gets generated for each interactive statement, then immediately
unloaded when it goes out of scope.  If you import a module (which is
stored in a $py.class file on disk), then delete it from sys.modules and
whatever Python namespaces it's compiled in, the corresponding Java
class will be unloaded.
--
Nicholas Riley <njriley@...>


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Jython-users mailing list
Jython-users@...
https://lists.sourceforge.net/lists/listinfo/jython-users

Re: Using __tojava__ - where is the class code running ?

by David Griffin :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thanks, v helpful.  I have a further question.

My app executes scripts at runtime, taken from files.
Each script is in essence a class definition based on an abstract
class in my Java.

So whatever is in the script, I know it should have a some key methods
defined in the abstract base class, and these are called from my java
code.

I read the script into my interpreter
  myInterpreter.execfile(scriptStream);
and this is void with no exceptions so I cannot really tell at that
point if script is OK

Then I get a reference for the class
 PyObject cls = interpreter.get(nameOfMyClass);
If cls != null then I think can be reasonably sure it found a valid
class in the interpreter namespace

I try to instantiate the class
 PyObject cls_instance = cls.__call__();

Then I convert that into a java object
 Object o = cls_instance.__tojava__(myAbstractClass.class);

If  o != Py.NoConversion  then I presumably have a usable java object.

I then cast  o   to (myAbstractClass) and I can start treating it as
an instance of myAbstractClass and call the base class methods.

This works a treat.




But suppose one of the methods implemented in the script contain a
dodgy bit of Python code ?

Currently I find out at runtime when
- it does not work (not always apparent)
- a load of (admittedly quite informative) Jython error messages
appear on stderr

But how can I capture this programmatically in my calling Java code ?

As far as Java is concerned, I called a method called
"baseMethod1()" on a normal instance of  myAbstractClass .

I guess what I would like to be able to do is say in my abstract Java
class definition something like

public abstract class myAbstractClass
{
   // This method will be implemented in my Jython script
   public abstract void baseMethod1(...)  throws SomeSortOfException;
}

and find a way to have the Jython Interpreter automatically throw this
SomeSortOfException  if it encountered a problem in my code at
runtime.

Is there a setting for this ?

I would rather not have to add a load of code in the script
itself for this because my whole aim here is to make the scripts
themselves simple and hide any infrastructure details from the user
who might have to view and tweak the scripts.


Hope I have explained this clearly.

Thanks in advance.


David Griffin

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Jython-users mailing list
Jython-users@...
https://lists.sourceforge.net/lists/listinfo/jython-users
LightInTheBox - Buy quality products at wholesale price!