Problems with static methods (and interface implementation?), java.lang.NoClassDefFoundError.

Frederico Muñoz fsmunoz at gmail.com
Mon Dec 28 15:15:34 UTC 2015


Hello,

I have been struggling with this for some hours now and would welcome
some pointers. I'm writing a small how-to on how to deploy Common Lisp
web applications (i.e. "something that replies to an HTTP request") in
IBM's Bluemix using ABCL. That part is taken care of and I have it up
and running (more on that in a separate post). I was going for a more
advanced version and I am having a problem with interface
implementation.

To showcase java interop I am not using CL web frameworks, but decided
to give Spark a try (http://sparkjava.com/documentation.html) just to
get a minimal example up and running (I already have Jetty working and
serving up an "(Hello World)" page):

#+BEGIN_SRC java
import static spark.Spark.*;

public class HelloWorld {
    public static void main(String[] args) {
        get("/hello", (req, res) -> "Hello World");
    }
}
#+END_SRC

I'm going to start with the Clojure example since that one I got
working; the API reference
(http://spark.screenisland.com/spark/Spark.html) helped me  and this
works

#+BEGIN_SRC clojure
=> (Spark/get "/hello" (reify spark.Route (handle [this req res] ("Hello World"))))
[Thread-34] INFO spark.webserver.JettySparkServer - == Spark has ignited ...
[Thread-34] INFO spark.webserver.JettySparkServer - >> Listening on 0.0.0.0:4567
nil[Thread-34] INFO org.eclipse.jetty.server.Server - jetty-9.3.2.v20150730
#+END_SRC

I have learned (thanks to bpalmer in #emacs, cheers!) that the Single
Abstract Method can be constructed using Java 8 lambda expressions,
which is why I couldn't find a reference to the "handle" method, which I
got from the API.

Now, back to ABCL; I'm unable to reproduce the above and I'm unsure if
it is because I'm not getting something right (likely) or because some
of the plumbing in ABCL isn't quite there yet.

I tried this using jss::jinterface-implementation (which I had used
previously with my MQTT code and worked perfectly):

#+BEGIN_SRC lisp
(#"get" 'spark.Spark "/hello"
	(jss::jinterface-implementation "spark.Route"
					"handle"
					(lambda (request response)
					  ("Hello World"))))
#+END_SRC

The (jinterface-implementation ...) returns #<com.sun.proxy.$Proxy5
com.sun.proxy.$Proxy5 at 4f0bbf2a {41CC48BB}>, but the (#"get"...) fails:

Java exception 'java.lang.NoClassDefFoundError: Could not initialize class spark.Spark$SingletonHolder'.

I have also tried with jmake-proxy to see if there was something
different going on.

#+BEGIN_SRC lisp
(java::jstatic "get" "spark.Spark" "/hello" (java::jmake-proxy "spark.Route" #'(lambda (lisp-this method request response) ("Hello World"))))
#+END_SRC

The result is the same, both in what jmake-proxy returns and the final
error. Note that I have added the jar to the classpath, otherwise I
would get "ClassNotFound".

Even more simply this also doesn't work:

#+BEGIN_SRC clojure
=> (Spark/stop)
[nREPL-worker-11] INFO spark.webserver.JettySparkServer - >>> Spark shutting down ...
#+END_SRC

... (#"stop" 'spark.Spark) returns the same "NoClassDefFoundError",
which makes me thing the issue is not with the jproxy bit but something
more fundamental...

With this in mind:

1) Is there anything obviously wrong about the way I'm going about it -
not limited to implementation errors on my part but including trying to
use parts of ABCL's Java interop which aren't done?

2) The java::jmake-proxy call... I wasn't able to find a single example
of it used (the only code I find when searching is the implementation
itself) so I'm not sure I'm understanding the documentation correctly:
are the arguments I'm using above correct? I'm using the method that
uses a function and if I understood it correctly the first argument is
"lisp-this" (which defaults to nil), the second the method name (which
would be "handle" in this example, and the rest are the method arguments
(request and response here).

I am of course available for any further clarification, and if this is
something that isn't obvious I can upload a minimal example using
quickproject and quicklisp.

Best regards,

-- 
Frederico Muñoz
fsmunoz at gmail.com




More information about the armedbear-devel mailing list