Maven是否可以组装具有不同配置的可执行JAR?

时间:2016-12-08 00:58:54

标签: java maven maven-2 maven-3 maven-assembly-plugin

我有一个具有以下概念结构的项目:

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

我正在寻找一种方法告诉maven以下内容:

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

此示例将从Core的main开始创建一个可执行的JAR文件,并且还打包/组装功能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();

}

这有可能吗?

谢谢!

3 个答案:

答案 0 :(得分: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;
            }
        }

}

下面的POM

 <?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 :(得分:1)

  

Maven是否可以使用不同的配置来组装可执行的JAR?

是的。一种相对简单的方法是使用maven-assembly-plugin

  

启动JAR时,主要方法应该能够知道安装了哪些功能

这与Maven无关。它接缝你正在尝试建立自己的模块系统。虽然这样做并非严格错误,但您可能需要考虑现有的解决方案:

  • Java的service loader可以是一种方法(在相对简单的情况下)。
  • OSGi实际上是模块化Java应用程序的标准。我知道很多人会争论(或许由于过时的知识)它太沉重/复杂,但实际上已经不再是这样了。如果您希望采用这种方式并从实际模块化的强大功能中受益,您可以检查这个多模块应用程序的base tutorial。该示例使用bndtools,但您可以执行the same with Maven

答案 2 :(得分: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