Clojure as scripting language in a Java Application

1,362 views
Skip to first unread message

iamcreasy

unread,
Nov 3, 2011, 10:21:22 AM11/3/11
to Clojure
I am going to make a game framework using jMonkeyEngine.site ::
jmonkeyengine.com

I want to include live modification / any kind of end user
modification of the game through writing script. At first I was a bit
biased towards Groovy but now I want to integrate clojure as scripting
language in my framework.

So far, I have only found an old **clojure-jsr223** project (whose
last update was on Feb 2, on this year). So, I am a little confused.
Is my choice is wrong as picking Clojure as a scripting language for
my game framework? Is there any good way to have Clojure working as a
scripting language with Java, at all?

I am mostly familier with Imperative language family, that's why I
really want to learn a functional one, like Clojure. But, I need to
find a good bridge between this two.

Thanks in advance for any kind of help.

Chas Emerick

unread,
Nov 3, 2011, 12:17:34 PM11/3/11
to clo...@googlegroups.com
Do you need to use JSR-233? I can see that being useful if you aim to have multiple scripting languages available in the game. I don't know what the functional status of clojure-jsr233 is, but I doubt it would take much to bring it up to part in any case.

However, if Clojure will be the only scripting language you use, then you can execute Clojure scripts without a problem by just using RT.var (a static method in the clojure.lang.RT class), and various methods on clojure.lang.Var. There is some code in clojure-jsr233 that demonstrates exactly this, for obtaining references to core functions, and loading/evaluating code:

https://github.com/pmf/clojure-jsr223/blob/master/src/de/torq/clojure/jsr223/ClojureScriptEngine.java

Hope that helps,

- Chas

> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clo...@googlegroups.com
> Note that posts from new members are moderated - please be patient with your first post.
> To unsubscribe from this group, send email to
> clojure+u...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

Sean Corfield

unread,
Nov 3, 2011, 12:53:03 PM11/3/11
to clo...@googlegroups.com
As Chas says, RT.var() is probably your easier point of entry here.

I use Clojure as a scripting language within a JVM-based application
(not Java, but it uses Java interop to access Clojure) and the
patterns I use are:
* clojure.lang.RT.var( "the.namespace", "some-name" ) - get a
reference to the.namespace/some-name
* clojure.lang.RT.var( "clojure.core", "load" ).invoke( "filename" ) -
to load a source file from the classpath
* reference.invoke( my, args ) - to call whatever var is in the
reference (like the clojure.core/load example above)

Sean

Gary Trakhman

unread,
Nov 3, 2011, 7:40:53 PM11/3/11
to clo...@googlegroups.com
You can even consider a live scripting facility (while the game's running) with the repl and some api to access your game's state.  All of those functions are available.

Sean Corfield

unread,
Nov 3, 2011, 7:52:06 PM11/3/11
to clo...@googlegroups.com

I'm a bit fuzzy on how to enable an application to be connected to
from a command line repl. Any good articles on that? Preferably using
Clojure 1.3.0 / clojure.tools.nrepl. I read the tools.nrepl doc but it
didn't really "click" for me...
--
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/

"Perfection is the enemy of the good."
-- Gustave Flaubert, French realist novelist (1821-1880)

Gary Trakhman

unread,
Nov 3, 2011, 7:56:28 PM11/3/11
to clo...@googlegroups.com
For the parent's post, it might be more useful to directly have a repl
instead of connecting to an outside one. I don't have any ideas
on-hand about it, but i'm interested in finding out. I've been
thinking it would be cool to have the repl for exploratory java dev
work, even in projects that don't use clojure.

Gary Trakhman

unread,
Nov 3, 2011, 8:00:16 PM11/3/11
to clo...@googlegroups.com

Chas Emerick

unread,
Nov 3, 2011, 9:20:41 PM11/3/11
to clo...@googlegroups.com
Indeed, if you have stdin/out, then you can use clojure.main/repl and be on your way.

If you don't, you'll need to start an nREPL server, and connect to that using an nREPL client. That actually has some advantages even if you do have stdin/out (multiple sessions, for one), but I wouldn't say that nREPL is necessarily preferable for those reasons. Use the right tool for the job. :-)

- Chas

iamcreasy

unread,
Nov 3, 2011, 9:41:08 PM11/3/11
to Clojure
Most probably I replied your post using "Reply to author" instead of
using "Reply" :(

iamcreasy

unread,
Nov 3, 2011, 9:43:12 PM11/3/11
to Clojure
I might have replied to you instead of posting here. Used the "Reply
to author" button instead of "Reply" :(

On Nov 3, 10:17 pm, Chas Emerick <cemer...@snowtide.com> wrote:
> Do you need to use JSR-233?  I can see that being useful if you aim to have multiple scripting languages available in the game.  I don't know what the functional status of clojure-jsr233 is, but I doubt it would take much to bring it up to part in any case.
>
> However, if Clojure will be the only scripting language you use, then you can execute Clojure scripts without a problem by just using RT.var (a static method in the clojure.lang.RT class), and various methods on clojure.lang.Var.  There is some code in clojure-jsr233 that demonstrates exactly this, for obtaining references to core functions, and loading/evaluating code:
>
> https://github.com/pmf/clojure-jsr223/blob/master/src/de/torq/clojure...

iamcreasy

unread,
Nov 3, 2011, 9:47:00 PM11/3/11
to Clojure
Sorry, I dont get the part of "advantages even if you do have stdin/
out (multiple sessions, for one)"

The main thing I am getting here is, that a clojure receiving(to a
particular port) end is attached with my game and there is another
stand along clojure REPL program which would send commands to that
particular port. Is that right?

On Nov 4, 7:20 am, Chas Emerick <cemer...@snowtide.com> wrote:
> Indeed, if you have stdin/out, then you can use clojure.main/repl and be on your way.
>
> If you don't, you'll need to start an nREPL server, and connect to that using an nREPL client.  That actually has some advantages even if you do have stdin/out (multiple sessions, for one), but I wouldn't say that nREPL is necessarily preferable for those reasons.  Use the right tool for the job. :-)
>
> - Chas
>
> On Nov 3, 2011, at 8:00 PM, Gary Trakhman wrote:
>
>
>
>
>
>
>
> >http://clojure.github.com/clojure/clojure.main-api.html#clojure.main/...
>
> > On Thu, Nov 3, 2011 at 7:56 PM, Gary Trakhman <gary.trakh...@gmail.com> wrote:
> >> For the parent's post, it might be more useful to directly have a repl
> >> instead of connecting to an outside one.  I don't have any ideas
> >> on-hand about it, but i'm interested in finding out.  I've been
> >> thinking it would be cool to have the repl for exploratory java dev
> >> work, even in projects that don't use clojure.
>
> >> On Thu, Nov 3, 2011 at 7:52 PM, Sean Corfield <seancorfi...@gmail.com> wrote:

Gary Trakhman

unread,
Nov 3, 2011, 9:47:51 PM11/3/11
to clo...@googlegroups.com
that's one way to do it, the other way is the direct way I mentioned
via clojure.main/repl

iamcreasy

unread,
Nov 3, 2011, 9:48:31 PM11/3/11
to Clojure
That's what I had in my mind. I was thinking about implementing a
console(like old quake days) and the clojure script would be executed
its written and pressed ctrl+enter. Behind there would be live update
of the game scene graph.

On Nov 4, 5:56 am, Gary Trakhman <gary.trakh...@gmail.com> wrote:
> For the parent's post, it might be more useful to directly have a repl
> instead of connecting to an outside one.  I don't have any ideas
> on-hand about it, but i'm interested in finding out.  I've been
> thinking it would be cool to have the repl for exploratory java dev
> work, even in projects that don't use clojure.
>
>
>
>
>
>
>
> On Thu, Nov 3, 2011 at 7:52 PM, Sean Corfield <seancorfi...@gmail.com> wrote:
> > On Thu, Nov 3, 2011 at 4:40 PM, Gary Trakhman <gary.trakh...@gmail.com> wrote:
> >> You can even consider a live scripting facility (while the game's running)
> >> with the repl and some api to access your game's state.  All of those
> >> functions are available.
>
> > I'm a bit fuzzy on how to enable an application to be connected to
> > from a command line repl. Any good articles on that? Preferably using
> > Clojure 1.3.0 / clojure.tools.nrepl. I read the tools.nrepl doc but it
> > didn't really "click" for me...
> > --
> > Sean A Corfield -- (904) 302-SEAN
> > An Architect's View --http://corfield.org/
> > World Singles, LLC. --http://worldsingles.com/

Gary Trakhman

unread,
Nov 3, 2011, 9:49:33 PM11/3/11
to clo...@googlegroups.com
indeed

Gary Trakhman

unread,
Nov 3, 2011, 9:54:05 PM11/3/11
to clo...@googlegroups.com
Just don't get to the end of developing your game in java before you start playing with clojure.  You might slap yourself and decide to rewrite it in clojure :-).

iamcreasy

unread,
Nov 4, 2011, 12:25:26 AM11/4/11
to Clojure
I was playing with Groovy yesterday. It was just several hours of work
to read through the important parts and took only a few attempts to
successfully load a complete level written in Groovy.

:(

Had to decide which one to pick. If I pick groovy, i will be always
stuck with Imperative family, and I just *don't* like it. On the other
hand functional looks like an alien language(in a good sense). Still
not quite sure how hard it going to be for me to pick a reasonable
speed.

The other thing is, if I want an in-game console server client
connection is not going to work. Right?

Armando Blancas

unread,
Nov 4, 2011, 12:44:30 AM11/4/11
to Clojure
There are two libs with that name; I maintain the one in google code.
In case that's the one you found, here's a status.

It supports the spec, but there are two differences described in
issues #4 and #5 (#3 is fixed) that arise from the spec's assumption
that you'll use an interpreter.
Works with 1.2 and 1.3.
I had intended to use #compile for AOT but there's no value there so
please ignore it.
You'll get a single Clojure runtime per process. There's no
classloader separation.

The RT doesn't change much, so you won't see a lot of activity there.
There's one thing, though: the sample program EvalScript needs this
change for 1.3 (at the bottom):
long bar = (Long) engine.get("user/bar"); // was int

Tal Liron

unread,
Nov 5, 2011, 7:21:09 PM11/5/11
to clo...@googlegroups.com
I'll plug Scripturian here, a library I wrote that has very good thread-aware support for embedding Clojure, as well as other JVM languages (JavaScript, Python, Ruby, PHP, Groovy):

http://threecrickets.com/scripturian/

I just recently wrote a detailed tutorial for it, which was missing for a long time.

Stdout redirection is fully supported, as well as a sophisticated "text-with-scriptlets" mode, very useful for templating.

Even if you don't want to use Scripturian, its source code will show you a few examples of how to access Clojure's RT and bindings from within Java. It's ... not trivial, to say the least.

iamcreasy

unread,
Nov 29, 2011, 3:06:56 AM11/29/11
to Clojure
Thank you. This one looks great!
Reply all
Reply to author
Forward
0 new messages