为什么带有“提供”范围的依赖项在Maven中隐藏传递依赖项?

时间:2021-08-12 11:10:14

I have three modules in my Maven project (this is slightly simplified):

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

  • model contains JPA annotated entity classes
  • 模型包含JPA注释的实体类。
  • persistence instantiates an EntityManager and calls methods on it
  • 持久性实例化一个EntityManager并调用它的方法。
  • application creates instances of the classes in model, sets some values and passes them to persistence
  • 应用程序在模型中创建类的实例,设置一些值并将它们传递给持久性

model and persistence obviously depend on javax.persistence, but application shouldn't, I think.

模型和持久性显然依赖于javax。持久性,但应用不应该。

The javax.persistence dependency is moved to a top-level POM's dependencyManagement section because it occurs in a number of submodules where I only reference that entry.

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

What's surprising to me is that I have to reference the dependency in application when I set its scope to provided, whereas I don't have to when its scope is compile.

令我惊讶的是,当我设置它的作用域时,我必须引用应用程序中的依赖项,而我不必在它的作用域被编译时引用它。

With a scope of provided, if I don't list it in the dependencies for application, the build fails with an error message from javac:

在提供的范围内,如果我不在应用程序的依赖项中列出它,那么构建将失败,其中包含来自javac的错误消息:

com.sun.tools.javac.code.Symbol$CompletionFailure: class file for javax.persistence.InheritanceType not found

com.sun.tools.javac.code。符号$CompletionFailure:用于javax.persistence的类文件。InheritanceType未找到

What's going on?

这是怎么呢

3 个解决方案

#1


12  

model and persistence obviously depend on javax.persistence, but application shouldn't, I think.

模型和持久性显然依赖于javax。持久性,但应用不应该。

That's true. But transitive dependencies resolution has nothing to do with your problem (and actually, javax.persistence is provided to model and persistence on which application depends with a compile scope so it's omitted as documented in 3.4.4. Transitive Dependencies).

这是真的。但是传递依赖关系解析与您的问题没有任何关系(实际上,还有javax。持久性提供给模型和持久性,应用程序依赖于一个编译范围,因此在3.4.4中省略了持久性。传递依赖关系)。

In my opinion, you are victim of this bug: http://bugs.sun.com/view_bug.do?bug_id=6550655

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

I have the same issues with an EJB3 entity that uses the Inheritance annotation: @Inheritance(strategy=InheritanceType.SINGLE_TABLE)

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

A client class using this entity won't compile when the ejb3 annatations are not on the classpath, but crash with the following message: com.sun.tools.javac.code.Symbol$CompletionFailure: class file for javax.persistence.InheritanceType not found

当ejb3声明不在类路径上时,使用该实体的客户端类将不会编译,而是与以下消息一起崩溃:com.sun.tools.javac.code。符号$CompletionFailure:用于javax.persistence的类文件。InheritanceType未找到

[...]

[…]

Note that is a special case of bug 6365854 (that is reported to be fixed); the problem here seems to be that the annotation is using an enum as its value.

请注意,这是一个bug 6365854的特殊情况(报告是修复的);这里的问题似乎是注释使用enum作为其值。

The current workaround is to add the missing enum to the CLASSPATH.

当前的解决方案是将缺失的枚举添加到类路径中。

In your case, the "less worse" way to do that would be to add javax.persistence as provided dependency to the application module. But that's a workaround to the JVM bug, application shouldn't need that dependency to compile.

在您的例子中,“不那么糟糕”的方法是添加javax。持久性提供了对应用程序模块的依赖性。但是这是对JVM错误的一种变通方法,应用程序不应该需要依赖这个来编译。

#2


2  

umm, because provided dependencies are not transitive? that's builtin behavior for maven.

因为提供的依赖关系不是传递性的?这就是maven的内置行为。

#3


1  

The dependencyManagement section declares what dependencies will look like if you use them, not that you will use them. So you still need to declare a minimal dependency declaration to have the configuration applied in your child project. See the dependency management section of the Maven book for details.

dependencyManagement一节声明如果您使用依赖项,那么依赖项将是什么样子,而不是您将使用它们。因此,您仍然需要声明一个最小的依赖项声明,以便在子项目中应用配置。有关详细信息,请参阅Maven book的依赖关系管理部分。

The minimum required is typically the groupId and the artifactId.

所需要的最小值通常是肌群和人工动脉。

If you want to inherit the configuration without declaring it at all, you should define it in the parent's dependencies section rather than dependencyManagement

如果您想要继承配置而不声明它,那么应该在父类的依赖项中定义它,而不是依赖于管理。

#1


12  

model and persistence obviously depend on javax.persistence, but application shouldn't, I think.

模型和持久性显然依赖于javax。持久性,但应用不应该。

That's true. But transitive dependencies resolution has nothing to do with your problem (and actually, javax.persistence is provided to model and persistence on which application depends with a compile scope so it's omitted as documented in 3.4.4. Transitive Dependencies).

这是真的。但是传递依赖关系解析与您的问题没有任何关系(实际上,还有javax。持久性提供给模型和持久性,应用程序依赖于一个编译范围,因此在3.4.4中省略了持久性。传递依赖关系)。

In my opinion, you are victim of this bug: http://bugs.sun.com/view_bug.do?bug_id=6550655

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

I have the same issues with an EJB3 entity that uses the Inheritance annotation: @Inheritance(strategy=InheritanceType.SINGLE_TABLE)

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

A client class using this entity won't compile when the ejb3 annatations are not on the classpath, but crash with the following message: com.sun.tools.javac.code.Symbol$CompletionFailure: class file for javax.persistence.InheritanceType not found

当ejb3声明不在类路径上时,使用该实体的客户端类将不会编译,而是与以下消息一起崩溃:com.sun.tools.javac.code。符号$CompletionFailure:用于javax.persistence的类文件。InheritanceType未找到

[...]

[…]

Note that is a special case of bug 6365854 (that is reported to be fixed); the problem here seems to be that the annotation is using an enum as its value.

请注意,这是一个bug 6365854的特殊情况(报告是修复的);这里的问题似乎是注释使用enum作为其值。

The current workaround is to add the missing enum to the CLASSPATH.

当前的解决方案是将缺失的枚举添加到类路径中。

In your case, the "less worse" way to do that would be to add javax.persistence as provided dependency to the application module. But that's a workaround to the JVM bug, application shouldn't need that dependency to compile.

在您的例子中,“不那么糟糕”的方法是添加javax。持久性提供了对应用程序模块的依赖性。但是这是对JVM错误的一种变通方法,应用程序不应该需要依赖这个来编译。

#2


2  

umm, because provided dependencies are not transitive? that's builtin behavior for maven.

因为提供的依赖关系不是传递性的?这就是maven的内置行为。

#3


1  

The dependencyManagement section declares what dependencies will look like if you use them, not that you will use them. So you still need to declare a minimal dependency declaration to have the configuration applied in your child project. See the dependency management section of the Maven book for details.

dependencyManagement一节声明如果您使用依赖项,那么依赖项将是什么样子,而不是您将使用它们。因此,您仍然需要声明一个最小的依赖项声明,以便在子项目中应用配置。有关详细信息,请参阅Maven book的依赖关系管理部分。

The minimum required is typically the groupId and the artifactId.

所需要的最小值通常是肌群和人工动脉。

If you want to inherit the configuration without declaring it at all, you should define it in the parent's dependencies section rather than dependencyManagement

如果您想要继承配置而不声明它,那么应该在父类的依赖项中定义它,而不是依赖于管理。