Navarro
Navarro

Reputation: 1384

Problems creating Uberjar in Clojure

I am using Clojure's java-time library, which is wrapper of java.time [1].

My program works when I invoke lein run or when I call the functions through the repl. On the other hand when I try to do lein uberjar I get the following error with the classes involved:

$ lein uberjar
Compiling foo.cli
Compiling foo.core
Compiling foo.holidays
nil
Syntax error (ClassCastException) compiling at (/tmp/form-init8528909580728167374.clj:1:73).
class java_time.graph.Types cannot be cast to class java_time.graph.Types (java_time.graph.Types is in unnamed module of loader 'app'; java_time.graph.Types is in unnamed module of loader clojure.lang.DynamicClassLoader @141c66db)

Full report at:
/tmp/clojure-6795557396101417445.edn
Compilation failed: Subprocess failed

I have isolated which expression causes this problem and it happens to be:

(java-time/minus  (java-time/local-date) (java-time/period 2 :days))

I am not sure why it is failing and the error is quite cryptic. My bet is that the compiler gets confused casting some classes when generating the uberjar but it surprises me that the repl works fine. Is it related to the :aot used for the uberjar creation?

This is a snippet of the project.clj file concerning that:

(defproject foo
  ...
  :main ^:skip-aot foo.core
  :target-path "target/%s"
  :profiles {:uberjar {:aot :all
                       :jvm-opts ["-Dclojure.compiler.direct-linking=true"]}})

[1] https://github.com/dm3/clojure.java-time

Upvotes: 3

Views: 856

Answers (1)

Alan Thompson
Alan Thompson

Reputation: 29958

It appears you have something wrong in your environment. A sample program works fine for me:

    (ns demo.core
      (:use tupelo.core)
      (:require [java-time :as jt])
      (:gen-class))
    
    (defn -main [& args]
      (print-versions)
      (let [result (java-time/minus
                     (java-time/local-date)
                     (java-time/period 2 :days))]
        (println :result result)))

with result:

    ~/expr/demo > lein clean ; lein run
    
    --------------------------------------
       Clojure 1.10.2-alpha1    Java 15
    --------------------------------------
    :result #object[java.time.LocalDate 0x61a309fe 2020-10-05]
    
    
    ~/expr/demo > lein clean ; lein uberjar 
    Compiling demo.core
    Created /home/alan/expr/demo/target/uberjar/demo-0.1.0-SNAPSHOT.jar
    Created /home/alan/expr/demo/target/uberjar/demo-0.1.0-SNAPSHOT-standalone.jar

For completeness, here is the project.clj:

(defproject demo "0.1.0-SNAPSHOT"
  :license {:name "Eclipse Public License"
            :url  "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [
                 [clojure.java-time "0.3.2"]
                 [org.clojure/clojure "1.10.2-alpha1"]
                 [prismatic/schema "1.1.12"]
                 [tupelo "20.08.27"]
                 ]
  :plugins [
            [com.jakemccrary/lein-test-refresh "0.24.1"]
            [lein-ancient "0.6.15"]
            [lein-codox "0.10.7"]
            ]

  :profiles {:dev     {:dependencies []}
             :uberjar {:aot :all}}

  :global-vars {*warn-on-reflection* false}
  :main ^:skip-aot demo.core

  :source-paths ["src/clj"]
  :java-source-paths ["src/java"]
  :test-paths ["test/clj"]
  :target-path "target/%s"
  :compile-path "%s/class-files"
  :clean-targets [:target-path]

  :jvm-opts ["-Xms500m" "-Xmx4g"]
  )

Upvotes: 2

Related Questions