Fork me on GitHub
#clojure
<
2023-02-28
>
grav10:02:43

How come this works:

(Integer/MAX_INT)
=> 2147483647
when this doesn't:
(42)
class java.lang.Long cannot be cast to class clojure.lang.IFn
The MAX_INT constant is defined like this:
@Native public static final int   MAX_VALUE = 0x7fffffff;

borkdude10:02:41

@U052XLL3A (Integer/MAX_INT) expands into (. Integer MAX_INT) and clojure supports both reading fields are calling 0-arity methods with this syntax

šŸ’” 6
grav10:02:47

Is it possible to somehow see the expansion in the repl?

delaguardo10:02:04

user=> (macroexpand '(Integer/MAX_INT))
(. Integer MAX_INT)

grav10:02:11

Oh, it's a macro? How did it end up being a macro?

borkdude10:02:10

it's not really a macro, more like a built-in syntax thing, but macroexpand also desugars this stuff

grav10:02:23

Ooh, didn't know.

grav10:02:27

Pretty cool

grav10:02:45

But also a bit šŸŖ„

borkdude10:02:52

Well, for better or for worse, I think it could be argued that field access should not be surrounded with () ;)

borkdude10:02:06

unless you write (.-foo ...)

borkdude10:02:25

but (.foo ...) also works for a field, unlike in CLJS for example

grav10:02:27

Totally agree - somehow I ended up writing it, and then when I found out, I was puzzled that it worked

Tomas Brejla11:02:07

interesting thread btw in babashka it doesn't translate to that mentioned (. Integer MAX_INT) form..

āžœ  ~ clojure -e "(macroexpand '(Integer/MAX_INT))" 2>/dev/null
(. Integer MAX_INT)
āžœ  ~ bb -e "(macroexpand '(Integer/MAX_INT))" 2>/dev/null 
(Integer/MAX_INT)
Is this expected?

borkdude11:02:59

It does work though, if the class/field is supported in bb:

user=> Long/MAX_VALUE
9223372036854775807
user=> (Long/MAX_VALUE)
9223372036854775807

borkdude11:02:20

the analyzer in bb handles the Long/MAX_VALUE form directly, it doesn't happen in macroexpand in bb, kind of a detail imo

šŸ‘ 2
pavlosmelissinos12:02:35

I'm trying to use cognitect/aws with localstack and facing this surprising behaviour:

(sh "aws" "--endpoint-url=" "sqs" "list-queues")
  ;; => {:exit 0, :out "", :err ""}
  
  (aws/invoke local-sqs {:op :CreateQueue :request {:QueueName "test_queue"}})
  ;;=> {:QueueUrl ""}
  (aws/invoke local-sqs {:op :ListQueues :request {}})
  ;;=>  {:QueueUrls [""]}

  (sh "aws" "--endpoint-url=" "sqs" "list-queues")
  ;;=> {:exit 0, :out "{\n    \"QueueUrls\": [\n        \"\"\n    ]\n}\n", :err ""}
Shelling out to aws CLI includes the port number in the queue URL when listing the queues but aws-api doesn't. Is this intentional or should I file a bug? edit: I just discovered #aws :face_palm:, should I move this there?

p-himik12:02:09

How did you create local-sqs? Also, a bit unrelated but I would suggest using something other than LocalStack if you need only S3. Had a lot of problems with it, always with something hard to debug. And recently they removed persistence in their free plan. So far, very happy with MinIO. It's also much, much faster to start. Ah, didn't realize that SQS is not S3, heh.

pavlosmelissinos12:02:48

> How did you create local-sqs?

(def local-sqs (aws/client {:api                  :sqs
                            :region               "us-east-1"
                            :credentials-provider (aws/default-http-client)
                            :endpoint-override    {:protocol :http
                                                   :hostname "localhost"
                                                   :port     4566}}))

p-himik12:02:25

Ah yeah, I use the same thing for the S3 client, and it works properly there. Interesting.

pavlosmelissinos12:02:43

It seems that the AWS CLI picks up the correct queue URL, so the queue is probably created as expected, but for some reason the port doesn't show when you print the url via aws-api :thinking_face: . It doesn't seem to cause any issues though (I think), so it's ok, just a bit of a surprise... By the way I need localstack (wish I didn't) because I want to develop against the AWS API, without requiring any actual AWS infrastructure when working in the REPL.

p-himik12:02:17

> I want to develop against the AWS API, without requiring any actual AWS infrastructure when working in the REPL Yeah, of course - that's why I mentioned MinIO, but unfortunately they only provide an object storage AFAIK.

šŸ‘ 2
p-himik12:02:30

> the port doesn't show when you print the url via aws-api Oh, right. Although I imagine that it might be LocalStack to blame. Maybe it checks for some optional headers that AWS CLI sends out, or maybe AWS CLI alters the URLs so that they include the port. Of course, it can still be aws-api that's to blame. But it's a really thin wrapper for the HTTP API, so that would surprise me.

Patrick Brown14:02:49

Iā€™m having a bugger of a time trying to understand this error Iā€™m getting. Iā€™m desctructuring a channel out of a map and then trying to pass it to my mulog publisher. (defmethod ig/init-key :sys/env [_ module-config] (let [{:sys/keys [app loc stage]} module-config {:module/keys [bb]} module-config {:module/keys [bb]} bb {:<bus/keys [eb]} bb module-config (assoc module-config :kill-publisher (select-publisher! #{:pretty-console {:type :custom :fqn-function "net.drilling.util.event.publishers.event-bus/event-bus-publisher" :transform #(event-bus-transform %) :eb eb :pretty-print true}})) module-config (assoc module-config :sys/bb bb :sys/eb eb :sys/<eb <eb :sys/>eb >eb)] (log/log :sys/bb-facts :eb eb :eb-type (type eb)) module-config)) The error Iā€™m getting is a class cast exception. The interesting part is; Exception in thread "async-dispatch-10" Exception in thread "async-dispatch-32" java.lang.ClassCastException: class clojure.core.async.impl.channels.ManyToManyChannel cannot be cast to class clojure.lang.IFn (clojure.core.async.impl.channels.ManyToManyChannel is in unnamed module of loader clojure.lang.DynamicClassLoader @20b2d351; clojure.lang.IFn is in unnamed module of loader 'app') Thing is everything works except my repl is spitting bloody murder about the class cast to IFn. For the life of me I canā€™t find where Iā€™m not passing something that looks like :eb #object[clojure.core.async.impl.channels.ManyToManyChannel 0x7beff931 "clojure.core.async.impl.channels.ManyToManyChannel@7beff931"], :eb-type clojure.core.async.impl.channels.ManyToManyChannel, This is what mulog is printing to the console. Based on my log statement at the end of the first code snippet. Can anyone elucidate where Iā€™m going wrong? Or how I should try to troubleshoot this if my mistake further upstream? CHEERS and CLJ!

Alex Miller (Clojure team)14:02:01

somewhere you are invoking a channel

delaguardo14:02:30

what is that you are passing to select-publisher! ? looks like it suppose to be a map but because there is # in front it tun out to be a set

Patrick Brown14:02:34

It is a set, the first item in the set is :pretty-console, the second is the map

Alex Miller (Clojure team)14:02:14

there is no "first" item in a set

Alex Miller (Clojure team)14:02:23

sets and maps are unordered and seq to arbitrary order

Patrick Brown14:02:27

Correct again, the first item in the code.

Patrick Brown14:02:45

The set has two unordered items, itā€™s not a map.

Alex Miller (Clojure team)14:02:13

eb is a channel - do you invoke that somewhere?

Patrick Brown14:02:38

so there is a kw and a map. Can I ask you about this Ifn? What would my wrong code look like, because all Iā€™m seeing is a put parking

Alex Miller (Clojure team)14:02:26

Clojure will try to cast the first thing in an invocation to an IFn, so somewhere you are doing the equivalent of (<a-channel> ...)

Patrick Brown14:02:48

(deftype EventBusPublisher [config buffer transform] com.brunobonacci.mulog.publisher.PPublisher (agent-buffer [_] buffer) (publish-delay [_] 500) (publish [_ buffer] (let [eb (:eb config)] (doseq [item (transform (map second (rb/items buffer)))] (a/>!! eb item))) (rb/clear buffer)))

Patrick Brown14:02:07

Correction, put blocking

Alex Miller (Clojure team)14:02:46

(surround with ` for code blocks btw)

Alex Miller (Clojure team)14:02:04

that code looks fine in the a/>!! call

Alex Miller (Clojure team)14:02:17

so I assume the problem is elsewhere :)

delaguardo14:02:36

can you see a stacktrace of ClassCastException? with core.async it is not always points to the right place but maybe it has something usefull now

Patrick Brown14:02:28

The reason I thought it was a destructuring thing is because when I just bind eb to a fresh call to (a/chan) in the let statement the error disappears.

Patrick Brown14:02:15

Exception in thread "async-dispatch-10" Exception in thread "async-dispatch-32" java.lang.ClassCastException: class clojure.core.async.impl.channels.ManyToManyChannel cannot be cast to class clojure.lang.IFn (clojure.core.async.impl.channels.ManyToManyChannel is in unnamed module of loader clojure.lang.DynamicClassLoader @20b2d351; clojure.lang.IFn is in unnamed module of loader 'app')
	at clojure.core.async$pub$fn__20980$state_machine__19381__auto____20993$fn__20995.invoke(async.clj:966)
	at clojure.core.async$pub$fn__20980$state_machine__19381__auto____20993.invoke(async.clj:966)
	at clojure.core.async.impl.runtime$run_state_machine.invokeStatic(runtime.clj:62)
	at clojure.core.async.impl.runtime$run_state_machine.invoke(runtime.clj:61)
	at clojure.core.async.impl.runtime$run_state_machine_wrapped.invokeStatic(runtime.clj:66)
	at clojure.core.async.impl.runtime$run_state_machine_wrapped.invoke(runtime.clj:64)
	at clojure.core.async.impl.runtime$take_BANG_$fn__14117.invoke(runtime.clj:75)
	at clojure.core.async.impl.channels.ManyToManyChannel$fn__13927.invoke(channels.clj:140)
	at clojure.lang.AFn.run(AFn.java:22)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at clojure.core.async.impl.concurrent$counted_thread_factory$reify__13780$fn__13781.invoke(concurrent.clj:29)
	at clojure.lang.AFn.run(AFn.java:22)
	at java.base/java.lang.Thread.run(Thread.java:833)
java.lang.ClassCastException: class clojure.core.async.impl.channels.ManyToManyChannel cannot be cast to class clojure.lang.IFn (clojure.core.async.impl.channels.ManyToManyChannel is in unnamed module of loader clojure.lang.DynamicClassLoader @20b2d351; clojure.lang.IFn is in unnamed module of loader 'app')
	at clojure.core.async$pub$fn__20980$state_machine__19381__auto____20993$fn__20995.invoke(async.clj:966)
	at clojure.core.async$pub$fn__20980$state_machine__19381__auto____20993.invoke(async.clj:966)
	at clojure.core.async.impl.runtime$run_state_machine.invokeStatic(runtime.clj:62)
	at clojure.core.async.impl.runtime$run_state_machine.invoke(runtime.clj:61)
	at clojure.core.async.impl.runtime$run_state_machine_wrapped.invokeStatic(runtime.clj:66)
	at clojure.core.async.impl.runtime$run_state_machine_wrapped.invoke(runtime.clj:64)
	at clojure.core.async.impl.runtime$take_BANG_$fn__14117.invoke(runtime.clj:75)
	at clojure.core.async.impl.channels.ManyToManyChannel$fn__13927.invoke(channels.clj:140)
	at clojure.lang.AFn.run(AFn.java:22)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at clojure.core.async.impl.concurrent$counted_thread_factory$reify__13780$fn__13781.invoke(concurrent.clj:29)
	at clojure.lang.AFn.run(AFn.java:22)
	at java.base/java.lang.Thread.run(Thread.java:833)
Exception in thread "async-dispatch-20" java.lang.ClassCastException: class clojure.core.async.impl.channels.ManyToManyChannel cannot be cast to class clojure.lang.IFn (clojure.core.async.impl.channels.ManyToManyChannel is in unnamed module of loader clojure.lang.DynamicClassLoader @20b2d351; clojure.lang.IFn is in unnamed module of loader 'app')
	at clojure.core.async$pub$fn__20980$state_machine__19381__auto____20993$fn__20995.invoke(async.clj:966)
	at clojure.core.async$pub$fn__20980$state_machine__19381__auto____20993.invoke(async.clj:966)
	at clojure.core.async.impl.runtime$run_state_machine.invokeStatic(runtime.clj:62)
	at clojure.core.async.impl.runtime$run_state_machine.invoke(runtime.clj:61)
	at clojure.core.async.impl.runtime$run_state_machine_wrapped.invokeStatic(runtime.clj:66)
	at clojure.core.async.impl.runtime$run_state_machine_wrapped.invoke(runtime.clj:64)
	at clojure.core.async.impl.runtime$take_BANG_$fn__14117.invoke(runtime.clj:75)
	at clojure.core.async.impl.channels.ManyToManyChannel$fn__13927.invoke(channels.clj:140)
	at clojure.lang.AFn.run(AFn.java:22)
	at java.base/java.util.concurrent.Thre{:mulog/event-name :sys/halt!,

delaguardo14:02:53

:mulog/event-name :sys/halt! this looks interesting. Does it sound like something familiar?

Patrick Brown14:02:56

Thatā€™s me telling integrant to shutdown the system so I can dig around. You can think of it as me calling interrupt. I think just having someone to talk it out with has helped me realize Iā€™m looking in the wrong place.

Patrick Brown14:02:55

If Iā€™m posting to the event bus channel and itā€™s got pubs on top of taps on top of mults, obviously I was looking at the wrong part of my code. This may be tricky.

delaguardo14:02:27

btw, regarding destructuring ā€” you can mix keys extraction with different namespaces: {:foo/keys [a b] :bar/keys [c d]} obj

Patrick Brown14:02:53

WHAT!!! How did I miss that? Thatā€™s cool.

delaguardo14:02:18

obviously as long as names are not the same

Patrick Brown14:02:19

Found it! Thanks so much for helping me talk through it. The error was in calling pub with two channels as arguments.

Patrick Brown14:02:52

Yup, Iā€™ve verified @U064X3EF3 and @U04V4KLKC as good guys for the day. Cheers, I would have been staring in the wrong place for way too long.

jpmonettas19:02:43

@U036UJBDM5G probably too late, but I made a tool that helps debugging those kinds of issues https://github.com/jpmonettas/flow-storm-debugger, maybe the next time it can help

Thierry14:02:20

I am looking for a way to either force clj-http to use TLSv1.3 with the provided keystore and truststore or a lightweight replacement. One of our providers switched to RHEL8 and is now enforcing TLSv1.3 which atm causes an error when using clj-http regarding an invalid certification path for one of the endpoints we connect to. I have asked questions regarding this in #CBE668G4R about enabling the logging for the dependency and a question in #C8860D6BS but that channel isn't very populated. Error thrown:

sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
     adjacencyList: #object[sun.security.provider.certpath.AdjacencyList 0x7f2de45 "[\nLinkedList[0]:\n]\n"]
And also:
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by clojure.core$bean$fn__7278$fn__7279 (file:/C:/Users/thier/.m2/repository/org/clojure/clojure/1.11.1/clojure-1.11.1.jar) to method sun.security.provider.certpath.SunCertPathBuilderException.getAdjacencyList()
WARNING: Please consider reporting this to the maintainers of clojure.core$bean$fn__7278$fn__7279
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

delaguardo15:02:13

clj-http should work with TLSv1.3 just fine. How do you call request function?

Thierry16:02:24

Here's the request (simplified but the same) (clj-http.core/request {:method :post :url "" :body "some xml string" :throw-exceptions false :connection-manager (clj-http.conn-mgr/make-reusable-conn-manager {:keystore "store" :keystore-pass "pwd" :trust-store "store" :trust-store-pass "pwd"})}) I just manually created a connection manager using java methods and explicitly setting TLSv1.3 but it resulted in the same errors. I guess it must be something to do with the illegal reflective access error ?

Thierry16:02:14

Cleared all cached and started a fresh repl. Did everything manual and the same error gets thrown.

WARNING: Illegal reflective access by clojure.core$bean$fn__7278$fn__7279 (file:/C:/Users/thier/.m2/repository/org/clojure/clojure/1.11.1/clojure-1.11.1.jar) to method sun.security.provider.certpath.SunCertPathBuilderException.getAdjacencyList()

Thierry16:02:17

Same issue on Clojure 1.10.1

Thierry16:02:55

I'm using jdk-11.0.16.1

Thierry16:02:39

I Know the certificate is okay, because when I try with curl I get a response from the server

Thierry16:02:30

I have debug logging enabled and this logs:

javax.net.ssl|DEBUG|16|nREPL-session-9a6d32af-28d2-40bc-9f19-df31980cb8d8|2023-02-28 17:04:47.966 CET|SSLCipher.java:1866|KeyLimit read side: algorithm = AES/GCM/NOPADDING:KEYUPDATE
countdown value = 137438953472
javax.net.ssl|DEBUG|16|nREPL-session-9a6d32af-28d2-40bc-9f19-df31980cb8d8|2023-02-28 17:04:47.968 CET|SSLCipher.java:2020|KeyLimit write side: algorithm = AES/GCM/NOPADDING:KEYUPDATE
countdown value = 137438953472
javax.net.ssl|ERROR|16|nREPL-session-9a6d32af-28d2-40bc-9f19-df31980cb8d8|2023-02-28 17:04:47.978 CET|TransportContext.java:361|Fatal (CERTIFICATE_UNKNOWN): PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target 

delaguardo16:02:42

Reflection warning points to the place where clj-http generates response for debugging, so I would ignore it for now. Could be something wrong with keystore or trust-store, do you use full-path to them or relative to the project root?

Thierry16:02:29

Okay, will try with a full path

Thierry16:02:44

As note, curl shows SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384

Thierry16:02:20

Same issue unable to find valid certification path to requested target

Thierry16:02:53

keystore does seem to get loaded? .ssl|DEBUG|16|nREPL-session-9a6d32af-28d2-40bc-9f19-df31980cb8d8|2023-02-28 17:09:31.914 CET|SunX509KeyManagerImpl.java:164|found key for and then a printout of the ssl. Followed by .ssl|DEBUG|16|nREPL-session-9a6d32af-28d2-40bc-9f19-df31980cb8d8|2023-02-28 17:09:31.974 CET|X509TrustManagerImpl.java:79|adding as trusted certificates and a prinout of the chain

Thierry16:02:06

Which is then followed by: .ssl|DEBUG|16|nREPL-session-9a6d32af-28d2-40bc-9f19-df31980cb8d8|2023-02-28 17:09:32.130 CET|SSLCipher.java:1866|KeyLimit read side: algorithm = AES/GCM/NOPADDING:KEYUPDATE countdown value = 137438953472 .ssl|DEBUG|16|nREPL-session-9a6d32af-28d2-40bc-9f19-df31980cb8d8|2023-02-28 17:09:32.132 CET|SSLCipher.java:2020|KeyLimit write side: algorithm = AES/GCM/NOPADDING:KEYUPDATE countdown value = 137438953472 .ssl|ERROR|16|nREPL-session-9a6d32af-28d2-40bc-9f19-df31980cb8d8|2023-02-28 17:09:32.135 CET|TransportContext.java:361|Fatal (CERTIFICATE_UNKNOWN): PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Thierry16:02:33

Kind lost on how to solve this

delaguardo16:02:00

me to, sorry. I never stumbled upon such exception and all I can find out points to some jvm related keystores

Thierry16:02:05

I've been at this for 2 days now, seen a zillion pages but nothing that points me in the correct direction. I've tried to enable debug logging on clj-http but my calva session seems to overrule the settings so I cant get it to produce any logs. Tried to find another library but not found one yet that can handle a jks keystore. Tried to manually create a connectionmanager with TLSv1.3 explicitly enabled but I keep on running into the same issue. I know it's not clj-http as we've been and are using this for connections to other service providers without any issue. The issue started after this specific provider updated to RHEL8, things worked fine before that.

Thierry16:02:17

I feel like I'm running in circles haha

delaguardo16:02:36

you could try another library that offers more control on the connection. for example https://github.com/gnarroway/hato

Thierry16:02:19

I'll have a look at it thanks. This whole project I maintain is built on using clj-http haha

Thierry17:02:17

Had quick look into it, seems simple enough to drop in replace. Will try this tomorrow

Craig Brozefsky17:02:42

They likely changed their certificate.

Thierry18:02:34

Wish it was that simple. Received a new certificate that has the same issue. Like I explained, the certificate works fine with curl.

Thierry11:03:04

Same issue with hato @U04V4KLKC :melting_face:

delaguardo11:03:02

hm... then I would blame JVM šŸ™‚ it maintain global certificate chains somewhere

delaguardo11:03:33

another way ā€” shell out to call curl %)

delaguardo11:03:09

šŸ¤· but at least it works šŸ™‚

Thierry15:03:08

In the end it was the keystore doing stuff it shouldnt.

Timofey Sitnikov19:02:14

Hello all, I am trying to write a custom test macro, is there a way to override what the (is ) function prints out. In my case it just says actual: false but I would like to give it more detail why it is false. The (1) macro can print the the details, println prints it to wrong place.

hiredman19:02:48

user=> (clojure.test/is false "foo")

FAIL in () (NO_SOURCE_FILE:1)
foo
expected: false
  actual: false
false
user=>

hiredman19:02:13

user=> (doc clojure.test/testing)
-------------------------
clojure.test/testing
([string & body])
Macro
  Adds a new string to the list of testing contexts.  May be nested,
  but must occur inside a test function (deftest).
nil
user=>

hiredman19:02:38

user=> (clojure.test/testing "something" (clojure.test/is false))

FAIL in () (NO_SOURCE_FILE:1)
something
expected: false
  actual: false
false
user=>

hiredman19:02:39

clojure.test/is has a multimethod under the hood, so it is extendable

Timofey Sitnikov19:02:55

That works perfect, I was actually trying to build function similar to the roughly

dpsutton19:02:39

(doc clojure.test) gives a manual on it. big fan of namespace docstrings

šŸ‘ 2