【问题标题】:How do I do exclusions for dependencies that are pulled in by leiningen when writing a plugin?如何排除 leiningen 在编写插件时引入的依赖项?
【发布时间】:2017-08-24 18:51:07
【问题描述】:

我正在为 Leiningen 编写一个自定义插件,这将有助于部署用 Clojure 编写的 AWS Lambda 函数。我正在使用aws-java-sdk-lambda 版本1.11.145,它依赖于Jackson 2.6.x,特别是2.6.5 IIRC。

由于我将其编写为插件,因此代码在 Leiningen 的上下文中执行(即:eval-in-leiningen true),并且,AFAIK 受制于 Leiningen 本身的依赖关系。

这是一个问题,因为我正在运行的 Leiningen 版本 (2.7.1) 依赖于 Cheshire 5.5.0,而 Cheshire 5.5.0 又依赖于 Jackson 2.5.3。当 AWS 开发工具包尝试调用 com.fasterxml.jackson.databind.JavaType.isReferenceType() 时,这会导致 NoSuchMethodError。 AFAIK,jackson-core-2.6.5(由 AWS 拉入)正试图呼叫jackson-databind-2.5.3(由 Cheshire 间接拉入)。至少这似乎是正在发生的事情。

第一个问题:这是一个已知问题吗?我在 SO、Google 或 Leiningen 的 GitHub 页面上的第一页问题上找不到任何直接引用它的东西(我没有在那里进行详尽的搜索)。第二:有人对解决这个问题有什么建议吗? :exclusions 似乎是显而易见的选择,但我不确定如何为 Leiningen 本身作为依赖项引入的东西指定排除项。

下面,我已经包含了简单的项目规范来重现错误:

插件的project.clj:

(defproject aws-plugin "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[com.amazonaws/aws-java-sdk-lambda "1.11.145"]]
  :eval-in-leiningen true)

插件源代码:

(ns leiningen.aws-plugin
  (:import (com.amazonaws.services.lambda AWSLambdaClient
                                          AWSLambdaClientBuilder)))

(def aws-lambda-client (-> (AWSLambdaClient/builder) (.build)))

(defn aws-plugin
  "I don't do a lot, or anything at all."
  [project &]
  (println "Create Lambda"))

插件用户的project.clj

(defproject aws-plugin-user "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.8.0"]]
  :target-path "target/%s"
  :plugins [[aws-plugin "0.1.0-SNAPSHOT"]]
  :profiles {:uberjar {:aot :all}})

设置完成后,从插件目录运行lein install,然后从插件用户目录运行lein aws-plugin。这应该会尝试创建AWSLambdaClient 的实例,这反过来会触发错误。

【问题讨论】:

    标签: plugins clojure leiningen


    【解决方案1】:

    第一个问题:这是一个已知问题吗?

    这是一个已知问题,也是许多编写 Leiningen 插件的人都面临的问题。根本原因是 Leiningen 构建了一个包含所有依赖项的 uberjar,而这些依赖项不是 shaded。这意味着如果 Jackson 类之间有任何冲突,将始终选择 Leiningen 的类。使这个特别狡猾的是,您不会收到任何有关冲突依赖项的警告,因为 JAR 不会冲突,但它们的内容会冲突。

    下面是这个问题的几个例子:https://github.com/s3-wagon-private/s3-wagon-private/issues/38https://github.com/technomancy/leiningen/issues/2215

    第二:有人对解决这个问题有什么建议吗?

    Issues with Clojure inter-dependency with different major versions of the same library 对一般情况有一些建议,尽管当 Lein 的依赖项被 uberjarred 时,它会变得有点棘手。

    我认为此时最好的选择是隐藏 Jackson 依赖项和 AWS 开发工具包。

    不过,Leiningen 大师 no longer depends on Cheshire,当 2.8.0 发布时,您应该会遇到更少的问题。

    【讨论】:

      猜你喜欢
      • 2015-01-29
      • 2013-04-22
      • 2015-10-26
      • 2021-12-29
      • 2016-02-28
      • 1970-01-01
      • 2012-07-07
      • 1970-01-01
      相关资源
      最近更新 更多