2016-12-08 9 views
0

У меня есть проект со следующей концептуальной структурой:Возможно ли Maven для сборки исполняемых JAR с различными конфигурациями?

-- Core project: Contains the main() function 
---- Feature A 
---- Feature B 
---- Feature C 
---- etc. 

Я ищу способ, чтобы сказать Maven следующее:

mvn package core--with--featureA--and--featureC

Этот пример создаст исполняемый файл JAR, начиная с Core main, а также функции A и C также упакованы/собраны, но не имеют функции B и других.

Хотя JAR запускается, метод main должен быть в состоянии знать, какие установлены особенности и самонастройки их всех, например, для .:

main() { 
    for(Runnable featureStarter : FeatureList.getFeatures()) { // Gets all features assembled by maven, which are now present in runtime 
    featureStarter.run(); // Starts each feature 
    } 
} 

или, более деревенское/жестко закодированы пример (менее предпочтительнее):

main() { 
    if(isInstalled("FeatureA")) 
    FeatureA.start(); 

    if(isInstalled("FeatureB")) 
    FeatureB.start(); 

    if(isInstalled("FeatureC")) 
    FeatureC.start(); 

} 

Это возможно?

Спасибо!

+0

Вы ищете банки, которые работают в различных средах или только одной баночке, которая будет обнаружить недостающую зависимость и отключить определенную функцию – Narrim

+0

У Maven есть проекты, а затем модули, поэтому вы можете создать 2 модуля выпуска, которые зависят от базового проекта. Каждый из них будет собираться по-разному, это зависит от вашей основной функции, чтобы проверить отсутствие классов в функции и отключить или включить функцию. – Narrim

+0

Это не имеет ничего общего с окружающей средой, это больше похоже на зависимость. Я думаю, что мы можем видеть функции как зависимости. Я не знаю, было бы лучшим способом добиться этого с помощью maven? – PedroD

ответ

1

У Maven есть проекты, а затем модули. Также вы можете создать 2 модуля выпуска, которые зависят от базового проекта. Они могут выпускать другую банку.

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

Проблема, с которой вы столкнетесь, заключается в том, что вам нужно будет использовать отражение, чтобы избежать проблем с сборкой в ​​главном приложении. т.е. он не будет компилироваться, если он не может разрешить включение.

Т.е. FeatureA.start()

public void Start(){ 
try { 
      clazz = Class.forName("org.group.ComponentA"); 
     } catch (ClassNotFoundException e) { 
      if (fallbackOk) { 
       clazz = Class.forName("org.group.Component"); 
      } else { 
       throw e; 
      } 
     } 

} 

ПОМ ниже

<?xml version="1.0" encoding="UTF-8"?> 
<project xmlns="http://maven.apache.org/POM/4.0.0" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
    <parent> 
     <artifactId>parent-artifact</artifactId> 
     <groupId>com.group</groupId> 
     <version>1.9</version> 
    </parent> 
    <modelVersion>4.0.0</modelVersion> 

    <artifactId>child-artifact</artifactId> 
    <packaging>war</packaging> 

    <name>Child Jar</name> 
    <build> 
     <finalName>Child</finalName> 
     <resources> 
      <resource> 
       <directory>${basedir}/src/conf/log4j</directory> 
       <includes> 
        <include>log4j.properties</include> 
       </includes> 
      </resource> 
      <resource> 
       <directory>${basedir}/src/conf/hibernate</directory> 
       <includes> 
        <include>hibernate.properties</include> 
       </includes> 
       <filtering>true</filtering> 
      </resource> 
     </resources> 
     <plugins> 
      <plugin> 
       <!-- extracts the messages*.properties files from to a staging area --> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-dependency-plugin</artifactId> 
       <executions> 
        <execution> 
         <id>unpack</id> 
         <phase>generate-sources</phase> 
         <goals> 
          <goal>unpack</goal> 
         </goals> 
         <configuration> 
          <artifactItems> 
           <artifactItem> 
            <groupId>com.group</groupId> 
            <artifactId>componentA</artifactId> 
            <version>${project.version}</version> 
            <type>jar</type> 
            <overWrite>false</overWrite> 
            <outputDirectory>${project.build.directory}/localisation</outputDirectory> 
            <includes>**/messages*.properties</includes> 
           </artifactItem> 
           <artifactItem> 
            <groupId>com.group</groupId> 
            <artifactId>componentB</artifactId> 
            <version>${project.version}</version> 
            <type>war</type> 
            <overWrite>false</overWrite> 
            <outputDirectory>${project.build.directory}/webapp/webstart</outputDirectory> 
           </artifactItem> 
          </artifactItems> 
         </configuration> 
        </execution> 
       </executions> 
      </plugin> 
      <plugin> 
       <!-- copies the messages*.properties files to classes/localisation --> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-resources-plugin</artifactId> 
       <executions> 
        <execution> 
         <id>unpack</id> 
         <phase>generate-resources</phase> 
         <goals> 
          <goal>copy-resources</goal> 
         </goals> 
         <configuration> 
          <outputDirectory>${basedir}/target/classes/localisation</outputDirectory> 
          <resources> 
           <resource> 
            <directory>${basedir}/target/localisation/org/group/web/resource/localisation/ 
            </directory> 
           </resource> 
          </resources> 
         </configuration> 
        </execution> 
        <execution> 
         <!-- copy webapp for tomcat plugin --> 
         <id>webapp</id> 
         <phase>generate-resources</phase> 
         <goals> 
          <goal>copy-resources</goal> 
         </goals> 
         <configuration> 
          <outputDirectory>${basedir}/target/webapp</outputDirectory> 
          <resources> 
           <resource> 
            <directory>${basedir}/src/webapp/</directory> 
           </resource> 
          </resources> 
         </configuration> 
        </execution> 
       </executions> 
      </plugin> 
      <plugin> 
       <artifactId>maven-war-plugin</artifactId> 
       <configuration> 
        <warSourceDirectory> 
         ${basedir}/src/webapp 
        </warSourceDirectory> 
        <archive> 
         <addMavenDescriptor>false</addMavenDescriptor> 
        </archive> 
        <overlays> 
         <overlay> 
          <groupId>org.group</groupId> 
          <artifactId>componentC</artifactId> 
          <targetPath>webstart</targetPath> 
         </overlay> 
        </overlays> 
       </configuration> 
      </plugin> 
      <plugin> 
       <artifactId>maven-source-plugin</artifactId> 
      </plugin> 
      <plugin> 
       <groupId>org.apache.tomcat.maven</groupId> 
       <artifactId>tomcat6-maven-plugin</artifactId> 
       <version>2.2</version> 
       <configuration> 
        <server>app-tomcat</server> 
        <!--port>${maven.tomcat.port}</port--> 
        <path>/${project.build.finalName}</path> 
        <warSourceDirectory>${basedir}/target/webapp</warSourceDirectory> 
       </configuration> 
       <dependencies> 
        <dependency> 
         <groupId>${jdbc.groupId}</groupId> 
         <artifactId>${jdbc.artifactId}</artifactId> 
         <version>${jdbc.version}</version> 
        </dependency> 
       </dependencies> 
      </plugin> 
      <plugin> 
       <groupId>org.apache.tomcat.maven</groupId> 
       <artifactId>tomcat7-maven-plugin</artifactId> 
       <version>2.2</version> 
       <configuration> 
        <server>app-tomcat</server> 
        <!--port>${maven.tomcat.port}</port--> 
        <path>/${project.build.finalName}</path> 
        <warSourceDirectory>${basedir}/target/webapp</warSourceDirectory> 
       </configuration> 
       <dependencies> 
        <dependency> 
         <groupId>${jdbc.groupId}</groupId> 
         <artifactId>${jdbc.artifactId}</artifactId> 
         <version>${jdbc.version}</version> 
        </dependency> 
       </dependencies> 
      </plugin> 
     </plugins> 
    </build> 
    <repositories> 
     <repository> 
      <!-- for jetty plugin dependencies --> 
      <id>java.net</id> 
      <url>http://download.java.net/maven/2/</url> 
      <snapshots> 
       <enabled>false</enabled> 
       <checksumPolicy>fail</checksumPolicy> 
       <updatePolicy>never</updatePolicy> 
      </snapshots> 
     </repository> 
    </repositories> 
    <dependencies> 
     <dependency> 
      <groupId>org.group</groupId> 
      <artifactId>componentA</artifactId> 
     </dependency> 
     <dependency> 
      <groupId>org.group</groupId> 
      <artifactId>componentB</artifactId> 
     </dependency> 
    </dependencies> 

    <properties> 
    </properties> 

</project> 
1

Возможно ли Maven для сборки исполняемых файлов JAR с различными конфигурациями?

Да, это так. Один относительно простой способ сделать это с помощью maven-assembly-plugin

Хотя JAR запускается, основной метод должен иметь возможность знать, какие функции будут установлены

Это не имеет ничего общего с Maven. Он швы, вы пытаетесь создать свою собственную модульную систему. Хотя это не является строго неправильно делать это, вы можете рассмотреть существующие решения, которые уже делают это:

  • в Java service loader может быть один способ приблизиться, что (в относительно простых случаях).
  • OSGi является фактически стандартом для модульных приложений Java.Я знаю, что многие люди будут спорить с (из-за устаревшего знания) слишком тяжело/сложно, но это уже не так. В случае, если вы хотите пойти этим путем и получить преимущество от реальной модульности, вы можете проверить этот base tutorial, который многократно использует многомодульное приложение. В примере используются bndtools, но вы можете сделать the same with Maven.
+0

Я использовал osgi в течение многих лет и ушел в этом году из-за проблемы адских атак и всех накладных расходов на управление пакетами. – PedroD

1

Зачем делать это сложным, когда вы можете сделать это простым! Проект

Pom Core:

<profile> 
      <id>active-Feature-A</id> 
     ... 
     ...    
</profile>   

<profile> 
      <id>active-Feature-B</id> 
     ... 
     ...    
</profile> 

<profile> 
      <id>active-Feature-C</id> 
     ... 
     ...    
</profile> 

Тогда:

mvn package -Pactive-Feature-A,active-Feature-B