[armedbear-cvs] r12524 - trunk/abcl/src/org/armedbear/lisp

Mark Evenson mevenson at common-lisp.net
Thu Mar 11 15:49:09 UTC 2010


Author: mevenson
Date: Thu Mar 11 10:49:05 2010
New Revision: 12524

Log:
Enable ABCL to load in an OSGi context.

OSGi abstracts the loading of resources via the "bundle:" URI schema,
providing a custom URLProtocolHandler implementation.  Unfortunately,
since these references cannot be handled by ABCL pathnames, the newly
revised logic for our FASL loading strategy breaks down.  This patch
kludingly addresses this issue to the point that ABCL can be loaded by
reference in an OSGi bundle, but should be revised when a correct
implementation strategy is decided upon.



Modified:
   trunk/abcl/src/org/armedbear/lisp/Debug.java
   trunk/abcl/src/org/armedbear/lisp/Lisp.java
   trunk/abcl/src/org/armedbear/lisp/Load.java
   trunk/abcl/src/org/armedbear/lisp/Pathname.java
   trunk/abcl/src/org/armedbear/lisp/Site.java

Modified: trunk/abcl/src/org/armedbear/lisp/Debug.java
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/Debug.java	(original)
+++ trunk/abcl/src/org/armedbear/lisp/Debug.java	Thu Mar 11 10:49:05 2010
@@ -41,8 +41,9 @@
     public static final void assertTrue(boolean b)
     {
         if (!b) {
-            System.err.println("Assertion failed!");
-            Error e = new Error();
+            String msg = "ABCL Debug.assertTrue() assertion failed!";
+            System.err.println(msg);
+            Error e = new Error(msg);
             e.printStackTrace();
             throw e;
         }

Modified: trunk/abcl/src/org/armedbear/lisp/Lisp.java
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/Lisp.java	(original)
+++ trunk/abcl/src/org/armedbear/lisp/Lisp.java	Thu Mar 11 10:49:05 2010
@@ -1226,16 +1226,32 @@
       } else if (truename instanceof Pathname) {
           load = Pathname.mergePathnames(name, (Pathname) truename, Keyword.NEWEST);
       } else {
-          load = name;
+          if (!Pathname.truename(name).equals(NIL)) {
+              load = name;
+          } else {
+              load = null;
+          }
+      }
+      InputStream input = null;
+      if (load != null) {
+          input = load.getInputStream();
+      } else { 
+          // Make a last-ditch attempt to load from the boot classpath XXX OSGi hack
+          URL url = null;
+          try {
+              url = Lisp.class.getResource(name.getNamestring());
+              input = url.openStream();
+          } catch (IOException e) {
+              error(new LispError("Failed to read class bytes from boot class " + url));
+          }
       }
-      InputStream input = load.getInputStream();
       byte[] bytes = new byte[4096];
       try {
           if (input == null) {
-              Debug.trace("Pathname: " + name);
-              Debug.trace("LOAD_TRUENAME_FASL: " + truenameFasl);
-              Debug.trace("LOAD_TRUENAME: " + truename);
-              Debug.assertTrue(input != null);
+                  Debug.trace("Pathname: " + name);
+                  Debug.trace("LOAD_TRUENAME_FASL: " + truenameFasl);
+                  Debug.trace("LOAD_TRUENAME: " + truename);
+                  Debug.assertTrue(input != null);
           }
 
           int n = 0;

Modified: trunk/abcl/src/org/armedbear/lisp/Load.java
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/Load.java	(original)
+++ trunk/abcl/src/org/armedbear/lisp/Load.java	Thu Mar 11 10:49:05 2010
@@ -252,12 +252,19 @@
         Pathname pathname = null;
         Pathname truename = null;
         pathname = new Pathname(filename);
-        Pathname mergedPathname = Pathname.mergePathnames(pathname, Site.getLispHome());
+        LispObject bootPath = Site.getLispHome();
+        Pathname mergedPathname;
+        if (bootPath instanceof Pathname) {
+            mergedPathname = Pathname.mergePathnames(pathname, (Pathname)bootPath);
+        } else {
+            mergedPathname = pathname;
+        }
+        URL url = null;
         truename = findLoadableFile(mergedPathname);
-        if (truename == null || truename.equals(NIL)) {
+        if (truename == null || truename.equals(NIL) || bootPath.equals(NIL)) {
             // Make an attempt to use the boot classpath
             String path = pathname.asEntryPath();
-            URL url = Lisp.class.getResource(path);
+            url = Lisp.class.getResource(path);
             if (url == null || url.toString().endsWith("/")) {
                 url = Lisp.class.getResource(path + ".abcl");
                 if (url == null) {
@@ -269,16 +276,21 @@
                                            + "'" + path + "'"
                                            + " in boot classpath."));
             }                
-            Pathname urlPathname = new Pathname(url);
-            truename = findLoadableFile(urlPathname);
-            if (truename == null) {
-                return error(new LispError("Failed to find loadable system file in boot classpath "
-                                           + "'" + url + "'"));
+            if (!bootPath.equals(NIL)) {
+                Pathname urlPathname = new Pathname(url);
+                truename = findLoadableFile(urlPathname);
+                if (truename == null) {
+                    return error(new LispError("Failed to find loadable system file in boot classpath "
+                                               + "'" + url + "'"));
+                }
+            } else {
+                truename = null; // We can't represent the FASL in a Pathname (q.v. OSGi)
             }
         }
 
         // Look for a init FASL inside a packed FASL
-        if (truename.type.writeToString().equals(COMPILE_FILE_TYPE) && Utilities.checkZipFile(truename))  {
+        if (truename != null
+            && truename.type.writeToString().equals(COMPILE_FILE_TYPE) && Utilities.checkZipFile(truename))  {
             Pathname init = new Pathname(truename.getNamestring());
             init.type = COMPILE_FILE_INIT_FASL_TYPE;
             LispObject t = Pathname.truename(init);
@@ -290,7 +302,19 @@
             }
         }
 
-        in = truename.getInputStream();
+        if (truename != null) {
+            in = truename.getInputStream();
+        } else { 
+            try {
+                Debug.assertTrue(url != null);
+                in = url.openStream();
+            } catch (IOException e) {
+                error(new FileError("Failed to load system file: " 
+                                    + "'" + filename + "'"
+                                    + " from URL: " 
+                                    + "'" + url + "'"));
+            } 
+        }
 
         if (in != null) {
             final LispThread thread = LispThread.currentThread();
@@ -373,7 +397,9 @@
                                                        boolean print,
                                                        boolean auto)
         {
-        return loadFileFromStream(pathname, truename, in, verbose, print, auto, false);
+            return loadFileFromStream(pathname == null ? NIL : pathname, 
+                                      truename == null ? NIL : truename, 
+                                      in, verbose, print, auto, false);
     }
 
     // A nil TRUENAME signals a load from stream which has no possible path

Modified: trunk/abcl/src/org/armedbear/lisp/Pathname.java
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/Pathname.java	(original)
+++ trunk/abcl/src/org/armedbear/lisp/Pathname.java	Thu Mar 11 10:49:05 2010
@@ -151,8 +151,16 @@
         init(s);
     }
 
+    public static boolean isSupportedProtocol(String protocol) {
+        return "jar".equals(protocol) || "file".equals(protocol);
+    }
+
     public Pathname(URL url) {
         String protocol = url.getProtocol();
+        if (!isSupportedProtocol(protocol)) {
+            error(new LispError("Unsupported URL: '" + url.toString() + "'"));
+        }
+
         if ("jar".equals(protocol)) {
             init(url.toString());
             return;
@@ -181,7 +189,8 @@
                 return;
             }
         }
-        error(new LispError("Unsupported URL: '" + url.toString() + "'"));
+        error(new LispError("Failed to construct Pathname from URL: "
+                            + "'" + url.toString() + "'"));
     }
 
     static final private String jarSeparator = "!/";

Modified: trunk/abcl/src/org/armedbear/lisp/Site.java
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/Site.java	(original)
+++ trunk/abcl/src/org/armedbear/lisp/Site.java	Thu Mar 11 10:49:05 2010
@@ -42,31 +42,34 @@
 
 public final class Site
 {
-    private static Pathname LISP_HOME;
+    private static LispObject LISP_HOME;
 
     private static void init() {
         String s = System.getProperty("abcl.home");
         if (s != null) {
             String fileSeparator = System.getProperty("file.separator");
             if (!s.endsWith(fileSeparator)) {
-                s += fileSeparator;;
+                s += fileSeparator;
             }
             LISP_HOME = new Pathname(s);
-            return;
         }
         URL url = Lisp.class.getResource("boot.lisp");
         if (url != null) {
-            LISP_HOME = new Pathname(url);
-            LISP_HOME.name = NIL;
-            LISP_HOME.type = NIL;
-            LISP_HOME.invalidateNamestring();
+            if (!Pathname.isSupportedProtocol(url.getProtocol())) {
+                LISP_HOME = NIL;
+            } else {
+                Pathname p = new Pathname(url);
+                p.name = NIL;
+                p.type = NIL;
+                p.invalidateNamestring();
+                LISP_HOME = p;
+            }
             return;
         }
         Debug.trace("Unable to determine LISP_HOME.");
     }
 
-
-    public static final Pathname getLispHome()
+    public static final LispObject getLispHome()
     {
       if (LISP_HOME == null) {
         init();
@@ -79,7 +82,7 @@
         exportSpecial("*LISP-HOME*", PACKAGE_EXT, NIL);
 
     static {
-        Pathname p  = Site.getLispHome();
+        LispObject p  = Site.getLispHome();
         if (p != null)
             _LISP_HOME_.setSymbolValue(p);
     }




More information about the armedbear-cvs mailing list