Fork me on GitHub

What event does one use at the end of all tests in clojure.test for report?

defmethod clojure.test/report :summary


I’m trying to debug a NoClassDefFoundError when instantiating a Java class. Here’s my situation: I am using deps.edn to load in an artifact from a private Maven repository (my company’s Nexus mirror). I can spin up a REPL (using CIDER) and (import) the class I need from the artifact just fine, but if I actually try to instantiate it I get a NoClassDefFoundError. I’m not sure how to go about debugging this or what next steps to take.


Is that NCDF error really about that class or is it something that class depends on? Can you show us the full error message? How about conflicting/duplicate JARs on the classpath?


Sure, putting the stack trace in a snippet


The NO_SOURCE_FILE bit makes me think that it can’t find the jar for some reason

Jeff Shelley18:11:53

maybe it has a static field (logger?) or static initializer that's bombing out?


Is it possible to elucidate what the repl is actually doing through JVM logging?


I am trying to teach Clojure and show what the repl is actually doing ... otherwise the fact that you are redefining code in process get slost


I was hoping that the JVM might spit something out on a class reload if you switched on some flag but googling is yielding nothing ...


I think chouser has a ticket on jira where he has clojure emit when it is reloading or adding classes to demonstrate a bug. But i can't imagine any info like this would benefit a beginner

Alex Miller (Clojure team)15:11:53

you could use -verbose:class flag, although not sure if that’s helping you at all

Alex Miller (Clojure team)15:11:30

a lot of the interesting bits are happening in Clojure’s DynamicClassLoader though, not at JVM level


Thanks @dpsutton they are not all beginners, some have been taught in Java and used Clojure without thinking too deeply about it ...


Thanks @alexmiller is that a flag on clj ... or a java flag ??


I'll try that thanks 🙂

Alex Miller (Clojure team)15:11:12

to use with clj: clj -J-verbose:class


it seems that Java Reflection has some limitations when it comes to generics. I wonder, is there an alternative way in clojure to call a java method dynamically (i.e. I have the method name as a string)?

Alex Miller (Clojure team)15:11:50

What do you mean? Java reflection can be used to invoke a method dynamically. (And you can use MethodHandles now as well.)


my problem is that I can't get the Method object properly with Class.getMethod(...) because I don't have the actual class, but Object, since it comes from a type parameter

Alex Miller (Clojure team)15:11:46

you can obtain the Class with Class.forName(), then use getMethod().


my class comes from Method.getReturnType, and it's Object instead of the real class, because it's a type Parameter


I get that this may be a limitation of the reflection api, but I'm thinking maybe it's possible in clojure itself, given its dynamic nature

Alex Miller (Clojure team)18:11:06

I’m saying if you know what type of class it is, you can tell the jvm to invoke whatever on it. The jvm is more dynamic than Java.


what do people use these days for testing? I was looking at speclj but it seems its not active


having worked on a project that uses speclj, I can’t recommend it, unless for some reason you want to use a clone of RSpec that makes for confusing Clojure code . clojure.test works just fine for nearly everything in my experience


clojure.test is the most used by far


I use standard clojure.test - simple and readable, with no macro hackery involved.

👍 4

clojure.test is standard and readable, but it for sure is macro land


I was referring to midje levels of macro hackery.


haven't looked into that but i hear it s complicated


so fair point 🙂


Is there an easy way to have clojure.pprint/pprint print newlines in strings as a new line? i.e. Instead of this:

(clojure.pprint/pprint {:text "asd\nasd"})
{:text "asd\nasd"}
you get this:
(clojure.pprint/pprint {:text "asd\nasd"})
{:text "asd


that's a newline plus a bunch of spaces


you could override print-method for String to do that maybe(?)


I was running some generative tests and ended up seem this behavior:

(= ##NaN ##NaN)
=> false


is this expected?


yes, that's described by the floating point spec


I only want to do that for particular prints, not all. Is there a way to bind it temporarily?


(def pprint-default
  (get (methods clojure.pprint/simple-dispatch)

(def ^:dynamic *pprint-newlines* false)

(defmethod clojure.pprint/simple-dispatch String [s]
  (let [lines (clojure.string/split s #"\n")
        default-impl (-> clojure.pprint/simple-dispatch
                         (get :default))]
    (if *pprint-newlines*
          :prefix "\""
          :per-line-prefix " "
          (doseq [l (butlast lines)]
            (print l)
            (clojure.pprint/pprint-newline :mandatory))
          (print (last lines))
          (print "\""))
      (default-impl s))))

(clojure.pprint/pprint {:text "asd\nasd"})

(binding [*pprint-newlines* true]
  (clojure.pprint/pprint {:text "asd\nasd"}))


Thanks @U0HJAJ570, I'll mess around with this 🙂


there's some amusing corner cases

user=> (conj #{##NaN} ##NaN ##NaN ##NaN)
#{##NaN ##NaN}


Now that's interesting. Any idea why that occurs?


it has to do with when and how the set is checked for the value being present - I forget the details though


it's possible to end up with three or more NaN in one set as well


I tried adding a couple more NaNs and couldn't get 3 🙂


yeah, it's more elaborate, trying to recreate...


user=> (into #{} [##NaN ##NaN ##NaN ##NaN ##NaN])
#{##NaN ##NaN ##NaN ##NaN ##NaN}


NaN's are a huge pain when generative testing


to the point where I have written tests that say something like (or (= a b) (.contains (pr-str a) "##NaN"))


Haha yeah I've struggle with that one too. I think I ended up doing a postwalk, replacing ##NaN with :nan then doing the equality check. Not very efficient though...


There are many other things that generative testing could choose to generate that would cause things to not always be = when you wish they were, e.g. mutable Java collections nested inside of Clojure sets or as map keys, regexes that look the same but are non-identical objects, and a handful of others. I have an article that lists all of the gotchas I know about for Clojure/Java equals here:


It sounds like the default spec generators don't generate those other things, but they do ##NaN


Seems like it would be worth having a spec generator that by default did not generate those.


I don't know of any way to "vote" on Github PR's, but I am hoping that article becomes a guide on some day:

Alex Miller (Clojure team)19:11:34

I look forward to adding it, but I need time to read and review it (which I do not have currently). so no need to “vote”.


Thanks for the note. My goal wasn't to add pressure on you, although I could probably have figured out on my own that such a statement may have that effect.

Alex Miller (Clojure team)20:11:46

I know it’s been out there a while…. but that knowledge does not increase my available time :)


> There are many other things that generative testing could choose to generate that would cause things to not always be = when you wish they were I wonder if this is part of the rationale behind 1.10's clojure.datafy.


how do peope that use clojure.test verify their mocks, bdd style? @noisesmith @sgerguri @dpsutton


I don't as I prefer to test side-effectful things with the real dependency in an integration test.