hello, i hava a java file in src/java/vinurs/utils
named http://hellojava.java and in lein project.clj
i set
:java-source-paths ["src/java"]
:prep-tasks ["javac" "compile"]
in my src/clj/app/core.clj
i import it (:import (vinurs.utils HelloJava))
then when i in shell run lein repl
, it output
Caused by: java.lang.ClassNotFoundException: vinurs.utils.HelloJava
then i have to comment the import (:import (vinurs.utils HelloJava))
in core.clj
then run lein repl, this time it compile the java file to .class
this time i restore the import , then run lein repl it works okeverytime i add a java file, i should do like this? comment the import?then lein javac, then import it?
It is because of the order of your prep tasks
@hiredman how to resolve this problem?
maybe by moving :prep-tasks first in the sequence.
No, sorry, I was misremembering but my guess is you have an issue like what is described here https://github.com/technomancy/leiningen/blob/master/doc/MIXED_PROJECTS.md#interleaving-compilation-steps
thanks, this is what i need
Cljs+Reagent. A simple menu div
that append an event listener to the document and decide if the document click
is inside or outside the component. I expect the handler to be called first, but the output is "second" and then "first". Why? Is caused from the re-rendering that add the component on-click listener multiple times?
(defn menu [mouse-pos]
(r/with-let [!menu-ref (atom nil)
handler (fn [evt]
(console-log "first")
(when (and @!menu-ref
(not (.contains @!menu-ref
(.-target evt))))
(console-log "outside")))
_ (.addEventListener js/document "click" handler)]
[:div.UI-menu {:style {:top (:y mouse-pos)
:left (:x mouse-pos)}
:ref #(reset! !menu-ref %)
:on-click #(console-log "second")}
"Adjust Diameter"]
(finally
(.removeEventListener js/document "click" handler))))
Hello, i've got general question about security. So i have a website and i would like traffic to be encrypted/hidden even for the client. Basically web app will know how to de-crypt it. I've never done this, i never heard about this, i dont think this is practice. Basically i want website to be usable but all traffic that it receives is hidden/unreadable/encrypted Is there a way for this to be done?
Typically using https protocol should be enough.
I was thinking of https too but: > So i have a website and i would like traffic to be encrypted/hidden even for the client.
makes me suspcious
Either the client can read the data or not. A web application is open to the client.
Yeah that makes sense. Like even if i do some voodoo JS functions that will decrypt that voodoo are still available for reading. Oki guys thanks
what's the point of communication, perhaps you mean client(human) cannot read but client(program) can read?
I'm trying to multiply all digits in a number together (e.g. 729 => 7 2 9), and so far I have
(->> digits
str
seq
(map Integer/parseInt)
(reduce *))
but I see that I cant do those functions to a sequence, which returns (\7 \2 \9)
, what does this mean?@zengxh that would have been the idea it seems. However, simply not sending the data they shouldnt be able to read is the only robust solution and is typically less work than trying to obfuscate. The visibility (authorization) logic has to live somewhere anyways.
those are literal chars. try doing (map #(Character/getNumericValue %) s))
instead
also, you don’t need to seq
a string. they have that abstraction on them already.
is the Character/
a default library that I can always call without requiring?
Integer
and Character
are both classes from java.lang
(which is available by default in CLJ)
you're actually calling a static method in this example: https://docs.oracle.com/javase/8/docs/api/java/lang/Character.html#getNumericValue-char-
there's also a different way of splitting a string you should be aware of:
user=> (seq (str 123))
(\1 \2 \3)
user=> (clojure.string/split (str 123) #"")
["1" "2" "3"]
In the first example you get back java Characters (the slashes are the giveaway); in the latter you get back strings (where you can then call Integer/parseInt
)
thank you so much, I've used the clojure.string/split
before but I seq
being used a lot when I google so I thought it might be better
weirdly i just want client to see the data they way i present it but not be able to read the data from response in json.
maybe obfuscate route is the way to go since authorization is solved. client won't see what i don't want him to see, but i want him to see data only via website if he calls api directly to receive jiberish that only website can read
hopefully it makes sense what i am asking
The two are semantically different (and both have their place). When you split a string, you're saying split this one string into a collection of smaller, disjoint strings. When you seq
you are iterating over a sequence (iterating over a string returns it's characters one-by-one).
I think Brave Clojure probably gives a much better explanation :) https://www.braveclojure.com/core-functions-in-depth/
well you can use something like messagepack or some other binary format. but those things wont help if they are technically adept. a CSRF token can at least give you some control over who can read from your API. I guess if you are just worried about cosmetics, then just put your stuff into a binary format, they typically have some good performance characteristics too.
makes sense, thanks
I have a project that will use AWS Dynamo to hold some key-value pairs, so wondering what recommendations people had on using it from Clojure. The value can be a string and I guess I can map between a keyword and what ever AWS Dynamo uses. https://github.com/Taoensso/faraday seems to be a common choice to access the AWS Dynamo API It seems pretty straightforward. Any thumbs up for this approach or other alternatives people have found useful. Thank you.
I use clj to create a library jar. how do I use that jar in and based java project?
i tried to copy generated jar but do not know how to use it on java side. the documentation is a bit confusing
Java only runs bytecode, so you need some hook into compiled Clojure. there are several ways to do this:
• pre-compile your Clojure code into bytecode with classes with static methods, then call into those • use the https://clojure.github.io/clojure/javadoc/clojure/java/api/Clojure.html to start the Clojure runtime, load vars, and invoke them (compiles dynamically from Clojure source) • other variants of the above, but those are the most common
i do not understand such vague details, my apologies. i use deps.edn https://github.com/bigos/Pyrulis/blob/master/Clojure/deps.edn
clj -X:jar :jar csvreport.jar
then i copy the jar file to the libs folder of netbeand based project and add the jar in netbeans properties
i do not know how to import the code and use it on java side
you say precompile clojure into bytecode
looking into the jar file doe not show similar content to other java jars
it just contins raw clojure files
yeah, if you read the depstar docs, you need to AOT compile the jar as well by specifying :compile-ns etc
what code do you want to run?
i want to run simple clojure hello world and point it on java side
I have noticed the deps.edn that i follow has changed, should I update it?
sorry, don't know the answer to that
what existing function do you want to run? I'm trying to be less vague for you
thank you for being honest 🙂 it is complex and requires patience
i have updated deps.edn and will try compiling again keeping your suggestions in mind. I may have more specific questions later
(ns sgs.lidlcsvreport) (defn foo "I don't do a whole lot." [x] (prn x "Hello, World!"))
this is my clojure code that i want run on java side
hopefully it will let me escape from the insanity of java type system
if you don't want to aot compile, you can use the Clojure Java API to load and compile this on the fly
jacekp@EID6043:~$ clj --help| grep Version Version: 1.10.1.727 jacekp@EID6043:~$ java -version java version "1.8.0_162" Java(TM) SE Runtime Environment (build 1.8.0_162-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.162-b12, mixed mode)
for the old java i use, which one is better?
import clojure.java.api.Clojure;
import clojure.lang.IFn;
...
// (require 'sgs.lidlcsvreport)
IFn require = Clojure.var("clojure.core", "require");
require.invoke(Clojure.read("sgs.lidlcsvreport"));
// (sgs.lidlcsvreport/foo "HI")
IFn foo = Clojure.var("sgs.lidlcsvreport", "foo");
foo.invoke("HI");
on the Java, doesn't matter, anything ≥ Java 1.8 is fine
(that version is pretty old and missing a lot of security fixes though fyi)
there is nothing I can do about the decade of compromise 🙂
hopefully, it that works we can gradually make progress
if I import clojure, how do I add clojure to the project?
i can copy a jar file in the project lib folder and add the jar to project proprties
if I understood correctly, you're building an uber jar that will include clojure
ah, so how do i import that uberjar into clojure?
an uberjar is the code from a project + all the code from its dependencies. in this case, the dependency includes clojure (which is just pulled in as a library)
so the uberjar you build in your project includes your project's code and clojure itself
if you did need to include clojure, it's on Maven Central like everything else - groupId= org.clojure, artifactId = clojure, latest version = 1.10.3
clj -X:uberjar :jar ./lidlcsvreport.jar :main-class sgs.lidlcsvreport
now the sgs has 'lidlcsvreport$fn__140.class' lidlcsvreport.clj 'lidlcsvreport$foo.class' lidlcsvreport__init.class 'lidlcsvreport$loading__6738__auto____138.class'
how do i import that on java side
?
the code I posted above
i will try it, we are on something because java ide tries to be helpful about the package
ide complains saying class interface or enum expected
are the Clojure classes in your jar?
if not, then you have a jar, not an uberjar and you will need to include Clojure as a dependency
clj -X:uberjar :jar ./lidlcsvreport.jar :main-class sgs.lidlcsvreport i have tried that, what options i am missing
the project deps.edn has alias for deploy
should i try that?
I don’t think so
Sorry, I need to step away for a bit
no problem 🙂
import clojure.java.api.Clojure; now ide says it is unused import
IFn require = Clojure.var("clojure.core", "require"); has the error
IFn require = Clojure.var("clojure.core", "require");
code compiles
import clojure.java.api.Clojure;
import clojure.lang.IFn;
import sgs.lidlcsvreport$foo;
what do I do about the foo?
i think I am making progress now. than you very much for your help
🙂
in terms of security, the client has full access to the js vm, and controls that vm implementation, there's nothing you can do that actually hides anything reliably in client code
obfuscation is possible but can't be relied on
seq
is called implicitly many places in clojure, including map
and reduce
user=> (map str "hello")
("h" "e" "l" "l" "o")
> you don’t need to seq a string. they have that abstraction on them already @tws almost - any clojure.core sequential function calls seq for you
usually, you only need to call seq in your own code when using interop with something outside clojure, or when you need the behavior of empty meaning nil which means false
what you do about the foo is you remove the import, use Clojure.var to reference it like alex has above
Hello! Is there an idiomatic way to thread data through converging functions similar to https://ramdajs.com/docs/#converge?
// JavaScript
const data = { a: 3, b: 4 }
pipe(
converge(add, [prop('a'), prop('b')]),
fn2,
fn3
)
This is what I have:
(+ (:a data) (:b data)) // 7
And I want to do something like:
;; Clojure
(def data {:a 3 :b 4})
(-> data
(something :a :b +)
fn2
fn3)
Something like (apply converge-fn ((juxt f g h) input))
(defn something [x fns f] (apply f ((juxt fns) x))
that should be (apply juxt fns)
in there I think
Ah yeah. Good point
Ah, thanks indy and dpsutton. I'll experiment with that!
apply and juxt seem to be super powerful
how do people perform benchmarking?
I see
Aliases in the deps.edn file can also be used to add optional dependencies that affect the classpath:
{:aliases
{:bench {:extra-deps {criterium/criterium {:mvn/version "0.4.4"}}}}}
Here the :bench alias is used to add an extra dependency, namely the criterium benchmarking library.
You can add this dependency to your classpath by adding the :bench alias to modify the dependency resolution: clj -A:bench.
from https://clojure.org/guides/deps_and_cli
but do you just run clj -A:bench
and do stuff from a repl?
Not sure how to integrate this from my REPL driven approach. right now it seems easier to require criterium and have some rich comment forms. (using CIDER/emacs)Yes, criterium
's README should show examples of how to run from a REPL -- which you could do from a Rich Comment Form in a source file.
(! 738)-> clj -A:bench
Downloading: criterium/criterium/maven-metadata.xml from clojars
Clojure 1.10.3
user=> (require '[criterium.core :refer [bench quick-bench]])
nil
user=> (bench (reduce + (range 10000)))
(time passes)
Evaluation count : 549420 in 60 samples of 9157 calls.
Execution time mean : 107.444260 µs
Execution time std-deviation : 5.941988 µs
Execution time lower quantile : 101.784873 µs ( 2.5%)
Execution time upper quantile : 125.506758 µs (97.5%)
Overhead used : 8.115184 ns
Found 6 outliers in 60 samples (10.0000 %)
low-severe 2 (3.3333 %)
low-mild 4 (6.6667 %)
Variance from outliers : 40.1884 % Variance is moderately inflated by outliers
I've found the clojure-goes-fast blog posts generally helpful, http://clojure-goes-fast.com/blog/
sorry, @seancorfield i wasn’t clear. i know how to do it, but my execution feels clunky, so wondering how others run any periodic benchmarks.
thanks, I’ll stick with RCF for now.
Yup, RCFs in the code is how I'd deal with this.
is it weird to have criterium in your deps.edn :deps
if it’s only used for RCF?
Or is there another way to get it on the classpath?
put it in an alias and add the alias when you are developing or benchmarking
I think a lot of folks have a :dev
alias that adds in all sorts of dev-only tooling (Polylith encourages that approach: :dev
for dev-only stuff, :test
for test-only stuff, so you start your REPL with clj -A:dev:test
or similar)
It looks like it is possible to have a multi-arity anonymous function. How to call anonymous fn with 1 arg from the one with no args?
(defn fun []
(fn
([] :call-anon-with-random)
([x] {:x x})))
; expected:
((fun)) ; => {:x :random}
((fun) :A) ; => {:x :A}
I think you mean def
there (or you don't need the fn
part)
This is simplified example, I want to use higher-order function and create a (fn) with optional argument
there is no magic here - if you want to invoke a thing, you either need the instance or a name to refer to it
oh, ok
you can use & to make optional arguments and then parse the args and handle both cases
What about?
(def fun
(fn my-fn
([] (my-fn :random))
([x] {:x x})))
(fun) ;; {:x :random}
(fun 42) ;; {:x 42}
(my-fn) ;; Unable to resolve symbol: my-fn in this context
this is it
actually I realised that I can call defn
from another defn
as well
(defn fun []
(defn anon
([] (anon :random))
([x] {:x x})))
but yours way is better. I didn't know that fn
can have a name 😄defn
is just shorthand or the long-form fn
invocation.
ps. that’s a first for me, seeing a todo
in the source.
Clojure 1.10.3
user=> (source defn)
(def
...
defn (fn defn [&form &env name & fdecl]
...
;;todo - restore propagation of fn name
...
Hello, I need help with using the chestnut template. I've been able to develope in re-frame and cljs with figwheel and i wanted to take it a step further and try to connect it to some sort of backend. So i setup a chestnut project, how ever i am very unexperienced with compojure/ring and everything todo with server side stuff. So i really need help with setting up extra routes with compojure in said environment. There is a route.clj that has the following code in it:
(defn home-routes [endpoint]
(routes
(GET "/" _
(-> "public/index.html"
io/resource
io/input-stream
response
(assoc :headers {"Content-Type" "text/html; charset=utf-8"})))
(resources "/")))
I would like to add extra routes to it and thought that i could just do that by adding another GET just like this:(defn home-routes [endpoint]
(routes
(GET "/" _
(-> "public/index.html"
io/resource
io/input-stream
response
(assoc :headers {"Content-Type" "text/html; charset=utf-8"})))
(GET "/bar" [] ("Please Work"))
(resources "/")))
But this, does unfortunately not work. Does anyone here know why or what i am doing wrong here? I basically want to be able to access a link "localhost:10555/bar", but nothing really shows up when i do this.Hi @moelfarri good job so far. You need to return a "ring response map" from your server which takes the form
{:status 200
:headers {"Content-Type" "text/html"}
:body "Your string or HTML here."
}
In the GET above yours that works already, you can see it is threading together index.html and a function called response
and associating into that map the key :headers
You can rearrange this a bit so it's more convenient to write new routes. There is a defroutes
macro that you can use to define new routes rather than operating each one as a new io/resource. Let me see if I can find a brief example for you.This page might help (and hopefully not confuse you) https://github.com/ring-clojure/ring/wiki/Concepts#requests This page about using Compojure ought to be very helpful to you @moelfarri https://learnxinyminutes.com/docs/compojure/