Welcome! Please see the About page for a little more info on how this works.

+3 votes
in tools.namespace by
edited by

I've run into an issue where refresh from tools.namespace (v. 0.3.0) seems to work with Java 8 but not Java 11. I tried with both Clojure 1.10.0 and 1.10.1. I was able to reproduce the problem on a clean virtual machine. In both cases, I was able to reload the namespaces on Java 8 but not Java 11.

It's weird though -- in some of my other projects, I can reload namespaces on Java 11. I haven't been able to track down the difference. (I'm also new to tools.deps, so it could be I'm doing something wrong there.)

I put together a reproduction here: https://github.com/thomascothran/namespace-repro

I'm assuming it's likely an error on my end, but the only thing I've been able to narrow it down to is the Java version.

Reference: https://clojure.atlassian.net/browse/TNS-54

1 Answer

+5 votes
selected by
Best answer

This is due to a known issue with a library java.classpath on which tools.namespace depends, which has been fixed and released, but in a later version of java.classpath than the one that tools.namespace currently depends upon.

I can create an issue to fix that in tools.namespace, but without waiting for a fix, you can explicitly add a dependency upon the later version of the java.classpath library in your project, and likely things will work for you with JDK 11:

org.clojure/java.classpath {:mvn/version "0.3.0"}

It is likely that in the projects you have seen where things are working, some other dependency you have requires a later version of java.classpath.

That did the trick. Wonder if it's worth a note in the README, if that's easier than pushing out a patch? Knowing that I need to add that dependency isn't a burden at all, and I'm perfectly content with doing that.

Thanks for diagnosing this, Andy. I really appreciate it.
I will work on getting tools.namespace updated.
Released as tools.namespace 0.3.1.
That was fast! I updated the version to 0.3.1 and it's working across my projects now. Thank you, Alex.
reshown by
This actually doesn't work for me on Java 9+ (tried OpenJDK 9 and 11 on Mac OS X).

This is what I get from `(clojure.java.classpath/classpath)`:
(#object[java.io.File 0x7c475f0b "/Library/Java/JavaVirtualMachines/jdk-9.jdk/Contents/Home/lib/src.zip"])

It's the result of `(classpath (clojure.lang.RT/baseLoader))` and so the `(system-classpath)` is ignored.

Works fine on JDK 8.

EDIT: so it seems to be a CIDER "issue" - when I try plain `lein repl` it works.
It seems that CIDER adds src.zip to the classloader's path.
I'm wondering if it would be better to actually merge those two classpaths instead of taking one or the another?
Here's the Cider issue I reported for the reference: https://github.com/clojure-emacs/cider/issues/2686
The problem, as Juraj Martinka has identified, is with `(clojure.java.classpath/classpath)` in certain contexts. I have added my own comments at https://github.com/clojure-emacs/cider/issues/2686#issuecomment-531366583

There have been multiple workarounds in java.classpath for different environments. The current behavior was added in https://clojure.atlassian.net/browse/CLASSPATH-8 to work around changes to the classloader hierarchy in Java 9. The relevant lines are  https://github.com/clojure/java.classpath/blob/68f972cd47adcc248d205265ae352ca4caaa117a/src/main/clojure/clojure/java/classpath.clj#L86-L87

At first glance, Juraj Martinka's suggestion — to combine the two classpath sources — looks like a viable solution, although I do have questions about possible duplication of paths. I would also like to understand why the CIDER jack-in process produces this result before making changes. I will wait to see if someone on the CIDER issue thread can help with an explanation.