【问题标题】:Is it possible for Maven to assembly executable JARs with different configurations?Maven 是否可以组装具有不同配置的可执行 JAR?
【发布时间】:2017-04-23 03:19:57
【问题描述】:

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

-- 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();

}

这有可能吗?

谢谢!

【问题讨论】:

  • 您是在寻找在不同环境下运行的 jar 还是仅在一个 jar 中会检测到缺失的依赖项并禁用某个功能
  • Maven 有项目,然后是模块。所以你可以创建 2 个依赖于基础项目的发布模块。每个都会以不同的方式组装,这取决于您的主要功能来检查功能中缺少的类并禁用或启用该功能
  • 与环境无关,更像是依赖。我认为我们可以将功能视为依赖项。我不知道,这会是使用 maven 实现这一目标的最佳方式吗?
  • 我明白了。我将尝试找到一个使用发布模块的示例。
  • 当你想过滤stackoverflow.com/questions/2424015/…时,这个问题可能会为 maven 的工作方式提供一些额外的信息

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


【解决方案1】:

既然可以变得简单,为什么还要让它变得复杂!

Pom 核心项目:

<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

【讨论】:

    【解决方案2】:

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

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

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

    这与 Maven 无关。这表明您正在尝试构建自己的模块系统。虽然这样做并非完全错误,但您可能需要考虑已经这样做的现有解决方案:

    • Java 的 service loader 可能是解决此问题的一种方法(在相对简单的情况下)。
    • OSGi 是模块化 Java 应用程序的事实上的标准。我知道很多人会争辩说(也许是由于过时的知识)它太重/太复杂了,但事实已不再如此。如果您想走这条路并从真正的模块化的力量中受益,您可以查看此base tutorial,它构建了多模块应用程序。该示例使用 bndtools,但您可以使用 the same with Maven

    【讨论】:

    • 我已经使用 osgi 多年,但由于依赖地狱问题和管理包的所有开销,我今年退出了。
    【解决方案3】:

    Maven 有项目,然后是模块。所以您可以创建 2 个依赖于基础项目的发布模块。他们可以发布不同的 jar。

    下面的模块在其源代码中只有配置文件。它基于包含依赖项构建应用程序。它还从这些依赖项中提取其他属性以在其构建中使用。

    您将遇到的问题是您需要使用反射来避免主应用程序中的构建问题。即如果它不能解决一个包含,它就不会编译。

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

    【讨论】:

      猜你喜欢
      • 2021-05-25
      • 1970-01-01
      • 2021-03-27
      • 1970-01-01
      • 2014-12-20
      • 2019-12-30
      • 2014-11-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多