Skip to content

Commit

Permalink
Fix for http://bugs.jython.org/issue1239. When jars where added to sy…
Browse files Browse the repository at this point in the history
…s.path,

they did not always trigger package caching, leading to unexpected import
failures.  This is Charlie Grove's fix, which was much better than mine.
  • Loading branch information
fwierzbicki committed Jan 22, 2009
1 parent 55dbb1f commit dafb389
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 65 deletions.
Binary file added Lib/test/bug1239.jar
Binary file not shown.
11 changes: 11 additions & 0 deletions Lib/test/test_classpathimporter.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@ def test_path_in_pyclasspath(self):
sys.path = ['__pyclasspath__/Lib']
self.setClassLoaderAndCheck("classimport_Lib.jar", "__pyclasspath__/Lib")

# I don't like the checked in jar file bug1239.jar. The *one* thing I
# liked about the tests in bugtests/ is that you could create a java file,
# compile it, jar it and destroy the jar when done. Maybe when we move to
# JDK 6 and can use JSR-199 to do runtime compiling, we can go back to
# that. Anyway, see http://bugs.jython.org/issue1239. In short, jars added
# with sys.path.append where not getting scanned if they start with a top
# level package we already have, like the "org" in org.python.*
def test_bug1239(self):
sys.path.append("Lib/test/bug1239.jar")
import org.test403javapackage.test403

def test_main():
test_support.run_unittest(ClasspathImporterTestCase)

Expand Down
85 changes: 49 additions & 36 deletions src/org/python/core/SyspathJavaLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public InputStream getResourceAsStream(String res) {

PyList path = sys.path;
for (int i = 0; i < path.__len__(); i++) {
PyObject entry = path.__getitem__(i);
PyObject entry = replacePathItem(sys, i, path);
if (entry instanceof SyspathArchive) {
SyspathArchive archive = (SyspathArchive) entry;
ZipEntry ze = archive.getEntry(entryRes);
Expand All @@ -65,8 +65,7 @@ public InputStream getResourceAsStream(String res) {
}
String dir = sys.getPath(entry.__str__().toString());
try {
return new BufferedInputStream(new FileInputStream(new File(
dir, res)));
return new BufferedInputStream(new FileInputStream(new File(dir, res)));
} catch (IOException e) {
continue;
}
Expand All @@ -75,11 +74,28 @@ public InputStream getResourceAsStream(String res) {
return null;
}

static PyObject replacePathItem(PySystemState sys, int idx, PyList paths) {
PyObject path = paths.__getitem__(idx);
if (path instanceof SyspathArchive) {
// already an archive
return path;
}

try {
// this has the side affect of adding the jar to the PackageManager during the
// initialization of the SyspathArchive
path = new SyspathArchive(sys.getPath(path.toString()));
} catch (Exception e) {
return path;
}
paths.__setitem__(idx, path);
return path;
}

// override from abstract base class
protected Class loadClass(String name, boolean resolve)
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException {
// First, if the Python runtime system has a default class loader,
// defer to it.
// First, if the Python runtime system has a default class loader, defer to it.
PySystemState sys = Py.getSystemState();
ClassLoader classLoader = sys.getClassLoader();
if (classLoader != null) {
Expand All @@ -97,43 +113,42 @@ protected Class loadClass(String name, boolean resolve)
return Class.forName(name, true, ClassLoader.getSystemClassLoader());
} catch(ClassNotFoundException e) {}

Class c = findLoadedClass(name);
Class<?> c = findLoadedClass(name);
if(c != null) {
return c;
}

PyList path = sys.path;
for(int i = 0; i < path.__len__(); i++) {
InputStream fis = null;
File file = null;
int size = 0;
PyObject entry = path.__getitem__(i);

InputStream fis;
int size;
PyObject entry = replacePathItem(sys, i, path);
if(entry instanceof SyspathArchive) {
SyspathArchive archive = (SyspathArchive)entry;
String entryname = name.replace('.', SLASH_CHAR) + ".class";
ZipEntry ze = archive.getEntry(entryname);
if(ze != null) {
try {
fis = archive.getInputStream(ze);
size = (int)ze.getSize();
} catch(IOException exc) {
;
}
if(ze == null) {
continue;
}
try {
fis = archive.getInputStream(ze);
size = (int)ze.getSize();
} catch (IOException exc) {
continue;
}
} else {
String dir = entry.__str__().toString();
file = getFile(dir, name);
if(file != null) {
size = (int)file.length();
try {
fis = new FileInputStream(file);
} catch(FileNotFoundException e) {
;
}
File file = getFile(dir, name);
if (file == null) {
continue;
}
size = (int)file.length();
try {
fis = new FileInputStream(file);
} catch (FileNotFoundException e) {
continue;
}
}
if(fis == null) {
continue;
}
try {
byte[] buffer = new byte[size];
Expand All @@ -143,14 +158,12 @@ protected Class loadClass(String name, boolean resolve)
}
fis.close();
return loadClassFromBytes(name, buffer);
} catch(IOException e) {
continue;
} catch (IOException e) {

} finally {
try {
fis.close();
} catch(IOException e) {
continue;
}
} catch (IOException e) {}
}
}

Expand All @@ -173,9 +186,9 @@ private File getFile(String dir, String name) {
return new RelativeFile(dir, accum + ".class");
}

private Class loadClassFromBytes(String name, byte[] data) {
private Class<?> loadClassFromBytes(String name, byte[] data) {
// System.err.println("loadClassFromBytes("+name+", byte[])");
Class c = defineClass(name, data, 0, data.length);
Class<?> c = defineClass(name, data, 0, data.length);
resolveClass(c);
Compiler.compileClass(c);
return c;
Expand Down
29 changes: 0 additions & 29 deletions src/org/python/core/imp.java
Original file line number Diff line number Diff line change
Expand Up @@ -318,41 +318,12 @@ static PyObject getPathImporter(PyObject cache, PyList hooks, PyObject p) {
return importer;
}

static PyObject replacePathItem(PySystemState sys, PyObject path) {
if (path instanceof SyspathArchive) {
// already an archive
return null;
}

try {
// this has the side affect of adding the jar to the PackageManager
// during the initialization of the SyspathArchive
return new SyspathArchive(sys.getPath(path.toString()));
} catch (Exception e) {
return null;
}
}

static PyObject find_module(String name, String moduleName, PyList path) {

PyObject loader = Py.None;
PySystemState sys = Py.getSystemState();
PyObject metaPath = sys.meta_path;

/*
* Needed to convert all entries on the path to SyspathArchives if
* necessary.
*/
PyList ppath = path == null ? sys.path : path;
for (int i = 0; i < ppath.__len__(); i++) {
PyObject p = ppath.__getitem__(i);
PyObject q = replacePathItem(sys, p);
if (q == null) {
continue;
}
ppath.__setitem__(i, q);
}

for (PyObject importer : metaPath.asIterable()) {
PyObject findModule = importer.__getattr__("find_module");
loader = findModule.__call__(new PyObject[] {
Expand Down

0 comments on commit dafb389

Please sign in to comment.