0

I'm trying to read from application.properties and I can't get it working.

this is my code:

package config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;

@Configuration
@PropertySource("classpath:application.properties")
public class PropertiesReader {

        @Autowired
        private Environment env;

        public String readProperty(String key) {
            return env.getProperty(key);
        }


}

this is where I invoke the readProperty:

public class JwtSettings {

    public String key;

    public long expiration;

    //The JWT signature algorithm we will be using to sign the token
    public SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

    public JwtSettings() {
        PropertiesReader propertiesReader = new PropertiesReader();
        key = propertiesReader.readProperty(ApplicationProperties.JWT_KEY.key);
    }

When I run this code, the env instance is null. My application.properties file is located in the resource folder. I'm out of ideas, please help.

Gal Sosin
  • 714
  • 7
  • 27
  • You are overthinking things. Spring Boot already reads the `application.properties` you don't need to do it again. – M. Deinum Dec 05 '17 at 08:19
  • so your'e saying I need to remove '@PropertySource("classpath:application.properties")' annotation ? – Gal Sosin Dec 05 '17 at 08:20
  • 1
    Yes and if you need properties just inject them with `@Value` or bind to a custom properties object (all of this is explained in the Spring Boot reference guide). – M. Deinum Dec 05 '17 at 08:21
  • I'm still getting null for the env instance – Gal Sosin Dec 05 '17 at 08:23
  • Then you are creating an instance yourself instead of letting Spring create one and inject it. – M. Deinum Dec 05 '17 at 08:25
  • can you please give me an example?? – Gal Sosin Dec 05 '17 at 08:30
  • As I saw in your comment, your JwtSettings class is used with @Service annotation and I guess it is instantiated by Spring. I cannot see any usage of any instance of your ApplicationService in your JwtSettings. Where do you use your ApplicationService? – L. Hanke Dec 05 '17 at 10:17
  • its a mistake, I was trying change some things – Gal Sosin Dec 05 '17 at 10:37

1 Answers1

1

Try to use your configuration like this:

@Service 
public class JwtSettings {

   private String key;

   private long expiration;

   //The JWT signature algorithm we will be using to sign the token
   public SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

   @Autowired
   public JwtSettings(PropertiesReader propertiesReader) {
      this.key = propertiesReader.readProperty(ApplicationProperties.JWT_KEY.key);
   }
}

You should never instantiate Spring managed components yourself (by invoking the constructor in your code). Instead you should use Spring Dependency-Injection via @Autowired to make sure that all your dependencies are resolved correctly.

To inject properties with Spring (generally):

If you try to get access to a property value from a property resource, try to inject it with Springs @Value annotation.

Your application.properties may look like:

myproperty.test1=mytestvalue
myproperty.test2=123

Now you have a Spring component, where you want to use the property values and you inject them like:

@Component
private class MyTestComponent {

   @Value("${myproperty.test1:mydefaultvalue}")
   private String test1Value;

   @Value("${myproperty.test2:-1}")
   private int test2Value;

}

Of course you can use other datatypes than String for your property.

L. Hanke
  • 116
  • 1
  • 5
  • I want to read the application.properties dynamically by using different 'keys' – Gal Sosin Dec 05 '17 at 08:25
  • So you have runtime computed keys you want to get resolved? Otherwise you can ofc inject ad many different properties by their keys as you want to. – L. Hanke Dec 05 '17 at 08:30
  • can you please give me an example? – Gal Sosin Dec 05 '17 at 08:31
  • I will adapt the above one, to show different keys by injection. For runtime computed keys you may want to have a look [here](https://stackoverflow.com/questions/10822951/how-do-i-get-a-property-value-from-an-applicationcontext-object-not-using-an-a). – L. Hanke Dec 05 '17 at 08:32
  • You say that your env instance is null. Maybe you try to access the instance (i.e. call readProperty) before Autowiring takes place as described [here](https://stackoverflow.com/questions/19421092/autowired-environment-is-null)? – L. Hanke Dec 05 '17 at 09:31
  • No that's not the case, because the readProperty is invoked in a endpoint – Gal Sosin Dec 05 '17 at 09:38
  • I guess your configuration is correctly created by Spring and injected into your Controller/Service? Could you please try to inject the Environment directly into your Controller/Service? – L. Hanke Dec 05 '17 at 09:42
  • I don't really understand what do you mean by injecting the Environment to My Controller/Service can you please add some more details ? – Gal Sosin Dec 05 '17 at 09:44
  • Can you please show me how exactly you call your readProperty function? – L. Hanke Dec 05 '17 at 09:50
  • @Service public class JwtSettings { public String key; public long expiration; //The JWT signature algorithm we will be using to sign the token public SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; public JwtSettings() { PropertiesReader propertiesReader = new PropertiesReader(); key = propertiesReader.readProperty(ApplicationProperties.JWT_KEY.key); } } – Gal Sosin Dec 05 '17 at 09:52
  • Can you please add this with code formatting to your question, so I can open another answer? – L. Hanke Dec 05 '17 at 09:58
  • have a look now – Gal Sosin Dec 05 '17 at 10:02
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/160494/discussion-between-l-hanke-and-gal-sosin). – L. Hanke Dec 05 '17 at 10:21