Search code examples
mavenspring-bootliquibasemulti-module

it always loads properties from a wrong path when I run a springboot application


Background:

We have a multi-module project which consists of four modules "assembly","configservice","adminservice" and "portal".And the dependencies between modules go like this, "configservice","adminservice" and "portal" are all dependency of "assembly".What "assembly" do is only to determine which application("portal","adminservice" and "configservice") to run.

Situation:

When I choose to run portal, It always load bootstrap.yml from configservice instead of portal.And also it loads other resources(like liquibase's property) from configservice's classpath not from portal's.
AssemblyApplication.java.assembly's entry class, also the only class "assembly" has:
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class,
    HibernateJpaAutoConfiguration.class})
public class AssemblyApplication {

  private static final Logger logger = LoggerFactory.getLogger(AssemblyApplication.class);

  public static void main(String[] args) throws Exception {
    ConfigurableApplicationContext commonContext =
        new SpringApplicationBuilder(AssemblyApplication.class).web(false).run(args);
    commonContext.addApplicationListener(new ApplicationPidFileWriter());

    // Run configservice
    if (commonContext.getEnvironment().containsProperty("configservice")) {
      ConfigurableApplicationContext configContext =
          new SpringApplicationBuilder(ConfigServiceApplication.class).parent(commonContext)
              .sources(RefreshScope.class).run(args);
    }

    // Run adminservice
    if (commonContext.getEnvironment().containsProperty("adminservice")) {
      ConfigurableApplicationContext adminContext =
          new SpringApplicationBuilder(AdminServiceApplication.class).parent(commonContext)
              .sources(RefreshScope.class).run(args);
    }

    // Run portal
    if (commonContext.getEnvironment().containsProperty("portal")) {
      ConfigurableApplicationContext portalContext =
          new SpringApplicationBuilder(PortalApplication.class).parent(commonContext)
              .sources(RefreshScope.class).run(args);
    }
  }
}

File structures:

configservice:
  -configservice
    -src
      -main
        -java
        -resources
          -liquibase
            -changelog.xml
        -application.yml
        -bootstrap.yml

adminservice:
  -adminservice
    -src
      -main
        -java
        -resources
          -application.yml
          -bootstrap.yml

portal:
  -portal
    -src
      -main
        -java
        -resources
          -liquibase
            -changelog.xml
        -application.yml

Properties content

configservice's bootstrap.yml
endpoints:
  health:
    sensitive: false

management:
  security:
    enabled: false
  health:
    status:
      order: DOWN, OUT_OF_SERVICE, UNKNOWN, UP

spring:
  datasource:
    continue-on-error: true
    platform: h2
  jpa:
    show-sql: true
    properties:
      hibernate:
        dialect: org.hibernate.dialect.H2Dialect
    hibernate:
      ddl-auto: none


liquibase:
  change-log: classpath:liquibase/changelog.xml
  user:
  password:
  url: 
${spring_datasource_url:jdbc:h2:~/.h2/default/configdb;AUTO_SERVER=TRUE}
  enabled: true
  drop-first: false
configservice's application.yml
spring:
  application:
    name: configservice
  profiles:
    active: ${active_profile}

server:
  port: ${config_port:8330}

logging:
  file: /opt/logs/configservice.log
portal's application.yml
spring:
  application:
    name: portal
  profiles:
    active: ${active_profile}
  datasource:
    continue-on-error: true
    platform: h2
  jpa:
    show-sql: true
    properties:
      hibernate:
        dialect: org.hibernate.dialect.H2Dialect
    hibernate:
      ddl-auto: none

server:
  port: 9080

logging:
  file: /opt/logs/100003173/portal.log

endpoints:
  health:
    sensitive: false
management:
  security:
    enabled: false
  health:
    status:
      order: DOWN, OUT_OF_SERVICE, UNKNOWN, UP

liquibase:
  change-log: classpath:liquibase/changelog.xml
  user:
  password:
  url: ${spring_datasource_url}
  enabled: true
  drop-first: false

Solution

  • The configservice.jar (or whatever name the artifact of your build is named) is the first in the classpath and wins.

    You should externalize your configuration or name your property files differently in each module.

    How to use a different name you can find here:

    http://roufid.com/rename-spring-boot-application-properties/