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

Reply via email to