Fork me on GitHub
#clojure
<
2018-11-02
>
borkdude14:11:36

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

defmethod clojure.test/report :summary
?

jdormit14:11:11

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.

jumar15:11:03

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?

jdormit15:11:06

Sure, putting the stack trace in a snippet

jdormit15:11:18

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?

apbleonard15:11:23

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

apbleonard15:11:07

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

apbleonard15:11:05

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 ...

dpsutton15:11:34

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

apbleonard15:11:06

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

apbleonard15:11:50

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

apbleonard15:11:53

I'll try that thanks 🙂

Alex Miller (Clojure team)15:11:12

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

roti15:11:16

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.)

roti15:11:10

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().

roti16:11:32

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

roti16:11:31

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.

mping16:11:33

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

taylor01:11:28

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

noisesmith16:11:44

clojure.test is the most used by far

sgerguri16:11:48

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

👍 4
dpsutton16:11:25

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

sgerguri16:11:40

I was referring to midje levels of macro hackery.

dpsutton16:11:58

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

dpsutton16:11:07

so fair point 🙂

kenny17:11:04

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
        asd"}

noisesmith18:11:33

that's a newline plus a bunch of spaces

noisesmith18:11:21

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

wilkerlucio18:11:01

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

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

wilkerlucio18:11:04

is this expected?

noisesmith18:11:22

yes, that's described by the floating point spec

kenny18:11:45

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

tristefigure18:11:26

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

(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
                         methods
                         (get :default))]
    (if *pprint-newlines*
      (clojure.pprint/pprint-logical-block
          :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"}))

kenny18:11:53

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

noisesmith18:11:24

there's some amusing corner cases

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

kenny18:11:59

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

noisesmith18:11:17

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

noisesmith18:11:37

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

kenny18:11:23

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

noisesmith18:11:43

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

hiredman18:11:23

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

hiredman18:11:46

NaN's are a huge pain when generative testing

hiredman18:11:12

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

kenny18:11:22

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...

andy.fingerhut18:11:36

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: https://github.com/jafingerhut/thalia/blob/master/doc/other-topics/equality.md

andy.fingerhut18:11:09

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

andy.fingerhut18:11:36

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

andy.fingerhut18:11:00

I don't know of any way to "vote" on Github PR's, but I am hoping that article becomes a guide on http://clojure.org some day: https://github.com/clojure/clojure-site/pull/267

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”.

andy.fingerhut20:11:55

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

zane19:11:01

> 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.

mping21:11:00

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

sgerguri10:11:40

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