On 11/10/2011 05:58 PM, eric@frog-water.com wrote:

Woops, looks like I left one out, sorry I didn't catch it. I'll send it here.

IBuilding is a java interface class, not a jython class.  Java can only cast to java classes, but as long as your jython class implements that java class, java will happily cast and use it. If that's what you're doing and are still getting ClassCastException, then you're doing something else funny.  Maybe one of the jython-users can help you on that front. 

 

Here ya go...

 

    /**
     * Set the python.home envar correctly.
     * </p>
     * Assuming jython's home is in MyPlugin, we hunt for it there.
     * Home is wherever jython.jar resides.
     */
    public static String setupJythonHomePointer() {
        //note: that there must be a "Lib" directory at a sibling level to jython.jar
        // (but we wont check for it).

        if (jyhome == null) {
            Bundle bundle = MyPlugin.getDefault().getBundle();
            File f = getJythonScript(bundle, "/", "jython.jar");
            jyhome = f.getParent(); //the jar's directory
        }

        // put it into the environment
        System.getProperties().put("python.home", jyhome);
        logger.debug("python.home -> " + jyhome);
        return jyhome;
    }


-Eric


On November 10, 2011 at 8:50 AM Philipp Zech <zech.ph@gmail.com> wrote:

On 11/09/2011 04:18 PM, eric@frog-water.com 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

 
Hej Eric,

thanks a lot for your efforts, it's working now! You definitely saved me a lot of time.

Cheers,

Philipp