hawkeye
hawkeye

Reputation: 35692

Why aren't namespaces the same as Java packages for interop access?

I'm doing the following on a Clojure REPL:

user=> (ns clojure.lang)
nil
clojure.lang=> (def tran (clojure.lang.LockingTransaction.))
#'clojure.lang/tran
clojure.lang=> (.getReadPoint tran)

This gives the following result:

IllegalArgumentException No matching field found: getReadPoint for class clojure.lang.LockingTransaction  clojure.lang.Reflector.getInstanceField (Reflector.java:271)

Now this method does exist.

Now I think I should be able to access default access methods from the REPL.

I'm reliably informed that Clojure namespaces are not the same as Java packages. (ie the way to solve this problem is via reflection - for something that wouldn't require reflection in Java).

Why aren't namespaces in Clojure the same as Java packages for interop access?

Upvotes: 3

Views: 181

Answers (1)

RJ Acuña
RJ Acuña

Reputation: 530

Yes classes aren't namespaces

boot.user=> (in-ns java.util.Date)
java.lang.ClassCastException: java.lang.Class cannot be cast to clojure.lang.Symbol

But the error you're getting isn't because the field doesn't exist, it's because it hasn't been initialized correctly. It's a Clojure concurrency primitive that requires instantiation with a java.util.concurrent.Callable and that is a pain to implement just look at the end of the class for the testing example.

When initialized correctly java classes return meaningful output:

boot.user=> (.getTime (java.util.Date.))
1445587895021

or

boot.user=> (def concurrent-queue (java.util.concurrent.ConcurrentLinkedQueue.))
#'boot.user/concurrent-queue
boot.user=> (.add concurrent-queue "example")
true
boot.user=> concurrent-queue
#object[java.util.concurrent.ConcurrentLinkedQueue 0x750ee622 "[example]"]

Upvotes: 0

Related Questions