Search code examples
javamavenspring-bootmaven-profiles

How to manage maven profiles through annotations/pom.xml?


Ref - Maven Profiles


I don't want to specify profile through command line arguments while running. Because, if I change it locally, then changes have to be made thoughout CI stream.


Scenario:

There are basically two profiles "PROD" and "TEST". I have annotated methods using these. Basically, I connect different databases under different profiles.

While the test classes are annotated with @ActiveProfile("TEST")

I run tests using mvn clean test-compile failsafe:integraton-test and run application using mvn springboot:run


Problem:

Case 1:
Issue: Only PROD related methods run for PROD and TEST.

If I don't use @Profile("PROD") and only use @Profile("TEST") and I use @ActiveProfiles("TEST") as specified in reference. Both mvn commands without any flag specified above only use the beans which are not annotated with profiles.
 

Case 2:
Issue: PROD doesn't run.

If I use both PROD and TEST without any flag, mvn clean test-compile failsafe:integraton-test command runs perfectly (only when @ActiveProfile("TEST") is specified otherwise I'd have to send a flag -Dspring.profiles.active=TEST) but springboot:run doesn't work as it cannot pick up any database configuration and no active profile found.

This is the case even when I Annotate PROD profiles with both PROD and @Primary

Surprisingly even If I provide command line argument the result is the same. mvn springboot:run -Dspring.profiles.active=PROD

If I annotate the main class where these profiles are run with @ActiveProfiles("PROD"), the result is the same.
 


Ideal Scenario/Expected:

To run tests using mvn test-compile failsafe:integration-test preferably without flag. (Already acheived but prod isn't working)

To run prod using mvn springboot:run emphasis of no flags.


Preferable changes:

Java annotations: Annotations such as @Profile, @ActiveProfile, @Primary which tells Spring-boot or maven what to use.

POM.xml: setting profiles for directing maven what to use.


Solution

  • in short i think you just need to add spring.profiles.active=PROD to your application.properties

    I put together an example which prints the contents of a bean which differs between prod ant test, hope this helps.

    When running the below code i get the following output:

    mvn spring-boot:run: The String in the context is: PROD

    mvn clean test: The String in the context is: TEST

    ProfilesApplication.java:

    @SpringBootApplication
    public class ProfilesApplication implements CommandLineRunner {
    
        Logger logger = LoggerFactory.getLogger(ProfilesApplication.class);
    
        @Autowired
        private String profiledString;
    
        public static void main(String[] args) {
            SpringApplication.run(ProfilesApplication.class, args);
        }
    
        @Bean
        @Profile("PROD")
        public String prodString() {
            return new String("PROD");
        }
    
        @Bean
        @Profile("TEST")
        public String testString() {
            return new String("TEST");
        }
    
        @Override
        public void run(String... args) throws Exception {
            logger.info("The String in the context is: {}", profiledString);
        }
    }
    

    application.properties:

    spring.profiles.active=PROD
    

    ProfilesApplicationTests.java:

    @RunWith(SpringRunner.class)
    @SpringBootTest
    @ActiveProfiles("TEST")
    public class ProfilesApplicationTests {
    
        @Test
        public void contextLoads() {
        }
    }