From: Bill K. <bi...@ct...> - 2001-10-03 18:01:14
|
From: "rohit seth" <ro2...@ya...> > > Hi, > > I am planning to use Jython scripts to extend the > runtime flexibility of my Java application. Just > wanted to know if it is possible to pass and retrieve > parameters/variables from Jython file to Java File and > vice versa. > > If yes, then how? What we've done here is create what we call a PyFactory. :-) (I *wish* the whole application could be written in Jython, but we're dealing with a lot of legacy code, so the thing is still Java-centric. (*)) The PyFactory looks something like this: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ import org.python.util.PythonInterpreter; public class PyFactory { public static void initialize () throws ClassNotFoundException { String pyPath = "wherever/your/python/scripts/are"; _py = new PythonInterpreter(); _py.exec("import sys"); _py.exec("sys.path.append('"+pyPath+"')"); _py.exec("import pyfactory"); Class pyfactoryClass = Class.forName("com.eb.py.PyFactoryInterface"); _py.exec("pie = pyfactory.PyFactory()"); _pie = (PyFactoryInterface) _py.get("pie", pyfactoryClass); } public static PyFactoryInterface pie () { return _pie; } private static PythonInterpreter _py; private static PyFactoryInterface _pie; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Where the PyFactoryInferface is our own interface in java that is implemented by Python code . . . interfaces are the key to having Java code be able to utilize Python classes (all this assumes you're not using jythonc, which is another approach entirely . . .) So for completeness, PyFactoryInterface looks something like: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ public interface PyFactoryInterface { public DictParser newDictParser (); public HtmlParser newHtmlParser (Hashtable tagToNode); public HtmlRenderComponent newHtmlRenderComponent (); public URLHandler newURLHandler (String productPath); // etc. } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ So. . . again with the 'interfaces'. Each of those guys being returned (DictParser, HtmlParser, etc.) are all Java interfaces implemented by the jython classes we're instantiating and returning here. The PyFactoryInterface itself is, of course, implemented in jython. So, again for completeness, it looks a bit like: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ from dictparser import DictParser from htmlparse import HtmlParser from htmlrender import HtmlRenderComponent from urlhandler import URLHandler # etc . . . class PyFactory(com.your.java.package.PyFactoryInterface): def newDictParser(self): return DictParser() def newHtmlParser(self, tagToNode): return HtmlParser(tagToNode) def newHtmlRenderComponent(self): return HtmlRenderComponent() def newURLHandler(self, productPath): return URLHandler(productPath) # etc . . . ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ . . . in re-reading the above, since I forgot to actually show a usage example of the factory, here it is (in case it wasn't obvious already :) From Java, PyFactory.initialize(); HtmlRenderComponent hr = PyFactory.pie().newHtmlRenderComponent(); Remember that HtmlRenderComponent is just an 'interface' implemented by the Python class providing that functionality. (*) On a side note, I had to re-implement our Python-based HTML layout engine in Java last weekend, 'cause jython just wasn't up to the task, speed-wise, unfortunately. (At least 2.1a3 - I didn't try other versions of the interpreter.) However, the Java re-implementation was still able to use the Python-based unit tests, almost totally unmodified. So that was nice. Incidentally, the Python implementation of the layout engine was 599 lines, while the Java came to 941. Hope this helps, Bill |