(I forgot to send this out a while back, probably because I didn't want to
distract myself with thinking about integrating Xwiki and Clojure any more
at the time :-) )
Got an interesting reply back from the Clojure list regarding JSR-223
support:
http://groups.google.com/group/clojure/msg/ad811b69d448e3db (see
below).
Regarding this message, and Xwiki's JSR-223 API usage, a question:
Does Xwiki's JSR-223 usage rely on the "Invocable interface" or the
"Compilable-interface" ?
Looking into what this all means,
http://java.sun.com/developer/technicalArticles/J2SE/Desktop/scripting/
states Invokable is optional:
Script engines are not required to support the
Invocable interface.
However, the Rhino JavaScript technology implementation included in JDK 6
does. If your script contains a function called sayHello, you could invoke
it repeatedly by casting your ScriptEngine object to an Invocable object and
by calling its invokeFunction method. Alternatively, if your script defines
objects, you can call object methods using the invokeMethod method.
Meanwhile., the author, Phil Frank, claims that Compilable is not
implemented for his JSR-223 bridge, and may not be necessary for Clojure:
The Compilable-interface is a bit harder to do, and
given Clojure's AOT
compilation, I'm not sure if there's really a use case (because if you use
require within a small script, Clojure will already out of the box
transparently choose a compiled implementation, given a proper classpath
setup). It's not quite the same, but comes pretty close.
Does Xwiki need anything from this Compilable interface, or will it's lack
of implementation be a problem?
As to the "active instance" issues brought up -- will these apply when
running multiple active instances out of a web container like tomcat?
According to
http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html
there's
a separate classloader per web application, which means, I guess, that the
JSR-223 clojure implementation will share any static initialization from
the Clojure implementation:
WebappX - A class loader is created for each web
application that is
deployed in a single Tomcat 6 instance. All unpacked classes and resources
in the /WEB-INF/classes directory of your web application archive, plus
classes and resources in JAR files under the /WEB-INF/lib directory of
your web application archive, are made visible to the containing web
application, but to no others. ... As mentioned above, the web application
class loader diverges from the default Java 2 delegation model (in
accordance with the recommendations in the Servlet Specification, version
2.3, section 9.7.2 Web Application Classloader).
So if all Clojure under Xwiki is shared via a common "WebAppX" classloader
under the Servlet Spec,
does this mean that all Clojure instances would share a :"symbol table" and
their values/properties? This could either become a useful feature, or an
egregious security hole in a multi-wikli environment.
----------------
From: Phil Frank
To: Clojure <clojure(a)googlegroups.com>
On Aug 1, 2:36=A0am, Niels Mayer <nielsma...(a)gmail.com> wrote:
PS: I've always seen xwiki as the "emacs of
webapps" (and wikis)...
So I'm looking forward to having a real emacsish type language -- clojure
-- to extend it via a more appropriate language for scripting.
I'm the author of the JSR 223 bridge for Clojure. At the moment, I
have several uncommitted changes (mainly related to wrapping it up in
a nice OSGi service component (to be used optionally). The Invocable-
stuff is not implemented at the moment, but will be painless to
implement. The Compilable-interface is a bit harder to do, and given
Clojure's AOT compilation, I'm not sure if there's really a use case
(because if you use require within a small script, Clojure will
already out of the box transparently choose a compiled implementation,
given a proper classpath setup). It's not quite the same, but comes
pretty close.
Aside from that, I have some unresolved design issues regarding
isolation of engines; this works differently for Clojure than for
other dynamic languages for the reasons explained below.
Due to the static initialization of the Clojure runtime, it is much
harder to create different independent Clojure-engine instances, since
this would require loading each Clojure-runtime under a separate
classloader, which I am not opposed to, but was unable to implement.
At the moment, I'm using a weird kind of isolation in which each
Clojure-engine runs in its own thread, using a shared runtime, and
bindings are isolated by pushing and popping them.
I'm going to abandon this rather stupid approach and use a simpler
"one namespace per engine"-scheme. This change should (hopefully) be
transparent for little scripts that don't have their own explicit
namespaces. If your scripts use user-defined namespaces, I'll just
assume you break this isolation intentionally (which is true to the
meaning of namespaces, after all).
If anybody would like to look into the classloader-based isolation,
I'd happily to integrate this change (even if this means a severe
startup-overhead for the creation of each engine-instance; it's simply
the proper way to do it).
For production (at least if you plan to have more than one active
engine instance), I'd recommend to wait for either the namespace-based
isolation or (should anybody get involved) the classloader-based
approach. I'll reply to this thread again if one of these approaches
is implemented.