编写插件时,如何排除leiningen引入的依赖项? [英] How do I do exclusions for dependencies that are pulled in by leiningen when writing a plugin?

查看:98
本文介绍了编写插件时,如何排除leiningen引入的依赖项?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm writing a custom plugin for Leiningen that will help in deploying AWS Lambda functions written in Clojure. I'm using aws-java-sdk-lambda version 1.11.145 which has a dependency on Jackson 2.6.x, specifically 2.6.5 IIRC.

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

Since I am writing this as a plugin, the code is executing in the context of Leiningen (i.e. :eval-in-leiningen true) and, AFAIK, is subject to the dependencies of Leiningen itself.

这是一个问题,因为我正在运行的Leiningen版本(2.7.1)依赖于柴郡5.5.0,而柴郡5.5.0则依赖于杰克逊2.5.3.当AWS开发工具包尝试调用com.fasterxml.jackson.databind.JavaType.isReferenceType()时,这将导致NoSuchMethodError. AFAIK,jackson-core-2.6.5(由AWS推入)正尝试调用jackson-databind-2.5.3(由Cheshire间接拉入).至少这似乎正在发生.

This is a problem since the version of Leiningen I am running (2.7.1) is dependent on Cheshire 5.5.0 which, in turn, is dependent on Jackson 2.5.3. This results in a NoSuchMethodError when the AWS SDK attempts to call com.fasterxml.jackson.databind.JavaType.isReferenceType(). AFAIK, jackson-core-2.6.5 (pulled in by AWS) is attempting to call into jackson-databind-2.5.3 (pulled in, indirectly, by Cheshire). At least that is what appears to be happening.

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

First question: is this a known issue? I was not able to find anything directly referencing it on SO, Google or the first page of issues on Leiningen's GitHub page (I did not do an exhaustive search there). Second: Does anyone have any suggestions for working around this problem? :exclusions seems like the obvious choice but I'm not sure how one would specify an exclusion for something that Leiningen itself is pulling in as a dependency.

下面,我提供了简单的项目规范来重现该错误:

Below, I have included simple project specifications to reproduce the error:

插件的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的实例,该实例反过来会触发错误.

Once this is setup, run lein install from the plugin directory and then run lein aws-plugin from the plugin users directory. This should attempt to create an instance of AWSLambdaClient which will, in turn, trigger the error.

推荐答案

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

First question: is this a known issue?

这是一个已知问题,许多编写Leiningen插件的人都会遇到这个问题.根本原因是Leiningen用其所有依赖项构建了一个uberjar,而这些依赖项不是阴影.这意味着,如果杰克逊班级之间发生冲突,将始终选择莱宁根的班级.使得这种情况特别令人反感的是,您不会收到有关冲突依赖项的任何警告,因为JAR不会发生冲突,但是它们的内容却会发生冲突.

This is a known issue, and one that many people writing Leiningen plugins face. The root cause is that Leiningen builds an uberjar with all of its dependencies, and those dependencies are not shaded. This means that if there is any collision between Jackson classes, Leiningen's one will always be chosen. What makes this especially devious is that you won't get any warnings about conflicting dependencies, as the JARs don't conflict, but the contents of them do.

以下是此问题的一些示例: https://github.com/s3-wagon-private/s3-wagon-private/issues/38

Here's a few examples of this problem: https://github.com/s3-wagon-private/s3-wagon-private/issues/38, https://github.com/technomancy/leiningen/issues/2215.

第二:有人对解决此问题有任何建议吗?

Second: Does anyone have any suggestions for working around this problem?

在同一个库的不同主要版本中具有Clojure相互依赖关系的问题对于一般情况有一些建议,尽管在Lein的依赖关系被超级压缩时会变得有些棘手.

Issues with Clojure inter-dependency with different major versions of the same library has some suggestions for the general case, although it gets a little trickier when Lein's dependencies are uberjarred.

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

I think your best bet at this point would be to shade the Jackson dependency and the AWS SDK.

莱宁根大师不再依赖于柴郡,并且当2.8.0是释放您应该有较少的问题.

Leiningen master no longer depends on Cheshire though, and when 2.8.0 is released you should have less problems.

这篇关于编写插件时,如何排除leiningen引入的依赖项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆