Is there a bug with foreign-libs in the cljsbuild repl? - clojure

When I:
clone the cljs-webgl project,
Compile it with:
lein cljsbuild once
Start the repl with
lein trampoline cljsbuild repl-listen
Paste the following into the REPL
`
(ns learningwebgl.lesson-06
(:require
[WebGLUtils]
[mat4]
[learningwebgl.common :refer [init-gl init-shaders get-perspective-matrix
get-position-matrix deg->rad animate load-image]]
[cljs-webgl.buffers :refer [create-buffer clear-color-buffer clear-depth-buffer draw!]]
[cljs-webgl.shaders :refer [get-attrib-location]]
[cljs-webgl.constants.buffer-object :as buffer-object]
[cljs-webgl.constants.capability :as capability]
[cljs-webgl.constants.draw-mode :as draw-mode]
[cljs-webgl.constants.data-type :as data-type]
[cljs-webgl.constants.texture-parameter-name :as texture-parameter-name]
[cljs-webgl.constants.texture-filter :as texture-filter]
[cljs-webgl.constants.webgl :as webgl]
[cljs-webgl.texture :refer [create-texture]]
[cljs-webgl.typed-arrays :as ta]))`
I get the following:
WARNING: No such namespace: WebGLUtils at line 1 <cljs repl>
(even though it is defined in the project.clj as:
:foreign-libs [
{:file "resources/js/gl-matrix-min.js" :provides ["mat4","mat3","vec3"]}
{:file "resources/js/webgl-utils.js" :provides ["WebGLUtils"]}]}
My question is: Is there a bug with foreign-libs in the cljsbuild repl?

:foreign-libs support in ClojureScript REPLs is quite new, and cljs-webgl is using a fairly old version of the compiler without the support.

Related

Using lein ring server, how to switch to another adapter than ring-jetty-adapter

Given a simple webapplication like
(ns webtest.handler
(:require [compojure.core :refer :all]
[compojure.route :as route]
[ring.middleware.defaults :refer [wrap-defaults site-defaults]]))
(defroutes app-routes
(GET "/" [] "Hello World")
(route/not-found "Not Found"))
(def app
(-> (wrap-defaults app-routes site-defaults)))
that can be started using lein ring server, how would one be able to adapt the project to switch out the jetty adapter for another ring adapter, for instance undertow or http-kit?
For reference, here's the excerpt of the lein project.clj in use:
:dependencies [[org.clojure/clojure "1.9.0"]
[ring "1.8.1" :exclusions [ring/ring-jetty-adapter]]
[luminus/ring-undertow-adapter "1.1.0"]
[ring/ring-defaults "0.3.2"]
[compojure "1.6.1"]]
:plugins [[lein-ring "0.12.5"]]
:ring {:handler webtest.handler/app}
You can use :adapter key.
Finally I tested and no, the tag :adapter allows to pass the options for ring.jetty.adapter only.
After analyse the source code, there is no possibility to switch the adapter.
Here an reponse from the plugin author to a similar query:
https://stackoverflow.com/a/24307363/5773724

Clojure: Timbre and clojure.test namespaces

Trying to get Timbre to load in my test project along with clojure.test. My first attempt is
(ns foo.core-test
(:require [clojure.test :refer :all]
[taoensso.timbre :as timbre]
[foo.core :refer :all]))
which compiles until I follow the next step in the Timbre documentation, adding
(timbre/refer-timbre) ; Provides useful Timbre aliases in this ns
I now get the following compile error
IllegalStateException report already refers to #'clojure.test/report in namespace foo.core-test
clojure.lang.Namespace.warnOrFailOnReplace (Namespace.java:88)
ok, groovy, I'll try
(ns foo.core-test ; ------vvvvvvvvvvvvvvvv-----
(:require [clojure.test :exclude [report]]
[taoensso.timbre :as timbre]
[foo.core :refer :all]))
mmmm, nope. I notice that clojure has a report, too. How about
(ns foo.core-test
(:refer-clojure :exclude [report])
(:require [clojure.test :refer :all]
[taoensso.timbre :as timbre]
[foo.core :refer :all]))
mmmmm, nope.
I hacked around for a while till I got tired of combinatorial trial-and-error. I haven't found a way to make them coexist. Any clues, please & thanks?
There's no report in clojure.core. In your second ns form you seem to be missing :refer :all for clojure.test. Try the following form:
(ns foo.core-test
(:require [clojure.test :refer :all :exclude [report]]
[taoensso.timbre :as timbre]
[foo.core :refer :all]))

Clojure FileNotFound exception when running uberjar, though file is in project source

I am pulling my hair out trying to resolve the following error:
Exception in thread "main" java.io.FileNotFoundException: Could not locate composer/midi/short_message__init.class or composer/midi/short_message.clj on classpath: , compiling:(events.clj:12:1)
The reference to short-message is in the namespace declaration of events.clj:
(ns composer.ui.events
(:use [seesaw core border chooser])
(:require [composer.midi
[io :as io]
[time :as time]
[player :as player]
[short-message :as short]]))
And here is the namespace declaration of short-message itself in short-message.clj:
(ns composer.midi.short-message
(:require [composer.algorithm.transform :refer :all]
[composer.algorithm.markov.transform :refer :all]
[composer.midi [io :refer :all] [message :as message]]))
short-message is in the same directory as all other files in composer.midi, and yet this seems to be the only one that is resulting in an issue. Indeed, after verifying the target directory in my project, this is the only namespace which doesn't seem to contain a corresponding class file. I thought it could be an error with the code, but if I try to load the file with (load-file "src/composer/midi/short-message.clj") at the REPL I don't have any issues.
Your comment is right. In clojure dashes in namespaces correspond to underscore in filenames. So your file name should be short_message.clj as you found.

How to Run Jetty Example with Ring in Clojure

I am following along with this example on creating a simple web service in Clojure using ring and jetty.
I have this in my project.clj:
(defproject ws-example "0.0.1"
:description "REST datastore interface."
:dependencies
[[org.clojure/clojure "1.5.1"]
[ring/ring-jetty-adapter "0.2.5"]
[ring-json-params "0.1.0"]
[compojure "0.4.0"]
[clj-json "0.5.3"]]
:dev-dependencies
[[lein-run "1.0.0-SNAPSHOT"]])
This in script/run.clj
(use 'ring.adapter.jetty)
(require '[ws-example.web :as web])
(run-jetty #'web/app {:port 8080})
And this in src/ws_example/web.clj
(ns ws-example.web
(:use compojure.core)
(:use ring.middleware.json-params)
(:require [clj-json.core :as json]))
(defn json-response [data & [status]]
{:status (or status 200)
:headers {"Content-Type" "application/json"}
:body (json/generate-string data)})
(defroutes handler
(GET "/" []
(json-response {"hello" "world"}))
(PUT "/" [name]
(json-response {"hello" name})))
(def app
(-> handler
wrap-json-params))
However, when I execute:
lein run script/run.clj
I get this error:
No :main namespace specified in project.clj.
Why am I getting this and how do I fix it?
You're getting this error because the purpose of lein run (according to lein help run) is to "Run the project's -main function." You don't have a -main function in your ws-example.web namespace, nor do you have a :main specified in your project.clj file, which is what lein run is complaining about.
To fix this, you have a few options. You could move the run-jetty code to a new -main function of the ws-example.web function and then say lein run -m ws-example.web. Or you could do that and also add a line :main ws-example.web to project.clj and then just say lein run. Or you could try using the lein exec plugin to execute a file, rather than a namespace.
For more info, check out the Leiningen Tutorial.
You have to put that (run-jetty) stuff into a -main somewhere and then add it to the project.clj like
:main ws-example.core)
From lein help run:
USAGE: lein run -m NAMESPACE[/MAIN_FUNCTION] [ARGS...]
Calls the main function in the specified namespace.
So, you would need to put your script.clj somewhere on the project source path and then call it as:
lein run -m script

Clojure CLR with multiple namespaces

I wrote a small namespace to do some database operations and I would like to use it from within another namespace. Normally having the files in the same directory and then doing
(ns program (:require [other-ns :as other]) (:gen-class))
would be all that's necessary. However this doesn't work in Clojure CLR, compiler complains about not knowing about other-ns. So what is the proper method of doing this? Having a seperate assembly for every namespace?
[EDIT] Another example
another.clj
(ns another)
(defn hello [name] (str "Hello " name))
program.clj
(ns program
(:require [another :as a])
(:gen-class))
I load up program.clj in the repl and get this message:
FileNotFoundException Could not locate another.clj.dll or another.clj on load path. clojure.lang.RT.load (d:\work\clojure-clr\Clojure\Clojure\Lib\RT.cs:3068)
I created two files in the same directory filea.clj and fileb.clj. Here's filea.clj:
(ns filea)
(defn hi []
(println "hi from filea"))
Here's fileb.clj:
(ns fileb
(require [filea :as a])
(:gen-class))
(defn -main []
(println "hi from fileb")
(a/hi))
I then changed into the directory where these files live and ran:
C:\temp\multi-ns>clojure.compile fileb
Compiling fileb to . -- 59 milliseconds.
And when I ran it I saw:
C:\temp\multi-ns>c:\Tools\clojure-clr-1.3.0-Debug-4.0\fileb.exe
hi from fileb
hi from filea
Are you using vsClojure or writing your code outside of VS?