Fork me on GitHub
#clojure-dev
<
2017-01-23
>
alexmiller20: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

alexmiller21:01:35

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

alexmiller21: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 :)

alexmiller21: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

alexmiller21: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

alexmiller21:01:52

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

alexmiller21: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)))

alexmiller21: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

alexmiller21:01:18

no, nil :result

alexmiller21:01:31

although ns expands to a do form that explicitly returns nil

alexmiller21:01:44

so might be buried inside

alexmiller21:01:58

nah, no errors in there

alexmiller21: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

alexmiller21:01:41

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

alexmiller21: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

alexmiller21:01:33

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

alexmiller21:01:41

java 8 classes on the boot classpath etc

alexmiller21: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

alexmiller21:01:35

it doesn’t throw :)

bronsa21:01:47

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

alexmiller21:01:37

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

alexmiller21: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

alexmiller21:01:53

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

alexmiller21:01:14

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

alexmiller21:01:48

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

alexmiller21:01:13

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

alexmiller21:01:21

I will try to isolate it a little better

alexmiller21: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