diff -r f4a20d4f27c8 src/org/armedbear/lisp/Lisp.java
--- a/src/org/armedbear/lisp/Lisp.java	Fri Aug 28 12:55:00 2009 +0200
+++ b/src/org/armedbear/lisp/Lisp.java	Sun Aug 30 00:58:47 2009 +0200
@@ -39,6 +39,7 @@
 import java.io.InputStream;
 import java.lang.reflect.Constructor;
 import java.math.BigInteger;
+import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLDecoder;
 import java.util.Hashtable;
@@ -1074,8 +1075,20 @@
       }
     if (device instanceof Pathname)
       {
-        // We're loading a fasl from j.jar.
+        // Are we loading a fasl from j.jar?  
+        // XXX this will collide with file names from other JAR files
         URL url = Lisp.class.getResource(namestring);
+        if (url == null) {
+          // Maybe device-->namestring references another JAR file?
+          String jarFile = ((Pathname)device).getNamestring();
+          if (jarFile.startsWith("jar:file:")) {
+            try {
+              url = new URL(jarFile + "!/" + namestring);
+            } catch (MalformedURLException ex) {
+              Debug.trace(ex);
+            }
+          }
+        }
         if (url != null)
           {
             try
@@ -1111,6 +1124,20 @@
                                 LispObject obj = loadCompiledFunction(in, (int) size);
                                 return obj != null ? obj : NIL;
                               }
+                            else 
+                              {
+                                // ASSERT type = "abcl"
+                                entryName 
+                                  = defaultPathname.name.getStringValue() 
+                                  + "." +  "abcl";//defaultPathname.type.getStringValue();
+				byte in[] 
+				  = Utilities
+				  .getZippedZipEntryAsByteArray(zipFile, 
+								entryName,
+								namestring);
+				LispObject o = loadCompiledFunction(in);
+				return o != null ? o : NIL;
+                              }
                           }
                         finally
                           {
diff -r f4a20d4f27c8 src/org/armedbear/lisp/Load.java
--- a/src/org/armedbear/lisp/Load.java	Fri Aug 28 12:55:00 2009 +0200
+++ b/src/org/armedbear/lisp/Load.java	Sun Aug 30 00:58:47 2009 +0200
@@ -33,6 +33,8 @@
 
 package org.armedbear.lisp;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
@@ -43,6 +45,7 @@
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipException;
 import java.util.zip.ZipFile;
+import java.util.zip.ZipInputStream;
 
 public final class Load extends Lisp
 {
@@ -103,47 +106,94 @@
 					boolean returnLastResult)
         throws ConditionThrowable
     {
-	String dir = null;
+        InputStream in = null;
+        String zipFileName = null;
+        String zipEntryName = null;
+        String dir = null;
+
         if (!Utilities.isFilenameAbsolute(filename)) {
-	    dir =
-                coerceToPathname(Symbol.DEFAULT_PATHNAME_DEFAULTS.symbolValue()).getNamestring();
+            dir = coerceToPathname(Symbol.DEFAULT_PATHNAME_DEFAULTS.symbolValue()).getNamestring();
         }
 
-	File file = findLoadableFile(filename, dir);
-        if (file == null) {
+        // attempt to load from a jar file
+        if (filename.startsWith("jar:file:")) {
+            String s = new String(filename);
+            s = s.substring(9);
+            int index = s.lastIndexOf('!');
+            if (index >= 0) {
+                zipFileName = s.substring(0, index);
+                zipEntryName = s.substring(index + 1);
+                if (zipEntryName.length() > 0 && zipEntryName.charAt(0) == '/')
+                    zipEntryName = zipEntryName.substring(1);
+                if (Utilities.isPlatformWindows) {
+                    if (zipFileName.length() > 0 && zipFileName.charAt(0) == '/')
+                        zipFileName = zipFileName.substring(1);
+                }
+            }
+        }
+
+        File file = findLoadableFile(filename, dir);
+        if (null == file && null == zipFileName) {
             if (ifDoesNotExist)
-                return error(new FileError("File not found: " + filename,
-                                            pathname));
+                return error(new FileError("File not found: " + filename, pathname));
             else
                 return NIL;
         }
+        if (checkZipFile(file)) {
+            zipFileName = file.getPath();
+            zipEntryName = file.getName();
+        }
+        
+        String truename = filename;
+        ZipFile zipfile = null;
 
-	filename = file.getPath();
-        ZipFile zipfile = null;
-        if (checkZipFile(file))
-        {
+        if (zipFileName != null) {
             try {
-                zipfile = ZipCache.getZip(file.getPath());
+                zipfile = ZipCache.getZip(zipFileName);
             }
             catch (Throwable t) {
-                // Fall through.
+                return error (new FileError("Zip file not found: " + filename, pathname));
             }
-        }
-        String truename = filename;
-        InputStream in = null;
-        if (zipfile != null) {
-            String name = file.getName();
-            int index = name.lastIndexOf('.');
-            Debug.assertTrue(index >= 0);
-            name = name.substring(0, index).concat("._");
-            ZipEntry entry = zipfile.getEntry(name);
-            if (entry != null) {
-                try {
+            ZipEntry entry = zipfile.getEntry(zipEntryName);
+            if (null == entry) {
+                // try appending "._" to base filename
+                int index = zipEntryName.lastIndexOf('.');
+                if (-1 == index) index = zipEntryName.length();
+                zipEntryName = zipEntryName.substring(0, index).concat("._");
+                entry = zipfile.getEntry(zipEntryName);
+            }
+            if (null == entry) {
+                // try appending ".abcl" to base filename
+                int index = zipEntryName.lastIndexOf('.');
+                if (index == -1)
+                  index = zipEntryName.length();
+                zipEntryName = zipEntryName.substring(0, index).concat(".abcl");
+                entry = zipfile.getEntry(zipEntryName);
+		if (entry == null) {
+		  return error(new LispError("Failed to find " + zipEntryName + " in "
+					     + zipFileName + "."));
+		}
+		
+                // Now we have to seek for the ._ file
+                int i = zipEntryName.lastIndexOf('.');
+                String subZipEntryName = zipEntryName.substring(0, i).concat("._");
+		in = Utilities.getZippedZipEntryAsInputStream(zipfile, 
+							      zipEntryName, 
+							      subZipEntryName);
+
+		// XXX Help out the truename loading
+		// truename += ".abcl";
+            }
+            if (null == entry) {
+                return error(new FileError("Can't read zip file entry " + zipEntryName, pathname));
+            }
+            try {
+                if (in == null) {
                     in = zipfile.getInputStream(entry);
                 }
-                catch (IOException e) {
-                    return error(new LispError(e.getMessage()));
-                }
+            }
+            catch (IOException e) {
+                return error(new LispError(e.getMessage()));
             }
         } else {
             try {
@@ -162,7 +212,8 @@
             }
         }
         try {
-            return loadFileFromStream(null, truename,
+
+          return loadFileFromStream(null, truename,
                                       new Stream(in, Symbol.CHARACTER),
                                       verbose, print, false, returnLastResult);
         }
diff -r f4a20d4f27c8 src/org/armedbear/lisp/Utilities.java
--- a/src/org/armedbear/lisp/Utilities.java	Fri Aug 28 12:55:00 2009 +0200
+++ b/src/org/armedbear/lisp/Utilities.java	Sun Aug 30 00:58:47 2009 +0200
@@ -33,8 +33,14 @@
 
 package org.armedbear.lisp;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipInputStream;
 
 public final class Utilities extends Lisp
 {
@@ -115,4 +121,60 @@
             return null;
         }
     }
+    
+    public static byte[] getZippedZipEntryAsByteArray(ZipFile zipfile,
+                                                      String entryName,
+                                                      String subEntryName) 
+      throws ConditionThrowable 
+  {
+      ZipEntry entry = zipfile.getEntry(entryName);
+      
+      ZipInputStream stream = null;
+      try {
+          stream = new ZipInputStream(zipfile.getInputStream(entry));
+      } 
+      catch (IOException e) {
+          Lisp.error(new FileError("Failed to open '" + entryName + "' in zipfile '"
+                                   + zipfile + "': " + e.getMessage()));
+      }
+      //  XXX Cache the zipEntries somehow
+      do {
+          try { 
+              entry = stream.getNextEntry();
+          } catch (IOException e){
+              Lisp.error(new FileError("Failed to seek for '" + subEntryName 
+                                       + "' in '" 
+                                       + zipfile.getName() + ":" + entryName + ".:"
+                                       + e.getMessage()));
+          }
+      } while (!entry.getName().equals(subEntryName));
+      
+      ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+        int count;
+        byte buf[] = new byte[1024];
+        try {
+            while ((count = stream.read(buf, 0, buf.length)) != -1) {
+                buffer.write(buf, 0, count);
+            }
+        } catch (java.io.IOException e) {
+          Lisp.error(new FileError("Failed to read compressed '"
+                                   + subEntryName 
+                                   + "' in '" 
+                                   + zipfile.getName() + ":" + entryName + ":"
+                                   + e.getMessage()));
+        }
+        return buffer.toByteArray();
+    }
+    
+    public static InputStream getZippedZipEntryAsInputStream(ZipFile zipfile,
+                                                             String entryName,
+                                                             String subEntryName) 
+      throws ConditionThrowable
+  {
+        return 
+            new ByteArrayInputStream(Utilities
+                                     .getZippedZipEntryAsByteArray(zipfile, entryName, 
+                                                                   subEntryName));
+  }
 }
+
