2017-10-04 145 views
0

我知道PROVIDED依赖项是由容器提供的,应用程序不需要生成这个JAR。 1)所以,我使用JBOSS EAP 7.0.0.GA,并且在这个模块文件夹中有以下jar:hibernate-core-5.0.9.Final-redhat-1.jar提供依赖关系和JBOSS EAP 7

在我的项目我使用以下依赖性:

<dependency> 
      <groupId>org.hibernate</groupId> 
      <artifactId>hibernate-core</artifactId> 
      <version>5.0.9.Final-redhat-1</version> 
     </dependency> 

它工作正常,没有错误。但我明白我应该使用“PROVIDED”范围,因为这个jar由容器提供。它为什么有效?

2)我有另一个例子。在Jboss Eap 7.0.0.GA中,我有以下jar:jboss-servlet-api_3.1_spec-1.0.0.Final-redhat-1.jar。但在我的项目中,我有以下几点:

<dependency> 
      <groupId>javax.servlet</groupId> 
      <artifactId>javax.servlet-api</artifactId> 
      <version>3.0.1</version> 
      <scope>provided</scope> 
      <optional>true</optional> 
     </dependency> 

它工作得很好,但我不明白为什么。对我来说,正确的依赖关系应该是servlet-api_3.1_spec-1.0.0.Final-redhat-1提供的。为什么它也起作用?

回答

0

在构建时,Maven将解析依赖关系并使相关的包可用于编译器。例如,您的应用程序服务器可能会提供包含类和接口的JAR,但这些类对于编译器不一定有用,因为它不知道它们在哪里。通过向Maven提供依赖关系,您可以让Maven找到它们自己的这些依赖关系的实现,仅供编译时使用。

在运行时,如果您已将依赖关系标记为provided,那么您的应用程序将使用appserver提供的版本,而不是Maven已知的版本。这可能是一件坏事,但它经常起作用,因为编译器确实只需要知道方法签名,而不需要知道它们的实现。由规范控制的类的方法签名(例如javax.servlet中的那些类)的方法签名很少发生更改,因此编译时JAR与运行时JAR之间的不匹配可能不被注意。与OSGi兼容的JAR不同,为JEE构建的JAR不包含指定特定兼容依赖项版本的元数据--JEE类加载器将使用他们发现的更好或更差的内容。

但是,您可能会被发现,特别是如果不匹配很严重。运行时问题可能非常明显,例如与缺少类或方法有关的异常,但它们可能很微妙。

因此,在可行的情况下,最好使用与运行时可用版本相同的编译时版本的依赖关系。对于EAP,我记得红帽发布了Maven物料清单(BOM)文件,该文件为特定的EAP版本指定了所有EAP JAR的所有版本。

+0

你能举一个真实的例子来更好地了解情况吗? – RonaldoLanhellas

+0

因此,如果我所有的依赖工作都没有“提供”范围,为什么我需要提供?只是为了一个轻量级的JAR? – RonaldoLanhellas

+0

如果您将自己的依赖关系添加到JAR中,那么您将面临具有相同名称但不同版本的类可用于应用程序的风险。除非你非常详细地研究JEE类的加载规则 - 而应用服务器实际上是尊重它的 - 否则告诉哪些类将在运行时加载会很尴尬。所以这不仅仅是一个较轻的JAR,而是在运行时保持一致。 –