A Simpler Way to Deal with Java Sources in CIDER
For ages dealing with Java sources in CIDER has been quite painful.1 Admittedly,
much of the problems were related to an early design decision I made to look for
the Java sources only in the classpath, as I assumed that would be easiest way
to implement this. Boy, was I wrong! Countless of iterations and refinements to
the original solution later, working with Java sources is still not easy.
enrich-classpath made
things better, but it required changes to the way CIDER (nREPL) was being started
and slowed down the first CIDER run in each project quite a bit, as it fetches
all missing sources at startup. It’s also a bit trickier to use it with
cider-connect
, as you need to start nREPL together with enrich-classpath
.
Fortunately, my good friend and legendary Clojure hacker Oleksandr
Yakushev recently proposed a different
way of doing things and today
I’m happy to announce that this new approach is a reality!
There’s an exciting new feature waiting for you in the latest CIDER MELPA build. After
updating, try turning on the new variable cider-download-java-sources
(M-x customize-variable cider-download-java-sources
and then toggle to enable
it). Now CIDER will download the Java sources of third-party libraries for Java
classes when:
- you request documentation for a class or a method (
C-c C-d C-d
) - you jump to some definition (
M-.
) within a Java class
Note that eldoc
won’t trigger the auto-download of Java sources, as we felt this might
be harmful to the user experience.
This feature works without enrich-classpath
.2 The
auto-downloading works for both tools.deps and Leiningen-based projects. In both
cases, it starts a subprocess of either clojure
or lein
binary (this is the same
approach that Clojure’s 1.12 add-lib
utilizes).
And that’s it! The new approach is so seamless that it feels a bit like magic.
This approach should work well for most cases, but it’s not perfect. You
might have problems downloading the sources of dependencies that are not public
(i.e. they live in a private repo), and the credentials are non-global but under
some specific alias/profile that you start REPL with. If this happens to you,
please report it; but we suspect such cases would be rare. The download usually
takes up to a few seconds, and then the downloaded artifact will be reused by
all projects. If a download failed (most often, because the library didn’t publish
the -sources.jar
artifact to Maven), CIDER will not attempt to download it again
until the REPL restarts. Try it out in any project by jumping to
clojure.lang.RT/toArray
or bringing up the docs for
clojure.lang.PersistentArrayMap
.
Our plan right now is to have this new feature be disabled by default in CIDER 1.17 (the next stable release), so we can gather some user feedback before enabling it by default in CIDER 1.18. We’d really appreciate your help in testing and polishing the new functionality and we’re looking forward to hear if it’s working well for you!
We also hope that other Clojure editors that use cider-nrepl
internally (think Calva,
iced-vim
, etc) will enable the new functionality soon as well.
That’s all I have for you today! Keep hacking!
P.S. The State of CIDER 2024 survey is still open and it’d be great if you took a moment to fill it in!