如何为不同的部署场景创建具有传递依赖的maven程序集?
我在协调构建一个在应用程序服务器中使用和用作独立应用程序的项目时遇到问题。
为了给出一个整体简化的上下文,假设我有三个项目 A、B、C。
项目 A 依赖于项目 B,而项目 B 又依赖于项目 C。
项目 C 有一个依赖项 X,该依赖项被标记为已提供,因为预计它将可用作为应用程序服务器中的 JEE 库。即jms.jar。
因此,如果我执行项目 A 的程序集构建,我会获得所有传递依赖项,除了那些标记为按预期提供的依赖项。
现在我有一个新的部署场景,其中项目 A 需要在独立环境(即应用程序服务器外部)中使用。
所以现在我需要 jms jar 作为编译依赖项。这是否意味着我应该在项目 A 中显式添加 X 的编译依赖项?这是否违反了迪米特法则,即不要与陌生人交谈,从某种意义上说,项目 A 不应该明确了解项目 C,而只能了解项目 B?
这是一个简单的示例,但实际上我有多个依赖项,这些依赖项已被标记为已提供,但现在需要编译或运行时依赖项,因此它们最终会出现在 Maven 程序集插件生成的工件中。
这是 Maven 的根本问题还是我没有正确使用这些工具?
预先感谢您的任何指导。
I'm having a problem reconciling building a project for use within an application server and for use as a stand-alone application.
To give an overall simplified context, say I have three Projects A, B, C.
Project A depends on Project B which depends on Project C.
Project C has a dependency X which is marked as provided since it was expected that it would be available as a JEE library within say an application server. i.e. jms.jar.
So if I perform an assembly build of Project A, I get all the transitive dependencies save for those marked as provided as expected.
Now I have a new deployment scenario where Project A needs to be used in a standalone environment i.e. outside an application server.
So now I need the jms jar to be a compile dependency. Does this mean that I should explicitly add a compile dependency for X in Project A? Doesn't this violate the Law of Demeter, i.e. don't talk to strangers, in the sense Project A shouldn't explicitly know about Project C but only about Project B?
This is a simple example but in reality I have multiple dependencies which have been marked as provided but are now need to be compile or runtime dependencies so they end up in the artifact produced by the maven assembly plugin.
Is this a fundamental problem with Maven or am I not using the tools correctly?
Thanks in advance for any guidance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您需要构建针对不同场景进行变化,则需要使用配置文件并在各种配置文件中保留某些内容(例如某些依赖项)。
http://maven.apache.org/pom.html#Profiles
Maven中不同构建配置文件的不同依赖项
回答了类似的问题 - 但你可以交换“项目 A”和“项目 C”的“发布”和“调试”
If you need your build to have variations in it for different scenarios, you need to use profiles and keep certain things (such as some of the dependencies) in the various profiles.
http://maven.apache.org/pom.html#Profiles
Different dependencies for different build profiles in maven
answers a similar question - but you can swap in the "release" and "debug" for "Project A" and "Project C"
提供的依赖关系是一个困难的主题。首先:提供的依赖项在以下意义上是不传递的:如果您的项目 C 具有对 X 的提供的依赖项,那么 A 将不会获得该依赖项。它被默默地忽略。这符合我建议的“提供”的以下含义:
只有实际部署的工件才应将依赖项标记为“提供”。未单独部署到特定服务器的库或其他 jar 不应提供依赖项。相反,他们应该将其依赖项声明为编译依赖项。在您的示例中:项目 C 应该具有对 X 的编译依赖项。如果项目 A 知道提供了 X,则会将 X 设置为在“dependencyManagement”中提供。由于项目 A 应该知道它运行的环境,因此它应该决定提供什么和不提供什么。 “dependenyManagement”是声明这一点的正确位置。
如果您的项目 A 应该能够在给定服务器内或没有给定服务器运行,您可能需要进行大量调整,甚至将类型从 Ear 更改为 jar。因此,您要么为此使用构建配置文件,然后该配置文件具有不同的 dependencyManagement 条目,要么将 A 拆分为两个项目,这两个项目依赖于包含公共元素的其他项目。
如果某个给定的项目 C 已经提供了对 X 的依赖关系,并且您无法更改它,那么这实际上与 C 中缺少的依赖关系相同。这必须在某个时候修复,这可能是项目 A 本身。
Provided dependencies are a difficult subject. First of all: Provided dependencies are not transitive in the following sense: If your project C has a provided dependency on X, then A will not get the dependency. It is silently ignored. This fits with the following meaning of "provided" which I propose:
Only the artifacts that are actually deployed should mark dependencies as "provided". Libraries or other jars that are not individually deployed to a specific server should not have provided dependencies. Instead, they should declare their dependencies as compile dependencies. In your example: Project C should have a compile dependency on X. If project A knows that X is provided, it sets X to provided in "dependencyManagement". As project A should know the environment in which it runs it should decide what is provided and what is not. And "dependenyManagement" is the right place to declare this.
If your project A should be able to run within and without a given server, you probably need to make a lot of adjustments, even change the type from ear to jar. So you either use build profiles for this, which then have different dependencyManagement entries, or you split A into two projects which depend on some other project that contains the common elements.
If some given project C already has a provided dependency on X and you cannot change that, this is effectively the same as a missing dependency in C. This has to be repaired at some point, and this could be project A itself.