This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-07-30
Channels
- # arachne (5)
- # beginners (42)
- # cider (35)
- # cljs-dev (25)
- # cljsrn (2)
- # clojure (107)
- # clojure-dev (32)
- # clojure-finland (2)
- # clojure-greece (3)
- # clojure-italy (6)
- # clojure-nl (7)
- # clojure-spec (27)
- # clojure-uk (45)
- # clojurescript (152)
- # core-async (3)
- # cursive (26)
- # data-science (4)
- # datomic (33)
- # defnpodcast (1)
- # duct (12)
- # editors (3)
- # emacs (6)
- # events (5)
- # fulcro (6)
- # jobs (1)
- # lein-figwheel (9)
- # off-topic (7)
- # onyx (7)
- # re-frame (1)
- # reagent (9)
- # reitit (31)
- # shadow-cljs (130)
- # slack-help (1)
- # spacemacs (53)
- # tools-deps (55)
- # yada (4)
Encountered a weird/interesting issue with Clojure 1.9.0 and uberjars. See #clojure for background. It seems that building an uberjar with Clojure 1.9.0 and :aot :all
in Leiningen produces a JAR with these entries
clojure/core__init.class
clojure/core_deftype.clj
clojure/core_deftype__init.class
clojure/core_instant18.clj
clojure/core_print.clj
clojure/core_print__init.class
clojure/core_proxy.clj
clojure/core_proxy__init.class
Note: there is no core_instant18__init.class
file. Should there be? The user is importing an uberjar into Robocode to provide both the Clojure runtime and their robot class. When Robocode tries to load the robot class, it tries to load/initialize Clojure and that fails on the attempt to (load "core_instant18.clj")
that is in clojure.core
. All the other files load up just file, which is why I suspect the missing __init.class
file is the cause... but I have no idea why it's missing?What JDK did you compile it on? (I believe that was guarded by a when-class
conditional)
Java 8. It's all I have installed. I confirmed Robocode runs on Java 8 too (the fact that it tries to load that file confirms that).
Ah, is it possible that core_instant18.clj
won't compile standalone? It refers to Inst
which is defined in clojure.core
...
something very weird is going on there, because the stacktrace has the error coming from the check that load does on the lastmodified time when determining if it should use a compiled class file, or load the source
FWIW, I can repro in any of my local Leiningen projects using 1.9.0 (in terms of there being no core_instant18__init.class
file)
Well, the issue here (I think) is how Clojure is loaded/initialized in Robocode (does something different to how it would be loaded normally via clojure.main
etc)?
As far as I can tell, Robocode is just looking to load one class and call methods on it so the initialization path isn't through clojure.main
or any of the standard entry points -- and Robocode is doing something dynamic (to load the JAR at runtime) so... ¯\(ツ)/¯
but where the exception comes from indicates that clojure was able to find a resource named clojure/core_instant18__init.class and that the protocol of the resource url is "jar", but that the jar file named in the url doesn't have an entry for clojure/core_instant18__init.class, which sounds like classloader sorcery to me
Yup, definitely something weird going on. But, at the root, why isn't core_instant18__init.class
in the uberjar?
I guess the uberjar was built with some java less than 1.8, java 1.6 was the minimum version then, I think
Nope.
I built the uberjars here on my system to repro, using Java 8.
But Clojure 1.9 itself might well have been built on pre-Java 8?
(! 934)-> jar tf ~/.m2/repository/org/clojure/clojure/1.9.0/clojure-1.9.0.jar|fgrep core_|sort
clojure/core__init.class
clojure/core_deftype.clj
clojure/core_deftype__init.class
clojure/core_instant18.clj
clojure/core_print.clj
clojure/core_print__init.class
clojure/core_proxy.clj
clojure/core_proxy__init.class
clojure/pprint$add_core_ns$fn__10758.class
clojure/pprint$add_core_ns.class
Yup, so it's missing in the Clojure JAR file.I wouldn't say missing, it isn't present and it makes sense that it isn't present, because of all that, and it should be ok to not be present, clojure should be fine loading the source code
I guess I'm a bit surprised that building an uberjar on Java 8 doesn't "fill in" the missing .class
file from Clojure...
but for some reason in the robocode environment, clojure is being told the classfile does exist, and then being told it doesn't exist when it goes to check the last mode it
Anyways, for the curious... the instructions are in the #clojure channel 🙂
my guess is robocode has a classloader that doesn't return null when a resource doesn't exist