Exclude dependency in a profile

后端 未结 6 1848
别那么骄傲
别那么骄傲 2021-02-06 23:49

I have a maven module which has some dependencies. In a certain profile, I want to exclude some of those dependencies (to be exact, all dependencies with a certain group id). Th

相关标签:
6条回答
  • 2021-02-07 00:28

    To my knowledge, no, you can't deactivate dependencies (you can exclude transitive dependencies but this is not what you are asking for) and yes, what you are currently doing with the POM (manually editing it) is wrong.

    So, instead of removing dependencies, you should put them in a profile and either:

    • Option #1: use the profile when required or
    • Option #2: mark the profile as activated by default or put it in the list of active profiles and deactivate it when required.

    A third option would be (not profile based):

    • Option #3: separate things in two separated modules (as you have separated concerns) and use inheritance.
    0 讨论(0)
  • 2021-02-07 00:29

    Instead of excluding dependencies in a profile, you can set them as provided in it. This doesn't require any overly complex configuration and will exclude the dependencies you don't want from the final build.

    In the desired profile, add a dependencies section, copy the declaration of the ones you want to exclude and scope them as provided.

    For example, let say you want to exclude slf4j-log4j12:

    <profiles>
    
        <!-- Other profiles -->
    
        <profile>
            <id>no-slf4j-log4j12</id>
            <dependencies>
                <dependency>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-log4j12</artifactId>
                    <version>1.7.2</version>
                    <scope>provided</scope>
                </dependency>
            </dependencies>
        </profile>
    
        <!-- Other profiles -->
    
    </profiles>
    
    0 讨论(0)
  • 2021-02-07 00:38

    I don't think it is possible to exclude direct dependencies either (at least, nothing is mentioned here).

    The best thing you can do is to enclose the desired dependencies for each case into different profiles (as suggested already), but, you'll need to create two "mutually exclusive" profiles with the one of them "active by default". The most reliable way to achieve this is by using a parameter for your profile activation e.g.

    <profiles>
      <profile>
        <id>default-profile</id>
        <activation>
          <property><name>!exclude</name></property>
        </activation>
        <dependencies>
          dependency-A
          dependency-B
          ...
        </dependencies>
      </profile>
    
      <profile>
        <id>exclude-profile</id>
        <activation>
          <property><name>exclude</name></property>
        </activation>
        <!-- exclude/replace dependencies here -->
      </profile>
    </profiles> 
    

    Then using "mvn [goal]" will use profile "default-profile", but "mvn [goal] -Dexclude" will use profile "exclude-profile".

    Note that using 'activeByDefault' instead of a parameter for your "default" profile might work in some cases but it also might lead to unexpected behavior. The problem is that 'activeByDefault' makes a profile active as long as there is no other active profile in any other module of a multi-module build.

    0 讨论(0)
  • 2021-02-07 00:45

    One way that occurs to me is to have the dependencies in a separate pom. You can then add an <exclusions> section via the profile.

    <dependencies>
        <dependency>
            <groupId>my.company.dependencies</groupId>
            <artifactId>my-dependencies</artifactId>
            <version>1.0.0-SNAPSHOT</version>
            <type>pom</type>
        </dependency>
    </dependencies>
    
    <profile>
        <activation>
            <activeByDefault>false</activeByDefault>
            <property>
                <name>exclude-deps</name>
            </property>
        </activation>
    
        <dependencies>
            <dependency>
                <groupId>my.company.dependencies</groupId>
                <artifactId>my-dependencies</artifactId>
                <version>1.0.0-SNAPSHOT</version>
                <type>pom</type>
                <exclusions>
                    <exclusion>
                        <groupId>my.company</groupId>
                        <artifactId>bad-dep-1</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>my.company</groupId>
                        <artifactId>bad-dep-2</artifactId>
                    </exclusion>
                </exclusions>
           </dependency>
    </dependencies>
    </profile>
    
    0 讨论(0)
  • 2021-02-07 00:48

    maven is a tool, we can hack it.

    • maven runs fine if you have the same artifact + version defined as dependency twice.
    • define a profile that eliminates an artifact + version by changing it to another package we already have.

    For example, in the pom.xml:

    ... other pom stuff ...
      <properties>
        <artifact1>artifact1</artifact1>
        <artifact2>artifact2</artifact2>
        <artifact1.version>0.4</artifact1.version>
        <artifact2.version>0.5</artifact2.version>
      </properties>
    
      <profile>
        <id>remove-artifact2</id>
        <properties>
          <artifact1>artifact1</artifact1>
          <artifact2>artifact1</artifact2>
          <artifact1.version>0.4</artifact1.version>
          <artifact2.version>0.4</artifact2.version>
        </properties>
      </profile>
    
    • Now if you install this pom.xml without the profile, artifact1:0.4 and artifact2:0.5 will be the dependency.
    • But if you install this pom.xml with the profile mvn -P remove-artifact2 The result pom.xml contains only artifact1:0.4

    This comes quite handy during api migration where artifact are renamed and versions are not compatible.

    0 讨论(0)
  • 2021-02-07 00:51

    Bit dirty but lightweight solution is to use <scope>import</scope>.

    Unlike the other scopes you could use this:

    • will disable compile-time and runtime dependecies; unlike provided or runtime which disables only one at a time
    • won't mess up your test scope
    • you don't need to specify path to some dummy jar as would system scope require

    Nothing gets imported as long as you use this hack outside dependencyManagement.

    0 讨论(0)
提交回复
热议问题