1

I’ve run across a Spring Issue that I need your help with. I'm trying to change from reading the following from a properties file to autowiring it directly into the class:

#Supported Versions of Tools
language.python=2.7.1
language.java=1.8
language.scala=2.10

The problem is that I want to be able to easily add additional languages. When it was a properties file, I was using the command String supportedVersion = props.getProperty("language." + language.toLowerCase());. After doing some research online I through the solution from this StackOverflow question would work nicely so I modified the code to be:

 @Component("PropertiesAnalyzer")
public class PropertiesAnalyzer implements FileAnalyzer, java.io.Serializable {

           @Autowired
       private Environment environment;
       …
       public boolean validLanguageVersion(String version, String language) {
              if (version == null) {
                     // assume default
                     return true;
              }
              // Get supported version from file
              String supportedVersion = getLanguageVersion(language);

              // Compare the provided versions
              if (compareVersions(version, supportedVersion) != -1)
                     return true;
              return false;
       }
       
       private String getLanguageVersion(String language){
              return environment.resolvePlaceholders("${language." + language.toLowerCase() + "}");
       }

But that returned a value of ${language.java} instead of 1.8 when I ran the unit test:

public class PropertiesAnalyzerTest {

       private static PropertiesAnalyzer analyzer;
       
       @BeforeClass
       public static void setUpBeforeClass() throws Exception {
              ApplicationContext applicationContext = new AnnotationConfigApplicationContext("com.my.package");
              analyzer = (PropertiesAnalyzer) applicationContext.getBean("PropertiesAnalyzer");
       }
       @Test
       public void testValidLanguage_java() {
              assertTrue(analyzer.validLanguageVersion("1.9", "java"));
       }
}

So then I tried updating my code to be:

private String getLanguageVersion(String language){
          String property = "language." + language.toLowerCase();
          return environment.getProperty(property);
   }

but environment.getProperty(property) returns null. I know it can read the properties file because if I update the code to use @Value the correct information is printed out.

       @Autowired
       private ApplicationContext applicationContext;
       private Environment environment;
       
       @Value("${language.java}")
       private String languageJava;

       /**
       * Empty constructor
       */
       public PropertiesAnalyzer() {
              System.out.println("Test");
       }
       
       @PostConstruct
       public void init(){
              System.out.println("TestInit");
              environment = applicationContext.getEnvironment();
              System.out.println("LanguageJava = " + languageJava);
              System.out.println("Environment: " + environment.getProperty("language.java"));   
              System.out.println("EnvironmnetResolver: " + environment.resolvePlaceholders("${language.java}"));
       }

which prints out:

Test
TestInit
LanguageJava = 1.8
Environment: null
EnvironmnetResolver: ${language.java}

What am I doing wrong? Why can't I read the properties from the file out of the environment?

Note - I am declaring the PropertyPlaceholderConfigurer to specify where the properties file is in a different class.

Community
  • 1
  • 1
jencoston
  • 1,262
  • 7
  • 19
  • 35

1 Answers1

0

I've faced similar issue during test execution. To fix it i've registered desired properties source in environment in next way:

@Configuration
public class SomeConfiguration {

   @Bean
   public PropertyPlaceholderConfigurer propertyPlaceholderConfigurer(Environment e) {
      ((StandardServletEnvironment)e).getPropertySources().addLast(new ResourcePropertySource("<path-to-properties-file>"));
   }
}

Afterwards you may access desired property in way you've mentioned in your code.

Hope this helps.

nndru
  • 2,057
  • 21
  • 16