Lein is not running my main method - clojure

Lein is not running my main method. I've even introduced syntax errors, and it doesn't catch them. I'm really stumped. I'd greatly appreciate any assistance from the community.
I believe the main method is specified correctly. The first code sample is server.clj, with the main method. Next is my project.clj.
(ns naac.server
(:require [naac.handler :refer [handler]]
[config.core :refer [env]]
[migratus.core :as migratus]
[ring.adapter.jetty :refer [run-jetty]]
[naac.db :refer [load-db!]])
(:gen-class))
(def db-config {:store :database
:db (get (System/getenv) "DATABASE_URL"
"jdbc:postgresql://localhost:5432/jeff")
:migration-dir "migrations"})
(defn -main [& args]
(println args)
(doseq [a args]
(cond
(= a "migrate")
(do
(println "Migrate database...")
(migratus/migrate db-config)
(println "...Migration done."))
(= a "rollback")
(do
(println "Rollback database...")
(migratus/rollback db-config)
(println "...Rollback done."))
(= a "load")
(do
(println "Load database...")
(load-db!)
(println "...Load done."))))
(if (> (count args) 0) (System/exit 0))
(let [port (Integer/parseInt (or (env :port) "3000"))]
(run-jetty handler {:port port :join? false})))
My project.clj:
(defproject naac "0.1.0-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.8.0"]
[org.clojure/clojurescript "1.9.229"]
[reagent "0.6.0"]
[re-frame "0.9.2"]
[compojure "1.5.0"]
[yogthos/config "0.8"]
[migratus "0.9.2"]
[ring "1.4.0"]
[com.layerware/hugsql "0.4.7"]
[org.postgresql/postgresql "9.4.1207"]]
:plugins [[lein-cljsbuild "1.1.4"]
[migratus-lein "0.4.1"]]
:min-lein-version "2.5.3"
:source-paths ["src"]
:clean-targets ^{:protect false} ["resources/public/js/compiled" "target"]
:figwheel {:css-dirs ["resources/public/css"]
:ring-handler naac.handler/dev-handler}
:profiles
{:dev {:dependencies [[binaryage/devtools "0.8.2"]]
:plugins [[lein-figwheel "0.5.9"]]
:resource-paths ["resources/config"]}
}
:migratus {:store :database
:db ~(get (System/getenv) "DATABASE_URL"
"jdbc:postgresql://localhost:5432/jeff")
:migration-dir "migrations"}
:cljsbuild
{:builds
[{:id "dev"
:source-paths ["src/cljs"]
:figwheel {:on-jsload "naac.core/mount-root"}
:compiler {:main naac.core
:output-to "resources/public/js/compiled/app.js"
:output-dir "resources/public/js/compiled/out"
:asset-path "js/compiled/out"
:source-map-timestamp true
:preloads [devtools.preload]
:external-config {:devtools/config {:features-to-install :all}}
}}
{:id "min"
:source-paths ["src/cljs"]
:jar true
:compiler {:main naac.core
:output-to "resources/public/js/compiled/app.js"
:optimizations :advanced
:closure-defines {goog.DEBUG false}
:pretty-print false}}
]}
:main naac.server
:aot [naac.server]
:uberjar-name "naac.jar"
:prep-tasks [["cljsbuild" "once" "min"] "compile"]
)
MY directory structure can be seen in this image. IF you need a deeper nesting level you can see it here.
When I run lein I get this output:
Compiling ClojureScript...
2017-05-09 12:12:12.739:INFO::main: Logging initialized #2438ms
May 09, 2017 12:12:12 PM clojure.tools.logging$eval18$fn__22 invoke
INFO: Starting migrations
May 09, 2017 12:12:12 PM clojure.tools.logging$eval18$fn__22 invoke
WARNING: skipping: '.DS_Store' migrations must match pattern: ^(\d+)-([^\.]+)((?:\.[^\.]+)+)$
May 09, 2017 12:12:12 PM clojure.tools.logging$eval18$fn__22 invoke
INFO: Ending migrations
May 09, 2017 12:12:12 PM clojure.tools.logging$eval18$fn__22 invoke
INFO: Starting migrations
May 09, 2017 12:12:12 PM clojure.tools.logging$eval18$fn__22 invoke
WARNING: skipping: '.DS_Store' migrations must match pattern: ^(\d+)-([^\.]+)((?:\.[^\.]+)+)$
May 09, 2017 12:12:12 PM clojure.tools.logging$eval18$fn__22 invoke
INFO: Ending migrations
May 09, 2017 12:12:12 PM clojure.tools.logging$eval18$fn__22 invoke
INFO: Starting migrations
May 09, 2017 12:12:12 PM clojure.tools.logging$eval18$fn__22 invoke
WARNING: skipping: '.DS_Store' migrations must match pattern: ^(\d+)-([^\.]+)((?:\.[^\.]+)+)$
May 09, 2017 12:12:12 PM clojure.tools.logging$eval18$fn__22 invoke
INFO: Ending migrations

The problem is :source-paths in your project.clj. Lein expects your namespace folder to be directly in the source path.
You can either move your naac folder directly into src (e.g. src/naac/server.clj) or use ["src/clj"] as the value for :source-paths

Related

clj-time.coerce java.sql.Date .toString decrements date?

test_ns.clj
(ns test-ns
(:require [clj-time.jdbc :as tj]
[clj-time.coerce :as tc]))
(.toString (tc/to-sql-date (tc/from-string "2018-09-28")))
=> "2018-09-27"
Why does .toString decrement the date?
The expectation is that the formatted date string would match its input
tc/to-sql-date converts to java.sql.Date class
The .toString method appears to be used by hugsql default jbdc adaptor, which is a project dependency used for sql transactions
project.clj:
(defproject my-project "0.1.0-SNAPSHOT"
...
:min-lein-version "2.0.0"
:dependencies [[org.clojure/clojure "1.10.0-beta1"]
[duct/core "0.7.0-alpha8"]
[duct/module.sql "0.5.0-alpha1"]
[duct/module.logging "0.4.0-alpha1"]
[duct/database.sql.hikaricp "0.3.3"]
[com.walmartlabs/lacinia "0.21.0"]
[com.rpl/specter "1.1.1"]
[net.mikera/core.matrix "0.62.0"]
[com.wsscode/pathom "2.2.4"]
[org.clojure/core.async "0.4.474"]
[org.postgresql/postgresql "42.2.5"]
[org.clojure/core.async "0.4.490"]
[com.layerware/hugsql "0.4.9"]
[cheshire "5.8.1"]
[camel-snake-kebab "0.4.0"]
[hickory "0.7.1"]
[incanter "1.9.3"]
[clj-http "3.9.1"]
[environ "1.1.0"]]
:plugins [[lein-environ "1.1.0"]
[duct/lein-duct "0.11.0-alpha6"]
[lein-exec "0.3.7"]]
:main ^:skip-aot portfolio-management.main
:test-paths ["test"]
:source-paths ["src"]
:target-path "target/%s"
:resource-paths ["resources" "target/resources"]
:prep-tasks ["javac" "compile" ["run" ":duct/compiler"]]
:profiles
{:dev [:project/dev :profiles/dev]
:repl {:prep-tasks ^:replace ["javac" "compile"]
:repl-options {:init-ns user}}
:uberjar {:aot :all}
:profiles/dev {}
:project/dev {:source-paths ["dev/src"]
:resource-paths ["dev/resources"]
:dependencies [[integrant/repl "0.3.1"]
[eftest "0.4.1"]
[kerodon "0.9.0"]
]}})
EDIT
~$ java -version
openjdk version "1.8.0_191"
OpenJDK Runtime Environment (build 1.8.0_191-8u191-b12-2ubuntu0.18.04.1-b12)
OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)
I'm pretty sure that this is a timezone issue as Carcigenicate already pointed out.
from-string parses a string in the UTC timezone and java.sql.Date uses the default JVM timezone.
The returned result is correct if you're in a timezone which is "behind" UTC (to the west) because in those timezones the date 2018-09-28 00:00:00 is actually 2017-09-27.
(java.util.TimeZone/setDefault(java.util.TimeZone/getTimeZone "GMT"))
(.toString (tc/to-sql-date (tc/from-string "2018-09-28")))
;; => "2018-09-28"
(java.util.TimeZone/setDefault(java.util.TimeZone/getTimeZone "GMT-1"))
(.toString (tc/to-sql-date (tc/from-string "2018-09-28")))
;; => "2018-09-27"
You shouldn't use java.sql.Date and expect that it returns a date in the UTC timezone as long as that's not your default timezone.

Clojure lein uberjar: java.lang.ClassNotFoundException

I have a Clojure library that has two gen-class directives. When I run lein run, there are no issues. However, when I run lein uberjar, I get errors:
$ lein uberjar
Compiling 6 source files to /Users/frank/src/user/target/uberjar/classes
Compiling user.common
Compiling user.core
java.lang.ClassNotFoundException: user.server.UserAuthenticationServer, compiling:(user/core.clj:15:30)
Exception in thread "main" java.lang.ClassNotFoundException: user.server.UserAuthenticationServer, compiling:(user/core.clj:15:30)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6926)
.....
at clojure.lang.Compiler.analyze(Compiler.java:6701)
Caused by: java.lang.ClassNotFoundException: user.server.UserAuthenticationServer
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
...
at clojure.lang.Compiler.analyzeSeq(Compiler.java:6919)
... 86 more
In addition to the generated java files, there is the project.clj, server.clj, and core.clj.
project.clj
(defproject user "0.1.0-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.9.0-alpha14"]
[io.grpc/grpc-core "1.7.0"]
[io.grpc/grpc-netty "1.7.0"
:exclusions [io.grpc/grpc-core]]
[io.grpc/grpc-protobuf "1.7.0"]
[io.grpc/grpc-stub "1.7.0"]]
:main ^:skip-aot user.core
:aot [user.server]
:target-path "target/%s"
:source-paths ["src/clj"]
:java-source-paths ["src/generated/proto"
"src/generated/grpc"]
:profiles {:uberjar {:aot :all}})
core.clj
(ns user.core
(:import [io.grpc Server ServerBuilder])
(:gen-class))
(defonce start-server-atom (atom nil))
(def port 8080)
(defn start-server []
(when-not #start-server-atom
(reset! start-server-atom
(-> (ServerBuilder/forPort port)
(.addService (new user.server.UserAuthenticationServer))
.build
.start
.awaitTermination))))
(defn -main
[& args]
(start-server))
server.clj
(ns user.server
(:gen-class
:main false
:name user.server.UserAuthenticationServer
:extends xyz.skroo.user.UserAuthenticationGrpc$UserAuthenticationImplBase))
(defn -startUserAuthentication [this req res]
(.onNext res req)
(.onCompleted res))
It's weird because this was working and I think the compile-time order changed and now I cannot generate a standalone jar.
:profiles {:uberjar {:aot :all}} means that when you run uberjar it will try to compile all Namespaces. When you do lein run it only compiles the namespace in the :aot key.
Try to update the uberjar profile to only aot the server namespace and see if that works.

How can I run a Luminus project which uses Overtone?

I'm writing a web app which uses Overtone. When I try running the app using lein run or when I try to start the repl while in the project's directory I get the same error: java.lang.ExceptionInInitializerError at clojure.main.<clinit>(main.java:20) Caused by: java.lang.Exception: Server needs to be connected before you can perform this action.
It seems to me that both of those actions make all the files in my project compile. Is there any way to compile the namespaces which use Overtone after I run the server? Or maybe this isn't the issue, and the problem is coming from something else?
Here is my project.clj file:
(defproject comusic "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:dependencies [[buddy "1.3.0"]
[compojure "1.5.2"]
[conman "0.6.3"]
[cprop "0.1.10"]
[funcool/struct "1.0.0"]
[luminus-immutant "0.2.3"]
[luminus-migrations "0.3.0"]
[luminus-nrepl "0.1.4"]
[markdown-clj "0.9.98"]
[metosin/muuntaja "0.1.0"]
[metosin/ring-http-response "0.8.2"]
[mount "0.1.11"]
[org.clojure/clojure "1.8.0"]
[org.clojure/tools.cli "0.3.5"]
[org.clojure/tools.logging "0.3.1"]
[org.postgresql/postgresql "42.0.0"]
[org.webjars.bower/tether "1.4.0"]
[org.webjars/bootstrap "4.0.0-alpha.5"]
[org.webjars/font-awesome "4.7.0"]
[org.webjars/jquery "3.1.1"]
[org.webjars/webjars-locator-jboss-vfs "0.1.0"]
[ring-webjars "0.1.1"]
[ring/ring-core "1.6.0-RC1"]
[ring/ring-defaults "0.2.3"]
[selmer "1.10.7"]
[overtone "0.10.1"]]
:min-lein-version "2.0.0"
:jvm-opts ["-server" "-Dconf=.lein-env"]
:source-paths ["src/clj"]
:test-paths ["test/clj"]
:resource-paths ["resources"]
:target-path "target/%s/"
:main ^:skip-aot comusic.core
:migratus {:store :database :db ~(get (System/getenv) "DATABASE_URL")}
:plugins [[lein-cprop "1.0.1"]
[migratus-lein "0.4.4"]
[lein-immutant "2.1.0"]]
:profiles
{:uberjar {:omit-source true
:aot :all
:uberjar-name "comusic.jar"
:source-paths ["env/prod/clj"]
:resource-paths ["env/prod/resources"]}
:dev [:project/dev :profiles/dev]
:test [:project/dev :project/test :profiles/test]
:project/dev {:dependencies [[prone "1.1.4"]
[ring/ring-mock "0.3.0"]
[ring/ring-devel "1.5.1"]
[pjstadig/humane-test-output "0.8.1"]]
:plugins [[com.jakemccrary/lein-test-refresh "0.18.1"]]
:source-paths ["env/dev/clj"]
:resource-paths ["env/dev/resources"]
:repl-options {:init-ns user}
:injections [(require 'pjstadig.humane-test-output)
(pjstadig.humane-test-output/activate!)]}
:project/test {:resource-paths ["env/test/resources"]}
:profiles/dev {}
:profiles/test {}})
EDIT: After booting a SC server and trying to connect to it in my main function I still get the same error. File which contains main function:
(ns comusic.core
(:require [comusic.handler :as handler]
[luminus.repl-server :as repl]
[luminus.http-server :as http]
[luminus-migrations.core :as migrations]
[comusic.config :refer [env]]
[clojure.tools.cli :refer [parse-opts]]
[clojure.tools.logging :as log]
[mount.core :as mount]
[overtone.core :as overtone])
(:gen-class))
(def cli-options
[["-p" "--port PORT" "Port number"
:parse-fn #(Integer/parseInt %)]])
(mount/defstate ^{:on-reload :noop}
http-server
:start
(http/start
(-> env
(assoc :handler (handler/app))
(update :port #(or (-> env :options :port) %))))
:stop
(http/stop http-server))
(mount/defstate ^{:on-reload :noop}
repl-server
:start
(when-let [nrepl-port (env :nrepl-port)]
(repl/start {:port nrepl-port}))
:stop
(when repl-server
(repl/stop repl-server)))
(defn stop-app []
(doseq [component (:stopped (mount/stop))]
(log/info component "stopped"))
(shutdown-agents))
(defn start-app [args]
(doseq [component (-> args
(parse-opts cli-options)
mount/start-with-args
:started)]
(log/info component "started"))
(.addShutdownHook (Runtime/getRuntime) (Thread. stop-app)))
(defn -main [& args]
(cond
(some #{"migrate" "rollback"} args)
(do
(mount/start #'comusic.config/env)
(migrations/migrate args (select-keys env [:database-url]))
(System/exit 0))
:else
(do
(overtone/connect-external-server 57110)
(start-app args))))

Auto-refresh/ Auto-reload assets

I'm new to clojure and i'm having a hard time figuring out how to reload/ refresh the browser when changes have been made to either html/ js/ css etc.
this is my current setup project.clj
(defproject app2 "0.1.0-SNAPSHOT"
:description "FIXME: write this!"
:url "http://exampl.com/FIXME"
:dependencies [[org.clojure/clojure "1.8.0"]
[org.clojure/clojurescript "1.9.89"]
[ring/ring-core "1.5.0"]
[ring/ring-jetty-adapter "1.5.0"]
[enfocus "2.0.0-SNAPSHOT"]]
:plugins [[lein-cljsbuild "1.1.3"]
[lein-ring "0.9.7"]]
:cljsbuild {:builds [{:source-paths ["src/cljs"],
:compiler {
:main "scripts.client"
:output-to "resources/public/js/main.js"
:output-dir "resources/public/js/out"
:asset-path "js/out"
;;:pretty-print true
;;:optimizations :none
}}]}
:main app2.server/app
:ring {:handler app2.server/app :auto-reload? true :auto-refresh? true :reload-paths ["src" "resources"]}
:profiles {
:dev {
:ring {
:nrepl {
:start? true
:port 9000
}
}
}
}
)
This is my server.clj
(ns app2.server
(:use [ring.middleware.resource :only [wrap-resource]]
[ring.middleware.file-info :only [wrap-file-info]]
[ring.middleware.reload :refer [wrap-reload]])
;;(:require app2.repl)
)
(defn handler
[request]
{:status 200}
)
;handling routing "/" -> "/index.html"
(defn wrap-index [handler]
(fn [req]
(println (pr-str req))
(if (= (:uri req) "/")
(handler (assoc req :uri "/index.html"))
(handler req))))
;setting up a simple resource handler for ring
(def app (-> handler
(wrap-resource "public")
(wrap-file-info)
(wrap-index)
(wrap-reload app {:dirs ["src" "resources"]})
))
How can this be accomplished?
I'm used to developing in node and you have tools like browser sync, weinre and supervisor. What are the equivalents in clojure?
I suggest you have a look at figwheel, which lets you do hot reloading of your ClojureScript and CSS in the browser.
There is of course not one good way of setting up your build, but my way to go for languages like SASS etc. is to watch and compile them as a separate process, and have Figwheel watch the generated CSS.
For example, on one of my ClojureScript projects, I had a script file for LESS compilation which used the LESS compiler and the wr utility directly:
#!/usr/bin/env bash
lessc src/styles/main.main.less resources/public/css/main.css --source-map && cp src/styles/*.less resources/public/css
wr "lessc src/styles/main.main.less resources/public/css/main.css --source-map && cp src/styles/*.less resources/public/css" src/**/*.less
Of course you can also use things like Gulp, Webpack - or any tool you're used to.
The alternative is to use Leiningen plugins, see the list here.

reloading from clojure file

I'm new to clojure and I'm trying to wrap my head around live reload in in clojure I want to be able to monitor/ watch all/ any project file and update the browser automatically
So far I have the following
(defproject app2 "0.1.0-SNAPSHOT"
:description "FIXME: write this!"
:url "http://exampl.com/FIXME"
:dependencies [[org.clojure/clojure "1.8.0"]
[org.clojure/clojurescript "1.9.89"]
[ring "1.5.0"]
[stasis "2.2.0"]
[hiccup "1.0.5"]
[clj-tagsoup "0.3.0"]
[optimus "0.18.5"]
[ring/ring-jetty-adapter "1.5.0"]
[cljs-ajax "0.5.8"]
[enfocus "2.1.1"]]
:plugins [[lein-cljsbuild "1.1.3"]
[lein-ring "0.9.7"]]
:cljsbuild {:builds [
{:id "dev"
:incremental true
:source-paths ["src/cljs"]
:compiler {
:main "scripts.client"
:output-to "resources/public/js/main.js"
:output-dir "resources/public/js/out"
:asset-path "js/out"
}}]}
:aliases {
"start-dev" ["pdo" ["cljsbuild" "auto"] ["ring" "server-headless"]]
}
:source-paths ["src"]
:resource-paths ["resources"]
:main app2.server
:repl-options {
:prompt (fn [ns] (str "your command for <" ns ">, master? " ))
:welcome (println "Welcome to the magical world of the repl!")
:init-ns app2.hawk
:init (app2.hawk/init)
:caught clj-stacktrace.repl/pst+
:skip-default-init false
:host "0.0.0.0"
:port 9000
:timeout 40000
}
:ring {
:init app2.hawk/init
:handler app2.server/app
:auto-reload? true :auto-refresh? true :reload-paths ["resources/public"]
:refresh-paths ["resrouces/public"]
}
:profiles {
:dev {
:repl-options {
:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]
}
:source-paths ["src"]
:ring {
:nrepl {
:start? true
:port 9000
:host "0.0.0.0"
}
}
:dependencies [
[ring-refresh "0.1.1"]
[http-kit "2.0.0"]
[org.clojure/tools.nrepl "0.2.11"]
[com.cemerick/piggieback "0.2.1"]
[hawk "0.2.10"]
]
:plugins [
[lein-pdo "0.1.1"]
]
}
}
)
for my handler I have
(ns app2.server
(:use [ring.middleware.resource :only [wrap-resource]]
[ring.middleware.file-info :only [wrap-file-info]]
[ring.middleware.file :only [wrap-file]]
[ring.middleware.reload :refer [wrap-reload]]
[ring.middleware.content-type :refer [wrap-content-type]]
[ring.middleware.refresh :refer [wrap-refresh]]
[ring.util.response :refer [file-response]]
)
(defn wrap-utf-8
"This function works around the fact that Ring simply chooses the default JVM
encoding for the response encoding. This is not desirable, we always want to
send UTF-8."
[handler]
(fn [request]
(when-let [response (handler request)]
(if (.contains (get-in response [:headers "Content-Type"]) ";")
response
(if (string? (:body response))
(update-in response [:headers "Content-Type"] #(str % "; charset=utf-8"))
response)))))
(defn handler [request]
(file-response (:uri request) {:root "resources/public"}))
(def app (-> handler
wrap-content-type
wrap-reload
wrap-refresh []
wrap-utf-8))
And then I am running hawk from repl
(ns app2.hawk
(:require [hawk.core :as hawk])
(:require [app2.server :refer [export-pages]]))
(defn init
[]
(export-pages)
(hawk/watch! [{:paths ["src/app2/templates" "resources/templates"]
:filter hawk/modified?
:handler (fn [ctx e]
(export-pages) ;; i'm compiling html pages dynamically to the server root but how do I then notify browser than html has changed? can i force server to reload from here?
ctx)}]))
If you don't mind using Boot instead of Leiningen, the system project will give you all the reload goodness you can expect from a Lisp, with plenty of examples.
Be sure to check the Holy Grail demo, which leverages system, to get started with minimal fuss.
It sounds like you have put together a great setup so far.
and for managing this workflow Figwheel is the logical next step. If you are doing any Clojurescript + clojure-web stuff you almost certainly should start with figwheel, you will have a much more pleasant experience.