Why I am getting Error compiling in Clojure? - clojure

I have recently started to work with Clojure. When I run a program in lein, I get the below error:
Exception in thread "main" Syntax error compiling at (bioavailability.clj:79:36).
at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3707)
at clojure.lang.Compiler$DefExpr.eval(Compiler.java:457)
at clojure.lang.Compiler.eval(Compiler.java:7181)
at clojure.lang.Compiler.load(Compiler.java:7635)
at clojure.lang.RT.loadResourceScript(RT.java:381)
at clojure.lang.RT.loadResourceScript(RT.java:372)
at clojure.lang.RT.load(RT.java:463)
at clojure.lang.RT.load(RT.java:428)
at clojure.core$load$fn__6824.invoke(core.clj:6126)
at clojure.core$load.invokeStatic(core.clj:6125)
at clojure.core$load.doInvoke(core.clj:6109)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.core$load_one.invokeStatic(core.clj:5908)
at clojure.core$load_one.invoke(core.clj:5903)
at clojure.core$load_lib$fn__6765.invoke(core.clj:5948)
at clojure.core$load_lib.invokeStatic(core.clj:5947)
at clojure.core$load_lib.doInvoke(core.clj:5928)
at clojure.lang.RestFn.applyTo(RestFn.java:142)
at clojure.core$apply.invokeStatic(core.clj:667)
at clojure.core$load_libs.invokeStatic(core.clj:5985)
at clojure.core$load_libs.doInvoke(core.clj:5969)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invokeStatic(core.clj:667)
at clojure.core$require.invokeStatic(core.clj:6007)
at clojure.core$require.doInvoke(core.clj:6007)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojush.core$_main.invokeStatic(core.clj:40)
at clojush.core$_main.doInvoke(core.clj:26)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.lang.Var.invoke(Var.java:384)
at user$eval140.invokeStatic(form-init8949943542898746617.clj:1)
at user$eval140.invoke(form-init8949943542898746617.clj:1)
at clojure.lang.Compiler.eval(Compiler.java:7176)
at clojure.lang.Compiler.eval(Compiler.java:7166)
at clojure.lang.Compiler.load(Compiler.java:7635)
at clojure.lang.Compiler.loadFile(Compiler.java:7573)
at clojure.main$load_script.invokeStatic(main.clj:452)
at clojure.main$init_opt.invokeStatic(main.clj:454)
at clojure.main$init_opt.invoke(main.clj:454)
at clojure.main$initialize.invokeStatic(main.clj:485)
at clojure.main$null_opt.invokeStatic(main.clj:519)
at clojure.main$null_opt.invoke(main.clj:516)
at clojure.main$main.invokeStatic(main.clj:598)
at clojure.main$main.doInvoke(main.clj:561)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.lang.Var.applyTo(Var.java:705)
at clojure.main.main(main.java:37)
Caused by: java.lang.IllegalArgumentException: No matching method findResource found taking 1 args for class jdk.internal.loader.ClassLoaders$AppClassLoader
at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:127)
at clojure.lang.Reflector.invokeInstanceMethod(Reflector.java:102)
at local_file$find_resource.invokeStatic(local_file.clj:30)
at local_file$find_resource.invoke(local_file.clj:26)
at local_file$project_dir.invokeStatic(local_file.clj:39)
at local_file$project_dir.invoke(local_file.clj:34)
at local_file$project_dir.invokeStatic(local_file.clj:47)
at local_file$project_dir.invoke(local_file.clj:34)
at local_file$file_STAR_.invokeStatic(local_file.clj:55)
at local_file$file_STAR_.invoke(local_file.clj:51)
at local_file$slurp_STAR_.invokeStatic(local_file.clj:60)
at local_file$slurp_STAR_.doInvoke(local_file.clj:57)
at clojure.lang.RestFn.invoke(RestFn.java:410)
at clojush.problems.regression.bioavailability$read_data.invokeStatic(bioavailability.clj:51)
at clojush.problems.regression.bioavailability$read_data.invoke(bioavailability.clj:49)
at clojush.problems.regression.bioavailability$define_fitness_cases.invokeStatic(bioavailability.clj:63)
at clojush.problems.regression.bioavailability$define_fitness_cases.invoke(bioavailability.clj:57)
at clojure.lang.AFn.applyToHelper(AFn.java:152)
at clojure.lang.AFn.applyTo(AFn.java:144)
at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3702)
... 46 more
The code I am trying to run is:
https://github.com/lspector/Clojush/blob/master/src/clojush/problems/regression/bioavailability.clj
and the command that I use is:
lein run clojush.problems.regression.bioavailability
Thanks in advance for your kind help.
I tried to run each section of the main code seperately to understand where the problem exactly is but it was not succesful.

The problem is that the code in bioavailability.clj calls the function find-resource that in turn calls a method findResource that (i) is protected and (ii) expects a string but is passed a File.
To fix this, I did two things:
First, copied the function find-resource from the local-file library and renamed it get-resource and replaced the call to findResource by a call to getResource which is public. I inserted this code just above the read-data function in bioavailability.clj.
Second, I changed a line in read-data that calls the slurp* (that was (slurp* "src/clojush/problems/regression/data/bioavailability.txt")) function to instead call (slurp (get-resource "../src/clojush/problems/regression/data/bioavailability.txt")) by calling slurp on the result of the get-resource function to which I pass a path that I have prepended with ../. The prepended path is relative to the default resources directory.
The modified code is
;; I added this function
(defn get-resource
[file]
(loop [cl (.. Thread currentThread getContextClassLoader)]
(when cl
(if-let [url (.getResource cl file)]
url
(recur (.getParent cl))))))
(defn read-data []
"Reads data from data/bioavailability.txt into a sequence of sequences."
;; This line has been updated:
(let [f (slurp (get-resource "../src/clojush/problems/regression/data/bioavailability.txt"))
lines (csv/parse-csv f :delimiter \tab)]
(map #(map (fn [x] (float (read-string x)))
%)
lines)))

Related

Clojure/Midje using AOT compilation with tests inside source fails to run

I'm trying to include midje "facts" alongside my source code in a project which uses aot. Trying to access the repl or run the project results in the following error, I've included a minimal sample project which reproduces the issue. Thanks for any help!
project.clj
(defproject test-midje "0.1.1"
:description "Why doesn't midje work?"
:min-lein-version "2.0.0"
:source-paths ["src/clj"]
:repl-options {
:timeout 120000
}
:main org.midjetest.core
:profiles {:dev {:dependencies [[midje "1.5.0"]]}}
:aot [org.midjetest.core])
src/clj/org/midjetest/core.clj
(ns org.midjetest.core
(:require [midje.sweet :refer [fact facts]]))
(defn addtwo [a] (+ 2 a))
(fact "addtwo adds two to numbers"
(addtwo 3) => 5)
(defn -main
"testing with main"
([] (println (addtwo 5))))
lein run or lein repl give the following error:
$ lein repl
Compiling org.midjetest.core
Exception in thread "main" java.lang.ExceptionInInitializerError
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:270)
at clojure.lang.RT.loadClassForName(RT.java:2056)
at clojure.lang.RT.load(RT.java:419)
at clojure.lang.RT.load(RT.java:400)
at clojure.core$load$fn__4890.invoke(core.clj:5415)
at clojure.core$load.doInvoke(core.clj:5414)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.core$load_one.invoke(core.clj:5227)
at clojure.core$load_lib.doInvoke(core.clj:5264)
at clojure.lang.RestFn.applyTo(RestFn.java:142)
at clojure.core$apply.invoke(core.clj:603)
at clojure.core$load_libs.doInvoke(core.clj:5298)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invoke(core.clj:603)
at clojure.core$require.doInvoke(core.clj:5381)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at org.midjetest.core$loading__4784__auto__.invoke(core.clj:1)
at org.midjetest.core__init.load(Unknown Source)
at org.midjetest.core__init.<clinit>(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:270)
at clojure.lang.RT.loadClassForName(RT.java:2056)
at clojure.lang.RT.load(RT.java:419)
at clojure.lang.RT.load(RT.java:400)
at clojure.core$load$fn__4890.invoke(core.clj:5415)
at clojure.core$load.doInvoke(core.clj:5414)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.core$load_one.invoke(core.clj:5227)
at clojure.core$load_lib.doInvoke(core.clj:5264)
at clojure.lang.RestFn.applyTo(RestFn.java:142)
at clojure.core$apply.invoke(core.clj:603)
at clojure.core$load_libs.doInvoke(core.clj:5298)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invoke(core.clj:603)
at clojure.core$require.doInvoke(core.clj:5381)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at user$eval5.invoke(form-init9180276290836069038.clj:1)
at clojure.lang.Compiler.eval(Compiler.java:6511)
at clojure.lang.Compiler.eval(Compiler.java:6500)
at clojure.lang.Compiler.eval(Compiler.java:6500)
at clojure.lang.Compiler.load(Compiler.java:6952)
at clojure.lang.Compiler.loadFile(Compiler.java:6912)
at clojure.main$load_script.invoke(main.clj:283)
at clojure.main$init_opt.invoke(main.clj:288)
at clojure.main$initialize.invoke(main.clj:316)
at clojure.main$null_opt.invoke(main.clj:349)
at clojure.main$main.doInvoke(main.clj:427)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at clojure.lang.Var.invoke(Var.java:419)
at clojure.lang.AFn.applyToHelper(AFn.java:163)
at clojure.lang.Var.applyTo(Var.java:532)
at clojure.main.main(main.java:37)
Caused by: java.lang.NullPointerException
at java.util.concurrent.ConcurrentHashMap.hash(ConcurrentHashMap.java:333)
at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:988)
at clojure.lang.Namespace.find(Namespace.java:188)
at clojure.core$find_ns.invoke(core.clj:3659)
at clojure.core$the_ns.invoke(core.clj:3691)
at clojure.core$ns_name.invoke(core.clj:3698)
at midje.Bootstrap$bootstrap.invoke(Bootstrap.clj:8)
at midje.sweet__init.load(Unknown Source)
at midje.sweet__init.<clinit>(Unknown Source)
... 53 more
Exception in thread "Thread-4" clojure.lang.ExceptionInfo: Subprocess failed {:exit-code 1}
at clojure.core$ex_info.invoke(core.clj:4327)
at leiningen.core.eval$fn__3532.invoke(eval.clj:226)
at clojure.lang.MultiFn.invoke(MultiFn.java:231)
at leiningen.core.eval$eval_in_project.invoke(eval.clj:326)
at clojure.lang.AFn.applyToHelper(AFn.java:167)
at clojure.lang.AFn.applyTo(AFn.java:151)
at clojure.core$apply.invoke(core.clj:619)
at leiningen.repl$server$fn__7443.invoke(repl.clj:201)
at clojure.lang.AFn.applyToHelper(AFn.java:159)
at clojure.lang.AFn.applyTo(AFn.java:151)
at clojure.core$apply.invoke(core.clj:617)
at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1788)
at clojure.lang.RestFn.invoke(RestFn.java:425)
at clojure.lang.AFn.applyToHelper(AFn.java:163)
at clojure.lang.RestFn.applyTo(RestFn.java:132)
at clojure.core$apply.invoke(core.clj:621)
at clojure.core$bound_fn_STAR_$fn__4102.doInvoke(core.clj:1810)
at clojure.lang.RestFn.invoke(RestFn.java:397)
at clojure.lang.AFn.run(AFn.java:24)
at java.lang.Thread.run(Thread.java:744)
The root problem here is that Bootstrap.clj is just not going to work when AOT-ed; it depends on some namespace being loaded before it is; however the static initializers for clojure AOTed classes are more or less equivalent to:
(binding [clojure.core/*ns* nil
clojure.core/*fn-loader* loader
clojure.core/*read-eval* true]
(my.class/load))
Since Bootstrap/bootstrap is called before midje.sweet defines it's own ns (https://github.com/marick/Midje/blob/master/src/midje/sweet.clj#L2), *ns* stays null, and (ns-name *ns*) crashes.
I don't think you can make this work, unless the bootstrap code for midje changes. I'd recommend putting your tests into separate files, and not aot-ing those.

lein ring uberwar NullPointerException

Working backwards from example ch17-webapp-lein in "Clojure Programming" by Emerick, Carper, and Grand, I've boiled my web service down to the bare minimum, hoping to deploy it to Elastic Beanstalk. I now have a repeatable NullPointerException in lein ring uberwar. I'd appreciate any help diagnosing or debugging this, or relaying it to the right people.
Here is my project.clj
(defproject com.clojurebook/sample-lein-web-project "1.0.0-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.3.0"]
[compojure/compojure "1.0.0"]
[ring "1.1.8"]]
:plugins [[lein-ring "0.6.2"]
[lein-beanstalk "0.2.7"]]
:ring {:handler com.clojurebook.hello-world/routes})
and here is the one and only src file in the project
(ns com.clojurebook.hello-world
(:use
[compojure.core :only (GET HEAD defroutes)]))
(defroutes routes
(HEAD "/" [] "")
(GET "*" request "hello"))
When I do
lein ring uberwar
in the project directory, I get
java.lang.NullPointerException
at clojure.lang.Numbers.ops(Numbers.java:942)
at clojure.lang.Numbers.isZero(Numbers.java:90)
at leiningen.ring.uberwar$uberwar.invoke(uberwar.clj:45)
at leiningen.ring.uberwar$uberwar.invoke(uberwar.clj:43)
at clojure.lang.AFn.applyToHelper(AFn.java:161)
at clojure.lang.AFn.applyTo(AFn.java:151)
at clojure.core$apply.invoke(core.clj:619)
at leiningen.ring$ring.doInvoke(ring.clj:19)
at clojure.lang.RestFn.invoke(RestFn.java:425)
at clojure.lang.Var.invoke(Var.java:419)
at clojure.lang.AFn.applyToHelper(AFn.java:163)
at clojure.lang.Var.applyTo(Var.java:532)
at clojure.core$apply.invoke(core.clj:619)
at leiningen.core.main$resolve_task$fn__1836.doInvoke(main.clj:149)
at clojure.lang.RestFn.applyTo(RestFn.java:139)
at clojure.lang.AFunction$1.doInvoke(AFunction.java:29)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invoke(core.clj:619)
at leiningen.core.main$apply_task.invoke(main.clj:189)
at leiningen.core.main$resolve_and_apply.invoke(main.clj:193)
at leiningen.core.main$_main$fn__1899.invoke(main.clj:257)
at leiningen.core.main$_main.doInvoke(main.clj:247)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at clojure.lang.Var.invoke(Var.java:419)
at clojure.lang.AFn.applyToHelper(AFn.java:163)
at clojure.lang.Var.applyTo(Var.java:532)
at clojure.core$apply.invoke(core.clj:617)
at clojure.main$main_opt.invoke(main.clj:335)
at clojure.main$main.doInvoke(main.clj:440)
at clojure.lang.RestFn.invoke(RestFn.java:457)
at clojure.lang.Var.invoke(Var.java:427)
at clojure.lang.AFn.applyToHelper(AFn.java:172)
at clojure.lang.Var.applyTo(Var.java:532)
at clojure.main.main(main.java:37)
Upgrading to lein-ring 0.8.5 fixed this.

How do I set local-paths for ritz.nrepl.middleware/wrap-javadoc?

In api docs for nrepl-middleware wrap-javadoc it says that it 'accepts local-paths a space separate list of paths'
How do I set this?
I've tried the following in my profiles.clj
{:user {:plugins []
:jvm-opts ["-Xmx4G"]
:injections [(require 'clojure.repl)]
:warn-on-reflection true
:dependencies [[ritz/ritz-nrepl-middleware "0.7.0"]]
:repl-options {:nrepl-middleware
[ritz.nrepl.middleware.javadoc/wrap-javadoc :local-paths "/usr/local/share/javadocs/7/docs/api"]
}}}
But that causes the following exception when I execute nrepl-jack-in
Starting nREPL server...
Mark set
error in process sentinel: nrepl-server-sentinel: Could not start nREPL server: Reflection warning, NO_SOURCE_PATH:1:483 - reference to field getLocalPort can't be resolved.
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn
at clojure.core$comp$fn__4166.doInvoke(core.clj:2347)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.tools.nrepl.server$default_handler.doInvoke(server.clj:89)
at clojure.lang.RestFn.invoke(RestFn.java:436)
at user$eval1192.invoke(NO_SOURCE_FILE:1)
at clojure.lang.Compiler.eval(Compiler.java:6619)
at clojure.lang.Compiler.eval(Compiler.java:6609)
at clojure.lang.Compiler.eval(Compiler.java:6582)
at clojure.core$eval.invoke(core.clj:2852)
at clojure.main$eval_opt.invoke(main.clj:308)
at clojure.main$initialize.invoke(main.clj:327)
at clojure.main$null_opt.invoke(main.clj:362)
at clojure.main$main$fn__6661.invoke(main.clj:440)
at clojure.main$main.doInvoke(main.clj:437)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at clojure.lang.Var.invoke(Var.java:419)
at clojure.lang.AFn.applyToHelper(AFn.java:163)
at clojure.lang.Var.applyTo(Var.java:532)
at clojure.main.main(main.java:37)
Subprocess failed
If I wrap :local-paths "..." in a map I don't get any javadoc middleware
If you look at the example of the nrepl-middleware on its github page, you will find that the vector to :nrepl-middleware sbould be a vector of middleware functions where as you are passing it a string path and that's why the exception "String cannot be cast to IFn".
As far as the local-paths is concerned that's something which is send by the nrepl client in the java-doc request itself. You can set local-paths in Emacs by calling:
(setq nrepl-ritz-javadoc-local-paths (list "/usr/local/share/javadocs/7/docs/api"))

Java Interop with Clojure, could not load the plugin

I'm trying to write a Bukkit plugin in Clojure.
Generally a Bukkit plugin needs to override the Plugin class, have an onEnable() and a onDisable() method.
There are also a few other requires, like the result being in a JAR file and a plugin.yml defined, but I have all that.
(ns net.jonnay.watershipdown.WatershipDown
(:import org.bukkit.Bukkit
org.bukkit.plugin.Plugin)
(:gen-class
:name net.jonnay.watershipdown.WatershipDown
:extends org.bukkit.plugin.Plugin
:methods [ [onEnable [] void]
[onDisable [] void] ]
)
)
(set! *warn-on-reflection* true)
(defn debug-to-mc-log [^String msg]
(let [logger (Bukkit/getLogger)]
(. logger info (str "(DEBUG) " msg))))
(defn -onEnable []
(debug-to-mc-log "Enabled Watership down. Super Clojure Powers!"))
(defn -onDisable []
(debug-to-mc-log "Disabled Watership down."))
My code compiles just fine, but when I try to load it in the server, I get this exception:
13:29:20 [SEVERE] Could not load 'plugins/watershipdown-0.1.jar' in folder 'plugins':
java.lang.ClassFormatError: Duplicate method name&signature in class file net/jonnay/watershipdown/WatershipDown
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:41)
at org.bukkit.plugin.java.PluginClassLoader.findClass(PluginClassLoader.java:29)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at org.bukkit.plugin.java.JavaPluginLoader.loadPlugin(JavaPluginLoader.java:131)
at org.bukkit.plugin.SimplePluginManager.loadPlugin(SimplePluginManager.java:285)
at org.bukkit.plugin.SimplePluginManager.loadPlugins(SimplePluginManager.java:200)
at org.bukkit.craftbukkit.CraftServer.loadPlugins(CraftServer.java:156)
at org.bukkit.craftbukkit.CraftServer.<init>(CraftServer.java:132)
at net.minecraft.server.ServerConfigurationManager.<init>(ServerConfigurationManager.java:52)
at net.minecraft.server.MinecraftServer.init(MinecraftServer.java:148)
at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:407)
at net.minecraft.server.ThreadServerApplication.run(SourceFile:465)
Are onEnable and onDisable defined in Plugin?
If so, they might be causing the issue.
The genClass documentation specifically says that you shouldn't redeclare inherited methods.

How do I eval a clojure data structure within the context of a namespace?

I'm writing a clojure app for internal use, and I want the config file to be in clojure too. I have defined a few macros to make writing the config file easier, but when I try to eval the data from the config file, it cant find my macros. This works fine from the REPL however. For example, I'm using
(load-string "/path/to/config")
I get this error:
Exception in thread "main" java.lang.RuntimeException: Unable to resolve symbol: defcmd in this context, compiling:(null:1)
at clojure.lang.Compiler.analyze(Compiler.java:6235)
at clojure.lang.Compiler.analyze(Compiler.java:6177)
at clojure.lang.Compiler$InvokeExpr.parse(Compiler.java:3452)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6411)
at clojure.lang.Compiler.analyze(Compiler.java:6216)
at clojure.lang.Compiler.analyze(Compiler.java:6177)
at clojure.lang.Compiler.eval(Compiler.java:6469)
at clojure.lang.Compiler.load(Compiler.java:6902)
at clojure.lang.Compiler.load(Compiler.java:6872)
at clojure.core$load_reader.invoke(core.clj:3625)
at clojure.core$load_string.invoke(core.clj:3635)
at serverStats.core$load_config.invoke(core.clj:67)
at serverStats.core$_main.doInvoke(core.clj:78)
at clojure.lang.RestFn.invoke(RestFn.java:397)
at clojure.lang.Var.invoke(Var.java:397)
at user$eval109.invoke(NO_SOURCE_FILE:1)
at clojure.lang.Compiler.eval(Compiler.java:6465)
at clojure.lang.Compiler.eval(Compiler.java:6455)
at clojure.lang.Compiler.eval(Compiler.java:6431)
at clojure.core$eval.invoke(core.clj:2795)
at clojure.main$eval_opt.invoke(main.clj:296)
at clojure.main$initialize.invoke(main.clj:315)
at clojure.main$null_opt.invoke(main.clj:348)
at clojure.main$main.doInvoke(main.clj:426)
at clojure.lang.RestFn.invoke(RestFn.java:421)
at clojure.lang.Var.invoke(Var.java:405)
at clojure.lang.AFn.applyToHelper(AFn.java:163)
at clojure.lang.Var.applyTo(Var.java:518)
at clojure.main.main(main.java:37)
Caused by: java.lang.RuntimeException: Unable to resolve symbol: defcmd in this context
at clojure.lang.Util.runtimeException(Util.java:156)
at clojure.lang.Compiler.resolveIn(Compiler.java:6720)
at clojure.lang.Compiler.resolve(Compiler.java:6664)
at clojure.lang.Compiler.analyzeSymbol(Compiler.java:6625)
at clojure.lang.Compiler.analyze(Compiler.java:6198)
... 28 more
However, running that same command from the REPL in my namespace works fine.
You probably want some more sophisticated loading scheme. I assume you want to put the configuration into a dedicated configuration namespace. It will only contain the configuration. Helper functions are held in a separate namespace use'd in the configuration namespace.
(defn setup-config-space
[]
(binding [*ns* *ns*]
(in-ns 'config.namespace)
(refer-clojure)
(use 'config.helpers)))
(defn load-config
[path]
(binding [*ns* *ns*]
(in-ns 'config.namespace)
(load-file path)))
See the example use:
..ojure/1.4.0-alpha3% cat config/helpers.clj
(ns config.helpers)
(defmacro defcmd
[x]
`(defn ~x [] "Hello"))
..ojure/1.4.0-alpha3% cat x.clj
(defcmd foo)
..ojure/1.4.0-alpha3% java -cp .:clojure-1.4.0-alpha3.jar clojure.main -r
Clojure 1.4.0-alpha3
user=> ; Paste above functions
#'user/setup-config-space
#'user/load-config
user=> (setup-config-space)
nil
user=> (load-config "x.clj")
#'config.namespace/foo
user=> (config.namespace/foo)
"Hello"