From: Ype K. <yk...@xs...> - 2001-05-09 19:54:53
|
Adam, (posted after mistakingly sending to Adam only) You wrote: >Well, I've been playing with Jython a bit, and I still >don't fully understand it. I'm even sad to say that I >find the javadoc sadly lacking. I'm hoping, then, that >some more knowledgable person can take pity on me and >give me a hand. I'm going to describe what I want to >do, in as much detail as I can think of, and I'm >hoping someone can explain how to do it. I wrote an environment for jython modules in jython itself, so I can only partially answer you questions. The answer is a bit long, but so was your post... > >I have a class written in Java with a few methods >defined. I want the user of my program to be able to >extend this class in Jython by writing a .py file with >a >known name. Then, when a certain event occurs in my >program, I wish to load this class (including >reloading it, if it has changed since the last time we >used it), instantiate it, and call a method with a >known name/signature (that is, one of the methods >defined in the parent class). In addition, since there Using an PythonInterpreter, you can do an execfile on a jython module. This has basically the same effect as using the module as the main program in a jython run. The interpreter will load java equivalent classes of all the classes defined in the module. I'm afraid you are going to have to write your own class loader and/or your own PythonInterpreter if you want to restrict class loading. >will be multiple python files floating around (that >is, the user can define more than one class in python, >although they all will extend the same java base >class), I want >to make sure there are no side effects; that is, I >don't want definitions and such to hang around between >calls to python classes. You can remove modules from sys.modules using del. To remove java classes have a look at the jreload docs on jython.sourceforge.org. > >How should I even begin to do this? I don't know >whether it is better to compile or interpret, in this >case, even. Speed is actually a relatively important >factor, which is a point for compiling, but only if >there's a way to recompile and reload classes without >restarting the VM (preferably a prettier way than the >usual hack for doing this in java). On the other hand, >while interpreting seems easier at first, I can't find >a way to enforce the contract that the .py file >contain only a class, and nothing else. Also, unless Have a look at linecache.py on how to check for changed modules. I don't think you need to worry about speed: jython is always compiled before being run/interpreted. Creating an interpreter from within the jython environment is quite fast: only the locals and globals to start off the interpreter must be provided in a basic setup, all the code is already available. To constrain a .py file to a single class you'll have to write your own interpreter, see the python docs on what constitutes a correct python program: any nr. of class definitions, function definitions and statements is allowable at module level. >we create a new interpreter each >time (which may, I wouldn't be surprised, take longer >than just recompiling a class), I don't see a way to >guarantee no side effects between calls. In general there is no such guarantee: only the module that is mentioned in execfile is dropped from the sys namespace, all it's imported modules are kept, although you can delete those. Having imported modules kept around is not only a disadvantage: it also speeds up later executions. > >Whatever help or advice you can give would be >appreciated. The more low-level (pseudocode, example >code, whatever) the better. I'm 95% sure that what I'm >asking for is possible, and 100% sure it should be >possible, so if I find out that it's not, for whatever >reason, I do intend to hack Jython until it is. If I >end up >doing this, I really will need all the detail I can >get, before I try to grok the code on my own. I can recommend trying to do it in jython first. Experimenting is a faster in jython than in java. Basically this boils down to writing a main program in jython, calling your java code from this while passing to the java code some jython objects, possibly subclasses of your java classes or implementations of java interfaces. One of these jython objects can then do the work: use execfile(), and evt. adapt sys.modules and sys.argv around the execfile call. Some thoughts: You'll probably need to setup a directory from which to load the user modules. Also you might(?) need to catch exceptions thrown from user code. In case your user code uses swing, you also get multiple threads. How will users debug their code? Where does print output go? At some point you may decide that you need to subclass your python classes in java code, I never got that far. To start off, it will help you a lot if you trust your users to put only your expected class in a module. After all, you have already accepted that you are going to call user code and you can control the moment the user module is going to be executed. Allowing your users a normal jython module will save you the work of adapting the jython interpreter. In case you need more isolation you might have to fall back on java security features like class loaders and security checks. I saw a basic howto for this on one of the jython lists recently. In case you want to have a look at some jython code calling execfile and unloading (sys.)modules, let me know. Good luck and have fun, Ype |