Fork me on GitHub

In ghostwheel's readme, there's this line about enabling it in a clojure project:

On Clojure – launch the REPL / build with the JVM system property -Dghostwheel.enabled=true
how would I have to edit my clojure cli repl command so that that's included? This doesn't work:
/run/current-system/sw/bin/clojure -Sdeps '{:deps {nrepl/nrepl {:mvn/version "0.8.3"} refactor-nrepl/refactor-nrepl {:mvn/version "2.5.1"} cider/cider-nrepl {:mvn/version "0.25.9"}} :aliases {:cider/nrepl {:main-opts ["-m" "nrepl.cmdline" "--middleware" "[cider.nrepl/cider-middleware]"]}}}' -M:cider/nrepl -Dghostwheel.enabled=true


@meditans -Dghostwheel.enabled=true needs to be -J-Dghostwheel.enabled=true when using the clojure tool. or within the -Sdeps map :jvm-opts ["-Dghostwheel.enabled=true"]


Thanks for the immediate response @U05224H0W 🙂 Neither option works for me, but maybe at this point it's because I'm trying to use a projectless approach with add-libs. Here's my standalone file:

(use '

(add-libs {'gnl/ghostwheel {:mvn/version "0.3.9"}})

(ns user
  #:ghostwheel.core{:check true, :num-tests 10}
  (:require [ghostwheel.core :as g :refer [>defn >defn- >fdef => | <- ?]]))

(>defn addition
  [a b]
  [pos-int? pos-int? => int? | #(> % a) #(> % b)]
  (- a b))

;; "Ghostwheel disabled => Start the REPL with the `-Dghostwheel.enabled=true` JVM system property to enable."


then I jack in into cider, editing the launch command as you suggested, then I eval the buffer. Is there any known reason for which this shouldn't work?


check (System/getProperties) if yours is actually set correctly


(get (System/getProperties) "ghostweel.enabled")


hmm, no it gives me nil 😮


where did you set it exactly? I think the position matters


I tried:

/run/current-system/sw/bin/clojure -Sdeps '{:deps {nrepl/nrepl {:mvn/version "0.8.3"} refactor-nrepl/refactor-nrepl {:mvn/version "2.5.1"} cider/cider-nrepl {:mvn/version "0.25.9"}} :aliases {:cider/nrepl {:main-opts ["-m" "nrepl.cmdline" "--middleware" "[cider.nrepl/cider-middleware]"]}}}' -M:cider/nrepl -J-Dghostwheel.enabled=true


and at the beginning of the -Sdeps map for the other solution


I think the -J needs to come before the -M if anything


but the map should be fine I think


dunno if cider maybe starts another JVM or so to make add-lib work


in fact, if I put it before -M, the get function returns true. But why? And how should I have known?


-M executes clojure.main so I think every argument coming after that is treated as an argument to clojure.main instead of the clojure script itself


just guessing though, not sure 🙂


I see, thank you for your help 🙂


the thing as a whole doesn't work yet, as I get cannot resolve user (where user is the namespace) when I try to issue (g/check) but at least it's not a configuration problem


oh, but it seems that if I substitute user with interesting.user as the name of the namespace, all works 😮

Jim Newton07:08:40

Does anyone know the history of the convention that clojure projects organize themselves such that all identifiers in one namespace are defined in a single file whose name indicates the namespace? This is not a requirement of the language, but seems to be a convention presumed by several tools. I suspect that this convention developed at some point after the birth of the language. A bit of evidence to support my hypothesis is the file cl_format.clj which defines the function cl-format as well as several helper functions in its implementation. The file cl_format.clj does not define a namespace named cl-format but rather contains a line at the top (in-ns 'clojure.pprint) which to me seems like the more logical way to organize projects. I.e., group definitions such as functions, data structures, and variables into files according to the purpose they serve rather than according to which namespace they happen to belong.

👀 1

although written for CLJS the same "content addressing" applies for clojure. things need to be discoverable by name so you can reference them. sure you can split them and use load tricks but that just becomes dirty after a while. IMHO, YMMV

Jim Newton09:08:24

content addressable vs ad-hoc loading are not the only options. but yes there needs to be a way to find the code given its name. but that mapping need not be the identity function.


IIRC ns :require was added later and wasn't part of the language at first. so the clojure.pprint may just be a remnant of that time


if you ask me that load style is horrible. its very very common in the JS world and re-exporting stuff all over the place. nightmare to find actual source for something sometimes. just jumping from one file to another following a trail of breadcrumbs 😛 much better to look at a name and directly know where to find it

☝️ 3
Adam Helins08:08:09

Regarding and current Deps support, when consuming external source (git or local) that has a build step, is there a way to parametrize that step at the level of the consumer? Eg. Consuming from a monorepo but I only need to build and use one of the many library it contains. Something like

{:deps { {:git/sha   "xxxxx"
                           :exec-args [:lib/baz true]}}}


Unless you mean exactly in clj code?

Adam Helins08:08:18

I mean something like this, in deps.edn:

{:deps { {:git/sha "xxxxx" :build :some-arg}}}
So that :deps/prep-lib in the consumed repo would forward :some-arg to the build function.

Adam Helins08:08:01

As as consumer of that repo, I would have the ability to influence the build process.

Adam Helins08:08:54

I'll edit my question, it's in the context of 😉

Adam Helins08:08:11

Supposing something like this is already setup

👍 3
Jim Newton09:08:33

is there a web page URL which contains the cl-format code? there is a source link on many packages in but not this one?


How can i isolate clojure instances? I have dynamically loaded code that define defmethods for dispatch. However, I also want to be able to dynamically load and test code (eg. "version n+1") in a way that won't affect the previous version. Obviously I could run in a separate process, but is there something I can do short of that?


with-redefs help?


You can put the new version in a new namespace. There`s also the dark art of classloader isolation, but tbh you're better off starting a new process.


ill take a look at with-redefs, i suspect though defmethod is problematic. yeah, i looked into classloader, but wasn't finding enough info, as you say "dark art".


yes, i was going to rename the namespaces, but that alone didn't seem sufficient, again the defmethod would be problematic, and I'm not sure what else might be.


i suppose i could change the defmulti :require, so that it's effectively a different defmethod, but then it all seems fragile.


on this page, i think they mean the last line that says ;;true should be ;;false??*use-context-classloader*

Jan K14:08:05

On a related note, do you guys think it would make sense to run independent Clojure apps (servers) in an app server like Tomcat to save memory by sharing a JVM?


If the apps are truly independent it's a bad idea, as they might have incompatible Maven dependency trees If 'apps' is more like 'logical services', yes. Polylith goes in that direction :) Still one has to take care of shared resources like thread pools, singletons, locks etc. Anything that might create contention


memory is cheap, I think extra work will cost more, than pay for memory. At least I use docker everywhere.

Jan K14:08:38

I think Tomcat has isolated classloaders, so incompatible deps should work. I run my stuff on cheapest VPS I could find, RAM is usually the biggest constraint for me.


this is my opinion: increasing complexity is not worth. I prefer to keep infrastructure simple. I believe it gives much more benefits. Try google cloud run. Probably for your needs you can run instances for free. Just guess.


Many issues can be solved on infrastructure level instead of in app itself.

Jan K14:08:09

I'll have a look at cloud hosting


I noticed that core.memoize has something called RetryableDelay and a d-lay ` It's private now, but I'm thinking this would be pretty useful for me, to have a delay that on deref exception will throw and not cache, so on the next deref it retries. Would it make sense to make this public?


It's not something I would want folks to rely on as part of a public API.


(I think it's nasty code but it serves a purpose)


You mean the concept or the implementation? Why do you think it's nasty?


I'd have to go revisit it to elaborate further and I'm not working on it right now.


I'll try to remember to review it in more detail and report back when I cut the next release -- because I need to bump its dependency on core.cache to pick up the LU/LRU bug fixes in that lib's 1.0.217 release from the other day.


Sweet, thanks!


Ya, I think for me I was thinking it might not fit conceptually with core.memoize, I could see maybe a separate thing just having various types of delays instead. One that doesn't cache on error, one with a ttl, one that can be invalidated, etc.

Jakub Holý (HolyJak)20:08:06

Hi folks! Any idea how to fix

❯ clojure -M:serve                                                                 • [master]
Execution error (UnsatisfiedLinkError) at java.lang.ClassLoader$NativeLibrary/load0 (
/private/var/folders/06/46ycckp94db7k29k022nxjp00000gn/T/jna9260967378841025822.tmp: dlopen(/private/var/folders/06/46ycckp94db7k29k022nxjp00000gn/T/jna9260967378841025822.tmp, 1): no suitable image found.  Did find:
	/private/var/folders/06/46ycckp94db7k29k022nxjp00000gn/T/jna9260967378841025822.tmp: code signature in (/private/var/folders/06/46ycckp94db7k29k022nxjp00000gn/T/jna9260967378841025822.tmp) not valid for use in process using Library Validation: mapped file has no cdhash, completely unsigned? Code has to be at least ad-hoc signed.
? I have never seen this before and this worked on another machine (with a different JVM). Using openjdk 12.0.2 2019-07-16, Clojure CLI version 🙏

Jakub Holý (HolyJak)20:08:32

downgrading from java 12 to 11 "fixed" it