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
Thanks! 👍
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))))
what does it depend on exactly whether (future-cancel)
works or not? current thread state?
[turned out i actually fixed this issue and encountered a similar one with a bigger xml (30mb) — apologies — that didn’t even parsed with 512mb. in that case, i only needed to count some elements, and eventually went with plain java stax route. thanks for the help!]
actually, i recently just wanted to count some elements in a jvm with 512mb heap with a ~30Mb xml. i got an out of memory error (with zippers as well), and went with plain java stax. any idea what could have been a clean clojure solution?
(->> "huge.xml"
io/resource
io/input-stream
xml/parse
xml-seq
(filter #(= (:tag %) :Event))
count)
Execution error (OutOfMemoryError) at clojure.data.xml/seq-tree$fn (xml.clj:183).
Java heap space
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.
@ban.istvan I wonder if this would work:
(x/count
(comp
xml-seq*
(filter #(= (:tag %) :Event)))
(-> "huge.xml"
io/resource
io/input-stream
xml/parse))
where
1. xml
is clojure.data.xml
2. x/count
is from https://github.com/cgrand/xforms
3. transducer version of xml-seq, something like:
(def xml-seq*
(fn [rf]
(fn
([] (rf))
([result] (rf result))
([result input]
(rf result (xml/xml-seq input))))))
(I have not actually tested this code ;))
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-
1🙏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/
1🙏So, speaking of - can anyone point to code, or pseudo-code, or any inspiration on how to idiomatically traverse a tree (SAX-style), where you obviously sometimes need to keep track of the depth or other data to figure out what to do with leaf nodes.
(Slowly trying to leave my Java/imperative brain behind, but it’s… sticky.)
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
SAX style is awful because it presumes mutation and accumulators
StAX is a bit nicer, IMHO, and lends itself to a more functional handling
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.
Ah, hadn’t even heard of StAX. Will study and catch up with the times…
non-lazy xml -> clojure data routine
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
🙂
I linked the Thread.interrupt docs above (future-cancel uses that method): > If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException. > > If this thread is blocked in an I/O operation upon an InterruptibleChannel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a ClosedByInterruptException. > > If this thread is blocked in a Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup method were invoked. > > If none of the previous conditions hold then this thread's interrupt status will be set
it always "works" in that if the thread in question doesn't invoke any of the specific methods mentioned there, a flag is set and you can check the flag
it "doesn't work" in that if you are doing work that never uses any of those methods, and don't check that flag, it has no effect on the thread's execution
there's a more powerful method to force stop a thread (which some code shared above uses), but there are no guarantees about safety when you use that, and it can crash the vm or leave objects in inconsistent states or leave locks that can't be unlocked
the code shared above is arguably OK, because it's for a IRC bot that's mainly there for entertainment and education and if it crashes it auto restarts
your code might deal with something more serious where those risks are not OK
you can use re-seq
to get a lazy seq of matches of a charsequence, there's at least one lib out there that implements charsequence over very large files https://github.com/fge/largetext - may or may not work for you
but for the use case where it applies it's probably the most straightforward approach
(charsequence is the superclass of string, and you can do most "string ops" on a charsequence, they are more abstract eg. unlike string don't need to promise to exist in memory all at once)
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
1👍what you do about the foo is you remove the import, use Clojure.var to reference it like alex has above
> that call to map would either be evaluated when it's returned or if I force it with dorun to be clear, returning something never realizes it, but it gives the caller a chance to realize it eventually if they want to
you can also use run!
which is exactly like the two-arg version of map, except it returns nil and is eager
(ins)user=> (run! println "hello, world")
h
e
l
l
...
nil
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
1I 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
1👍this is it
1actually 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 😄1😁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/