罐子应该“提供”依赖吗?

时间:2016-11-24 15:21:17

标签: java maven java-ee jar

我们正在构建一个将在提供j2ee.jar的Websphere上运行的耳朵。

现在我们的情况是ejb(称为ejb.jar)依赖于另一个jar(称为util.jar),它依赖于j2ee.jar。

如果将util.jar的pom中的j2ee.jar标记为“已提供”,则不会构建ejb.jar,因为提供的内容不是传递的。如果我们将其标记为“compile”,它可能会成为耳朵的编译依赖项,除非我们覆盖范围。

最好的方法是什么? util.jar应该提供依赖关系,即使它只是一个简陋的jar?或者jar应该只有编译依赖?

1 个答案:

答案 0 :(得分:3)

JAR可以提供依赖关系...但是依赖于它的用户需要确保在运行时实际提供此依赖关系。由于提供的依赖项不可传递,因此它们还需要确保它们不依赖于它进行编译;但如果他们这样做,最好的做法是使用编译(或提供)范围明确声明它,而依赖于某种形式的传递性(查看analyze目标Dependency Plugin,例如,列出已使用但未声明的依赖项。)

  • 在创建可执行JAR时,JAR中提供的依赖项非常有用。考虑构建一个超级jar(一个JAR,其中包含所有依赖项的类):你可能想说一个特定的依赖不应该在uber-jar中结束,因为容器启动它将在运行时提供。
  • 此外,JAR可能需要依赖项来编译其代码,但实际上并不需要它来运行;例如,考虑声明maven-plugin-annotations as a provided dependency的Maven插件,因为它们只需要构建注释。
  • 最后一点,有些JAR可以很好地了解它们将在哪种上下文中使用:例如,Spring WebMVC肯定依赖于要编译的Servlet API,但在运行时,它知道它&#39 ; s将在Java EE上下文中使用,并且Servlet API将由Java EE服务器提供。

作为经验法则,除了上述情况之外,您可能不希望在JAR项目中提供JAR依赖项:它应该由客户端决定是否有一些编译时依赖性将根据具体情况提供您的,并让客户端覆盖范围。作为图书馆作家,你真的不知道你的图书馆将如何被使用。

在您的特定情况下,由于ejb.jar实际上需要j2ee.jar进行编译,因此最好在编译中声明该依赖关系,或者甚至在您的情况下使用提供的范围声明,无论范围如何util.jar设置为j2ee.jar。 (我注意到,实用程序JAR依赖于Java EE Web应用程序类中的JAR似乎很奇怪。)