有没有一种方法可以为具有相同基础但对运行时会发现的某些功能具有模块化的不同客户端构建项目?

Is there a way to build a project for different client with the same base but with modularity for some feature that would be discovered at runtime?

习惯使用E4 Eclipse框架构建桌面应用,现在想迁移到一个简单的maven项目。

在带有 OSGi 的 Eclipse 平台中,有 bundle、feature 和 product 的概念。

当我想为客户 A 构建项目时,我有一个描述所有依赖项的文件 A.product。对于客户 B,我有 B.product 等等。

当然,我的软件共享相同的基础,但如果客户想要新功能(如插件),我必须将其添加到我的产品文件中,新功能将在运行时发现并呈现给我的软件。

在 maven 中,我找不到做同样事情的好方法,因为只有一个 pom.xml 描述了整个项目。如何为运行时发现的插件引入模块化?
我应该为每个客户准备多个 POM 吗? 我应该使用配置文件来做到这一点吗?我试过,但我不好管。

是否有另一种 Maven 好方法来做到这一点,并轻松管理可变性?

关于“和(也许)另一个 Pom.xml(或个人资料?)“在您对问题的评论之一中:

Maven 的原则之一是:一个 项目(在 POM 中声明),一个 生成的(主要)工件(JAR, WAR, ...). („main“ since there can be accompanying artifacts like ...-sources.jar, ...-javadoc.jar, ...-jar-with-dependencies.jar, ....zip, ...)

Maven POM 具有声明性。这意味着,没有(强制性的)ifs 偶尔跳过声明,你也不能在构建期间 add/remove 声明(XML)元素(你“只是”可以 add/change 元素文本内容通过 properties)。 (有些插件带有 <skip>false|true 参数,可以是带有 属性 的 set/overridden,但这不是一般规则,因此数量不多。)

Profiles are a way to overcome this no-if-principle. With them you can activate ("inject") declarations which set or override existing declarations at build time via various profile activation methods.

关于您在删除 osgi 标签后的评论,我稍后会更新此答案。同时你可以看看我对 Maven: Lifecycle vs. Phase vs. Plugin vs. Goal.

的回答

更新

+- jojal-main
   +- pom.xml   ... contains declarations common for all of your projects
   +- base-main
      +- pom.xml   ... contains declarations common for all base projects
      +- A
         +- src/main/java/your/package/Plugin.java
         +- pom.xml
      +- B
         +- src/main/java/your/package/ClassA.java   ... implements Plugin
         +- pom.xml
      +- C
         +- src/main/java/your/package/ClassB.java   ... implements Plugin
         +- pom.xml
   +- product-main
      +- pom.xml   ... contains declarations common for all product projects
      +- product1
         +- src/main/java/your/package/Product1.java   ... references A & B
         + pom.xml
      +- product2
         +- src/main/java/your/package/Product2.java   ... references A & C
         +- pom.xml
      +- product3
         +- src/main/java/your/package/Product3.java  ... references A & B & C
         +- pom.xml

jojal 主 POM

<project ...>
  ...

  <groupId>name.jojal</groupId>
  <artifactId>jojal-main</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>  <!-- different to the default 'jar'[1] -->

  <modules>  <!-- to build projects in sub-dirs at once[2] -->
    <module>base-main</module>
    <module>product-main</module>
  </modules>

  ... declarations common for all of your projects like dependencies for unit testing, logging etc. ..

<project>

[1] POM Reference, Packaging
[2] POM Reference, Aggregation

基本主 POM

<project ...>
  ...

  <parent>   <!-- declarations are inherited from this parent POM[3] -->
    <groupId>name.jojal</groupId>
    <artifactId>jojal-main</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>

  <artifactId>jojal-base-main</artifactId>  <!-- <groupId>, <version> can be omitted if the same as in parent -->
  <packaging>pom</packaging>

  <modules>
    <module>A</module>
    <module>B</module>
    <module>C</module>
  </modules>

  ... declarations common for all base projects ...

<project>

[3] POM Reference, Inheritance

POM

<project ...>
  ...

  <parent>
    <groupId>name.jojal.base</groupId>
    <artifactId>jojal-base-main</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>
 
  <artifactId>project-a</artifactId>

<project>

B POM

<project ...>
  ...

  <parent>
    <groupId>name.jojal.base</groupId>
    <artifactId>jojal-base-main</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>

  <artifactId>project-b</artifactId>

  <dependencies>
    <dependency>
      <groupId>name.jojal.base</groupId>
      <artifactId>project-a</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>
  </dependencies>

<project>

C POM

<project ...>
  ...

  <parent>
    <groupId>name.jojal.base</groupId>
    <artifactId>jojal-base-main</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>
 
  <artifactId>project-c</artifactId>

  <dependencies>
    <dependency>
      <groupId>name.jojal.base</groupId>
      <artifactId>project-a</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>
  </dependencies>

<project>

产品主 POM

<project ...>
  ...

  <parent>
    <groupId>name.jojal</groupId>
    <artifactId>jojal-main</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>

  <artifactId>jojal-product-main</artifactId>
  <packaging>pom</packaging>

  <modules>
    <module>product1</module>
    <module>product2</module>
    <module>product3</module>
  </modules>

  ... declarations common for all product projects ...

<project>

产品 1 POM

<project ...>
  ...

  <parent>
    <groupId>name.jojal.product</groupId>
    <artifactId>jojal-product-main</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>

  <artifactId>product-1</artifactId>

  <dependencies>
    <dependency>
      <groupId>name.jojal.base</groupId>
      <artifactId>project-b</artifactId>  <!-- project-a is resolved automatically by Maven
                                               as a transitive dependency[4] -->
      <version>1.0-SNAPSHOT</version>
    </dependency>
  </dependencies>

<project>

[4] POM Reference, Dependencies

产品 2 POM

<project ...>
  ...

  <parent>
    <groupId>name.jojal.product</groupId>
    <artifactId>jojal-product-main</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>

  <artifactId>product-2</artifactId>

  <dependencies>
    <dependency>
      <groupId>name.jojal.base</groupId>
      <artifactId>project-c</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>
  </dependencies>

<project>

产品 3 POM

<project ...>
  ...

  <parent>
    <groupId>name.jojal.product</groupId>
    <artifactId>jojal-product-main</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>

  <artifactId>product-3</artifactId>

  <dependencies>

    <dependency>
      <groupId>name.jojal.base</groupId>
      <artifactId>project-b</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>

    <dependency>
      <groupId>name.jojal.base</groupId>
      <artifactId>project-c</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>

  </dependencies>

<project>

[请注意:未经真实测试,可能出现错别字]