From: annegrl <an...@ya...> - 2007-10-01 06:48:15
|
I've seen this error over and over in the forums (cannot import name), but I still haven't found what exactly I'm doing wrong. I'm using a test jar now just to simplify the situation I'm running an Eclipse based Java application, and attempting to run the Python interpreter to run a python script. Here's how I'm setting up the environment: .... Properties props = new Properties(); props.setProperty("python.path", jars); //jars is set to include my TestAnne jar, jython.jar System.setProperty("java.class.path", jars); //just in case PySystemState.initialize(props, System.getProperties(), new String[]()); python = new PythonInterpreter(); ... and the script import: from com.ibm.anne import TestAnne ..but then as it tries to run the script... ImportError: cannot import name TestAnne however this class is defined in a jar in the python.path which I set, and also its jar shows up in sys.path. But for some reason jython is not recognizing it (although I do notice it finds the package, since it's not complaining about the module). This works fine if I point to the directory of the class files instead of jar files. Just something about it being in a jar. Please help! Completely baffled! anne -- View this message in context: http://www.nabble.com/Cannot-import-name...but-jar-in-classpath-tf4546539.html#a12974125 Sent from the jython-dev mailing list archive at Nabble.com. |
From: David H. <dav...@gm...> - 2007-10-01 15:00:25
|
On 10/1/07, annegrl <an...@ya...> wrote: > I'm running an Eclipse based Java application, and attempting to run the > Python interpreter to run a python script. > > Here's how I'm setting up the environment: > > .... > Properties props = new Properties(); > props.setProperty("python.path", jars); //jars is set to include my > TestAnne jar, jython.jar > System.setProperty("java.class.path", jars); //just in case > PySystemState.initialize(props, System.getProperties(), new String[]()); > python = new PythonInterpreter(); By Eclipse-based do you mean you're writing plugins for Eclipse or an RCP application? Eclipse uses some magic to ensure that code running in Eclipse can only load classes from plugins that are declared as dependencies. Jython doesn't automatically inherit this magic. I handled this by writing a class loader that can load exactly the same classes a plugin does. I use an instance of that class loader to initialize the PySystemState: state.setClassLoader(pluginLoader); Since PySystemState is fairly static, there may be problems with embedding Jython in different plugins while respecting Eclipse's class loading limitations. You may get into problems there. I create Jython objects from a single plugin, so I don't have any problems. Here's my class loader. It seems that I hardcoded the plugin name; you should probably do it right ;-) Feel free to ask more questions; I'm using Jython extensively in an RCP app, so it's definitely doable. /** * Class loader that is able to load all classes available to this plugin. */ class PluginClassLoader extends ClassLoader { /** * Creates an instance of <code>PluginClassLoader</code>. */ public PluginClassLoader(ClassLoader parent) { super(parent); } /** * Attempt to load the class named by <code>className</code>, first * by delegating to the parent class loader and then by trying each * of the OSGi bundles available to this plugin. * * @throws ClassNotFoundException If the class is not successfully loaded. */ protected Class<?> findClass(String className) throws ClassNotFoundException { try { return super.findClass(className); } catch (ClassNotFoundException e) { Bundle[] bundles = MonitoringPlugin.getInstance().getBundles(); // Look for the class from the bundles. for (int i = 0; i < bundles.length; ++i) { try { return bundles[i].loadClass(className); } catch (ClassNotFoundException e2) { // keep looking } } // Didn't find the class anywhere, rethrow e. throw e; } } } -David |
From: annegrl <an...@ya...> - 2007-10-01 16:59:44
|
Thanks David, this is a huge help. This application is plug-in based, and the plugin that is actually calling the jython code was the one that couldn't be found (before I created the test scenario)--based on your response, I would guess that this plugins classloader would look for its own classes differently. So I'm trying out my own classloader as you suggested. Iin this line, how do you get an array of all the bundles? I'm looking through the eclipse API, but it's not popping out at me (a bit new to eclipse also!) >> Bundle[] bundles = MonitoringPlugin.getInstance().getBundles(); Thanks again! anne -- View this message in context: http://www.nabble.com/Cannot-import-name...but-jar-in-classpath-tf4546539.html#a12983127 Sent from the jython-dev mailing list archive at Nabble.com. |
From: annegrl <an...@ya...> - 2007-10-01 22:51:03
|
Just to update since this was continued via emails...I was able to resolve my problem with all the great help on here, especially David. Here are some more details about getting this to work. A bundleContext is passed in to a plugin's start method. BundleContext.getBundles() returns a Bundle[] to determine all the applicable bundles. To use the PySystemState's new class loader, you can do something like this: PySystemState state = new PySystemState(); ClassLoader pluginLoader = new PluginClassLoader(Thread.currentThread().getContextClassLoader()); state.setClassLoader(pluginLoader); PythonInterpreter interpreter = new PythonInterpreter(null, state); -- View this message in context: http://www.nabble.com/Cannot-import-name...but-jar-in-classpath-tf4546539.html#a12989632 Sent from the jython-dev mailing list archive at Nabble.com. |