Why am I unable to load files in Clojure? - clojure

I have just started learning clojure, but have a hard time understanding why my file structure is erroneous. In the main file(main.clj),
I have just this:
(ns example.core
(:gen-class)
(:load "declare"))
...some code...
and in 'declare.clj', which is in the exact same classpath "project/src", I have this:
(in-ns 'example.core)
...some code...'
From what I understand I should be hitting the right syntax, but I only receive
Could not locate
clojurepractice2/src/clojurepractice2/declarations__init.class or
clojurepractice2/src/clojurepractice2/declarations.clj on classpath.
from REPL. I am using lein to code, which I know is supposed to automatically set the classpath. Is there something I am missing?
I have tried using load-file With the same results.

The main.clj should have namespace example.main. Or rename it to core.clj. This is definitely an issue with file name and namespace mismatch.

Because the file name should be same as the namespace name.
If your file is in src/example/main.clj then the namespace should be example.main.
The usage is
(ns example.main
(:gen-class)
(:load "declare"))
Is the file path as src/example/main.clj ? Is the main inside the example folder in src?

Related

Custom files in luminus

Where should I use put code files I write myself in a Clojure luminus application? And how can I export a function from it and import it to another file? Say, I've create a file "helper1.clj", how can I access the functions from it in "src/clj/my_app/routes/home.clj"? And where should I put the file "helper1.clj"?
Look at the project.clj file. You will see a line that reads:
:source-paths ["src/clj"]
This means that the src/clj directory will be the root of all namespaces. The namespace is the directory path separated by dots, with the final portion of the namespace being the file name. An example:
File name: my_app/src/clj/dirone/dirtwo/myfile.clj
Namespace in this file: (ns dirone.dirtwo.myfile ...)
With that now established: you should probably put new files in src/clj/my_app for now. The namespace for helper.clj would then look like:
(ns my-app.helper ...)
You can create new directories under src/clj, for example, src/clj/newdir. A file in that directory called anotherfile.clj would have a namespace of:
(ns newdir.anotherfile ...)
Look in your my_app/routes/home.clj file and look at the top, and you will see where :require [my-app.layout :as layout]. You would add the following to reference your function myfunc in your file helper.clj:
;... list of items under :require
[my-app.helper :as h]
;...
(def something (h/myfunc ...))

Clojure not requiring a cljc file

I need to share a namespace between my Clojure (Garden) and my ClojureScript (Reagent).
Currently the project folder looks like this:
src/
clj/
name/
css.clj
cljs/
name/
core.cljs
cljc/
name/
config.cljc
The config.cljc file has the following namespace: (ns name.config).
I've tried to reference this namespace from inside clj/name/css.clj with a require.
(ns name.css
(:require [name.config :as config]))
However, this results in a compile error from Garden.
Caused by: java.io.FileNotFoundException: Could not locate name/config__init.class or name/config.clj on classpath.
I guess it's not even checking for cljc files.
I added "src/cljc" to the :source-paths vector in project.clj and :garden :builds but I get the same error even after restarting the build processes.
I see this behaviour on Clojure 1.7.0 and 1.8.0.
It might also be worth mentioning that it works without issues in ClojureScript (with Figwheel handling the build). I can require and use the new namespace without problems.
It seems like I must be missing something really simple, because none of the documentation around .cljc files even mentions requiring them.
Check if you’re using Clojure 1.7 or above in your project.clj. This error message:
Caused by: java.io.FileNotFoundException: Could not locate name/config__init.class or name/config.clj on classpath.
indicates that you’re using Clojure 1.6 or below, as those versions of Clojure only know to look for .class or .clj files.
I got this same error when I moved a file from .clj to .cljc in my project. I did lein clean but that had no effect. Eventually I renamed the module namespace and that fixed it.
(My guess is that there was some sort of cache of compiled modules and it was referencing a module which no longer existed, but the cljc wasn't re-compiled because a module of that name was still cached.)
When I renamed the module namespace it worked, with no other changes to the code.

Locating Clojure Browser Dom

I am using the following namespace for a graphics demo
(ns foo.core
(:use [clojure.browser.dom :only [get-element]]))
However, I return a File not found exception for clojure browser dom in the classpath.
Clojurescript has been pulled, and is contained within the file I cd into. But is not contained in the file I am trying to load, after having accessed the REPL.
Is clojure.browser.dom out of date? Or, am I missing something within the implementation?
Edit
I have not included the dependency for this file.
That namespace is correct:
https://github.com/clojure/clojurescript/blob/master/src/cljs/clojure/browser/dom.cljs
Maybe the problem is the ns form? Try
(ns foo.core
(:require [clojure.browser.dom :refer [get-element]]))
Also, just in case, be sure to name your file .cljs and restart the cljsbuild compiler, just in case.

Problems while opening the REPL

Anytime I fire up a fresh REPL I always get the same message, namely
#<FileNotFoundException java.io.FileNotFoundException: Could not locate test_app/core_init.class or test_app/core.cljon classpath:>
The namespace I've been using is ns test-app.core
The REPL still continues to come up and I am able to execute code with it. I am just unsure if this will lead to future problems, such as trying to work with incanter or other libraries.
Does your project.clj contain the following line, per chance?
...
:main test-app.core
...
Leiningen will try to switch into that namespace before showing the REPL to you. If it cannot find it, you'll see the error you mentioned. Now, the reason it cannot find it is another topic to explore, so first make sure that this is how your directory structure looks like:
.
|-- project.clj
|-- src
|-- test_app
|-- core.clj
If it does, I guess it's time to post Leiningen and Java versions (and ideally your project.clj) to let SO try to tackle this miraculous REPL. :)
Edit: The solution to this problem would - if any of the above suggestions match your case - of course be to either remove the :main line from your project file or to adjust the directory structure.
There needs to be a core.clj file in the folder named test_app in your project structure.
Basically, the file name should apply the naming towards whatever you've declared in your ns form.
As the Clojure Documentation FAQ says,
In order to use a Java class or Clojure namespace in your program,
that class or namespace must be "on the classpath," that is, inside a
directory or JAR file listed in the classpath.

Clojure namespacing converting - to _

The error as shown on the Noir error page: java.io.FileNotFoundException: Could not locate boundaries/lat_long__init.class or boundaries/lat_long.clj on class path
The code that requires it:
(ns boundaries.views.boundary
(:use noir.core
hiccup.core
hiccup.page-helpers)
(:require
[boundaries.lat-long :as lat-long]
[noir.response :as resp]))
Why is it looking for lat_long instead of the specified lat-long? boundaries/lat-long.clj exists as well as the corresponding boundaries.lat-long namespace.
the JVM does not allow -s in class names so the Clojure compiler converts them to _s
the problem is most likely with the project.clj dependencies.
When diagnosing this sort of issue:
is the namespace available from the REPL?
does the .class file appear in the lib directory for the project?
re-run lein deps
You need to rename the boundaries/lat-long.clj to boundaries/lat_long.clj.
Note that you don't have to change the namespace name. The clojure convention is to use "-" for functions and namespace names.
From Stuart Sierra response at https://stackoverflow.com/a/4451693/151650: "It's a necessary workaround for Java interoperability."