Exception while setting namespace from Java

282 views
Skip to first unread message

Josip Gracin

unread,
Sep 3, 2008, 5:06:14 PM9/3/08
to clo...@googlegroups.com
Hi!

Why is the following code throwing an exception?

PushbackReader rdr = new PushbackReader( new StringReader( "(in-ns
'user)" ) );
Object input = LispReader.read(rdr, false, null, false );
clojure.lang.Compiler.eval( input );

java.lang.IllegalStateException: Can't change/establish root binding
of: *ns* with set
at clojure.lang.Var.set(Var.java:170)
at clojure.lang.RT$1.invoke(RT.java:206)
at clojure.eval__2237.invoke(Unknown Source)
at clojure.lang.Compiler.eval(Compiler.java:3847)
...

I'm trying to set the namespace so that subsequent expressions are
evaluated within it.

Michael Reid

unread,
Sep 3, 2008, 5:48:13 PM9/3/08
to clo...@googlegroups.com
Hi Josip,

Have a look in jvm/clojure/lang/Repl.java which demonstrates creating
and entering the 'user namespace.

The key is that you need to wrap the call to in-ns in
Var.pushThreadBindings(IPersistentMap) / Var.popThreadBindings().

This is analogous to:

(binding [*ns* *ns*] ;; bind a thread-local copy of *ns* so changes
are isolated to this thread
(....))

See also:
http://clojure.org/vars

The root binding of Clojure vars are immutable, but using the
(binding) construct you can override the value within the scope of the
(binding) form.

The clojure/*ns* var is no different and this is why you see Repl.java
establishes a thread-local binding before evaluating user code. This
allows you to change the namespace at the REPL.

Hope this helps.

/mike.

Josip Gracin

unread,
Sep 4, 2008, 6:19:38 AM9/4/08
to clo...@googlegroups.com
On Wed, Sep 3, 2008 at 11:48 PM, Michael Reid <kid....@gmail.com> wrote:
> The key is that you need to wrap the call to in-ns in
> Var.pushThreadBindings(IPersistentMap) / Var.popThreadBindings().

Thanks, Mike! Works perfectly! (btw, only on Java 1.5 and not on 1.6.
On 1.6 there's a problem with arguments to RT.map)

Michael Reid

unread,
Sep 4, 2008, 11:41:35 AM9/4/08
to clo...@googlegroups.com
Hi,

On Thu, Sep 4, 2008 at 6:19 AM, Josip Gracin <josip....@gmail.com> wrote:
> Thanks, Mike! Works perfectly! (btw, only on Java 1.5 and not on 1.6.
> On 1.6 there's a problem with arguments to RT.map)

Care to share? I've been using Clojure on OpenJDK 1.6.0 for some time
without trouble. This includes calls to RT.map().

/mike.

Josip Gracin

unread,
Sep 4, 2008, 2:39:51 PM9/4/08
to clo...@googlegroups.com

In Maven compile plugin, when I set source and target (which
correspond to -source and -target options in javac) to either 1.5 or
1.6, everything works normally. But if I leave it undefined, compiler
reports the following failure.

/home/gracin/src/workspaces/main/maven-cljexec-plugin/src/main/java/com/ingemark/cljexec/CljExecMojo.java:[63,14]
map(java.lang.Object...) in clojure.lang.RT cannot be applied to
(clojure.lang.Var,java.lang.Object,clojure.lang.Var,java.lang.Object)

I don't have time (will, actually) to investigate further.

Reply all
Reply to author
Forward
0 new messages