I am relatively novice at Clojure and Java. I have an existing Clojure project someone else wrote that I am trying to embed in NodeJS using node-java.
Clojure
The project defines a namespace that provides certain public functions, like so:
(ns my.namespace
(:require ...etc...))
(defn dosomething ...)
(defn dosomethingelse ...)
I have built the project with leiningen (lein jar
and lein uberjar
).
Questions
The #import() docs on node-java say I need to import a java class like so:
const java = require('java');
var Test = java.import('Test');
Update
Thanks to Magos (answer below) I made a little more progress. It turns out I can use (:gen-class :name my.name)
in the (ns ...)
scope to tell it to generate a class. If I add a profile to the project.clj like so:
...
:profiles {
...
:uberjar {:aot :all}
}
...
It will compile and I can now see the class in Node. I still haven't figured out how to export the methods, though. Working on that part now.
Note: I arrived at this through a combination of Magos's answer and clartaq's comment to the question.
Here are simple instructions for how to do it. Let's assume you have this (simple) clojure code:
(ns my.namespace
"a trivial library"
(:require [something.else :as other]))
(defn excite
"make things more exciting"
[mystr]
(print-str mystr "!"))
Use these steps to expose the excite
method.
Create an exposed version of the method with the same signature by prefixing it with -
. It should simply call the function you wish to expose.
(defn -excite [mystr] (excite mystr))
Declare in (ns ...)
that you want to generate a class and export methods.
(ns my.namespace
"a trivial library"
(:require [something.else :as other])
(:gen-class
:name my.classname
:methods [
; metadata mtd.name signature returns
#^{:static true} [excite [String] void]
]))
Note that you may optionally remove the #^{:static true}
if you do not wish to provide this as a static method.
In your project.clj (assuming you are using leiningen), add ahead-of-time compilation instructions to your :profiles
entry:
:profiles {:uberjar {:aot :all}}
Compile your uberjar:
lein uberjar
The resulting .jar
file will have a class my.classname
with a static method excite
.