Java 在编译时在pom.xml中动态添加依赖项,无需知道工件id和版本

Java 在编译时在pom.xml中动态添加依赖项,无需知道工件id和版本,java,eclipse,maven,Java,Eclipse,Maven,我有一个项目a,它依赖于一个项目I,该项目I包含由第三个项目B实现的接口 我希望项目B能够在编译时直接插入到项目A的pom.xml中,而不会更改A的pom.xml,也不会通过命令行向Maven提供属性(例如 )其中B_ARTIFACTID和B_VERSION指的是项目B 其目的是标记项目a的一个版本,并通过I中包含的接口,使用第四个项目C中包含的实现,该项目C使用相同版本的项目a实现I,只是更改构建它的命令行 我知道这是可能的使用配置文件属性,但在项目A将被标记时,它将不会解决依赖关系,如何在不

我有一个项目a,它依赖于一个项目I,该项目I包含由第三个项目B实现的接口

我希望项目B能够在编译时直接插入到项目A的pom.xml中,而不会更改A的pom.xml,也不会通过命令行向Maven提供属性(例如

)其中
B_ARTIFACTID
B_VERSION
指的是项目B

其目的是标记项目a的一个版本,并通过I中包含的接口,使用第四个项目C中包含的实现,该项目C使用相同版本的项目a实现I,只是更改构建它的命令行

我知道这是可能的使用配置文件属性,但在项目A将被标记时,它将不会解决依赖关系,如何在不使用默认依赖关系的情况下修复此问题

B和C取决于以下项目:

项目
我
0.1.0.0
项目A


项目
我
0.1.0.0
项目
???
???
运行时

编辑:我说过我不想对属性进行编辑,因为在我标记项目A时,它不会解决依赖关系。

所以
A
可以对
i
进行良好编译;
a
I
之间存在依赖关系

C
I
的实现可以作为jar添加到
A
中,方法如下:

  • 运行时
  • 提供
    如果运行jar
    A
    的地方有一个jar
    C
然后是没有依赖性的问题

如果jar
C
使用JavaSPI(服务提供商接口),它可以让
A
在某些接口上进行查找:

  • C

    • 文本文件
      /META-INF/services/net.i.api.api

      net.c.api.ApiImpl
      

    • 也许你没有采取正确的方法。对我来说,这听起来像是试图将您的程序与一个或另一个库进行静态链接——Java不是这样工作的

      Java是关于动态链接的。没有任何东西可以阻止您在不引用任何B或C的情况下一起编译A和I-它只是编译,但在执行过程中的某个时候会抛出异常,因为它没有I中接口的实现

      您应该实现某种抽象工厂,在寻找合适的实现之后返回I对象。此工厂的决策标准可能来自某些属性文件,或者深入研究反射/注释类等

      当您发布应用程序时,您只需将A和I jar与实现打包:B、C,或者您希望在将来扩展应用程序的任何东西(D、E等)。一旦在运行时,您的AbstractFactory将不得不根据应用程序设置和可用实现做出决定


      举个例子,想想Windows Media Player(我知道,技术不同,但想法相同),它是如何寻找编解码器实现的,以及一旦我们下载并注册了它们,它就可以在不修改软件本身的情况下播放剪辑。

      你不应该这样做。首先,
      artifactId
      至关重要。您不能在
      项目A
      中实现任何依赖于特定工件的东西,只要它未知/未加载。第二:任何版本的差异都可能破坏整个应用程序。假设您对版本(或artifactId)进行了输入错误,您可能会在错误中搜索很长时间,因为您不确定原因可能是什么。但如果您真的想解决这个问题,请仔细阅读关于如何在A中动态添加B或C的依赖关系的可能副本?项目A在其开发过程中不知道存在多少个I实现,我们不想仅仅为了发布项目A-b(A带有依赖项b)或A-c(带有依赖项c)而编辑pom.xml。使用Java SPI,可以将c添加到应用程序的类路径(没有依赖项),并检测I接口的一个或多个实现类。例如,这是通过Xerces和Xalan实现的XMLAPI实现的。请记住,类路径也可以是JARSO的目录。如果不在pom.xml中插入B,就不可能在包含B的jar中构建a。我们需要它来创建一种可插拔模块(a)。还要求A-b模块(其中包含依赖项为b的A)包含在单个jar中。您可以将b jar作为分发文件添加到pom中,而无需依赖项/artifactId。如何添加此依赖项?我们正试图找到一种方法,在CI/CD传递一些参数(groupId、artifactId、version)时添加此依赖项,而无需编辑pom.xml。有可能吗?我们正试图找到一种方法,用一个jar和一个I实现一个jar。我们使用的是SPI,所以我们需要在“mvn包”中集成C或B,因为在生产中我们必须发布一个jar,然后我应该坚持我的建议:用抽象工厂分离依赖项,分别编译所有内容,准备CI/CD管道以构建不同的可交付包,每个包都有适当的实现(B、C等),并让每个生产设置在运行时找到其实现类。这里的问题可能是假设所有内容都必须在project pom.xml中解决。可能pom.xml不应该在构建一个依赖于I的项目时承担太多的责任。对我来说,构建不同的可交付成果似乎是一个不同的问题,需要在不同的层面上解决——可能是在另一个pom的CI管道中?这是我们的目标,但我们希望找到一种方法来集成适当的实现,而不必编辑“pom.xml”,只需传递一些参数(artifactId、groupId、version)。你有什么想法吗,也许在maven生命周期中还有别的什么?我的
      package net.i.api; interface Api { ... }
      
      package net.c.api; class ApiImpl implements Api { ... }
      
      net.c.api.ApiImpl