|
From: Phil S. <phi...@is...> - 2001-12-23 22:17:47
|
On Saturday 22 December 2001 03:15 pm, Finn Bock wrote:
> [Phil Surette]
>
> >I submitted a patch to support this to jython-dev a while back.
>
> I'm sorry that I didn't reply to you back then.
>
No problem.
> >After poking through the jython code, I found that this patch to
> >org/jython/core/imp.java in jython-2.1a3 does the trick:
> >imp.java
> >498a499,502
> >
> >> //if it's not a builtin or in the python path, try the classpath
> >> ret = loadFromClassLoader(name, imp.class.getClassLoader());
> >> if (ret != null) return ret;
>
> It isn't general enough and it doesn't work.
>
> It can only import top-level modules. Modules in packages can't be
> imported. That can be fixed by enabling the snippet in PyModule that is
> commented out.
>
Uncomment? :)
> Other issues with the patch are:
>
> - Only support for .py files. That is too slow for a general solution.
Okay. Would it be hard to get it to load from .class files as well? Or
is that not the issue?
> - Setting __path__ to None to signal classloader is probably OK for a
> specialized solution, but we have to come up with something more
> general.
> - The classloader is hardcoded. Eventually a user want to put the python
> modules into a .jar loaded by another classloader.
>
Agreed. My main motivation is to be able to create a jython jar with
the python modules in it and carry that around as a complete unit.
I just want to be able to go java -jar jython.jar and in this case
everything is in the system classloader.
The problem I wanted to solve is now solved with -Dpython.path
/path/to/jar/python/subpath command-line option. Perhaps that
option was always there, but it's not obvious (better now that
the ! was replaced with a /). Anyway, it unfortunately does not
solve Duane's problem.
> All in all, more though have to go into this. We also want to
> restructure the "imp" code a bit. At the moment a lot of logic is
> duplicated in loadFromZipFile and loadFromPath. The loadFromClassLoader
> method will eventually contain the same logic one more time.
>
> I understand the desire for this feature, I just don't think we are able
> to add it the Right Way in version 2.1.
>
I'm glad to hear that you understand the desire for the feature!
>
> Instead we could maybe make the loadFromClassLoader() method public and
> suggest that embedding user temporarily use the hack below to load
> python modules from their classloader. The hack must be explicit enabled
> with a call like this:
>
> org.python.util.ClassLoaderImport.install()
>
> Comments?
>
First, if I understand the code correctly, the classloader would take
precedence over the python.path. Since the python.path is specific
to python, IMO python.path should take precedence over the
classloader for loading python modules. I.e. you
should try to delegate to the importer before trying the classloader.
[There should probably be a registry setting for this!]
As to which classloader to use, I agree with you that it is bad
to have the classlader hardcoded to imp's classloader. In
java 2 environments maybe some combination like, try
the context classloader, then the system classloader, then
imp's classloader, would work. I haven't thought through the
proper order. Probably it should be configurable.
I'd like to be able to enable the hack from the registry. Then, if I
read the documentation on the registry correctly, you could
add a registry to jython.jar with the appropriate property enabled
and you're away. The property name could be 'allowImportFromClassloader'
and there could be related properties like
'classloaderImportPrecedence=context,system,class'.
I realize I'm suggesting a lot of registry settings and I have no
idea how much work this would be. But I would say that
if adding these settings is too much for 2.1, then
just leave classloading until until there is time to do it right.
Thanks, finn, for taking an interest in this issue!
By the way, I am still planning to submit some ant/jython
tasks to this group, and should actually have time
to do it between Christmas and New Year's.
> regards,
> finn
>
>
> package org.python.util;
>
> import org.python.core.*;
>
> public class ClassLoaderImport extends PyObject {
> PyObject importer;
>
> ClassLoaderImport(PyObject importer) {
> this.importer = importer;
> }
>
> public PyObject __call__(PyObject args[], String keywords[]) {
> if (!(args.length < 1 || args[0] instanceof PyString))
> throw Py.TypeError("first argument must be a string");
> if (keywords.length > 0)
> throw Py.TypeError("__import__() takes no keyword "+
> "arguments");
>
> int argc = args.length;
> String module = args[0].__str__().toString();
>
> PyObject globals = (argc > 1 && args[1] != null)
> ? args[1] : null;
> PyObject fromlist = (argc > 3 && args[3] != null)
> ? args[3] : Py.EmptyTuple;
>
> System.out.println("module:" + module);
> PyObject ret = imp.loadFromClassLoader(module,
>
> imp.class.getClassLoader());
> if (ret != null)
> return ret;
>
> return importer.__call__(args, keywords);
> }
>
>
> public static void install() {
> PyObject builtin = Py.getSystemState().modules.
> __finditem__("__builtin__");
> PyObject importer = builtin.__getattr__("__import__");
> builtin.__setattr__("__import__",
> new ClassLoaderImport(importer));
> }
> }
>
>
> _______________________________________________
> Jython-dev mailing list
> Jyt...@li...
> https://lists.sourceforge.net/lists/listinfo/jython-dev
--
Phil Surette
phi...@is...
phi...@ya...
psu...@es...
|