【问题标题】:How do I create a Clojure application with lein uberjar if I have a dependency in checkouts?如果我在结帐中有依赖项,如何使用 lein uberjar 创建 Clojure 应用程序?
【发布时间】:2020-08-28 16:55:32
【问题描述】:

我有一个 Clojure 应用程序,它正在使用从“checkouts”目录中符号链接的库。

这让我可以同时处理应用程序和库。并且 lein 知道如何毫无问题地编译和运行程序。

但我想用 lein uberjar 做一个独立的,它在抱怨

Caused by: java.io.FileNotFoundException: Could not locate mylib/core__init.class, mylib/core.clj or mylib/core.cljc on classpath.

我认为这是因为我的 project.clj 文件中没有提到 mylib。不是,正是因为我想在“checkouts”中使用符号链接的 mylib 版本。

但是uberjar命令好像看不到。

我该如何解决这个问题?

【问题讨论】:

  • 您的project.clj 应该在project.clj 中列出[mylib "0.1"],无论您是否使用lein 的“结帐”功能。在 ./checkouts 中放置一个符号链接以指向 mylib 的开发版本将覆盖 Maven/Clojars 查找。也许您应该在问题中添加您的project.clj 以澄清这一点?
  • 我在 StackOverflow 上看到的另一个答案似乎表明,如果我将 [mylib "0.1"] 放在我的 projects.clj 中,这将使用来自 Clojars 的版本,而不是我当前/开发中的版本。

标签: clojure leiningen uberjar


【解决方案1】:

您可以通过在本地存储库 (~/.m2/repository) 中安装 mylib 来完成此操作。

  1. 在依赖项目中运行 lein install 以将其安装到本地存储库中。
  2. 将项目添加到:dependencies: in project.clj:

    [mylib "version"]

  3. 在主项目中运行lein uberjar

该项目将在您的本地存储库中找到该 jar。

/编辑

如果您想同时开发两个库,您可以使用 checkouts 文件夹,其中 checkouts 包含指向依赖库的符号链接。

mkdir checkouts
ln -nfs full-path-other-lib-dir full-path-checkouts-dir

现在 other-lib 中的更改可以立即在主项目中使用。

请参阅 [https://github.com/technomancy/leiningen/blob/master/doc/TUTORIAL.md#checkout-dependencies](theLeiningen 结帐文档)。

【讨论】:

  • 谢谢。但这正是我希望避免的。我想要一种能够同时开发和测试我的项目和 mylib 的方法,包括测试构建的产品,而不必一直将库检查到 repo 中,给它一个版本号等。
  • 啊@interstar 我更新了答案以帮助使用结帐。
  • 现在我发现您还需要 uberjar 的功能。然后我不确定这是否可能。有趣的问题,但我现在没有时间。你也可以在 Clojurians Slack 上提问!
【解决方案2】:

好的,看来 lein 的“结帐”功能适用于 lein testlein run,但不适用于 lein uberjar

我在一个库tupelo.core的本地源代码中添加了以下内容:

(def dummy-sample-data "Bogus!")

在消费项目demo.core我们可以访问新的Var:

(ns demo.core
  (:use tupelo.core tupelo.test))

(defn -main [& args]
  (println :foo-enter)
  (spyx dummy-sample-data)
  (println :foo-leave))

lein run 产生:

:foo-enter
dummy-sample-data => "Bogus!"
:foo-leave

project.clj 保持不变:

(defproject demo "0.1.0-SNAPSHOT"
  :license {:name "Eclipse Public License"
            :url  "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [
     [criterium "0.4.5"]
     [org.clojure/math.combinatorics "0.1.6"]
     [org.clojure/clojure "1.10.1"]
     [prismatic/schema "1.1.12"]
     [tupelo "0.9.201"]
   <snip>

"0.9.201" 是 Clojars 上 tupelo 的最新版本。结帐看起来像:

~/expr/demo > ls -ldF checkouts/*
lrwxrwxrwx 1 alan alan 17 May 12 13:57 checkouts/tupelo -> /home/alan/tupelo/

但 uberjar 失败了:

~/expr/demo > lein clean ; lein uberjar
Compiling demo.core
Syntax error compiling at (demo/core.clj:6:3).
Syntax error compiling at (demo/core.clj:6:3).
Unable to resolve symbol: dummy-sample-data in this context

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

选项

如果您想要部署应用程序,您有 2 个选择:

  1. 如果该库存在于 Clojars 或 Maven 上,您可能应该在制作 uberjar 之前在那里部署一个版本。如果该库尚未准备好用于 Clojars 或 Maven,也许您还没有准备好在 uberjar 中使用它...?

  2. 只需在项目中的./src 目录下复制mylib 的源代码树(或使用符号链接!)。您还必须将依赖项复制到myproj/project.clj。您正在有效地合并 myproj 和 mylib,至少暂时使用这种方法。如果它们耦合得足够紧密,需要共同开发,也许它应该是永久合并?

【讨论】:

  • 感谢您的研究。不幸的是,这些选项看起来都不是很好。我正在制作 uberjar 来测试 uberjar 作为我开发的一部分。我正在尝试在 Windows 中测试某些东西(但在 WSL 中开发),所以我需要 Uberjar 绝对在 WSL 环境之外。我不想永久合并它们,因为该库肯定在此上下文之外使用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-25
  • 1970-01-01
  • 2016-03-06
  • 2020-03-18
  • 1970-01-01
  • 1970-01-01
  • 2019-01-21
相关资源
最近更新 更多