Fork me on GitHub
#clojure-dev
<
2017-01-23
>
Alex Miller (Clojure team)20:01:48

@bronsa trying to figure out if this me being crazy or if it’s something that should work. Given a namespace:

(ns foo (:import [java.nio.file StandardWatchEventKinds]))
(def a StandardWatchEventKinds/ENTRY_CREATE)
if I (anj/analyze-ns ‘foo) I get: CompilerException clojure.lang.ExceptionInfo: No such namespace: StandardWatchEventKinds {:ns StandardWatchEventKinds, :form StandardWatchEventKinds/ENTRY_CREATE…

bronsa21:01:25

@alexmiller I can't see why that shouldn't work, I'll take a look now

Alex Miller (Clojure team)21:01:35

I just tried in a different repl env and it worked … hrm

Alex Miller (Clojure team)21:01:49

I wonder if I’m getting java 6 somehow where it’s not available

bronsa21:01:11

yeah I'd be very surprised if that didn't work at all -- everything would've been broken then :)

Alex Miller (Clojure team)21:01:23

see prior comment re being crazy :)

bronsa21:01:26

hmm although if that were the case I'd expect it to fail on the ns

Alex Miller (Clojure team)21:01:37

well import doesn’t load now right?

bronsa21:01:07

it should still throw on classnotfound

bronsa21:01:39

do you still have that broken repl env available?

bronsa21:01:30

analyze+ns puts the thrown exception in the returned map as an ExceptionThrown object in the :result key

bronsa21:01:13

it might be that an exception did get thrown while evaluating the ns form but analyze+ns just kept on analyzing & failed on analysis of the next form

bronsa21:01:50

analyze-ns should probably handle that better

Alex Miller (Clojure team)21:01:52

I still have it - I’m in Cursive and I reliably get this

Alex Miller (Clojure team)21:01:04

did not see it running lein repl from same project

bronsa21:01:12

can you just do something like (->> (try (analyze-ns 'foo) (catch Exception _)) (map :result)))

Alex Miller (Clojure team)21:01:16

If I remove the second line, the analyze-ns succeeds

bronsa21:01:30

and see if there's an ExceptionThrown in there

bronsa21:01:18

or just analyze the first form and see if that has an ExceptionThrown object as its :result

Alex Miller (Clojure team)21:01:31

although ns expands to a do form that explicitly returns nil

Alex Miller (Clojure team)21:01:44

so might be buried inside

Alex Miller (Clojure team)21:01:58

nah, no errors in there

Alex Miller (Clojure team)21:01:49

I think the ns line succeeds

bronsa21:01:38

allright I can repro this

bronsa21:01:25

this is a funny one

bronsa21:01:47

allright, so the exception is getting thrown for the missing namespace

bronsa21:01:57

but because ns expands into a do form

bronsa21:01:26

the ExceptionThrown object is deep there

bronsa21:01:56

t.a.jvm should definitely provide a way of handling this better, I'll have a think about it

bronsa21:01:07

but yeah, the error in this case is that your class is not found

Alex Miller (Clojure team)21:01:41

still not sure I get how the class is not found in the first place

Alex Miller (Clojure team)21:01:59

but I think that’s a cursive question

bronsa21:01:19

if you wrap your ns form in like a (let [] ..) you'll get the ExceptionThrown in the top-level map -- it's not there but in a deeper node because of the do unrolling thing

bronsa21:01:22

@alexmiller yeah dunno, t.a.jvm uses (RT/makeClassLoader) to get the classloader it uses to analyze/evaluate forms

bronsa21:01:36

check (System/getProperty "java.version") maybe?

bronsa21:01:50

I know that cursive has to run on java6 for some weird bug in intellij

Alex Miller (Clojure team)21:01:33

yeah, I assume that has something to do with it, but I’m not observing that

Alex Miller (Clojure team)21:01:41

java 8 classes on the boot classpath etc

Alex Miller (Clojure team)21:01:26

I was also able to trigger it by just pulling the import out of the ns

bronsa21:01:05

smallest repro case should be (with-bindings {clojure.lang.Compiler/LOADER (clojure.lang.RT/makeClassLoader)} (eval '(import 'java.nio.file.StandardWatchEventKinds)))

bronsa21:01:11

if that throws than it's not my fault

bronsa21:01:23

if it doesn't then t.a.jvm is somehow doing classloading wrong

bronsa21:01:47

I'll make a ticket & take a look in the next few days under intellij then

Alex Miller (Clojure team)21:01:37

I’m continuing to try things in both environments and see things that make no sense

Alex Miller (Clojure team)21:01:55

I will prob poke at it some more to see if I can make it make sense :)

bronsa21:01:49

yeah I'm reasonably sure there's a classloader issue at play there -- I've only ever run t.a.jvm from lein or java -cp and never had those issues, it's possible that cursive does something completely legal with classloaders but that I simply never incurred into & t.a.jvm doesn't handle it

cfleming21:01:30

@bronsa @alexmiller Actually only old IntelliJ versions use Java 6 these days - 2016 versions on mandate Java 8.

bronsa21:01:00

even weirder then

cfleming21:01:06

I don’t do anything very strange with classloaders in the REPL, I can’t see why that would fail or act differently.

cfleming21:01:33

Also, the Java 6 thing was for IntelliJ itself, not for user processes - they could always use whichever JVM they wanted.

bronsa21:01:00

correctly handling classloading has be one of the most fun things I've had to do /s

Alex Miller (Clojure team)21:01:53

yeah, it’s not obvious to me what the difference is

Alex Miller (Clojure team)21:01:14

I do definitely see different behavior between the Cursive repl and a lein repl though

Alex Miller (Clojure team)21:01:48

I feel like I’m seeing possibly bad state lingering in *env* too maybe?

Alex Miller (Clojure team)21:01:13

where once something fails, I get subsequent failures that I do not expect

Alex Miller (Clojure team)21:01:21

I will try to isolate it a little better

Alex Miller (Clojure team)21:01:43

I am using IntelliJ 2016.3.2 and Cursive 1.4.3

bronsa21:01:44

well t.a.jvm fallsback to the mutable namespace system of clojure so if that gets into a bad state so will subsequent calls of analyze-ns

cfleming21:01:56

So the funky bit about Cursive REPLs is that I invoke lein in trampoline mode in order to get the REPL classpath. That has caused issues because that’s done in the IntelliJ process, and hence with its JVM. However once the classpath is created, I just run it like any other process and don’t do anything else IIRC. So unless there are some classloader issues causing the REPL classpath to be created incorrectly, I’m not sure what could be going on.

bronsa21:01:52

*env* being otherwise tainted should be unlikely given that it gets rebound afresh on every analyze-ns call

bronsa21:01:12

the only state there comes from the clojure ns map