I understand ClojureScript can be executed within a JavaScript REPL or it can be compiled into JavaScript, then run in a browser. I couldn't find a way to use it on the server side with Rhino. Here is my way of thinking, I have a simple source file:
(ns simple.hello)
(println "Hello, world")
I compile it to hello.js. I try to run
java -jar js.jar out/goog/base.js out/goog/deps.js out/hello.js
Nothing happens. How can I make it work, or is only Node.js supported on the command line?
This works for me:
src/app.js:
(ns simple.app)
(ns hello)
(defn ^:export greet [n]
(print (str "Hello " n)))
(greet "World")
To compile:
cljsc src '{:optimizations :advanced}' > app-prod.js
Then, to run with Rhino:
java -jar js.jar app-prod.js
Output: Hello World
Hope that helps!
Related
I've made simplest Pedestal project and run it in my repl locally. However, after checking browser at localhost:8890 I saw � (replacement characters) instead of actual text (cyrillic symbols) I put in my Pedestal route.
I also checked in browser devtools response headers:
Content-Type:text/html;charset=utf-8 is present.
Before you ask:
Yes, I set up charset=UTF-8 in response, as you can see in code below.
My core.clj file is also in UTF-8 encoding.
I've tried other browsers as well, same thing.
Additional info: I'm using Windows, but have never encountered this issue before with other libraries and frameworks (ring, yada). Could it be that Pedestal somehow corrupts my code internally while passing it to jetty server? I dunno.
The whole code of project:
(ns samplepedestal.core
(:require [io.pedestal.http :as http]
[io.pedestal.http.route :as route])
(:gen-class))
(defn html-response
[req]
{:status 200
:body "<html lang=\"ru\">
<head>
<meta charset=\"utf-8\" />
<title>Текст на русском</title>
</head>
<body>Текст на русском</body>
</html>"
:headers {"Content-Type" "text/html; charset=UTF-8"}})
(def routes
(route/expand-routes
[[["/" {:get `html-response}]]]))
(def service-map
{::http/routes routes
::http/type :jetty
::http/port 8890})
(defn start []
(http/start (http/create-server service-map)))
;; -- Interactive development
(defonce server (atom nil))
(defn start-dev []
(reset! server
(http/start (http/create-server
(assoc service-map
::http/join? false)))))
(defn stop-dev []
(http/stop #server))
(defn restart []
(stop-dev)
(start-dev))
;; ---
(defn -main
"I don't do a whole lot ... yet."
[& args]
(println "Hello, World!"))
This is kind of strange behaviour, I have no clue what I'm missing, so any help would be appreciated. Thanks!
I think the problem is in how REPL starts. Have you got something along the lines of
Starting nREPL server... "C:\Program
Files\Java\jdk1.8.0_66\jre\bin\java" -Dfile.encoding=Cp1251
-XX:-OmitStackTraceInFastThrow -Dclojure.compile.path=D:\workspace-clojure\the-next-big-server-side-thing\target\classes
-Dthe-next-big-server-side-thing.version=0.0.1-SNAPSHOT -Dclojure.debug=false -Didea.launcher.port=50071 "-Didea.launcher.bin.
when REPL starts?
If so, you might want to add new JVM parameter to fix that.
I'm working through the newly released Vulkan Tutorial in Clojure with CIDER, and I've hit a bit of a snag. The example makefile project works perfectly, but I'm having trouble translating it into Clojure.
My build.boot file just specifies the :source-paths and adds LWJGL as a dependency:
(set-env!
:source-paths #{"src"}
:dependencies
(let [lwjgl-version "3.0.0"]
[['org.lwjgl/lwjgl lwjgl-version]
['org.lwjgl/lwjgl-platform lwjgl-version :classifier "natives-linux"]]))
Then, in src/example/core.clj, I have an extension-count function that uses vkEnumerateInstanceExtensionProperties as demonstrated in the original example:
(ns example.core
(:import (org.lwjgl.vulkan VK10)))
(defn extension-count []
(let [^String layer-name nil
property-count (int-array 1)]
(VK10/vkEnumerateInstanceExtensionProperties layer-name property-count nil)
(first property-count)))
Now, from Bash, I can set the relevant environment variables LD_LIBRARY_PATH and VK_LAYER_PATH as I start up a REPL:
$ VULKAN_SDK_PATH=~/VulkanSDK/1.0.21.1/x86_64 LD_LIBRARY_PATH=$VULKAN_SDK_PATH/lib VK_LAYER_PATH=$VULKAN_SDK_PATH/etc/explicit_layer.d boot repl
boot.user=> (require '[example.core :refer [extension-count]])
nil
boot.user=> (extension-count)
4
As you can see, everything works correctly. But of course, when I use cider-jack-in by C-c M-j instead, I get an UnsatisfiedLinkError because CIDER isn't setting those variables:
boot.user> (import (java.util.function Consumer)
(org.lwjgl.system Configuration))
org.lwjgl.system.Configuration
boot.user> (Configuration/setDebugStreamConsumer
(reify Consumer
(accept [_ message]
(println message))))
nil
boot.user> (require '[example.core :refer [extension-count]])
nil
boot.user> (extension-count)
[LWJGL] Failed to load a library. Possible solutions:
a) Set -Djava.library.path or -Dorg.lwjgl.librarypath to the directory that contains the shared libraries.
b) Add the JAR(s) containing the shared libraries to the classpath.
[LWJGL] Enable debug mode with -Dorg.lwjgl.util.Debug=true for better diagnostics.
java.lang.UnsatisfiedLinkError: Failed to locate library: libvulkan.so.1
Am I supposed to be setting java.library.path or org.lwjgl.librarypath, as suggested in the above error message, instead of LD_LIBRARY_PATH? I can set either of those variables from profile.boot:
(System/setProperty
"java.library.path"
(str (System/getProperty "user.home") "/VulkanSDK/1.0.21.1/x86_64/lib"))
Now when I try C-c M-j again, it works:
boot.user> (require '[example.core :refer [extension-count]])
nil
boot.user> (extension-count)
4
However, this still doesn't let me set VK_LAYER_PATH, which will be fairly important in the future:
We will start using validation layers in Vulkan and you need to tell the Vulkan library where to load these from using the VK_LAYER_PATH variable:
test: VulkanTest
LD_LIBRARY_PATH=$(VULKAN_SDK_PATH)/lib VK_LAYER_PATH=$(VULKAN_SDK_PATH)/etc/explicit_layer.d ./VulkanTest
How can I set these environment variables for cider-jack-in? I'd prefer not to have to manually configure CIDER's dependencies for a standalone repl in a separate terminal and then connect to it using cider-connect, but if there's no other option here, I guess that's what I'll have to do.
I'm trying to test mire.
When I execute this code
(ns mire
(:use [clojure.contrib server-socket duck-streams]))
I have java.io.FileNotFoundException error.
Googling to find that clojure.contrib is deprecated, I added server-socket as dependencies in the project.clj, and executed leon repl to install the jar libraries
mire> lein repl
Retrieving server-socket/server-socket/1.0.0/server-socket-1.0.0.pom from clojars
Retrieving server-socket/server-socket/1.0.0/server-socket-1.0.0.jar from clojar
Then in the emacs/cider, I tried to use this code to get the same FileNotFoundException error.
(ns mire
(:use [server.socket server-socket duck-streams]))
java.io.FileNotFoundException: Could not locate server/socket/server_socket__init.class or
server/socket/server_socket.clj on class path:
In command line REPL, (use [server.socket server-socket]) gives me the same error message.
What might be wrong? I use emacs/cider/nREPL. This is the project.clj.
(defproject mire "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:dependencies [[org.clojure/clojure "1.5.1"]
[server-socket "1.0.0"]])
This is the code that causes an error:
(ns mire
(:use [clojure.contrib server-socket duck-streams]))
(def port (* 3 1111))
(defn mire-handle-client [in out]
(binding [*in* (reader in)
*out* (writer out)]
(loop []
(println (read-line))
(recur))))
(def server (create-server port mire-handle-client))
From the code in Building an Echo Server in Clojure - Part 2, this is the working code with server.socket.
(ns mire
(:use server.socket))
(import '[java.io BufferedReader InputStreamReader OutputStreamWriter])
(def port (* 3 1111))
(defn mire-handle-client [in out]
(binding [*in* (BufferedReader. (InputStreamReader. in))
*out* (OutputStreamWriter. out)]
(loop []
(println (read-line))
(recur))))
(def server (create-server port mire-handle-client))
The namespaces are usually dot-separated. server.socket in this library is.
Try this:
(ns mire (:use [server.socket]))
I run tests with:
lein midje :autotest
And I get error:
Exception in thread "main" java.lang.Exception: No namespace: sprint-is.json-export found
File is in: sprint-is/src/sprint_is/json_export.clj
It contains code:
(ns sprint-is.json-export)
(require [[noir.response :as response]])
(defn serialize [value] (response/json value))
It throws this error even when I don't have no test file. When I create test file, I get similar error:
No namespace: sprint-is.test.json-export found
Test is in: sprint-is/test/sprint_is/json_export.clj
And contains:
(ns sprint-is.test.json-export
(:require [sprint-is.json-export :as json-export]))
(fact "module can serialize scalar values"
(json-export/serialize 123) => 123)
When I try to import it from REPL, it cannot find the namespaces too. I tried to rename file, move files, rename directories, remove ns (it compiles but it doesn't work), asked on Clojure IRC. I compared the code with other projects (including those working on my computer) and it seems same.
Source code is here: https://bitbucket.org/jiriknesl/sprintis
You have a compilation error in one of your namespaces, I suspect sprint-is.json-export
On bitbucket, you have this:
(ns sprint-is.json-export)
(require [[noir.response :as response]])
(defn serialize [value] (response/json value))
which won't compile because noir.response and response are not defined.
you should have:
(ns sprint-is.json-export
(:require [noir.response :as response]))
(defn serialize [value] (response/json value))
If you insist on using require outside of the ns macro, you can do the following, but be aware this is not idiomatic usage.
(ns sprint-is.json-export)
(require '[noir.response :as response])
(defn serialize [value] (response/json value))
I'm new to the whole JVM thing, and trying to play with clojure. I'm attempting to load clojure-contrib and failing:
# in bash
$ java -cp /path/to/clojure.jar:/path/to/contrib.jar clojure.main
# in REPL
user=> (require 'clojure.contrib.math)
nil
user=> (sqrt 2)
java.lang.Exception: Unable to resolve symbol: sqrt in this context (NO_SOURCE_FILE:10)
Any pointers will be great - thanks.
I'm no expert, but it seemed like a namespace issue. The solution I employed was this:
;; for REPL
user=> (ns user (:use clojure.contrib.math))
nil
user=> (sqrt 2)
1.4142135623730951
You should put refer after require which will map all the symbols into current namespace
(require 'clojure.contrib.math)
(refer 'clojure.contrib.math)
(sqrt 2)
(expt 2 3)
For detailed intro you may read wikibooks article.
http://en.wikibooks.org/wiki/Clojure_Programming/Concepts#Refer_and_Use