Spring-Boot multi module unable to read properties file from another module

11,382

Solution 1

After looking in Mikhail Kholodkov post(Thanks!),

The solution is to add the following annotation to the using service Execution point:

 @PropertySources({
    @PropertySource("classpath:jwtConfig.properties"),
    @PropertySource("classpath:app.properties")
})
public class OtherServiceApplication {
public static void main(String[] args) {
    SpringApplication.run(OtherServiceApplication.class, args);
    }
}

Solution 2

I think instead of using @PropertySources , the better approach and more suitable one would be to use @ComponentScan in your module that contains the "main method". Since you would need an instance of JWTConfiguration class rather than the actual .property file, it is more recommended to expose the bean and make springboot scan it from another module, rather than to expose the property file (because that makes the jwtConfiguration.java file in another module rather useless.) So you could probably try something like this

Say we have two modules - Module1 and Module2 inside the main module (that has only pom). I presume you know the drill that the no-code module just packages the app as "pom" and describes the dependant modules inside

Your main pom

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>XXX</groupId>
    <artifactId>XXXX</artifactId>
    <packaging>pom</packaging>
    <version>1.0</version>
    <name>ws-cms-engine</name>
    <url>http://maven.apache.org</url>
    <properties>
        <spring-boot.version>2.0.0.RELEASE</spring-boot.version>
        <spring-kafka.version>2.2.3.RELEASE</spring-kafka.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <!-- Import dependency management from Spring Boot -->
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
............
............
    <modules>
      <module>Module1</module>
      <module>Module2</module>
    </modules>

Now lets consider that your JWTConfiguration is in Module1 and it uses the property file in the resources folder declared - application.properties

Sample JWTConfiguation.java file

package common.module2.config
@Configuration
@PropertySources("classpath:application.properties")
public class JWTConfiguration{

  @Value("${config1}")
  private String someConfig;


}

Now if your Module2, has the main class that needs to make use of this configuration then probably something like this would make sense

We need to make the SpringBoot container read from the bean declared in module1 rather than read the actual property file

@ComponentScan(basepackages={"common.module2.config", "common.module1.this.config"})
@SpringBootApplication
public class Application(){
    public static void main(String args[]){
     SpringApplication.run(Application.class);
   }
}

So here we inform that beans declared in module2 package needs to be scanned by the spring container when it starts and initializes

Now you can Autowire the bean in your required service and use it

@Service
public class SampleService{
   @Autowired
   JWTConfiguration config;

}

That should autowire the managed instance of JWTConfiguration for you to use

Share:
11,382

Related videos on Youtube

Roie Beck
Author by

Roie Beck

Hi all, A software dev for the last 9 years, Had a startup that failed, but had a great time failing, Currently working for citi innovation labs, love to ask and be asked question that is the only way you learn in my opinion...

Updated on June 04, 2022

Comments

  • Roie Beck
    Roie Beck almost 2 years

    I have searched High and low and still I am unable to find a simple answer to this very annoying problem,

    I have followed this great guide: JWT with multi service app Everything works great but in the end of the guide we are suggested to create a config-service(module) , which I have done.

    The problem is that I am unable to override the default configuration of JwtConfig class

    The project structure is as follows:

    -config-service 
    
        | JwtConfig.java
         \
            | resources 
            \
             | jwtConfig.properties
    
     -other-service (add dependency in the pom file of the config-service)
         |
           someOtherclass.java (import the JwtConfig class & using @Bean to initialize )
    

    The JwtConfig class:

    /*all the imports*/ 
    @PropertySource(value = "classpath:jwtConfig.properties")
    public class JwtConfig {
    
    @Value("${security.jwt.uri:/auth/**}")
    private String Uri;
    
    @Value("${security.jwt.header:Authorization}")
    private String header;
    
    @Value("${security.jwt.prefix:Bearer }")
    private String prefix;
    
    @Value("${security.jwt.expiration:#{24*60*60}}")
    private int expiration;
    
    @Value("${security.jwt.secret:JwtSecretKey}")
    private String secret;
    
     //getters
    

    The someOtherclass.java:

    /*imports*/
    
    @Configuration
    @EnableWebSecurity
    public class SecurityCredentialsConfig  extends WebSecurityConfigurerAdapter 
    { 
    
       private JwtConfig jwtConfig; 
    
       @Autowired
       public void setJwtConfig(JwtConfig jwtConfig) {
           this.jwtConfig = jwtConfig;
       }
       @Bean
       public JwtConfig jwtConfig() {
        return new JwtConfig();
       }
       /*other code*/
    

    The problem is that it does not matter what parameters I put in the jwtConfig.properties file,

    For example:

       security.jwt.uri=test 
    

    It will not appear in the JwtConfig bean when the other service loads it.

    Only the default @Value's are loaded.

    can someone have any advice? how may I fix it? Many thanks!

  • Roie Beck
    Roie Beck about 5 years
    please close artifactId opening xml tab, I ended up using spring's config server, IMHO it is currently the best solution for providing configuration(with profile) to any environment, monolith or microServices
  • vijayakumarpsg587
    vijayakumarpsg587 about 5 years
    @RoieBeck thank you. I typed the code in stackoverflow and hence did not look at the closures. I've corrected it. Using spring boot cloud is actually the best way as well. that is a really welcome addition. If possible could you post your answer as well.