Проблемы с созданием Uberjar в Clojure

Я использую библиотеку 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 работает нормально. Это связано с :aot, используемым для создания uberjar?

Это фрагмент файла project.clj, касающийся этого:

(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


person Navarro    schedule 07.10.2020    source источник
comment
Я также хотел добавить, что в .edn, созданном компилятором, не так много информации, которой нет в сообщении об ошибке...   -  person Navarro    schedule 07.10.2020
comment
В сообщении об ошибке говорится, что java_time.graph.Types, загруженный приложением, несовместим с java_time.graph.Types, загруженным clojure.lang.DynamicClassLoader... Вы делаете что-то необычное с загрузчиками классов?   -  person Biped Phill    schedule 07.10.2020
comment
Ничего! Единственное, что сделано в этом проекте, кроме Clojure, — это обращение к библиотеке org.apache.poi для написания файлов Excel. И это прекрасно работает! У меня проблемы только с оболочкой java.time java-time, с функциями plus и minus...   -  person Navarro    schedule 08.10.2020
comment
У меня точно такие же симптомы с (some-> 1614703906000 instant) (но не с (-> 1614703906000 instant) и опять же это происходит только с флагом прямой ссылки. Вроде та же проблема, но я не понимаю вашей проблемы с minus. Все страньше и страньше   -  person Andy    schedule 02.03.2021


Ответы (1)


Похоже, у вас что-то не так в вашей среде. Пример программы отлично работает для меня:

    (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"]
  )
person Alan Thompson    schedule 07.10.2020
comment
Ну, как вы сказали, проблема в моем окружении. "-Dclojure.compiler.direct-linking=true" блокировал его компиляцию. Хотя теперь я еще больше заинтригован, почему это вызывало эту проблему... - person Navarro; 07.10.2020
comment
Мы используем clojure.java-time на работе и собираем uberjar с -Dclojure.compiler.direct-linking=true, и у нас нет проблем. Возможно, вам просто нужно запустить lein clean перед lein uberjar? - person Sean Corfield; 07.10.2020
comment
К сожалению, это тоже не сработало. У меня тоже есть сборки uberjars с java-time. Это работало до тех пор, пока не было задействовано jt/plus или jt/minus. Как только я использовал эти функции, компилятор выдавал эту ошибку. Это случилось со мной, а также с коллегой, работающим над той же кодовой базой. - person Navarro; 07.10.2020