ClojureScript compiler NullPointerException on OS X when trying to compile simple project - clojure

I tried following the ClojureScript quick start guide http://clojurescript.org/guides/quick-start and hit an NPE trying to manually invoke the clojurescript compiler on OS X.
I have java 1.8.0_92
% javac -version
javac 1.8.0_92
I made a new directory (for the sake of completeness ~/tmp/clojure/cljstest/). All paths are relative to this directory. I think I am using version 1.9.293 of clojurescript.
% cat $(which cljsc)
#!/bin/bash
exec java -jar /usr/local/Cellar/clojurescript/1.9.293/libexec/cljs.jar "$#"
The cljsc jar by itself, however, works fine.
% cljsc
Clojure 1.8.0
user=>
I also downloaded the standalone cljs.jar mentioned in the tutorial and checked the md5sum to make sure that they're the same.
% wget https://github.com/clojure/clojurescript/releases/download/r1.9.293/cljs.jar
% md5 cljs.jar
MD5 (cljs.jar) = 658d7b722cebe46e36604baf9eecfcb5
% md5 /usr/local/Cellar/clojurescript/1.9.293/libexec/cljs.jar
MD5 (/usr/local/Cellar/clojurescript/1.9.293/libexec/cljs.jar) = 658d7b722cebe46e36604baf9eecfcb5
I ran
% mkdir -p src/hello_world
and then
% touch ./src/hello_world/core.cljs
The contents of ./src/hello_world/core.cljs are:
(ns hello-world.core)
(enable-console-print!)
(println "Hello World!")
The contents of ./build.clj are:
(require 'cljs.build.api)
(cljs.build.api/build "src" {:output-to "out/main.js"})
I downloaded clojure through homebrew
% where cljsc
/usr/local/bin/cljsc
This is a shell script that I used to locate the .jar
% cat $(which cljsc)
#!/bin/bash
exec java -jar /usr/local/Cellar/clojurescript/1.9.293/libexec/cljs.jar "$#"
I tried running the compiler with the explicit classpath given in the tutorial
% java -cp /usr/local/Cellar/clojurescript/1.9.293/libexec/cljs.jar:src clojure.main build.clj
That produced the following stack trace:
% java -cp /usr/local/Cellar/clojurescript/1.9.293/libexec/cljs.jar:src clojure.main build.clj
Exception in thread "main" java.lang.NullPointerException, compiling:(/Users/gregnisbet/tmp/clojure/cljstest/build.clj:3:1)
at clojure.lang.Compiler.load(Compiler.java:7391)
at clojure.lang.Compiler.loadFile(Compiler.java:7317)
at clojure.main$load_script.invokeStatic(main.clj:275)
at clojure.main$script_opt.invokeStatic(main.clj:335)
at clojure.main$script_opt.invoke(main.clj:330)
at clojure.main$main.invokeStatic(main.clj:421)
at clojure.main$main.doInvoke(main.clj:384)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.lang.Var.invoke(Var.java:379)
at clojure.lang.AFn.applyToHelper(AFn.java:154)
at clojure.lang.Var.applyTo(Var.java:700)
at clojure.main.main(main.java:37)
Caused by: java.lang.NullPointerException
at cljs.closure$build.invokeStatic(closure.clj:1920)
at cljs.build.api$build.invokeStatic(api.clj:198)
at cljs.build.api$build.invoke(api.clj:187)
at cljs.build.api$build.invokeStatic(api.clj:190)
at cljs.build.api$build.invoke(api.clj:187)
at user$eval24.invokeStatic(build.clj:3)
at user$eval24.invoke(build.clj:3)
at clojure.lang.Compiler.eval(Compiler.java:6927)
at clojure.lang.Compiler.load(Compiler.java:7379)
... 11 more
I expected the clojurescript compiler to either produce main.js or give me a clojurescript-related error message. Why is the ClojureScript compiler throwing a NullPointerException? Is it a compiler bug?

Related

requre deps in idea clojure repl, get FileNotFoundException

I created a new Leiningen project in idea, and imported some deps in project.clj as follows:
deps
and deps seems to be imported:
external libraries
But when I try to run repl, and required some deps that I imported in project.clj before, an FileNotFoundException has occurred:
FileNotFoundException
Starting nREPL server...
"E:\Program Files\Java\jdk-11.0.8\bin\java.exe" -Dfile.encoding=GBK -XX:-OmitStackTraceInFastThrow -Dclojure.compile.path=E:\idea_projects\clojure_test_second\target\classes -Dclojure_test_second.version=0.1.0-SNAPSHOT -Dclojure.debug=false "-javaagent:D:\Program Files\JetBrains\IntelliJ IDEA 2021.1.3\lib\idea_rt.jar=50688:D:\Program Files\JetBrains\IntelliJ IDEA 2021.1.3\bin" -classpath E:\idea_projects\clojure_test_second\test;E:\idea_projects\clojure_test_second\src;E:\idea_projects\clojure_test_second\dev-resources;E:\idea_projects\clojure_test_second\resources;E:\idea_projects\clojure_test_second\target\classes;C:\Users\asus\.m2\repository\org\clojure\clojure\1.10.1\clojure-1.10.1.jar;C:\Users\asus\.m2\repository\org\clojure\spec.alpha\0.2.176\spec.alpha-0.2.176.jar;C:\Users\asus\.m2\repository\org\clojure\core.specs.alpha\0.2.44\core.specs.alpha-0.2.44.jar;C:\Users\asus\.m2\repository\hiccup\hiccup\1.0.5\hiccup-1.0.5.jar;C:\Users\asus\.m2\repository\clojure\jdbc\clojure.jdbc\0.4.0\clojure.jdbc-0.4.0.jar;C:\Users\asus\.m2\repository\com\h2database\h2\1.4.193\h2-1.4.193.jar;C:\Users\asus\.m2\repository\nrepl\nrepl\0.6.0\nrepl-0.6.0.jar;C:\Users\asus\.m2\repository\clojure-complete\clojure-complete\0.2.5\clojure-complete-0.2.5.jar clojure.main -i C:\Users\asus\AppData\Local\Temp\form-init14732922726375964945.clj
Connecting to local nREPL server...
Clojure 1.10.1
nREPL server started on port 50817 on host 127.0.0.1 - nrepl://127.0.0.1:50817
(require '[clojure.java.jdbc :as jdbc])
Execution error (FileNotFoundException) at clojure-test-second.core/eval1555 (form-init14732922726375964945.clj:1).
Could not locate clojure/java/jdbc__init.class, clojure/java/jdbc.clj or clojure/java/jdbc.cljc on classpath.
jdk version is 11, idea version is 2021.1.3.
I searched solution for a long time, but didn't solve it. And I am a noob in clojure.
Thanks.
You have to
add [org.clojure/java.jdbc "0.7.12"] in project.clj file of your leiningen project folder. under :dependencies [ <add into this list> [org.clojure/java.jdbc "0.7.12"]].
Then you do $ lein deps from inside folder of your leiningen project folder, to ensure installation of that dependencies.
Then if you did M-x cider-jack-in from inside emacs opened inside project folder, you can do your require command. OR you just do $ lein repl from there and you can then do your (require '[clojure.java.jdbc :as j]) - voila!
Coming from Common Lisp, I was also quite lost like you.
Clojure requires Leiningen or Boot to function reasonably.
Whenever you have to install Clojure in a new machine, install first Leiningen, because you can install Cloure also using Leiningen.
With Boot, you can even create standalone scripts/executives which uses Clojure.
But also with Leiningen see here.
Install and use Boot
I think the way you want to use the repl - more freely -
suits more to Boot:
# install boot e.g. by (for linux)
$ sudo bash -c "cd /usr/local/bin && curl -fsSLo boot https://github.com/boot-clj/boot-bin/releases/download/latest/boot.sh && chmod 755 boot"
# upgrade!
$ boot -u
# create your project folders and move into toplevel
mkdir -p my-project/src
cd my-project
# then open repl
$ boot repl
;; within the repl:
;; declare resource-paths and dependencies
(set-env! :resource-paths #{"src"}
:dependencies '[[org.clojure/java.jdbc "0.7.12"]])
;; create a minimal project declaration
(task-options!
pom {:project 'my-project
:version "0.1.0"}
jar {:manifest {"Foo" "bar"}})
;; build the minimal project (to install the dependencies!)
(deftask build
"Build my project."
[]
(comp (pom) (jar) (install)))
;; call build
(build)
;; now, in the repl, you can do:
(require '[org.clojure/java.jdbc :as j])
Boot is more dynamic - since you can from the repl introduce dependencies and build.

How can I run lein repl outside of a project?

I spent some time last night messing with my leinigen profiles.clj to get rid of all the errors that were being printed when starting cider in my project. Today I went to start a repl from the terminal (I like to keep one open while I work) but it didn't work. I thought it was a cider issue so I tried it from Emacs but even in Emacs if I'm not in a project the repl won't start.
Here's the error:
Error loading refactor-nrepl.middleware: clojure.lang.ArityException: Wrong number of args (4) passed to: StringReader, compiling:(abnf.clj:186:28)
Exception in thread "Thread-4" java.lang.RuntimeException: Unable to resolve var: refactor-nrepl.middleware/wrap-refactor in this context, compiling:(NO_SOURCE_PATH:0:0)
...
Caused by: java.lang.RuntimeException: Unable to resolve var: refactor-nrepl.middleware/wrap-refactor in this context
My ~/.lein/profiles.clj
{:user {:plugins [[lein-try "0.4.3"]
[refactor-nrepl "1.1.0"]
[cider/cider-nrepl "0.9.1"]]
:dependencies [[org.clojure/tools.nrepl "0.2.12"]
[acyclic/squiggly-clojure "0.1.4"]
^:replace [org.clojure/tools.nrepl "0.2.12"]
[refactor-nrepl "1.1.0"]]}}
The versions of things when cider starts in a project
; CIDER 0.9.1 (Java 1.8.0_45, Clojure 1.7.0, nREPL 0.2.12)
I'm still pretty new to Clojure, Leinigen, Emacs, etc so I'm not sure why everything above made made my cider errors go away but it did. The cider errors I was getting were having to do with the nrepl version being too low and not having certain things installed (like refactor-nrepl).
When starting a repl from lein using lein repl, it really wants to run in a lein project dir. I keep an empty lein project named clj around in my home dir for this purpose. That way, my common dependencies are already there in the project.clj file, and lein is pre-configured just the way I like it.
You can start lein repl in an empty dir, but you get 10-20 error messages each time before it starts.
Another way is to use the plain repl built into the clojure jar file:
~/dummy > cp /home/alan/.m2/repository/org/clojure/clojure/1.8.0-RC1/clojure-1.8.0-RC1.jar .
~/dummy > d *
-rw-rw-r-- 1 alan alan 3935726 Nov 19 14:11 clojure-1.8.0-RC1.jar
~/dummy > java -jar clojure-1.8.0-RC1.jar
Clojure 1.8.0-RC1
user=>
As you can see, I created an empty directory named dummy and copied in the clojure-*.jar file. You can then run it with the syntax java -jar xxx.jar and it will fire up a repl completely independently of lein.
I also just keep a scratch project which I use for quick/simple repl sessions. There is a lien-oneoff plugin which is supposed to make it easy to work with simple single file lein projects which might be useful.
The other thing you could do is setup a boot config for basically getting a repl up to work with
what is your lein version, I am use 2.5.3, I can start lein repl anywhere.
Shell:~ >: lein repl
nREPL server started on port 52343 on host 127.0.0.1 - nrepl://127.0.0.1:52343
REPL-y 0.3.7, nREPL 0.2.10
Clojure 1.7.0
Java HotSpot(TM) 64-Bit Server VM 1.8.0_60-b27
Docs: (doc function-name-here)
(find-doc "part-of-name-here")
Source: (source function-name-here)
Javadoc: (javadoc java-object-or-class-here)
Exit: Control+D or (exit) or (quit)
Results: Stored in vars *1, *2, *3, an exception in *e
user=> Bye for now!
Shell:~ >: lein version
Leiningen 2.5.3 on Java 1.8.0_60 Java HotSpot(TM) 64-Bit Server VM
Shell:~ >: cat .lein/profiles.clj
{:1.2 {:dependencies [[org.clojure/clojure "1.2.0"]]}
:1.3 {:dependencies [[org.clojure/clojure "1.3.0"]]}
:1.4 {:dependencies [[org.clojure/clojure "1.4.0"]]}
:user {:plugins [[lein-immutant "2.0.0-alpha2"]
[lein-clojars "0.9.1"]
[lein-ancient "0.5.5"]
[lein-kibit "0.0.8"]
[lein-try "0.4.3"]
[venantius/ultra "0.2.0"]]
:ultra {:color-scheme :solarized_dark}}}

Leiningen has problems building a working uberjar

We're trying to build our Clojure project with Leiningen. We've succeeded in creating an uberjar by doing the following:
preconditions:
project.clj file lists dependencies
:main my-project.core in project.clj
a core.clj file with a -main function
(:gen-class :main true) in core.clj
procedure:
ran lein test; completed with no failures
ran lein deps; completed successfully
from project.clj's directory: rain lein uberjar
This created two jar files: My-Project-1.0.0-SNAPSHOT-standalone.jar, and My-Project-1.0.0-SNAPSHOT.jar.
ran java -jar BioClojure-1.0.0-SNAPSHOT-standalone.jar, which resulted in this exception:
Exception in thread "main" java.lang.SecurityException: Invalid signature file digest for Manifest main attributes
My research into this problem has not been fruitful. Apparently, it's a known problem with no good solution. I do not understand the answers there.
What do we need to do to get our uberjar working?
determine which of our dependencies is causing the problem?
remove dependencies from our project?
compile the project some other way?
patch leiningen?
use the suggested command: zip *-standalone.jar -d META-INF/DUMMY.SF (I have no idea what this does)
do something with :uberjar-exclusions in the project.clj file? (if so, what?)
Lein and java versions:
$ lein version
Leiningen 1.6.1 on Java 1.6.0_26 Java HotSpot(TM) 64-Bit Server VM
Update: running the command suggested gives:
$ unzip -l BioClojure-1.0.0-SNAPSHOT-standalone.jar | grep -i -e "\.sf"
49911 08-27-09 15:57 META-INF/RCSB-PDB.SF
0 03-23-10 08:21 META-INF/maven/net.sf.alxa/
0 03-23-10 08:21 META-INF/maven/net.sf.alxa/jlatexmath/
929 03-23-10 08:20 META-INF/maven/net.sf.alxa/jlatexmath/pom.xml
115 03-21-10 14:01 META-INF/maven/net.sf.alxa/jlatexmath/pom.properties
175241 08-17-11 20:25 META-INF/SELFSIGN.SF
0 09-21-09 06:45 META-INF/maven/net.sf.opencsv/
0 09-21-09 06:45 META-INF/maven/net.sf.opencsv/opencsv/
5510 09-21-09 06:44 META-INF/maven/net.sf.opencsv/opencsv/pom.xml
106 09-21-09 06:45 META-INF/maven/net.sf.opencsv/opencsv/pom.properties
My understanding from reading the comments in that issue is that your problem would go away if you add the following to your project.clj
:uberjar-exclusions [#"foo.sf"]
where foo.sf is the particular .sf file you want to ignore from the jar. You can determine this by running:
unzip -l BioClojure-1.0.0-SNAPSHOT-standalone.jar | grep -i -e "\.sf"
The suggested zip command deletes the particular file from the jar (which is of the ZIP format).

How to run a Clojure app with command line parameters

To run Clojure files from command line, I'm using a zhs alias I added to my .zshrc:
alias 'clojure=java -cp /home/sinan/cclojure/lib/clojure-1.2.1.jar:/home/sinan/cclojure/lib/clojure-contrib-1.2.0.jar clojure.main -i '
With this, I can run my Clojure app like this:
clojure test3.clj
But it doesn't work when I want to send command line parameters.
➜ src clojure test3.clj arg1 arg2
Exception in thread "main" java.io.FileNotFoundException: arg1 (No such file or directory)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:120)
at java.io.FileInputStream.<init>(FileInputStream.java:79)
at clojure.lang.Compiler.loadFile(Compiler.java:5817)
at clojure.main$load_script.invoke(main.clj:221)
at clojure.main$script_opt.invoke(main.clj:273)
at clojure.main$main.doInvoke(main.clj:354)
at clojure.lang.RestFn.invoke(RestFn.java:457)
at clojure.lang.Var.invoke(Var.java:377)
at clojure.lang.AFn.applyToHelper(AFn.java:172)
at clojure.lang.Var.applyTo(Var.java:482)
at clojure.main.main(main.java:37)
What am I doing wrong? Is my way of running Clojure apps wrong?
Thanks.
you just need to specify name of script, without -i key after clojure.main. In your case, clojure.main thinks, that test.clj is program to eval before (and it do it), while arg1 is script to execute
See description of option for clojure.main/main function

How to run clojure on Mac OS X?

I'm following the examples from the book 'Programming Clojure', and I'm at page
17 to run (require 'example.introduction).
I have set clojure at ~/bin/clojure as follows
java -server \
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8888 -cp ... clojure.lang.Repl
The -cp contains . (current directory). When I try it with clojure, I get the following error message.
Exception in thread "main" java.lang.ExceptionInInitializerError
at clojure.lang.Repl.(Repl.java:23)
Caused by: java.lang.RuntimeException: java.lang.NoSuchMethodError: clojure.lang.MultiFn.(Ljava/lang/String;Lclojure/lang/IFn;Ljava/lang/Object;Lclojure/lang/IRef;)V (utils.clj:0)
at clojure.lang.RT.(RT.java:290)
... 1 more
Caused by: java.lang.NoSuchMethodError: clojure.lang.MultiFn.(Ljava/lang/String;Lclojure/lang/IFn;Ljava/lang/Object;Lclojure/lang/IRef;)V (utils.clj:0)
at clojure.lang.Compiler.eval(Compiler.java:4153)
at clojure.lang.Compiler.load(Compiler.java:4470)
at clojure.lang.RT.loadResourceScript(RT.java:327)
at clojure.lang.RT.loadResourceScript(RT.java:316)
at clojure.lang.RT.load(RT.java:406)
at clojure.lang.RT.load(RT.java:376)
at clojure.core$load__4557$fn__4559.invoke(core.clj:3427)
at clojure.core$load__4557.doInvoke(core.clj:3426)
at clojure.lang.RestFn.invoke(RestFn.java:413)
at clojure.core$load_one__4520.invoke(core.clj:3271)
...
at clojure.lang.RT.loadResourceScript(RT.java:327)
at clojure.lang.RT.loadResourceScript(RT.java:312)
at clojure.lang.RT.maybeLoadResourceScript(RT.java:308)
at clojure.lang.RT.doInit(RT.java:430)
at clojure.lang.RT.(RT.java:286)
... 1 more
Caused by: java.lang.NoSuchMethodError: clojure.lang.MultiFn.(Ljava/lang/String;Lclojure/lang/IFn;Ljava/lang/Object;Lclojure/lang/IRef;)V
at clojure.contrib.duck_streams__init.load(Unknown Source)
at clojure.contrib.duck_streams__init.(Unknown Source)
...
at clojure.lang.Compiler.eval(Compiler.java:4142)
... 28 more
I tried to run clojure as follows.
alias clojure='java -jar $JARDIR/clojure.jar '
But it doesn't have the CLASSPATH that I setup in .bashrc correctly, when I run the command as follows.
(println (seq (.getURLs (java.lang.ClassLoader/getSystemClassLoader))))
What might be wrong?
The easiest way is to use Stuart Halloway's code that accompanies the book:
Clone Stu's code from GitHub: $ git clone http://github.com/stuarthalloway/programming-clojure.git
cd into the programming-clojure directory that was created: $ cd programming-clojure
Run the repl.sh script in the bin/ directory: $ ./bin/repl.sh (make sure you run it from the repo root, not the bin/ directory, otherwise it won't work).
The script will set up all the necessary paths, including the paths to the examples in the book.
(You can do it manually, of course, but at any rate, you have to download or clone the programming-clojure source code anyway for the examples to work.)