Есть ли способ создать проект для другого клиента с той же базой, но с модульностью для некоторых функций, которые будут обнаружены во время выполнения?

Я привык использовать среду E4 Eclipse для создания настольных приложений, и теперь я хотел бы перейти на простой проект maven.

В платформе Eclipse с OSGi есть понятие пакета, функции и продукта.

Когда я хочу создать свой проект для клиента A, у меня есть файл A.product, описывающий все зависимости. Для клиента B у меня есть B.product и так далее.

Конечно, мое программное обеспечение использует ту же базу, но если клиенту нужна новая функция (например, плагин), я должен добавить ее в свой файл продукта, и новая функция будет обнаружена во время выполнения и представлена ​​в моем программном обеспечении.

В maven я не нахожу хорошего способа делать то же самое, потому что есть только один pom.xml, описывающий весь проект. Как я могу ввести модульность для подключаемого модуля, обнаруженного во время выполнения?
Должен ли я иметь несколько POM для каждого клиента? Следует ли мне использовать для этого профиль? Я пытался, но мне было непросто.

Есть ли другой хороший способ сделать это maven и легко управлять изменчивостью?


person jojal    schedule 10.08.2020    source источник
comment
Вы уже видели Tycho?   -  person Gerold Broser    schedule 10.08.2020
comment
Да, я видел Тихо, но я бы хотел покинуть мир e4 и прийти более обычным способом maven. Мне нужно не настольное приложение, поэтому я использую Quarkus с cdi для инъекций. Я просто хочу изменить свой Pom.xml. Один для клиента A с N плагинами, обнаруженными во время выполнения. И (возможно) еще один Pom.xml (или профиль?) Для клиента B с N ’Plug-ins Discoverer во время выполнения.   -  person jojal    schedule 11.08.2020
comment
Вы отметили свой вопрос с помощью [osgi]. На главной странице Tycho написано: «Tycho - это набор подключаемых модулей и расширений Maven для создания [...] пакетов OSGi с Maven.». Может быть, есть другой способ создания (веб, серверная часть или локальная, а не Eclipse) приложений на основе OSGi с Maven, но я пока не видел другого.   -  person Gerold Broser    schedule 11.08.2020
comment
Ты прав. Я только что удалил тег [osgi], прежде чем на самом деле я ищу удаление метода osgi. По сути, вопрос только в том, как создать базовое развертывание только с помощью A.jar. Например, A.jar объявляет подключаемый модуль интерфейса, и у меня есть одна реализация этого интерфейса в B.jar и другая реализация в C.jar. В итоге я хотел бы создать 2 продукта. Один с A.jar и B.jar, а другой, например, с A.jar и C.jar, или A.jar с B.jar и C.jar. Должен ли я создавать один файл pom.xml для каждого развертывания? Или есть лучший способ сделать это?   -  person jojal    schedule 11.08.2020


Ответы (1)


Повторите „И (возможно) еще один файл Pom.xml (или профиль?)“ в одном из ваших комментариев к вопросу:

Один из принципов Maven: один проект (объявленный в POM), один результирующий (главный) артефакт (JAR, WAR, ...). («Main», поскольку могут быть сопутствующие артефакты, такие как ...-sources.jar , ...-javadoc.jar, ...-jar-with-dependencies.jar, ....zip , ...)

Maven POM носят декларативный характер. Это означает, что нет (обязательных) ifs для пропуска объявлений время от времени, и вы также не можете добавлять / удалять элементы объявления (XML) во время сборки (вы просто можете добавлять / изменять текстовое содержимое элемента через properties). (Существуют плагины с параметром <skip>false|true, который можно установить / переопределить с помощью свойства, но это не общее правило, и поэтому их не так много.)

Профили - это способ преодолеть этот принцип «нет, если» . С их помощью вы можете активировать (вводить) объявления, которые установить или переопределить существующие объявления во время сборки с помощью различных методов активации профиля.

Что касается вашего комментария после удаления тега osgi, я собираюсь обновить этот ответ позже. А пока вы можете взглянуть на мой ответ на Maven: жизненный цикл против фазы против плагина против цели.

ОБНОВИТЬ

+- 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 main 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, упаковка
[2] Справочник по 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, наследование

ПОМ

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

Основной ПОМ продукта

<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 ПОМ

<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, зависимости

Продукт 2 ПОМ

<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 ПОМ

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

[Обратите внимание: на практике не тестировалось, возможны опечатки]

person Gerold Broser    schedule 11.08.2020
comment
Вау отличный ответ! Это именно то, чего я хотел бы достичь. Спасибо за отличный ответ с большим количеством деталей и ссылок. - person jojal; 12.08.2020
comment
Есть ли способ пропустить сборку всех продуктов, когда мы выполняем mvn clean package на jojal-main? Если я задам этот вопрос, то это нужно для того, чтобы каждый раз не перестраивать весь клиентский проект. Может быть, еще одна идея - разделить на разные репозитории? - person jojal; 12.08.2020
comment
Пожалуйста. Перейдите в каталог /base-main и запустите mvn ... там. Тогда будут построены только модули, объявленные в POM jojal-base-main. И это также относится к конечным проектам, как правило, к каждому проекту в дереве: перейдите в каталог B, запустите там mvn ..., и будет построено только project-b. Альтернативой является mvn -f /path/to/pom.xml из любого места. - person Gerold Broser; 12.08.2020
comment
Отлично, теперь все работает отлично. Спасибо за помощь. Моя последняя проблема с maven - поделиться своим application.properties, который находится в base-main во всех продуктах, чтобы поделиться глобальной конфигурацией, но я думаю, что это выходит за рамки первоначальной проблемы :) Еще раз спасибо. Очень полезно. - person jojal; 12.08.2020