clojure.java.io/resource returns nil - javafx

i need to load an fxml based JavaFX Scene in Clojure,
but when i try to load the resource "view.fxml" it returns nil.
Here is my present code:
(ns ui.ui_controller
(:import (javafx.application Application)
(javafx.fxml FXMLLoader)
(javafx.scene Scene)
(javafx.stage Stage)))
(gen-class
:name ui.ui_controller
:extends javafx.application.Application)
(defn -main [& args]
(Application/launch ui.ui_controller args))
(defn -start [this stage]
(let [loc (clojure.java.io/resource "view.fxml")
root (FXMLLoader/load loc)]
(.setScene stage (Scene. root))
(.setTitle stage "JavaFXML with Clojure Example")
(.show stage)))
And in the resources folder is the view.fxml file, which should be loaded.
When in call (println (clojure.java.io/resource "view.fxml")) it returns nil...
Any idea what goes wrong here?
Thanks!

Here is an example
(ns tst.clj.core
(:use clj.core
clojure.test )
(:require
[clojure.java.io :as io]
))
(def words (slurp (io/file (io/resource "count.txt"))))
(println words)
> ls -ldF resources/count.txt
-rw-rw-r-- 1 alan alan 14 Jan 3 09:01 resources/count.txt
> cat resources/count.txt
one
two
three
> lein test
one
two
three

Related

Async Compojure-Api Middleware not Working

My middleware is throwing an error only for async requests, not sure why:
project.clj
(defproject asyncy "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:dependencies [[org.clojure/clojure "1.9.0"]
[metosin/compojure-api "1.1.11"]
[org.clojure/core.async "0.3.442"]]
:ring {:handler asyncy.handler/app}
:uberjar-name "server.jar"
:profiles {:dev {:dependencies [[javax.servlet/javax.servlet-api "3.1.0"]]
:plugins [[lein-ring "0.12.0"]]}})
handler.clj
To make this even easier to talk about and diagnose, i've made a bare minimum version of the problem using the lein new compojure-api template
(ns asyncy.handler
(:require [compojure.api.sweet :refer :all]
[ring.util.http-response :refer :all]
[schema.core :as s]
[clojure.core.async :as async]))
(s/defschema Pizza
{:name s/Str
(s/optional-key :description) s/Str
:size (s/enum :L :M :S)
:origin {:country (s/enum :FI :PO)
:city s/Str}})
(def app
(api
{:async? true
:swagger
{:ui "/"
:spec "/swagger.json"
:data {:info {:title "Asyncy"
:description "Compojure Api example"}
:tags [{:name "api", :description "some apis"}]}}}
(context "/api" []
:tags ["api"]
:middleware [(fn [handler]
;; this sync-style handler always handles both sync and async requests
(fn ([request]
(clojure.pprint/pprint request)
(if (some-> request :params :x (= "1"))
(bad-request {:error true :message "one is the loneliest number that you'll ever do"})
;; this throws an error on async requests
(handler request)))
;; this async 3-arity handler is never called
([request b c]
(clojure.pprint/pprint ["never called, doesnt matter." request b c]))
))]
(GET "/plus" []
:return {:result Long}
:query-params [x :- Long, y :- Long]
:summary "adds two numbers together"
(ok {:result (+ x y)}))
(GET "/plus-async" []
:return {:result Long}
:query-params [x :- Long, y :- Long]
:summary "adds two numbers together"
(fn [request respond raise]
(respond (ok {:result (+ x y)}))))
)))
(handler request) in the middleware is what throws the error, for async requests only:
ERROR Wrong number of args (1) passed to: handler/fn--26289/fn--26301/fn--26303
clojure.lang.ArityException: Wrong number of args (1) passed to: handler/fn--26289/fn--26301/fn--26303
at clojure.lang.AFn.throwArity(AFn.java:429)
at clojure.lang.AFn.invoke(AFn.java:32)
at compojure.response$eval1960$fn__1961.invoke(response.clj:47)
at compojure.response$eval1882$fn__1883$G__1873__1890.invoke(response.clj:7)
at compojure.core$wrap_response$fn__3839.invoke(core.clj:158)
at compojure.core$pre_init$fn__3938.invoke(core.clj:328)
at compojure.api.coerce$body_coercer_middleware$fn__14642.invoke(coerce.clj:51)
at compojure.core$pre_init$fn__3940$fn__3943.invoke(core.clj:335)
at compojure.core$wrap_route_middleware$fn__3823.invoke(core.clj:127)
at compojure.core$wrap_route_info$fn__3828.invoke(core.clj:137)
at compojure.core$wrap_route_matches$fn__3832.invoke(core.clj:146)
at compojure.core$wrap_routes$fn__3950.invoke(core.clj:348)
at compojure.api.routes.Route.invoke(routes.clj:74)
at compojure.core$routing$fn__3847.invoke(core.clj:185)
at clojure.core$some.invokeStatic(core.clj:2693)
at clojure.core$some.invoke(core.clj:2684)
at compojure.core$routing.invokeStatic(core.clj:185)
at compojure.core$routing.doInvoke(core.clj:182)
at clojure.lang.RestFn.applyTo(RestFn.java:139)
at clojure.core$apply.invokeStatic(core.clj:659)
at clojure.core$apply.invoke(core.clj:652)
at compojure.core$routes$fn__3851.invoke(core.clj:192)
at asyncy.handler$fn__26289$fn__26290$fn__26291.invoke(handler.clj:32)
at compojure.core$routing$fn__3847.invoke(core.clj:185)
at clojure.core$some.invokeStatic(core.clj:2693)
at clojure.core$some.invoke(core.clj:2684)
at compojure.core$routing.invokeStatic(core.clj:185)
at compojure.core$routing.doInvoke(core.clj:182)
at clojure.lang.RestFn.applyTo(RestFn.java:139)
at clojure.core$apply.invokeStatic(core.clj:659)
at clojure.core$apply.invoke(core.clj:652)
at compojure.core$routes$fn__3851.invoke(core.clj:192)
at compojure.core$make_context$handler__3919.invoke(core.clj:285)
at compojure.core$make_context$fn__3921.invoke(core.clj:293)
at compojure.api.routes.Route.invoke(routes.clj:74)
at compojure.api.core$handle$fn__14853.invoke(core.clj:8)
at clojure.core$some.invokeStatic(core.clj:2693)
at clojure.core$some.invoke(core.clj:2684)
at compojure.api.core$handle.invokeStatic(core.clj:8)
at compojure.api.core$handle.invoke(core.clj:7)
at clojure.core$partial$fn__5561.invoke(core.clj:2616)
at compojure.api.routes.Route.invoke(routes.clj:74)
at ring.swagger.middleware$wrap_swagger_data$fn__14015.invoke(middleware.clj:35)
at ring.middleware.http_response$wrap_http_response$fn__8034.invoke(http_response.clj:19)
at ring.swagger.middleware$wrap_swagger_data$fn__14015.invoke(middleware.clj:35)
at compojure.api.middleware$wrap_options$fn__14077.invoke(middleware.clj:74)
at ring.middleware.format_params$wrap_format_params$fn__7105.invoke(format_params.clj:119)
at ring.middleware.format_params$wrap_format_params$fn__7105.invoke(format_params.clj:119)
at ring.middleware.format_params$wrap_format_params$fn__7105.invoke(format_params.clj:119)
at ring.middleware.format_params$wrap_format_params$fn__7105.invoke(format_params.clj:119)
at ring.middleware.format_params$wrap_format_params$fn__7105.invoke(format_params.clj:119)
at compojure.api.middleware$wrap_exceptions$fn__14067.invoke(middleware.clj:43)
at ring.middleware.format_response$wrap_format_response$fn__7930.invoke(format_response.clj:194)
at ring.middleware.keyword_params$wrap_keyword_params$fn__8076.invoke(keyword_params.clj:36)
at ring.middleware.nested_params$wrap_nested_params$fn__8134.invoke(nested_params.clj:89)
at ring.middleware.params$wrap_params$fn__4079.invoke(params.clj:67)
at compojure.api.middleware$wrap_options$fn__14077.invoke(middleware.clj:74)
at compojure.api.routes.Route.invoke(routes.clj:74)
at clojure.lang.Var.invoke(Var.java:381)
at ring.middleware.reload$wrap_reload$fn__1829.invoke(reload.clj:39)
at ring.middleware.stacktrace$wrap_stacktrace_log$fn__1211.invoke(stacktrace.clj:26)
at ring.middleware.stacktrace$wrap_stacktrace_web$fn__1277.invoke(stacktrace.clj:96)
at ring.adapter.jetty$proxy_handler$fn__487.invoke(jetty.clj:25)
at ring.adapter.jetty.proxy$org.eclipse.jetty.server.handler.AbstractHandler$ff19274a.handle(Unknown Source)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
at org.eclipse.jetty.server.Server.handle(Server.java:499)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:258)
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
at java.lang.Thread.run(Thread.java:748)
How does one do middleware with async compojure-api? Feel like i'm just totally off on how to implement this.

ClojureScript file preloader - function or pattern to emulate promise?

I'm trying to create a file preloader within ClojureScript. My idea was a pattern like this:
(def urls (atom[]))
(def loaded-resources (atom []))
(def all-resources (promise))
(defn loading-callback []
(if (= (count urls) (count loaded-resources))
(deliver all-resources loaded-resources)))
;; fill urls array
;; start ajax-loading with loading-callback on success
So my main function could go on until it would require the resources and then wait for them, which works well in Clojure.
Unfortunately, promises don't exist in ClojureScript, so how can I work around that issue? There's promesa bringing promises to CLJS based on core.async channels, but it only allows future-like promises that wait for a single function to execute which won't suffice my needs (at least in the way I've been thinking about it yesterday...).
Any suggestions to solve this issue? Maybe use a completely different pattern? I want to keep the code as simple as possible to convince people in my team to try out CLJ/S.
EDIT:
After Alan's second idea:
(def urls (atom[]))
(def loaded-resources (atom []))
(defn loading-callback [data]
(swap! loaded-resources conj data))
(defn load! [post-loading-fn]
(add-watch loaded-resources :watch-loading
(fn [_ _ _ cur]
(if (= (count cur) (count #urls)) (post-loading-fn))))
;; init ajax loading
)
(defn init []
;; fill urls array
(load! main))
(main []
(do-terrific-stuff #loaded-resources))
Meanwhile I had tried to use core.async
(def urls (atom []))
(def loaded-resources (atom []))
(def resource-chan (chan))
(defn loading-callback [data]
(go (>! resource-chan data)))
;; fill url array from main
(load! []
;; init ajax loading
(go-loop []
(when-not (= (count #loaded-resources) (count #urls))
(swap! loaded-resources conj (<! resource-chan))
(recur)))
Not sure which version is better.
I can think of 2 approaches.
Change all-resources to another atom, initialized at nil. Poll it 2x-5x/sec until it is not nil and has the "delivered" result.
Use add-watch to register a callback function to execute when the value is changed. This takes the place of blocking until the value is delivered. It is described here: http://clojuredocs.org/clojure.core/add-watch
They show a good example:
(def a (atom {}))
(add-watch a :watcher
(fn [key atom old-state new-state]
(prn "-- Atom Changed --")
(prn "key" key)
(prn "atom" atom)
(prn "old-state" old-state)
(prn "new-state" new-state)))
(reset! a {:foo "bar"})
;; "-- Atom Changed --"
;; "key" :watcher
;; "atom" #<Atom#4b020acf: {:foo "bar"}>
;; "old-state" {}
;; "new-state" {:foo "bar"}
;; {:foo "bar"}
Assuming your load resource function returns a channel (like cljs-http/get).
In clj, all you need to do is hold on to them to do a "wait-all".
(let [cs (doall (map load-resource urls)) ;; initiate the get
... ;; other initialisation
res (map <!! cs)] ;; wait-all for the resources
(do-other-things res))
In cljs, you can accumulate the responses before you continue:
(go
(let [res (atom [])]
(doseq [c cs]
(swap! res conj (<! c)))
(do-other-things #res)))
JavaScript is a single threaded environment so there is no blocking wait.
If you wish to request multiple resources and continue iff they have all been served, I do recommend using core.async and especially pipeline-async. It has a knob to finetune the parallelism of asynchronous requests. Here is idiomatic ClojureScript code to achieve what you want:
(ns example.core
(:require [cljs.core.async :refer [chan take! put! pipeline-async]
:as async]))
(defn load-resources [urls on-resources]
(let [urls-ch (chan (count urls))
resources-ch (chan)]
;; Create pipeline:
(pipeline-async 10 ;; have at most 10 requests in flight at
;; the same time, finetune as desired
resources-ch
(fn [url done-ch]
;; Pseudo code:
(request-resource
url
(fn [loaded-resource]
(put! done-ch loaded-resource))))
urls-ch)
;; Eagerly aggregate result until results-ch closes, then call back:
(take! (async/into [] resources-ch) on-resources)
;; Start the party by putting all urls onto urls-ch
;; and then close it:
(async/onto-chan urls-ch urls)))

Writing a JavaFX project in Clojure

I'm trying to understand how to properly setup JavaFX to work with a Clojure project. By reading various sources this is what I've come up with:
This is project.clj:
(defproject cljfx "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.8.0"]]
:resource-paths ["lib/jfxrt.jar"]
:main ^:skip-aot cljfx.core
:target-path "target/%s"
:profiles {:uberjar {:aot :all}})
I don't know if I should use :resource-paths or add JavaFX to the classpath via the :dependencies vector...
This is core.clj:
I've basically translated to Clojure an example from this tutorial:
http://docs.oracle.com/javafx/2/get_started/hello_world.htm
(ns cljfx.core
(:gen-class
:extends javafx.application.Application)
(:import
[javafx.application Application]
[javafx.stage Stage]
[javafx.scene Scene]
[javafx.scene.control Button]
[javafx.scene.layout StackPane]
[javafx.event ActionEvent EventHandler]))
(defn -main [& args]
(Application/launch cljfx.core args))
(defn button [text]
(doto (Button.)
(.setText (str "Say " text))
(.setOnAction (proxy [EventHandler] []
(handle [event]
(println text))))))
(defn -start [primaryStage]
(let [root (doto (StackPane.)
(-> (.getChildren)
(.add (button "Hello World!"))))]
(doto primaryStage
(.setScene (Scene. root 300 250))
(.show))))
This doesn't compile, and I don't know what I'm doing wrong... can you help me?
Here is the error:
http://pastebin.com/sYeK7MJd
There may be other problems, but the root problem in the pastebin log is:
Caused by: clojure.lang.ArityException: Wrong number of args (2) passed to: core/-start
When using gen-class and providing method implementations, every method needs to take the instance itself as the first parameter. The convention is to use "this":
(defn -start [this primaryStage]
Try that, and ensure that local instance method calls are applied to "this".

How to integrate flowtype with spacemacs

I'm spacemacs fan. I want to use Facebook Flow but I have not idea how to integrate it with spacemacs. I'm using flow with nuclide but I need to relearn everything to be productive. There is this script on flow repository to use it with emacs. I need a guide for how to use it within spacemacs.
Thanks.
I used Bodil's flow flycheck config here: https://github.com/bodil/emacs.d/blob/d28264cf072bb8a62459a48813d0cb30804b4f5b/bodil/bodil-js.el#L121-L154
I made it work with spacemacs's react-mode and default eslint flychecker by adding the following to my dotspacemacs/user-config (https://github.com/saltycrane/.spacemacs.d/blob/9d985ace9251529c2b8d7857e2ec9835b103084c/init.el#L383-L414):
;; Flow (JS) flycheck config (http://flowtype.org)
;; from https://github.com/bodil/emacs.d/blob/master/bodil/bodil-js.el
(require 'f)
(require 'json)
(require 'flycheck)
(defun flycheck-parse-flow (output checker buffer)
(let ((json-array-type 'list))
(let ((o (json-read-from-string output)))
(mapcar #'(lambda (errp)
(let ((err (cadr (assoc 'message errp))))
(flycheck-error-new
:line (cdr (assoc 'line err))
:column (cdr (assoc 'start err))
:level 'error
:message (cdr (assoc 'descr err))
:filename (f-relative
(cdr (assoc 'path err))
(f-dirname (file-truename
(buffer-file-name))))
:buffer buffer
:checker checker)))
(cdr (assoc 'errors o))))))
(flycheck-define-checker javascript-flow
"Javascript type checking using Flow."
:command ("flow" "--json" source-original)
:error-parser flycheck-parse-flow
:modes react-mode
:next-checkers ((error . javascript-eslint))
)
(add-to-list 'flycheck-checkers 'javascript-flow)
Also be sure the Flow command line tool is installed. Install it like this:
npm install -g flow-bin
I think Bodil intended to make the messages short, but I would like to have flycheck display more verbose messages. If anyone knows how to do that, I'd appreciate it.
EDIT 2016-08-12: the original version I posted gave a Symbol's function definition is void: flycheck-define-checker error on initial load. I updated the code above to add a require 'flycheck to get rid of that error.
The answer by saltycrane worked fine for me. Thanks! The solution gives a very short error messages as he points out. I have improved the error messages to be more verbose and look more like the output from flow cli output.
A note to new users who wants to use this script is to make sure you edit it to use the correct mode in flycheck-define-checker at the bottom. I use this in js2-mode, and saltycrane uses react-mode. Edit it to use whatever you are using.
(require 'f)
(require 'json)
(require 'flycheck)
(defun flycheck-parse-flow (output checker buffer)
(let ((json-array-type 'list))
(let ((o (json-read-from-string output)))
(mapcar #'(lambda (errp)
(let ((err (cadr (assoc 'message errp)))
(err2 (cadr (cdr (assoc 'message errp)))))
(flycheck-error-new
:line (cdr (assoc 'line err))
:column (cdr (assoc 'start err))
:level 'error
:message (concat (cdr (assoc 'descr err)) ". " (cdr (assoc 'descr err2)))
:filename (f-relative
(cdr (assoc 'path err))
(f-dirname (file-truename
(buffer-file-name))))
:buffer buffer
:checker checker)))
(cdr (assoc 'errors o))))))
(flycheck-define-checker javascript-flow
"Static type checking using Flow."
:command ("flow" "--json" source-original)
:error-parser flycheck-parse-flow
:modes js2-mode)
(add-to-list 'flycheck-checkers 'javascript-flow)

doseq in core.async go macro not working

I'm new to core.async and I'm wondering why the following does NOT work (no output at all):
(def jackie (chan 2))
(go (loop [food (<! jackie)]
(if food
(do
(println "Some" food "is what I was waiting for.")
(Thread/sleep 1000)
(recur (<! jackie))))))
(go (doseq [food ["carrots" "peas"]]
(println "deliver" food)
(>! jackie food)
(Thread/sleep 1000)))
... while this DOES work:
(def jackie (chan 2))
(go (loop [food (<! jackie)]
(if food
(do
(println "Some" food "is what I was waiting for.")
(Thread/sleep 1000)
(recur (<! jackie))))))
(doseq [food ["carrots" "peas"]]
(println "deliver" food)
(>!! jackie food)
(Thread/sleep 1000))
The only difference here is the missing go block around the last doseq.
I found the combined go and doseq in an example in this blog post, but it doesn't work for me. Also doing it the other way round and nesting the go inside the doseq like in this question does not work for me.
>!! will block the current thread if the target channel/buffer is full. To have the current go block park instead, use the single-bang variant >!

Resources