The two-arg constructor for clojure.lang.ExceptionInfo chains to the 3-arg version, passing null as the cause. The 3-arg constructor then calls super with the null cause, above which line is the comment "null cause is equivalent to not passing a cause".
This is not actually true, as passing null here means the cause has been initialised, regardless of value. As a consequence, you can not call .initCause on the ex-info exception later. In my case, the 'cause' is not known when thrown: the exception is caught upstack, the cause added, then rethrown.
In summary, this expression will always throw an exception: (-> (ex-info "ex" {}) (.initCause (Exception. "cause"))).
The simple solution would be to call the 2-arg super, and call .initCause if cause is non-null.
Cheers,
Matt.