EwenG / badigeon

A Clojure build library based on tools.deps.
144 stars 19 forks source link

Getting a completely AOT'ed uberjar #13

Closed danieroux closed 5 years ago

danieroux commented 5 years ago

This is like #3 - except I can't get it to work. I want no .clj files, ultimately. Not from dependencies or my code. badigeon.uberjar/bundle does not compile, so:

With this in user.clj:

(clean/clean "target")

(compile/compile '[play.core clojure.core clojure.main]
  {:compile-path     "target/classes"
   :compiler-options {:disable-locals-clearing false
                      :elide-meta              [:doc :file :line :added]
                      :direct-linking          true}
   :classpath        (classpath/make-classpath)}) 

(compile/extract-classes-from-dependencies
  {:out-path             "target/classes"
   :deps-map             (deps-reader/slurp-deps "deps.edn")
   :allow-unstable-deps? true})

And trying to invoke Java using the generates classes, I get:

$ java -cp target/classes play.core
Exception in thread "main" java.lang.ExceptionInInitializerError
    at java.base/java.lang.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Class.java:398)
    at clojure.lang.RT.classForName(RT.java:2211)
    at clojure.lang.RT.classForName(RT.java:2220)
    at clojure.lang.RT.loadClassForName(RT.java:2239)
    at clojure.lang.RT.load(RT.java:449)
    at clojure.lang.RT.load(RT.java:424)
    at clojure.lang.RT.<clinit>(RT.java:338)
    at clojure.lang.Namespace.<init>(Namespace.java:34)
    at clojure.lang.Namespace.findOrCreate(Namespace.java:176)
    at clojure.lang.Var.internPrivate(Var.java:156)
    at play.core.<clinit>(Unknown Source)
Caused by: java.lang.NullPointerException
    at clojure.core$fn__8493$fn__8494.invoke(core.clj:7055)
    at clojure.core$fn__8493.invokeStatic(core.clj:7055)
    at clojure.core$fn__8493.invoke(core.clj:7055)
    at clojure.core__init.load(Unknown Source)
    at clojure.core__init.<clinit>(Unknown Source)

This did work:

But it's not an uberjar, of course:

java -cp target/classes:lib/clojure-1.10.1.jar:lib/spec.alpha-0.2.176.jar:lib/core.specs.alpha-0.2.44.jar play.core

EwenG commented 5 years ago

Hi, You can use the badigeon.uberjar/bundle function to extract all resources from all dependencies

(clean/clean "target")

;; No need to compile clojure.core and clojure.main because their classes will be extracted by badigeon.uberjar/bundle
(compile/compile '[play.core]
  {:compile-path     "target/classes"
   :compiler-options {:disable-locals-clearing false
                      :elide-meta              [:doc :file :line :added]
                      :direct-linking          true}
   :classpath        (classpath/make-classpath)}) 

(badigeon.uberjar/bundle
 "target/play-uberjar"
  {:deps-map             (assoc (deps-reader/slurp-deps "deps.edn") :paths ["target/classes"]] )
   :allow-unstable-deps? true})

(badigeon.zip/zip "target/play-uberjar" "target/play-uberjar.jar")

The ".clj" files of dependencies will be extracted too. I just pushed a badigeon.uberjar/walk-directory function on master that you can use to remove them:

(badigeon.uberjar/walk-directory
   "target/play-uberjar"
   (fn [dir f] (when (.endsWith (str f) ".clj")
                 (java.nio.file.Files/delete f))))
EwenG commented 5 years ago

Does it solve your issue ?

EwenG commented 5 years ago

Closing due to inactivity