I have a small Clojure project with /project.clj
:
(defproject testjackson "0.1.0-SNAPSHOT"
:main testjackson.core
:dependencies [[org.clojure/clojure "1.10.3"]
[ring/ring-json "0.5.0"]])
and /src/testjackson/core.clj
:
(ns testjackson.core
(:gen-class)
(:require [ring.middleware.json :refer [wrap-json-body]]))
(defn -main [& _] (println :testing wrap-json-body))
When I run it, it just prints:
$ java -jar target/testjackson-0.1.0-SNAPSHOT-standalone.jar
:testing #object[ring.middleware.json$wrap_json_body 0x37cd92d6 ring.middleware.json$wrap_json_body@37cd92d6]
It runs as expected. I can also execute jdeps on the uberjar to get the list of used modules:
$ jdeps --print-module-deps --ignore-missing-deps target/testjackson-0.1.0-SNAPSHOT-standalone.jar
java.base,java.desktop,java.sql,jdk.unsupported
However, when I bump ring-json
version to 0.5.1
, the jdeps call fails:
$ jdeps --print-module-deps --ignore-missing-deps target/testjackson-0.1.0-SNAPSHOT-standalone.jar
Exception in thread "main" java.lang.module.FindException: Module com.fasterxml.jackson.core not found, required by com.fasterxml.jackson.dataformat.smile
at java.base/java.lang.module.Resolver.findFail(Resolver.java:877)
at java.base/java.lang.module.Resolver.resolve(Resolver.java:191)
at java.base/java.lang.module.Resolver.resolve(Resolver.java:140)
at java.base/java.lang.module.Configuration.resolve(Configuration.java:422)
at java.base/java.lang.module.Configuration.resolve(Configuration.java:256)
at jdk.jdeps/com.sun.tools.jdeps.JdepsConfiguration$Builder.build(JdepsConfiguration.java:564)
at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.buildConfig(JdepsTask.java:603)
at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.run(JdepsTask.java:557)
at jdk.jdeps/com.sun.tools.jdeps.JdepsTask.run(JdepsTask.java:533)
at jdk.jdeps/com.sun.tools.jdeps.Main.main(Main.java:49)
How can this be fixed in the context of this small example program?
As near I as can find from searching,
jdeps
is from way back in Java 9. In fact, the version on my computer won't even accepts the 2 flags you used in the example, and it doesn't even have a--version
option. Web searching shows no obvious uses for clojure.What is the goal here? Your plain code works fine for me:
project.clj deps
code
and results
Speculation
Although my
jlink
doesn't seem to work right, I can guess a little. Looking atproject.clj
, we can ask for a tree of depencencies:So we see that ring-json needs cheshire, which needs jackson.
Going back to ring-json 0.5.0 we see different version of cheshire and jackson:
Note that you can force newer versions in
project.clj
if you want. Just manually requirecheshire
andjackson
, and put them near the top!with result
Perhaps something similar will solve your problem. It has been crucial for me in the past.
Specifically, the jackson libs absolutely must have all 3 sub-libraries on the same version. Because dependent libs often don't update their own deps like jackson as often as they could, it is easy to get version conflicts when 2 or more libs each require different versions of jackson. The above technique of forcing a specific version of jackson (or any other lib) is a lifesaver. IMHO, it is also much better than trying to put in a bunch of lein
:exclusions
clauses.