有没有一种方法可以为具有相同基础的不同客户端构建项目,但要为在运行时发现的某些功能提供模块化功能? jojal主POM 基本主POM 一个POM B POM C POM 产品主要POM 产品1 POM 产品2 POM 产品3 POM

问题描述

我曾经使用E4 Eclipse框架构建桌面应用程序,现在我想迁移到一个简单的maven项目。

在带有Osgi的Eclipse平台中,存在捆绑,功能和产品的概念。

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

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

在maven中,我找不到一种执行相同操作的好方法,因为只有一个pom.xml描述了整个项目。如何为在运行时发现的插件引入模块化?
每个客户应该有多个POM吗? 我应该使用个人资料来做到这一点吗?我尝试过,但管理起来并不容易。

还有另一种行之有效的方法,可以轻松地管理可变性吗?

解决方法

在对问题的评论之一中,再加上“ 以及(也许)另一个Pom.xml(或配置文件?)”:

Maven的原则之一是:一个项目(在POM中声明),一个生成的(主要)工件(JAR,WAR,...)。 (之所以称为“主要”,是因为可能会伴随...-sources.jar,...-javadoc.jar...-jar-with-dependencies.jar,....zip,...之类的伪像)

Maven POM具有声明性。这意味着,没有(强制性的)if会偶尔跳过声明,并且您也无法在构建过程中添加/删除声明(XML)元素(您“可以”通过{ {3}})。 (有一些带有<skip>false|true参数的插件,可以使用属性来设置/覆盖它们,但这不是一般性的规则,因此没有很多。)

properties是克服这种“如果没有原则”的方法。使用它们,您可以Profiles通过activate ("inject") declarations在构建时设置或覆盖现有声明。

关于删除 osgi 标记后的评论,我稍后将更新此答案。同时,您可以查看我对various profile activation methods的回答。

更新

+- 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] Maven: Lifecycle vs. Phase vs. Plugin vs. Goal
[2] POM Reference,Packaging

基本主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,Aggregation

一个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,Inheritance

产品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>

[请注意:未经测试,可能有错字]