为什么“提供”范围的依赖关系会隐藏Maven中的传递依赖?

时间:2009-10-15 15:11:43

标签: java maven-2

我的Maven项目中有三个模块(稍微简化):

  • model 包含JPA带注释的实体类
  • 持久性实例化 EntityManager 并在其上调用方法
  • application 模型中创建类的实例,设置一些值并将它们传递给持久性

模型持久性显然取决于javax.persistence,但我认为应用程序不应该。

javax.persistence依赖项被移动到顶级POM的dependencyManagement部分,因为它出现在许多子模块中,我只引用该条目。

令我感到惊讶的是,当我将其范围设置为application时,我必须在provided中引用依赖关系,而我的范围是compile时则不必。

范围为provided,如果我没有在应用程序dependencies中列出,则构建将失败并显示来自javac的错误消息:

  

com.sun.tools.javac.code.Symbol $ CompletionFailure:找不到javax.persistence.InheritanceType的类文件

发生了什么事?

3 个答案:

答案 0 :(得分:12)

  

模型和持久性显然取决于javax.persistence,但我认为应用程序不应该。

这是真的。但是,传递依赖性解决方案与您的问题无关(实际上,javax.persistenceprovidedmodelpersistence application取决于compile 1}}范围所以它被省略,如3.4.4. Transitive Dependencies)中所述。

在我看来,你是这个错误的受害者:http://bugs.sun.com/view_bug.do?bug_id=6550655

  

我对EJB3有同样的问题   使用继承注释的实体:   @Inheritance(strategy=InheritanceType.SINGLE_TABLE)

     

使用此实体的客户端类不会   在ejb3 annatations时编译   不在类路径上,但崩溃了   以下消息:   com.sun.tools.javac.code.Symbol$CompletionFailure: class file for javax.persistence.InheritanceType not found

     

[...]

     

请注意,这是bug 6365854的特例(据报道已修复);这里的问题似乎是注释使用枚举作为其值。

当前的解决方法是将缺少的枚举添加到CLASSPATH。

在您的情况下,“更糟糕”的方法是将javax.persistence作为provided依赖项添加到application模块。但这是JVM错误的解决方法,application不需要编译依赖项。

答案 1 :(得分:2)

嗯,因为提供的依赖项不可传递?这是maven的内置行为。

答案 2 :(得分:1)

dependencyManagement部分声明了如果使用它们的依赖关系,而不是使用它们。因此,您仍需要声明一个最小依赖项声明,以便在子项目中应用该配置。有关详细信息,请参阅Maven书籍的dependency management section

所需的最低要求通常是groupId和artifactId。

如果要继承配置而不声明配置,则应在父dependencies部分中定义,而不是dependencyManagement