cont... Take in consideration /** Hashtable of URLClassLoaders for each of the jars loaded */ private Hashtable<String, URLClassLoader> classLoaders;
Here's an example: org.python.core.PySystemState pySys = new org.python.core.PySystemState(); //classLoaders is a set that refers to a bunch of URLClassLoader objects pySys.setClassLoader(((URLClassLoader) classLoaders.get(jarFile))); //We also have to pass the jar to JYTHON_PATH (sys.path) //so that it can properly import inner python modules. pySys.path.insert(0,new PyString(jarFile)); //We pass the PythonInterpreter the modified PySystemState PythonInterpreter i = new PythonInterpreter (null, pySys); i.exec(pythonScriptName); Here's my method to create a classLoader that has a jarFile in its classpath: /** * Adds a given Jar to the Classpath. * Jython uses both classloaders, and it's JYTHONPATH (sys.path) * The classloaders help it find Java classes, in this case inside the jar * that contains the plugin. * * @param jarFile * * Where jarFile is the path (String) to the jarFile. * * I won't delete it though, in case it might be needed to load resources from * the jar. However, I believe the adition to the sys.path of jython will be enough. */ public void addJar2Classpath(String jarFile) throws Exception { if (jarFile == null) throw new Exception("PluginLoader.addJar2Classpath() - the jar file path can't be null"); File f = new File(jarFile); if (!f.exists()) { LOG.error("Jar doesn't exist ("+jarFile+")"); throw new Exception("PluginLoader.addJar2Classpath() - The jar file doesn't exist ("+ jarFile +")"); } URL jarURL = null; try { jarURL = new URL("jar:file:"+jarFile+"!/"); //jarURL = f.toURI().toURL(); LOG.info("The jar as an url " + jarURL); } catch (Exception e) { LOG.error("Bad URL for jar ("+jarFile+"):\n"+e.toString() +" ("+jarURL+")\n"); return; } if (loadedJar(jarURL)) { LOG.info("Jar was already loaded ("+jarURL+")"); return; } synchronized (classLoaders) { getLoadedJars().add((URL) jarURL); } //Create a new class loader for this jar. classLoaders.put(jarFile, URLClassLoader.newInstance(new URL[] {jarURL})); LOG.info("Jar loaded ("+jarURL+")"); } //addJar2Classpath So if we had a Jar like this: M Filemode Length Date Time File - ---------- -------- ----------- -------- ------------------------------------- drwxrwxrwx 0 3-Dec-2008 12:46:22 meta-inf/ -rw-rw-rw- 71 3-Dec-2008 12:46:22 meta-inf/manifest.mf drwxrwxrwx 0 3-Dec-2008 12:46:22 twoScriptsTest/com/ -rw-rw-rw- 491 3-Dec-2008 12:46:22 twoScriptsTest/com/ HelloFromJar.class drwxrwxrwx 0 3-Dec-2008 12:46:18 twoScriptsTest/guba/ -rw-rw-rw- 0 3-Dec-2008 06:24:22 twoScriptsTest/guba/ __init__.py -rw-rw-rw- 959 3-Dec-2008 12:46:18 twoScriptsTest/guba/ test.py -rw-rw-rw- 124 2-Dec-2008 17:50:56 twoScriptsTest/guba/ pleaseWork.py -rw-rw-rw- 0 3-Dec-2008 12:29:56 twoScriptsTest/ __init__.py - ---------- -------- ----------- -------- ------------------------------------- When we executed: i.exec("from guba import test") if test.py had this code, it'd work perfectly: #Import and use the Java Object inside the jar from com import HelloFromJar h = HelloFromJar() h.sayHello() #Import the other python module inside the jar from pleaseWork import echo echo("FrostWire") NOTE: It's very important that you have the __init__.py on the folders otherwise Jython won't find the modules. On Dec 3, 12:54 pm, Gubatron <[EMAIL PROTECTED]> wrote: > I've managed to solve this problem. > > I can now run a python script that lives inside a Jar. The python > script is now able to import other scripts within the same jar, and > it's also able to import java classes that live within the jar. > > The problem was solved by giving the Jython Interpreter the proper > initialization. This entails: > > - Giving it a class loader that has put the Jar on it's class path > - Adding the path of the jar to the interpreter's sys.path > > Here's an example: > > org.python.core.PySystemState pySys = new > org.python.core.PySystemState(); > pySys.setClassLoader(((URLClassLoader) > classLoaders.get(jarFile))); > > //We also have to pass the jar to JYTHON_PATH > (sys.path) > //so that it can properly import inner python modules. > pySys.path.insert(0,new PyString(jarFile)); > > //We pass the PythonInterpreter the modified > PySystemState > PythonInterpreter i = new PythonInterpreter(null, > pySys); > i.exec(pythonScriptName); > > On Dec 3, 6:31 am, Gubatron <[EMAIL PROTECTED]> wrote: > > > Hello all, > > > I've a problem with Jython and importing .py inside a jar. > > > I'm putting .class and .py files inside .jar files. > > > myjar.jar > > MyJar\SomeClass.class > > MyJar\main.py > > MyJar\otherModule.py > > > So I add the myjar.jar to Jython's sys.path > > > org.python.core.PySystemState pySys = new > > org.python.core.PySystemState(); > > pySys.path.insert(0,new > > PyString("/path/to/myjar.jar")); > > > and execute main.py > > > //We pass the PythonInterpreter the modified > > PySystemState > > PythonInterpreter i = new PythonInterpreter(null, > > pySys); > > > //Find the entry in the jar for the python file and > > execute it. > > //It should be able to find any resource inside the > > jar. > > JarFile jFile = new JarFile("/path/to/myjar.jar"); > > ZipEntry zipEntry = jFile.getEntry("MyJar/main.py"); > > > InputStream pythonInputStream = > > jFile.getInputStream(zipEntry); > > i.execfile(pythonInputStream); > > > main.py will execute fine, it'll be able to do > > > from MyJar import SomeClass > > > with no problem > > > However, If I try to import the other .py in the same jar, it won't > > find it: > > > from otherModule import * > > > or > > > from MyJar.otherModule import * > > > I always get this: > > > ImportError: no module named otherModule > > > at org.python.core.Py.ImportError(Unknown Source) > > at org.python.core.imp.import_first(Unknown Source) > > at org.python.core.imp.import_name(Unknown Source) > > at org.python.core.imp.importName(Unknown Source) > > at org.python.core.ImportFunction.load(Unknown Source) > > at org.python.core.ImportFunction.__call__(Unknown Source) > > at org.python.core.PyObject.__call__(Unknown Source) > > at org.python.core.__builtin__.__import__(Unknown Source) > > at org.python.core.imp.importFromAs(Unknown Source) > > at org.python.core.imp.importFrom(Unknown Source) > > at org.python.pycode._pyx1.f$0(<iostream>:26) > > at org.python.pycode._pyx1.call_function(<iostream>) > > at org.python.core.PyTableCode.call(Unknown Source) > > at org.python.core.PyCode.call(Unknown Source) > > at org.python.core.Py.runCode(Unknown Source) > > at org.python.util.PythonInterpreter.execfile(Unknown Source) > > > I've tried adding more paths to sys.path, with no luck: > > > pySys.path.insert(0,new PyString("/path/to/myjar.jar/MyJar")); > > pySys.path.insert(0,new PyString("file:jar:/path/to/myjar.jar!")); > > > and nothing works, any ideas would help. I know this has to work, > > because I previously had a problem where I couldn't do > > > import os > > > and then I added the "Lib/" folder inside jython.jar and now I'm able > > to import all those standard jython modules, so, somehow, jython is > > able to import .py within a .jar, help would be very much appreciated. > > > Angel Leon > > -- http://mail.python.org/mailman/listinfo/python-list