Index: org/python/core/SyspathArchive.java =================================================================== --- org/python/core/SyspathArchive.java (revision 4148) +++ org/python/core/SyspathArchive.java (working copy) @@ -23,6 +23,10 @@ this.zipFile = zipFile; } + public String getName() { + return zipFile.getName(); + } + static String getArchiveName(String dir) { String lowerName = dir.toLowerCase(); int idx = lowerName.indexOf(".zip"); Index: org/python/core/SyspathJavaLoader.java =================================================================== --- org/python/core/SyspathJavaLoader.java (revision 4148) +++ org/python/core/SyspathJavaLoader.java (working copy) @@ -12,11 +12,84 @@ import java.util.StringTokenizer; import java.util.zip.ZipEntry; +import java.util.Enumeration; +import java.util.Vector; +import java.net.URL; +import java.net.MalformedURLException; + import org.python.core.util.RelativeFile; public class SyspathJavaLoader extends ClassLoader { private static final char SLASH_CHAR = '/'; + + public URL findResource(String name) { + PySystemState sys = Py.getSystemState(); + + for (int i = 0; i < sys.path.__len__(); i++) { + PyObject entry = sys.path.__getitem__(i); + if (entry instanceof SyspathArchive) { + SyspathArchive archive = (SyspathArchive) entry; + ZipEntry zipEntry = archive.getEntry(name); + if (zipEntry != null) { + /* probably not quite right */ + File testFile = new File(archive.getName()); + if (testFile.isFile() || testFile.isDirectory()) { + try { + return new URL("jar:" + testFile.toURL() + "!/" + zipEntry.getName()); + } catch (MalformedURLException e) { + throw Py.ValueError(e.getMessage()); + } + } + } + } else { + File testFile = new File(entry.__str__().toString(), name); + if (testFile.isFile() || testFile.isDirectory()) { + try { + return testFile.toURL(); + } catch (MalformedURLException e) { + throw Py.ValueError(e.getMessage()); + } + } + } + } + return null; + } + + public Enumeration findResources(String name) { + PySystemState sys = Py.getSystemState(); + final Vector resources = new Vector(); + + for (int i = 0; i < sys.path.__len__(); i++) { + PyObject entry = sys.path.__getitem__(i); + if (entry instanceof SyspathArchive) { + SyspathArchive archive = (SyspathArchive) entry; + ZipEntry zipEntry = archive.getEntry(name); + if (zipEntry != null) { + /* probably not quite right, so skip for now */ + File testFile = new File(archive.getName()); + if (testFile.isFile() || testFile.isDirectory()) { + try { + resources.add(new URL("jar:" + testFile.toURL() + "!/" + zipEntry.getName())); + } catch (MalformedURLException e) { + throw Py.ValueError(e.getMessage()); + } + } + } + } else { + File testFile = new File(entry.__str__().toString(), name); + if (testFile.isFile() || testFile.isDirectory()) { + try { + resources.add(testFile.toURL()); + } catch (MalformedURLException e) { + throw Py.ValueError(e.getMessage()); + } + } + } + } + + return resources.elements(); + } public InputStream getResourceAsStream(String res) { Py.writeDebug("resource", "trying resource: " + res); @@ -81,10 +154,11 @@ // First, if the Python runtime system has a default class loader, // defer to it. PySystemState sys = Py.getSystemState(); + // I think we should override findClass and not loadClass... ClassLoader classLoader = sys.getClassLoader(); if (classLoader != null) { return classLoader.loadClass(name); - } + } // Search the sys.path for a .class file matching the named class. try { @@ -136,6 +210,18 @@ nread += fis.read(buffer, nread, size - nread); } fis.close(); + + // From the GNU ClassLoader impl docs + int lastDot = name.lastIndexOf('.'); + if (lastDot != -1) { + String packageName = name.substring(0, lastDot); + // Look if the package already exists + if (getPackage(packageName) == null) { + // define the package + definePackage(packageName, null, null, null, null, null, null, null); + } + } + return loadClassFromBytes(name, buffer); } catch(IOException e) { continue;