简体   繁体   中英

Multiple Maven profiles activate multiple Spring profiles

I want to put together an environment in Maven, where I want to activate multiple spring profiles cumulatively depending on what Maven profiles are active.

Currently the relevant part of my pom.xml looks like this:

<profiles>
    <profile>
        <id>local-db-development</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>

        <dependencies>
            <dependency>
                <groupId>com.h2database</groupId>
                <artifactId>h2</artifactId>
                <scope>runtime</scope>
            </dependency>
        </dependencies>
        <properties>
            <spring.profiles.active>local-db</spring.profiles.active>
        </properties>
    </profile>
    <profile>
        <id>live-db-development</id>
        <dependencies>
            <dependency>
                <groupId>org.postgresql</groupId>
                <artifactId>postgresql</artifactId>
                <scope>runtime</scope>
            </dependency>
        </dependencies>
        <properties>
            <spring.profiles.active>live-db</spring.profiles.active>
        </properties>
    </profile>
    <profile>
        <!--
        If active, the user authentication will be through LDAP and AD,
        Database auth will be used otherwise
         -->
        <id>ldap-authentication</id>
        <properties>
            <spring.profiles.active>ldap-authentication</spring.profiles.active>
        </properties>

        <dependencies>
            <dependency>
                <groupId>org.springframework.security</groupId>
                <artifactId>spring-security-ldap</artifactId>
            </dependency>
            <dependency>
                <groupId>org.apache.directory.server</groupId>
                <artifactId>apacheds-server-jndi</artifactId>
                <version>1.5.5</version>
            </dependency>
        </dependencies>
    </profile>
</profiles>

My problem is that when I activate ldap-authentication profile, only the relevant spring profile will be active, not taking into account any of the *-db profiles.

I'd like to make it so that I can activate the ldap-authentication and local-db maven profiles and then both relevant spring profiles should be activated, or when I activate let's say ldap-authentication and live-db in maven, then those 2 spring profiles will be active.

I haven't really found a way to concat the spring profiles, so if you know better, let me know.

Thanks in advance

I faced a similar problem where I had to use either Artemis or RabbitMQ component based on the spring profile but also wanted to include other profiles (eg dev, prod).

I did this in my pom.xml:

    <profiles>
    <profile>
        <id>artemis</id>
        <activation>
            <property>
                <name>messaging.service</name>
                <value>artemis</value>
            </property>
        </activation>

        <properties>
            <includeSpringProfile>artemis-profile</includeSpringProfile>
        </properties>
    </profile>

    <profile>
        <id>rabbitmq</id>
        <activation>
            <property>
                <name>!messaging.service</name>
            </property>
        </activation>

        <properties>
            <includeSpringProfile>rabbitmq-profile</includeSpringProfile>
        </properties>
    </profile>
</profiles>

And this in my application.yml

spring:
  profiles.include: @includeSpringProfile@

Now when I run: mvn spring-boot:run -Dspring-boot.run.arguments=--spring.profiles.active=prod

Both prod and rabbitmq profiles are activated:

2019-12-11 18:46:52.296  INFO 837 --- [  restartedMain] c.l.tacocloud.TacoKitchenApplication     : The following profiles are active: rabbitmq-profile,prod

Reference: Spring boot adding active profiles

Okay, I found one solution: You need a groovy plugin, which looks like this:

<plugin>
            <groupId>org.codehaus.gmavenplus</groupId>
            <artifactId>gmavenplus-plugin</artifactId>
            <version>1.6</version>
            <dependencies>
                <dependency>
                    <groupId>org.codehaus.groovy</groupId>
                    <artifactId>groovy-all</artifactId>
                    <version>2.4.9</version>
                    <scope>runtime</scope>
                </dependency>
            </dependencies>
            <executions>
                <execution>
                    <id>concatMavenProfiles</id>
                    <phase>initialize</phase>
                    <goals>
                        <goal>execute</goal>
                    </goals>
                    <configuration>
                        <scripts>
                            <script><![CDATA[
                                def value = ""
                                (project.activeProfiles).each{ profile -> value += profile.properties.springProfiles + "," }
                                project.properties.setProperty('spring.profiles.active', value.substring(0, value.length() - 1))
                            ]]>
                            </script>
                        </scripts>
                    </configuration>
                </execution>
            </executions>
        </plugin>

This scripts gets all <springProfiles> properties from the active profiles and concatenates them into one string. It then sets the <spring.active.profiles> property in the main <properties> tag.

I switched <spring.profiles.active> tag in the profiles to <springProfiles>, so that they have 0 chance of clashing and overwriteing one another.

In my experience, you also need to define an empty <spring.profiles.active> tag in the project <properties> tag.

I solved multiple profile selections by using different variables and setting them in a list in the applications.yml file.

@activeEnv@ - to set the environment @activeClient@ - to set the client

This is an example of my application.yml file:

spring:
  profiles:
    active:
      - @activeEnv@
      - @activeClient@

In the pom.xml I set the profiles like this:

<profiles>
    <!-- Environment Profiles -->
    <profile>
        <id>production</id>
        <properties>
            <activeEnv>production</activeEnv>
        </properties>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
    </profile>
    <profile>
        <id>development</id>
        <properties>
            <activeEnv>development</activeEnv>
        </properties>
    </profile>
    <!-- Environment Profiles -->
    <!-- Tax Client Profiles -->
    <profile>
        <id>clientA</id>
        <properties>
            <activeTaxClient>ClientA</activeTaxClient>
        </properties>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
    </profile>
    <profile>
        <id>clientB</id>
        <properties>
            <activeTaxClient>ClientB</activeTaxClient>
        </properties>
    </profile>
    <!-- Client Profiles -->
</profiles>

This setting results in the following:

org.springframework.boot.SpringApplication: The following 2 profiles are active: "production", "clientA"

Note : if you use IntelliJ remember to click the refresh button after selecting the desired profiles

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM