我知道PROVIDED依赖项是由容器“提供”的,应用程序不需要生成这个JAR .
1)所以,我正在使用JBOSS EAP 7.0.0.GA,这个模块文件夹中有以下jar: hibernate-core-5.0.9.Final-redhat-1.jar .
在我的项目中,我使用以下依赖项:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.0.9.Final-redhat-1</version>
</dependency>
它工作正常,没有错误 . 但我明白我应该使用“提供”范围,因为这个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 with provided . 为什么它也有效?
1 回答
在构建时,Maven将解析依赖关系并使编译器可以使用相关的包 . 例如,您的appserver可能提供包含
javax.servlet
中的类和接口的JAR,但这些类赢得了't necessarily be useful to the compiler, because it doesn'知道它们的位置 . 通过向Maven提供依赖项,您可以让Maven找到自己的这些依赖项实现,只是为了在编译时使用 .在运行时,如果您已将依赖项标记为
provided
,那么您的应用程序将使用appserver提供的版本,而不是Maven已知的版本 . 这可能是一件坏事,但它通常有效,因为编译器确实只需要知道方法签名,而不是它们的实现 . 由规范控制的类的方法签名(例如javax.servlet
中的那些)只会偶尔更改,因此编译时JAR和运行时JAR之间的不匹配可能会被忽视 . 与OSGi兼容的JAR不同,为JEE构建的JAR不包含指定特定兼容依赖版本的元数据 - JEE类加载器将使用它们找到的内容,无论好坏 .然而,你可能会被 grab - 特别是如果不匹配很大的话 . 问题在运行时可能非常明显,例如与缺少类或方法相关的异常,但它们可能很微妙 .
因此,在可行的情况下,通常最好使用与运行时可用的版本相同的编译时依赖项版本 . 对于EAP,我记得Red Hat分发了一个Maven物料清单(BOM)文件,该文件指定了特定EAP版本的所有EAP JAR的所有版本 .