beginners

sheluchin 2025-10-21T17:47:26.147909Z

I keep running into this certificate error when trying to make an external request using something like httpkit ๐Ÿงต

sheluchin 2025-10-21T17:47:55.306639Z

{:cause "unable to find valid certification path to requested target",
 :via
 [{:type javax.net.ssl.SSLHandshakeException,
   :message
   "(certificate_unknown) PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target",
   :at [sun.security.ssl.Alert createSSLException "Alert.java" 130]}
  {:type sun.security.validator.ValidatorException,
   :message
   "PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target",
   :at
   [sun.security.validator.PKIXValidator
    doBuild
    "PKIXValidator.java"
    387]}
  {:type sun.security.provider.certpath.SunCertPathBuilderException,
   :message
   "unable to find valid certification path to requested target",
   :at
   [sun.security.provider.certpath.SunCertPathBuilder
    build
    "SunCertPathBuilder.java"
    148]}],
 :trace
 [[sun.security.provider.certpath.SunCertPathBuilder
   build
   "SunCertPathBuilder.java"
   148]
  [sun.security.provider.certpath.SunCertPathBuilder
   engineBuild
   "SunCertPathBuilder.java"
   129]
  [java.security.cert.CertPathBuilder build "CertPathBuilder.java" 299]
  [sun.security.validator.PKIXValidator
   doBuild
   "PKIXValidator.java"
   382]
  [sun.security.validator.PKIXValidator
   engineValidate
   "PKIXValidator.java"
   270]
  [sun.security.validator.Validator validate "Validator.java" 256]
  [sun.security.ssl.X509TrustManagerImpl
   checkTrusted
   "X509TrustManagerImpl.java"
   284]
  [sun.security.ssl.X509TrustManagerImpl
   checkServerTrusted
   "X509TrustManagerImpl.java"
   144]
  [sun.security.ssl.CertificateMessage$T13CertificateConsumer
   checkServerCerts
   "CertificateMessage.java"
   1273]
  [sun.security.ssl.CertificateMessage$T13CertificateConsumer
   onConsumeCertificate
   "CertificateMessage.java"
   1172]
  [sun.security.ssl.CertificateMessage$T13CertificateConsumer
   consume
   "CertificateMessage.java"
   1115]
  [sun.security.ssl.SSLHandshake consume "SSLHandshake.java" 421]
  [sun.security.ssl.HandshakeContext
   dispatch
   "HandshakeContext.java"
   477]
  [sun.security.ssl.SSLEngineImpl$DelegatedTask
   run
   "SSLEngineImpl.java"
   1207]
  [org.httpkit.client.HttpsRequest doHandshake "HttpsRequest.java" 91]
  [org.httpkit.client.HttpClient doRead "HttpClient.java" 218]
  [org.httpkit.client.HttpClient run "HttpClient.java" 519]
  [java.lang.Thread run "Thread.java" 1474]]}

2025-10-21T18:06:33.309399Z

a usefull sniff test is to curl the url and see if curl trusts the cert

sheluchin 2025-10-21T18:07:35.547989Z

Yeah, curl does. It's "https://google.com"

2025-10-21T18:07:57.609759Z

if it does you may need to update the certs that java trusts, potentially by upgrading java

sheluchin 2025-10-21T18:08:04.720129Z

I was behind a firewall but have removed it. I think some firewall thing is hanging around. I tried to reinstall java and clojure.

2025-10-21T18:09:16.380729Z

what version of java? reinstalled from where?

sheluchin 2025-10-21T18:10:01.941279Z

% which java
/Users/mbp25/.local/share/mise/installs/java/temurin-25.0.0+36.0.LTS/bin/java

sheluchin 2025-10-21T18:10:38.258369Z

I'm using mise for managing my dependencies like Clojure and Java.

2025-10-21T18:11:37.392039Z

how sure are you that java is actually what is being used when you get the stacktrace?

2025-10-21T18:12:24.207849Z

(seems unlikely you would have something old enough to have trouble trusting google's certs though)

sheluchin 2025-10-21T18:12:58.615879Z

You mean how sure am I that it's that version?

2025-10-21T18:13:27.268129Z

that when you ran the code that gave you the error it was actually using that java

2025-10-21T18:14:07.449799Z

like if you have JAVA_HOME set to something else, or started jvm from emacs which might have a different env

sheluchin 2025-10-21T18:14:20.046169Z

if I'm not in a directory being managed by mise:

~ % java --version
The operation couldnโ€™t be completed. Unable to locate a Java Runtime.
Please visit  for information on installing Java.

2025-10-21T18:18:08.672989Z

ah, I bet the temurin install has its own trust store, where curl is using the macos keychain, and something (is this a work provisioned laptop?) has inserted a root cert in the macos keychain, and something is mitm attacking your traffic

sheluchin 2025-10-21T18:19:10.040179Z

Yeah, it's a work laptop but we made an effort to remove anything that might be MITM'ing my traffic. I'm this close:ok_hand: to a factory reset.

2025-10-21T18:20:19.326849Z

it might be possible to find the java trust store in the temurin-25.0.0+36.0.LTS diractory, and maybe use keytool to dump the certs in it, then compare those to the certs in the keyring

2025-10-21T18:20:44.466659Z

may not be something on your laptop

sheluchin 2025-10-21T18:22:31.924529Z

What do you mean, not something on my laptop?

2025-10-21T19:16:00.695489Z

If you are on a company network they might have some mitm appliance, and require the certs for it to be installed on all provisioned machines

1
Bob B 2025-10-22T00:53:59.290099Z

^ Very much this. I have a similar situation on my company machine. One way to potentially confirm would be to look at the cert info for http://google.com in the company machine browser and a "public"/personal machine browser. The http://google.com cert on the "public" machine will likely be issued by something like "Google Trust Services", while on the company machine, it might be issued by something like "my-company-ca" or "SomeSecurityProvider Intermediate CA". If you connect to company stuff via a VPN or something along those lines, the MITM is likely happening on the network, and company machines will have those CAs in their system cert stores (so things like curl will trust them), but a "fresh" java installation usually won't.

sheluchin 2025-10-22T00:58:48.566729Z

I suppose there's no easy path to fix it for all your development needs at once? I've run into similar issues with node, Python, docker, etc.. In the Clojure case I initially patched it by setting some CLJ_JVM_OPTS to use the osx keystore and it fixed deps downloading but for some reason it didn't fix REPL invocations that made requests.

Bob B 2025-10-22T01:07:59.251069Z

The short-ish, not that helpful answer is "install the certs where they're needed". There might be a company repo of the certs, but different tools are going to have different paths to adding certs/telling a platform to use the system cert store. I'm not aware of a panacean answer.

๐Ÿ‘ 1
Oleh K. 2025-10-21T21:07:23.720999Z

how can I get an evaluated result here?:

(defmacro example [data]
  `(let [foo# ~(first data)]
     (cons 'and (list 1 foo#))))

(example [2])
It returns (clojure.core/and 1 2) , but I want 2 .

Harold 2025-10-21T21:09:59.971369Z

user> (defn example
        [data]
        (let [foo (first data)]
          (and 1 foo)))
#'user/example
user> (example [2])
2

Samuel Ludwig 2025-10-21T21:26:03.500779Z

Is the purpose here merely practice with macros in particular? If not, and you're instead looking for general evaluation, then @hhausmanโ€™s answer, using a function, is definitely preferred. But if you're trying to play with macros themselves, this technically gives you the answer you want (it explicitly evals the form you created with cons)

(defmacro example [data]
  `(let [foo# ~(first data)]
     (eval (cons 'and (list 1 foo#)))))
It's effectively the same as
(defmacro example [data]
  `(let [foo# ~(first data)]
     (cons 'and (list 1 foo#))))

(eval (example [2]))

Samuel Ludwig 2025-10-21T21:28:31.653759Z

This, a bit simpler, but still a macro, also gives you what you want, i believe, by not consing up a new form in the first place

(defmacro example [data]
  `(let [foo# ~(first data)]
     (and 1 foo#))) ; edit: corrected by phronmophobic

โž• 1
โ›” 1
Samuel Ludwig 2025-10-21T21:31:49.792679Z

Your call to cons is returning a new form (read: new clojure code); it doesn't evaluate it

Harold 2025-10-21T21:32:34.851959Z

๐Ÿ˜ฎ

user> (and 1 2)
2
user> ('and 1 2)
2
simple_smile

Harold 2025-10-21T21:34:26.252029Z

And.... well outside the scope of the #beginners channel:

user> (#'and 1 2)
true
๐Ÿคญ

phronmophobic 2025-10-21T21:37:42.532809Z

The above example gives the wrong impression. Try:

(defmacro example [data]
  `(let [foo# ~(first data)]
     ('foo 1 foo#)))

> (example [2])
2
What is happening is that you're invoking a symbol. Invoking a symbol is similar to invoking a keyword. It's more or less equivalent to:
(get 1 'foo 2)
Since 1 doesn't contain 'foo, it returns 2.

๐Ÿ‘ 2
Samuel Ludwig 2025-10-21T21:41:07.515319Z

whoopsie

Samuel Ludwig 2025-10-21T21:42:27.465429Z

it would also help if you would specify exactly what you're trying to play with/figure out @okilimnik, there's many many ways to get an output of 2 from both macros and functions :^)

Oleh K. 2025-10-21T22:25:23.158579Z

Yes, I'm playing with macros to get more understanding. In my example the (list 1 foo#) is a simulation of calling another function that accepts foo# as a parameter and returns a form.

Oleh K. 2025-10-21T22:30:39.849889Z

So seems there is no way other than using eval ?

Oleh K. 2025-10-21T22:30:48.554079Z

Thank you, guys

phronmophobic 2025-10-21T22:37:53.633929Z

I doubt you need eval here. You should be able to do:

(defmacro example [data]
  `(let [foo# ~(first data)]
     (and 1 foo#)))

Oleh K. 2025-10-21T22:39:06.356479Z

As I said above I need to (list 1 foo#) and then to add and to the resulting form

phronmophobic 2025-10-21T22:42:28.993199Z

Can you provide a bit more context about the actual goal? I still donโ€™t think eval is necessary, but itโ€™s hard to give a better answer without more context.

phronmophobic 2025-10-21T22:46:34.503059Z

Another way to write it that's a bit more dynamic is:

(defn example3* [data]
  (let [foo## (gensym "foo")]
    `(let [~foo## ~(first data)]
       ~(cons 'and (list 1 foo##)))))

(defmacro example3 [data]
  (example3* data))
I'm also using a common trick where the macro defers to a pure function that is easier to test. note: Sometimes you need to refer to a symbol inside of backtick, but also programmatically. I use ## as a suffix for these situations, but that is a thing I came up with and I'm not aware of anyone else that does it.

phronmophobic 2025-10-21T22:51:05.139619Z

Just based on experience, I have a feeling that the code could be less complicated using some regular old function like some.

Oleh K. 2025-10-21T23:03:56.584699Z

Wow @smith.adriane! Thank you so much! That's what I was looking for. And your last point is brilliant as well. It works as I want if I replace cons 'and with every? identity :

(defmacro example [data]
  `(let [foo# ~(first data)]
     (every? identity (list 1 foo#))))

phronmophobic 2025-10-21T23:11:32.468479Z

Iโ€™m pretty sure Iโ€™ve seen similar questions here over the years regarding and . ๐Ÿ˜…

phronmophobic 2025-10-21T23:12:10.578479Z

You may want to ponder whether you need a macro at all in this situation.

๐Ÿ‘ 2
1
2025-10-21T01:28:50.300129Z

Does anyone really use the io! macro?

ghadi 2025-10-21T01:33:31.062069Z

no

2025-10-21T01:38:55.416069Z

Lol that was to the point ๐Ÿ˜„

2025-10-21T01:39:38.652079Z

What prompted it to be in core then? An experiment that didn't really bear fruit?

2025-10-21T01:52:35.477279Z

It is part of the stm(could apply to swap! to avoid retry io, but doesn't), which itself is rarely used

๐Ÿ‘๐Ÿป 1
phronmophobic 2025-10-21T01:55:12.616129Z

It's pretty rare, https://cloogle.phronemophobic.com/name-search.html?q=clojure.core%2Fio%21&tables=var-usages

๐Ÿ‘๐Ÿป 1
2025-10-21T02:06:09.016639Z

Would be interesting to find the age range of those usages

phronmophobic 2025-10-21T02:08:30.468249Z

That is a neat idea. There's a couple different ways to measure age, but I think most reasonable methods would be interesting in their own way.

phronmophobic 2025-10-21T02:11:27.250449Z

just spot checking and most of the repos haven't been updated in over a decade.