5

I have an issue with Spring, I have to load a system property using an annotation.

I'm trying this approach:

@Value("${mySystemProperty}")
private String mySystemPropertyValue;

But when I make this:

System.out.println("mySystemPropertyValue="+mySystemPropertyValue);
System.out.println("system.mySystemProperty="+System.getProperty("mySystemProperty"));

It returns:

mySystemPropertyValue=null
system.mySystemProperty=myValue

What's wrong?

Thanks

EDIT

I'm trying all, but I always get in return a null value for every System property.

I also tried:

@Autowired
private Environment environment;

But the "environment" variable is null...

Alessandro C
  • 3,310
  • 9
  • 46
  • 82
  • 2
    Try this: http://stackoverflow.com/questions/6285978/is-there-any-syntax-like-systempropertiesenvironment-variable-name-to-g – rapasoft Apr 18 '16 at 09:54
  • Where is the `System.out` placed? Also is the `@Value` on a Spring managed bean or just a regular thing. – M. Deinum Apr 18 '16 at 10:00
  • I tried both @Value("#{systemProperties['mySystemProperty']}") and @Value("#{systemProperties.mySystemProperty}"), but i always get null in return. – Alessandro C Apr 18 '16 at 10:03
  • My property name has a "-" character (the exact name is "my-property"). But I don't think that it depends on it... – Alessandro C Apr 18 '16 at 10:05

2 Answers2

5

Try something like :

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, proxyTargetClass = true)
public class SecurityContextConfig extends WebSecurityConfigurerAdapter
{
    @Value("#{systemProperties['your.system.property']}") 
    private String property;
    ...
}
JimHawkins
  • 4,843
  • 8
  • 35
  • 55
Shekhar Khairnar
  • 2,643
  • 3
  • 26
  • 44
2

It seems your configuration class contains some BeanFactoryPostProcessor. I beleive it is PropertySourcesPlaceholderConfigurer as you need this bean to have properties resolved.

Some explanation from Spring javadoc:

Special consideration must be taken for @Bean methods that return Spring BeanFactoryPostProcessor (BFPP) types. Because BFPP objects must be instantiated very early in the container lifecycle, they can interfere with processing of annotations such as @Autowired, @Value, and @PostConstruct within @Configuration classes. To avoid these lifecycle issues, mark BFPP-returning @Bean methods as static.

That is why @Autowired and @Value("#{systemProperties['your.system.property']}") don't work within the config class.


So to solve your issue just make method that returns PropertySourcesPlaceholderConfigurer static or add such method if you don't have it
@Bean
public static PropertySourcesPlaceholderConfigurer pspc() {
    return new PropertySourcesPlaceholderConfigurer();
}

And make sure that there is no more non-static BFPP-returning @Bean methods. Also you can move BFPP beans to separate @Configuration class.


UPDATE
Simple app demonstrating usage of @Value within @Configuration
@Configuration
public class SimpleJavaConfig {

    @Value("${java.version}")
    private String property;

    public static void main(String[] args) throws IOException {
        ApplicationContext app = new AnnotationConfigApplicationContext(SimpleJavaConfig.class);
        System.out.println("|" + app.getBean("propertyBean") + "|");
    }

    @Bean
    public static PropertySourcesPlaceholderConfigurer pcc() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Bean
    public String propertyBean() {
        return property;
    }
}
Evgeny
  • 2,483
  • 1
  • 17
  • 24
  • Thanks for your answer, but I don't understand how can I read the property with using the bean PropertySourcesPlaceholderConfigurer. Can you please show me an idea? Thanks – Alessandro C Apr 18 '16 at 15:15
  • @AlessandroC You don't need to do with `PropertySourcesPlaceholderConfigurer` anything special. Just add it to the context and it will resolve property values. This bean is required to make `@Value("${mySystemProperty}")` work. – Evgeny Apr 18 '16 at 15:28
  • I have added the bean like your indication, but if I try to make a variable with @Value("${my-property}"), it still returns null... I don't understand why! – Alessandro C Apr 18 '16 at 15:36
  • @AlessandroC Have you passed `my-property` value somehow? e.g. -Dmy-property=myValue – Evgeny Apr 18 '16 at 15:45
  • @AlessandroC I've added simple example to the answer. Try it – Evgeny Apr 18 '16 at 15:48
  • of course, the property value is passed to the startup of the application as a system property. It works if I make System.getProperty("my-property"); I tried your suggest, but I had a java.lang.NoClassDefFoundError: org.springframework.beans.FatalBeanException – Alessandro C Apr 18 '16 at 16:03