Start an nREPL using JVM Opts (Like socket REPL)
It's not possible to start the clj tools in jack-in with a main or additional -e options.
Starting the nREPL should be similar to starting a socket REPL. If it was a JVM opt it can be placed as the first parameter, always, as CLJ doesn't distinguish on order.
Using JVM opts in this way would also benefit production systems which wish to add nREPL. Currently it requires being able to evaluate code early, or altering the component/integrant/mount system in order to load nREPL in production (but not in dev, because leiningen does that!). This would also open up nREPL for easier use with general java software systems, such as Datomic.
Sounds like a cool idea, but you'd have to share a few more details, as I haven't used the socket REPL in a while and I don't even remember how you were supposed to start it. :-)
It's not possible to start the clj tools in jack-in with a main or additional -e options.
So, we basically want to run the app and also start the nREPL server "by the way", right? Maybe you can share how exactly the ideal run invocation would look like?
Seems we're after:
-Dnrepl.server="{:port 5555 :bind ... :middleware []}"
This would be awesome indeed, so a PR would be most welcomed by me!
It would seem that clojure's socket repl isn't as magical as I thought. It doesn't start until clojure itself does, relying on the loading of clojure.lang.RT. Getting nrepl to autostart requires finding a way to get something in Java/clojure to reference it, as initialization is lazy.
@SevereOverfl0w Did you check nrepl.cmdline namespace? And there is also Java main class. Or is there some reason why -e would be better?
clj -Sdeps '{:deps {nrepl {:mvn/version "0.4.5"}}}' -m nrepl.cmdline --help
java -cp $(clj -Sdeps '{:deps {nrepl {:mvn/version "0.4.5"}}}' -Spath) nrepl.main
@Deraen the problem I have currently is that I can't specify -m and -e. I think this is a clojure.main limitation.
See:
$ clj -A:user/rebel -Sdeps '{:deps {refactor-nrepl {:mvn/version "2.4.0-SNAPSHOT"} cider/cider-nrepl {:mvn/version "0.18.0"} }}' -e '(require (quote cider-nrepl.main)) (cider-nrepl.main/init [ "refactor-nrepl.middleware/wrap-refactor" "cider.nrepl/cider-middleware"])'
[Rebel readline] Type :repl/help for online help info
user=>
Which doesn't start an nrepl server.
java -cp $(clj -Sdeps '{:deps {nrepl {:mvn/version "0.4.5"}}}' -Spath) nrepl.main
FYI - I'm currently wondering if we need this at all. I don't really see any benefits from it, but I might be missing something.
@bbatsov Sorry, I should been explicit. The key thing missing is that I want -A:user/rebel (which has -m rebel.main in) to not prevent nrepl from starting.
I want to be able to start a command line REPL (or anything else) without being prevented from starting nREPL simultaneously.
This would be particularly nice for the case where I'm trying to debug a process primarily run via the main (e.g. pack) or for Edge where we're trying to provide a great CLI & nREPL experience out of the box.
@SevereOverfl0w No, I totally get this now. I was actually facing a similar problem with REPL-y - I want to potentially start a default REPL-y repl using clj, but it's hard to do it in the current setup. One idea I had to was to check in nrepl.cmdline if it's on the classpath and use it instead of simple built-in REPL (and I guess we can do the same for rebel) or maybe to actually create a separate project nrepl.main that just can depend on all those CLI stuff and provide the great experience. Still, I believe that if we can find a way to start the server with java opts that'd be extremely useful, regardless of the alternatives.
I'm currently thinking about trying to solve this via a third party with a some kind of "main.hopper" which would in some manner allow you to call multiple mains.
Perhaps if -background-main or similar was defined adjacently to a -main then it would be called instead. Alternatively, if the user specifies that it's a "daemonizing main" then perhaps the main could be started in a Thread and it's state monitored in order to determine when it's "done" (e.g. if BLOCKED and stack unchanged for N seconds then assume done). In the case on nrepl this is discordant as we are daemonizing something which un-daemonizes the starting of a server.
I don't see too much value in adding support for the current way clj does argument composition as well. It is just not straightforward.
Even if we had nrepl.cmdline -m ... -m ... (or similar args for JVM opts) one would still need to guess/discover/understand that vectors in different aliases are concatenating in clj.
I found the idea of nrepl.edn much better. My 2c.