I'm building a demo app with 2 different situations, first one is development and second one is production. This is my pom.xml
... (version, name, etc)
<properties>
<java.version>11</java.version>
<spring-cloud.version>2020.0.3</spring-cloud.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!--DEFAULT PROFILE-->
<env>development</env>
</properties>
<dependencies>
... (lombok, junit, swagger, datarest, datatest, web, webmvc...)
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<filters>
<filter>src/main/resources/${env}.yml</filter>
</filters>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>*.yml</include>
<include>*.xml</include>
<include>*.properties</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>development</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<start-class>com.central.CentralApplication</start-class>
<env>development</env>
</properties>
<dependencies>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
</dependencies>
</profile>
<profile>
<id>production</id>
<activation>
<property>
<name>production</name>
</property>
</activation>
<properties>
<env>production</env>
<start-class>com.central.CentralApplicationProd</start-class>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-eureka-client</artifactId>
<version>3.0.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.2.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
</profile>
</profiles>
</project>
There seems to be no problem in the pom, but when I try to create the main I need for production purposes, it can't find the Eureka and Feign dependencies (@EnableEurekaClient and @EnableFeignClients). On the other hand, if I change the <activeByDefault>true</activeByDefault>
and I put it in production profile, it loads its dependencies but, obviously, not the development ones.
How can I load both dependencies when coding? Is my approach wrong?
Thanks in advance!
CodePudding user response:
If you have a spring boot application you should not define any profile for any dependency.
If you need to have different configurations for dev, prod you should use spring profiles instead. That means you can define files like application.properties
(works also with .yml
) or application-dev.properties
which can simply being activated via --spring.profiels.active=dev
would mean to activate the application-dev.properties
.
Furthermore if you need the h2 database only for testing you should simply use the <scope>test</scope>
instead.
Which looks strange that you have defined the spring-boot-starter-actuator
dependency in your prod profile but not for dev.
Another thing is that you have defined <start-class>com.central.CentralApplication</start-class>
which is by default defined via the class which contains the @SpringBootApplication
annotation on it. This means you have only a single class for that purpose and it does not matter for which environment etc.
I strongly recommend to read the spring boot documentation etc. The question is why not defining for both.
Also I've seen that you have explicitly excluded lombok in the spring-boot-maven-plugin configuration. This means usually you have not correctly defined the dependency scope of lombok.
It is best practice not to define versions of dependencies yourself if you are using bom imports..otherwise you could have version mixtures which could cause issues.
One final recommendation is never use profiles to use different dependencies.
https://docs.spring.io/spring-boot/docs/current/reference/html/
CodePudding user response:
You should put shared dependencies outside of profiles tags in the main section of your pom file. Java classes in your code require this dependencies.
If you want to implement different logic in different environments, I recommend you to use different profiles on your Spring configuration files.