Maven配置文件激活属性不适用于依赖项目吗?

时间:2015-03-07 06:01:40

标签: java eclipse maven

我需要使用相同的父pom文件支持多种类型的客户端构建。对我来说,挑战是不同的客户将使用略有不同的库。例如,一个客户端可能使用SQL服务器而另一个客户端可能使用MySQL。这是一个简单的例子,但其他图书馆可能包括那些可能需要我们内部没有的许可证的图书馆,但我们的客户会有。不在内部排除它们会导致mavens不再进行构建,因为库不会出现在我们的存储库中。我最初的想法是在我们的父pom中为每个客户端创建一个配置文件,然后定义在这些配置文件中仅用于该客户端的任何依赖项。这些简档将由没有财产或具有特定价值的财产激活。当涉及多个模块时,我遇到了解决依赖关系的问题,特别是当一个孩子是另一个孩子的依赖时。我相信问题的关键在于在解决过程中触发配置文件未在某个时刻设置的变量,但让我举一个简单的例子:

家长pom:

<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">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.test</groupId>
  <artifactId>parent</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>pom</packaging>

  <modules>
    <module>../child-a</module>
    <module>../child-b</module>
  </modules>

<profiles>
    <profile>
        <id>client-a</id>
        <activation>
            <property>
                <name>!clientbuild</name>
            </property>
        </activation>
        <dependencies>
            <dependency>
                <groupId>com.microsoft.sqlserver</groupId>
                <artifactId>sqljdbc4</artifactId>
                <version>4.0</version>
            </dependency>
        </dependencies>
    </profile>
    <profile>
        <id>client-b</id>
        <activation>
            <property>
                <name>clientbuild</name>
                <value>clientb</value>
            </property>
        </activation>
        <dependencies>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.34</version>
            </dependency>
        </dependencies>
    </profile>
  </profiles>
</project>

我在父pom中定义了client-a和client-b配置文件。客户端 - 配置文件应在缺少&#34; clientbuild&#34;财产和&#34;客户-b&#34; &#34; clientbuild&#34; property设置为&#34; clientb&#34;。如果我运行dependency:tree on parent并指定&#34; clientb&#34;在我的maven用户&#34; setting.xml&#34;文件,我得到以下内容:

--- maven-dependency-plugin:2.8:tree (default-cli) @ parent ---
com.test:parent:pom:0.0.1-SNAPSHOT
\- mysql:mysql-connector-java:jar:5.1.34:compile

--- maven-dependency-plugin:2.8:tree (default-cli) @ child-a ---
com.test:child-a:jar:0.0.1-SNAPSHOT
\- mysql:mysql-connector-java:jar:5.1.34:compile

--- maven-dependency-plugin:2.8:tree (default-cli) @ child-b ---
com.test:child-b:jar:0.0.1-SNAPSHOT
+- com.test:child-a:jar:0.0.1-SNAPSHOT:compile
|  \- com.microsoft.sqlserver:sqljdbc4:jar:4.0:compile
\- mysql:mysql-connector-java:jar:5.1.34:compile

&#34;父&#34;和&#34;孩子-a&#34;项目具有正确的依赖关系,但是&#34; child-b&#34;具有两个配置文件的依赖关系。从树上我可以看到包含了不正确的依赖,因为maven相信&#34; child-a&#34;具有sqljdbc的依赖关系。我的信念是,在建筑的同时,maven正在捡起孩子 - 一个&#34;并且不使用&#34; clientbuild&#34;从父pom解析它的依赖关系。我在maven中设置的属性&#34; settings.xml&#34;文件。有没有办法让maven使用&#34; clientbuild&#34;整个依赖关系解析过程中的属性?

通过各种实验,我确定如果我要删除&#34;!clientbuild&#34;并将其替换为特定值的检查(然后在我的settings.xml中指定该值),或者如果我没有激活要求并使用-P手动触发配置文件,我会得到所需的结果。不幸的是,我们不能强制我们的第一个客户端在构建过程中使用-P或指定任何其他参数,因此使用缺少&#34; clientbuild&#34;属性是我此时可用于&#34; client-a&#34;的唯一激活检查。另外,如果我用&#34; activeByDefault&#34;替换此检查,我在添加&#34; clientb&#34;时会得到与上面相同的行为。作为我的&#34; settings.xml&#34;的属性文件。

所以,鉴于所有这一切,我的问题是:我试图做的甚至可能吗?我知道我的要求很不寻常。理想情况下,我希望在构建期间始终指定配置文件,但不幸的是,这对我们的客户来说是不可能的。

简而言之,我需要默认激活一个包含某些依赖项的配置文件,但如果属性激活,这些依赖项将被另一个配置文件中的另一组依赖项替换。另外,当属于同一父节点的某些模块彼此依赖时,这需要工作,如上所示。任何人都有这方面的经验或有任何其他可以尝试的方法吗?

作为最后一个脚注,我使用Eclipse(特别是Spring Tool Suite)和随附的嵌入式Maven 3。

编辑(子POM和settings.xml): 根据要求,这里是儿童-a和儿童-B的POM。我还包含了我的用户settings.xml文件,当我尝试应用&#34; clientbuild&#34;属于&#34; clientb&#34;。

child-a POM:

<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">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.test</groupId>
    <artifactId>parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>child-a</artifactId>
  <packaging>jar</packaging>
</project>

child-b POM:

<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">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.test</groupId>
    <artifactId>parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
  </parent>
  <artifactId>child-b</artifactId>
  <packaging>jar</packaging>

  <dependencies>
    <dependency>
        <groupId>com.test</groupId>
        <artifactId>child-a</artifactId>
        <version>${project.version}</version>
    </dependency>
  </dependencies>
</project>
clientb&#34; clientbuild&#34;

settings.xml财产有效:

<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" 
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">

  <pluginGroups>
  </pluginGroups>

  <proxies>
  </proxies>

  <servers>
  </servers>

  <mirrors>
  </mirrors>

  <profiles>
   <profile>
    <id>client-profile</id>
    <activation>
        <activeByDefault>true</activeByDefault>
    </activation>
    <properties>
        <clientbuild>clientb</clientbuild>
    </properties>
   </profile>
  </profiles>
</settings>

我还尝试设置标签以激活&#34;客户端构建&#34;我的settings.xml中的配置文件,而不是使用activeByDefault标记,但这产生了相同的结果。

编辑2(澄清关系和使用JVM参数):为了澄清,client-a / client-b配置文件对child-a / child-b模块之间的关系没有影响。无论情况如何,这种关系都是孩子-b依赖于孩子-a。 client-a / client-b配置文件唯一影响的是sqljdbc或mysql-connector-java是否作为父依赖项添加。

至于在命令行使用的clientbuild变量。传递-Dclientbuild = clientb将产生所需的依赖树。

--- maven-dependency-plugin:2.8:tree (default-cli) @ parent ---
com.test:parent:pom:0.0.1-SNAPSHOT
\- mysql:mysql-connector-java:jar:5.1.34:compile

--- maven-dependency-plugin:2.8:tree (default-cli) @ child-a ---
com.test:child-a:jar:0.0.1-SNAPSHOT
\- mysql:mysql-connector-java:jar:5.1.34:compile

--- maven-dependency-plugin:2.8:tree (default-cli) @ child-b ---
com.test:child-b:jar:0.0.1-SNAPSHOT
+- com.test:child-a:jar:0.0.1-SNAPSHOT:compile
\- mysql:mysql-connector-java:jar:5.1.34:compile

但是,我想/需要使用settings.xml的原因是因为在修复手动maven构建时使用命令行参数并不能解决Eclipse的嵌入式Maven仍将解决的问题。我在上面的初始依赖关系中显示的依赖关系:树输出(child-b将具有两个配置文件的依赖关系,而不仅仅是client-b配置文件)。这本身是可以接受的(即使行为不像预期的那样),但是我们没有激活配置文件中的某些依赖项,而这些依赖项不应该是(来自客户端 - 配置文件)到期许可和其他原因。如果存在两个配置文件的依赖关系,则会导致Eclipse中出现许多缺失的工件错误。

1 个答案:

答案 0 :(得分:1)

我发现以下内容:

  1. child-b使用settings.xml中设置的属性从父级激活正确的配置文件

  2. child-a在child-b的依赖项解析期间没有继承此属性,因此激活了错误的配置文件。我无法完全解释为什么属性没有被继承,但我能想到的唯一解释是该属性仅适用于正在构建的项目而不是它的依赖项。我不确定我是否认为这应该是行为,但这是我所观察到的。

  3. <强> TLDR

    为了解决上述问题,我最终要做的是将两个配置文件中的所有依赖项设置为可选,使用:true。由于可选的副作用/功能之一禁用了传递性,因此正在构建的任何给定项目(在这种情况下为child-b)将激活正确的配置文件,但是具有相同父项的任何其他项目依赖项将不会继承不正确的依赖项。请注意,child-a的错误配置文件仍将被激活,因此如果配置文件中有其他标签(例如插件或其他内容),这些仍将被错误激活。这在我的用例中不是问题,因为配置文件只包含依赖项。