From: Philipp Z. <ze...@gm...> - 2011-11-10 15:50:44
|
On 11/09/2011 04:18 PM, er...@fr... wrote: > > Philipp, I feel your pain. The Jython object factories are a PITA > when used from Eclipse. I could not get them to work no matter what I > tried. The debugger kept showing me what appeared to be a bug in the > jython guts, but I couldn't fix it. So try this. This works for me. > > The first snippet is just to show you how to invoke it from > java/eclipse. The two functions at the bottom are just support > functions we use to find scripts in our plugins and set up the engine > to use them. The use of ScriptEngine is because we use the Java > embedded scripting support to find the Jython engine. > > Good luck! > > > -Eric > > org.osi.framework.Bundle bundle = MyPlugin.getDefault().getBundle(); > File scriptPath = JythonExecutor.getJythonScript(bundle, "/", > "MyPyScript.py"); //search bundle from the top > javax.script.ScriptEngine engine = > createJythonEngine(scriptPath.getParent()); > assert engine != null; > > try { > engine.eval("import MyPyScript"); > engine.eval("myBuilding = MyPyScript.myFunction()"); > IBuilding myBuilding = (IBuilding) engine.get("myBuilding"); > myBuilding.doSomething(); > } > catch(Throwable t) {...} > > ... > > > > /** > * Gets an instance of a jython engine. > * @param pathEntries [optional] absolute pathnames (to > directories only) > * to put into the engine's sys.path (where are your scripts?) > * @return an initialized intance of a jython engine, or > <em>null</em> if it can't be constructed > */ > @Nullable > public static javax.script.ScriptEngine > createJythonEngine(String... pathEntries) { > setupJythonHomePointer(); > PySystemState state = new PySystemState(); > for (String pathEntry : pathEntries) { > state.path.append(Py.newString(pathEntry)); > } > Py.setSystemState(state); > ClassLoader loader = EftPlugin.class.getClassLoader(); > ScriptEngineManager engineManager = new > ScriptEngineManager(loader); > return engineManager.getEngineByName("python"); > } > > /** > * Gets the pathname to a bundled script > * @param bundle your eclipse plugin's Bundle > * @param startingLocation > * @param scriptName the file you're hunting for > * @return a File instance pointing to the script you ask for, or > <em>null</em> if it can't be found > */ > @SuppressWarnings({"unchecked"}) > @Nullable > public static File getJythonScript(Bundle bundle, String > startingLocation, String scriptName) { > File file = null; > String location = bundle.getLocation(); > String needsPrefix = location.split("@", 2)[1]; > String installPath = System.getProperty( > "osgi.install.area") //eg. file:/c:/eftinstall > .split("file:/")[1]; > > Enumeration<URL> entries = > bundle.findEntries(startingLocation, scriptName, true); > if (entries != null) { > URL url = entries.nextElement(); > String s = String.format("%s/%s/%s)", > installPath, // c:/eftinstall > needsPrefix, // path to plugin > url.getPath()); // path to script > > try { > file = new File(s).getCanonicalFile(); > } > catch (IOException e) { > logger.debug(e); > e.printStackTrace(); > } > } > return file; > } > Hi Eric, thanks for this solution! actually it is far more than i requested and also expected, but it's totally what i need, as my next goal was to use python from inside eclipse plugins, so again, thanks a lot for your answer. The only questions that remain at first sight are - what does setupJythonHomePointer(); and - what needs to be done that the class cast works (to IBuilding) as I currently get ClassCastException related errors (i.e.: pytzhon objects cannot be casted into java ones, although they implement the interface)? thanks a lot for your help! cheers, philipp |