我正在使用Clojure的java-time
库,它是java.time
[1]的包装。
当我调用lein run
或通过 repl 调用函数时,我的程序可以工作。另一方面,当我尝试做lein uberjar
时,所涉及的类出现以下错误:
$ 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
我已经隔离出哪个表达式导致了此问题,而恰好是:
(java-time/minus (java-time/local-date) (java-time/period 2 :days))
我不确定为什么它会失败,并且错误非常隐晦。我敢打赌,在生成 uberjar 时,编译器会迷惑地转换某些类,但令我惊讶的是 repl 可以正常工作。它与用于创建 uberjar 的:aot
有关吗?
这是project.clj
文件的摘要,有关以下内容:
(defproject foo
...
:main ^:skip-aot foo.core
:target-path "target/%s"
:profiles {:uberjar {:aot :all
:jvm-opts ["-Dclojure.compiler.direct-linking=true"]}})
答案 0 :(得分:2)
看来您的环境有问题。一个示例程序对我来说很好用:
(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)))
结果:
~/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
为完整起见,这里是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"]
)