-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Hello guys.
This is my first post on the list, and beg your forgiveness if this question was already answered, but alas, my search-fu was incapable of finding anything that could have helped me.
Here is my situation:
I am trying to build a servlet using ABCL. The servlet is a middleware that will expose an API, consume JSON, and return JSON. I will also store some data into a postgres RDBMS.
I've used the google-app-engine example as a basis to build a skeleton of my app, with a Java class providing a proxy for the servlet. If I don't use any dependencies on my project, everything runs ok. My problem is that I have the following system descriptor:
(asdf:defsystem #:abcl-servlet :serial t :description "An example of a servlet using the ABCL stack." :author "Eduardo Bellani ebellani@gmail.com" :license "Beerware v. 42" :depends-on (:jsown :postmodern) :components ((:module :src :components ((:file "package") (:file "servlet-interface")))))
As you can see, I have some dependencies on my code. Dependencies which I must load before my packages can run. I'm wondering how I can load this dependencies without explicitly coding the load calls. FWIWI, the java proxy class is here:
public class ServletProxy extends HttpServlet {
static private Symbol doGet = null; static private Symbol doPost = null; static private Symbol doDestroy = null; static private Object lock = new Object(); static private boolean initialized = false;
private static void doWithStreamsBound(Symbol whatToDo, HttpServletRequest req, HttpServletResponse resp) throws IOException { LispThread currentThread = LispThread.currentThread(); SpecialBindingsMark mark = currentThread.markSpecialBindings(); currentThread.bindSpecial(Symbol.STANDARD_OUTPUT, new Stream(Symbol.SYSTEM_STREAM, resp.getOutputStream(), Symbol.CHARACTER, false)); currentThread.bindSpecial(Symbol.STANDARD_INPUT, new Stream(Symbol.SYSTEM_STREAM, resp.getInputStream(), Symbol.CHARACTER, false)); try { currentThread.execute(whatToDo); } finally { currentThread.resetSpecialBindings(mark); } }
/** * Initialize the lisp interpreter that the symbols that will be * called on the lisp servlet interface. Not surprisingly, these * symbols mirror the HttpServlet interface. This is a result of * this class being only a proxy for the internal lisp system. */ public void init(ServletConfig config) throws ServletException { // No need for any external usage of theInit Symbol theInit = null; Interpreter.initializeLisp();
Load.load(config.getServletContext().getRealPath("fasls/first-servlet.abcl")); LispThread.currentThread(); doGet = Lisp.internInPackage("DO-GET", "SERVLET-INTERFACE"); doPost = Lisp.internInPackage("DO-POST", "SERVLET-INTERFACE"); theInit = Lisp.internInPackage("INIT", "SERVLET-INTERFACE"); theDestroy = Lisp.internInPackage("DESTROY", "SERVLET-INTERFACE"); }
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { ServletProxy.doWithStreamsBound(doGet, req, resp); } }
I'm planning to write down a tutorial that covers building a web app in ABCL from scratch up to a running servlet that touches a DB and returns JSON, so I want to know the best way to do those things.
Thanks for the attention, and please let me know if you guys have any questions or pointers.
See you.
_______________________________________________ Armedbear-devel mailing list Armedbear-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/armedbear-devel
On 17 Aug 2014, at 22:37, Eduardo Bellani ebellani@gmail.com wrote:
[…]
I am trying to build a servlet using ABCL. The servlet is a middleware that will expose an API, consume JSON, and return JSON. I will also store some data into a postgres RDBMS.
I've used the google-app-engine example as a basis to build a skeleton of my app, with a Java class providing a proxy for the servlet. If I don't use any dependencies on my project, everything runs ok. My problem is that I have the following system descriptor:
(asdf:defsystem #:abcl-servlet :serial t :description "An example of a servlet using the ABCL stack." :author "Eduardo Bellani ebellani@gmail.com" :license "Beerware v. 42" :depends-on (:jsown :postmodern) :components ((:module :src :components ((:file "package") (:file "servlet-interface")))))
N.b. my more recent experimentation with Lisp servlets can be found in [abcl-servlet][1], which should (eventually) supersede the googlecode work. Unfortunately, building ‘abcl-servlet’ at the moment requires Netbeans to be intalled, which is something I eventually want to make an optional dependency. Never-the-less, studying org.abcl.servlet.Lisp is probably worth something to you.
[1]: https://bitbucket.org/easye/abcl-servlet
If you have ABCL running in the servlet, you should be able to use ASDF to find these dependencies.
In my recent project I added all of my ASDF dependencies to WAR as “asdf/<SYSTEM>” including “illithid” the system that I am running, and then use the following code in the servlet to kick things off. This requires that one runs the servlet in “exploded mode” so that ServletContext.getRealPath() returns a location on the filesystem. Not all servlet containers support an "exploded mode”, but Tomcat certainly does.
(defun servlet-root () (concatenate ‘string ;; relies on there being a static field to reference the ServletContext ;; cf. https://bitbucket.org/easye/abcl-servlet (#"getRealPath" (java:jfield "org.abcl.servlet.Lisp" "servletContext") "/") "/"))
(defun configure-asdf () (asdf:initialize-source-registry `(:source-registry :ignore-inherited-configuration (:tree ,(merge-pathnames "asdf/" (servlet-root))))))
(cl:in-package #:cl-user) (illithid-servlet::configure-asdf) (setf *load-verbose* t) (push :hunchentoot-no-ssl *features*) (asdf:load-system :illithid) (illithid:start)
armedbear-devel@common-lisp.net