请分享您的想法,参加 2024 年 Clojure 状态调查!

欢迎!请查看 关于 页面以了解更多关于如何使用本站的信息。

+2
tools.build
编辑

我正在创建一个 uberjar,使用以下代码

build=> (b/uber {:class-dir class-dir
                 :uber-file "uberjar.jar"
                 :basis     basis})

这引发了错误

build=> (b/uber {:class-dir class-dir
                 :uber-file "uberjar.jar"
                 :basis     basis})
Execution error (FileNotFoundException) at java.io.FileOutputStream/open0 (FileOutputStream.java:-2).
/var/folders/_h/3fpgc8pj4fb2_w3mfqfl59fr0000gn/T/uber8421760143696109740/license/LICENSE (Not a directory)
build=> *e
#error {
 :cause "/var/folders/_h/3fpgc8pj4fb2_w3mfqfl59fr0000gn/T/uber8421760143696109740/license/LICENSE (Not a directory)"
 :via
 [{:type java.io.FileNotFoundException
   :message "/var/folders/_h/3fpgc8pj4fb2_w3mfqfl59fr0000gn/T/uber8421760143696109740/license/LICENSE (Not a directory)"
   :at [java.io.FileOutputStream open0 "FileOutputStream.java" -2]}]
 :trace
 [[java.io.FileOutputStream open0 "FileOutputStream.java" -2]
  [java.io.FileOutputStream open "FileOutputStream.java" 298]
  [java.io.FileOutputStream <init> "FileOutputStream.java" 237]
  [java.io.FileOutputStream <init> "FileOutputStream.java" 187]
  [clojure.tools.build.tasks.uber$explode invokeStatic "uber.clj" 66]
  [clojure.tools.build.tasks.uber$explode invoke "uber.clj" 53]
  [clojure.tools.build.tasks.uber$uber$fn__16290 invoke "uber.clj" 114]
  [clojure.core$run_BANG_$fn__8813 invoke "core.clj" 7717]
  [clojure.core.protocols$naive_seq_reduce invokeStatic "protocols.clj" 62]
  [clojure.core.protocols$interface_or_naive_reduce invokeStatic "protocols.clj" 72]
  [clojure.core.protocols$fn__8181 invokeStatic "protocols.clj" 169]
  [clojure.core.protocols$fn__8181 invoke "protocols.clj" 124]
  [clojure.core.protocols$fn__8136$G__8131__8145 invoke "protocols.clj" 19]
  [clojure.core.protocols$seq_reduce invokeStatic "protocols.clj" 31]
  [clojure.core.protocols$fn__8166 invokeStatic "protocols.clj" 75]
  [clojure.core.protocols$fn__8166 invoke "protocols.clj" 75]
  [clojure.core.protocols$fn__8110$G__8105__8123 invoke "protocols.clj" 13]
  [clojure.core$reduce invokeStatic "core.clj" 6830]
  [clojure.core$run_BANG_ invokeStatic "core.clj" 7712]
  [clojure.core$run_BANG_ invoke "core.clj" 7712]
  [clojure.tools.build.tasks.uber$uber invokeStatic "uber.clj" 114]
  [clojure.tools.build.tasks.uber$uber invoke "uber.clj" 104]
  [clojure.lang.Var invoke "Var.java" 384]
  [clojure.tools.build.api$uber invokeStatic "api.clj" 277]
  [clojure.tools.build.api$uber invoke "api.clj" 266]
  [build$eval16234 invokeStatic "NO_SOURCE_FILE" 11]
  [build$eval16234 invoke "NO_SOURCE_FILE" 11]
  [clojure.lang.Compiler eval "Compiler.java" 7181]
  [clojure.lang.Compiler eval "Compiler.java" 7136]
  [clojure.core$eval invokeStatic "core.clj" 3202]
  [clojure.core$eval invoke "core.clj" 3198]
  [clojure.main$repl$read_eval_print__9110$fn__9113 invoke "main.clj" 437]
  [clojure.main$repl$read_eval_print__9110 invoke "main.clj" 437]
  [clojure.main$repl$fn__9119 invoke "main.clj" 458]
  [clojure.main$repl invokeStatic "main.clj" 458]
  [clojure.core.server$repl invokeStatic "server.clj" 180]
  [clojure.core.server$repl invoke "server.clj" 180]
  [clojure.lang.AFn applyToHelper "AFn.java" 152]
  [clojure.lang.AFn applyTo "AFn.java" 144]
  [clojure.lang.Var applyTo "Var.java" 705]
  [clojure.core$apply invokeStatic "core.clj" 667]
  [clojure.core.server$accept_connection invokeStatic "server.clj" 73]
  [clojure.core.server$start_server$fn__8902$fn__8903$fn__8905 invoke "server.clj" 117]
  [clojure.lang.AFn run "AFn.java" 22]
  [java.lang.Thread run "Thread.java" 829]]}
build=> 

这个错误实际上是由我们的类路径上的两个库抛出的
- .m2/repository/xml-apis/xml-apis/1.4.01/xml-apis-1.4.01.jar
- .m2/repository/xml-apis/xml-apis-ext/1.3.04/xml-apis-ext-1.3.04.jar

这些库中的每一个都有一个条目 license/LICENSE。问题似乎是在 osx 上我使用的文件系统不区分大小写,但保留大小写,并且已经存在一个来自另一个 jar 的顶级 LICENSE 文件。因此,它无法在已经存在 LICENSE 文件的情况下创建 license/LICENSE 条目。

我用以下创建几个 jar 的代码进行了重现

(ns build
  (:require [clojure.tools.build.api :as b]))

;; create a jar with just a single namespace and a license/LICENSE file
(b/write-file {:path "target/liba/a.clj"
               :content (symbol "(ns a)")})
(b/write-file {:path "target/liba/license/LICENSE"
               :content (symbol "this is the license from a")})
(b/write-file {:path "target/liba/deps.edn"
               :content '{:paths ["."]}})
(b/write-pom {:basis (b/create-basis {:project "target/liba/deps.edn"})
              :class-dir "target/liba"
              :lib 'liba/liba
              :version "1.0.0"
              :src-dirs ["target/liba"]})
(b/jar {:class-dir "target/liba"
        :jar-file "target/jars/liba.jar"})

;; create another jar libb with just a single ns and a license file
(b/write-file {:path "target/libb/b.clj"
               :content (symbol "(ns b)")})
(b/write-file {:path "target/libb/license"
               :content (symbol "this is the license from b")})
(b/write-file {:path "target/libb/deps.edn"
               :content '{:paths ["."]}})
(b/write-pom {:basis (b/create-basis {:project "target/libb/deps.edn"})
              :class-dir "target/libb"
              :lib 'libb/libb
              :version "1.0.0"
              :src-dirs ["target/libb"]})
(b/jar {:class-dir "target/libb"
        :jar-file "target/jars/libb.jar"})

;; create a consumer of these
(b/write-file {:path "target/libc/license"
               :content (symbol "this is the license from c")})
(b/write-file {:path "target/libc/deps.edn"
               :content '{:deps {liba/liba {:local/root "../jars/liba.jar"}
                                 libb/libb {:local/root "../jars/libb.jar"}}}})

(def old-project-root b/*project-root*)
(b/set-project-root! "target/libc")
#_(b/set-project-root! old-project-root)

(b/uber {:class-dir "."
         :uber-file "uberjar.jar"
         :basis (b/create-basis {:project "deps.edn"})
         :main 'clojure.main})

但在尝试解压 jar 并创建文件 LICENSE 已经存在时的 license 文件夹时发生基本错误。

编辑
Sean 提到 depstar 有一个 api 兼容的 uber 函数,这对我来说很有效。由于 jar 的内容从未击中文件系统,因此避免了此约束。

1 个回答

+2
...