spring #Value("${property.value}") not returning value - java

Hi I'm using Spring PropertyPlaceholderConfigurer to fetch values from a properties file.
It's working when i get the value in xml. but in a java class
#Value("${application.imagesPath}")
private String imagesPath;
Returns the literal value "${application.imagesPath}" even though when running the server if the variable application.imagesPath is not in the properties file i get the error
Could not autowire field: private java.lang.String com.ymobility.filltrack.controller.ApiController.imagesPath; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'application.imagesssPath' in string value
(the typo imagesssPath is on purpose to show that if i misspell it, it is knowing that the property doesn't exist which indicates that it is actually reading the properties file correctly, my issue is when there is no error, the value retrieved is the literal string "${application.imagesPath}" instead of it's value in properties file)
So the controller is actually getting the value from the properties file, but the value of the string when used is still the literal value "${application.imagesPath}".
My context.xml file contains the following config
<bean id="appProperties"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>/WEB-INF/properties/app.properties</value>
</list>
</property>
</bean>
The class I'm using has the following annotations
#RestController
#RequestMapping("/api")
Any idea what might be the problem ?
Thanks

Related

Spring annotation to create a jexl2.Expression

I’m trying to understand a piece of Spring code that I need to adapt.
I have:
<bean id="…" class="…">
<property name="expr"
value="teams.contains(member.team) and not empty(member.projects)" />
</bean>
The corresponding class has a field
private Expression expr;
of type
org.apache.commons.jexl2.Expression
Now I am trying to find the appropriate Spring annotation to get rid of the XML file. But I cannot even understand how a simple String property can be injected as a jexl2.Expression object. How does this work?
A friend found the answer:
There was another XML file with this:
<bean id="bean_for_ExprConverter" class="package.of.custom.ExpressionConverter">
<constructor-arg ref="bean_for_JexlEngine"/>
</bean>
and also, in the project’s properties:
application.spring.converters = #{{\
#'bean_for_ExprConverter'\
}}
Thus, as long as the converter bean is defined, it should be enough to simply inject the expression string with the #Value annotation.

Loading String from file into Spring bean property

In my spring xml file I have a bean:
<bean id="config" class="com.example.BeanConfig">
<property name="description" value="Long Description Here" />
</bean>
Instead of defining the long string inline, I want to read the string from description.txt. Is there any way to do this in the xml without writing a Java class to handle it?
I already came across How do I load a resource and use its contents as a string in Spring but I am unclear how to get the bean contents into a property value.
You can use Spring's property placeholder and ${property_name} see https://dzone.com/articles/properties-spring

Can't import a property value while using a placeholder

I am using Spring Boot.
I declared properties in an external file outside the classpath.
I added that to one of my XML files:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="ignoreResourceNotFound" value="true" />
<property name="locations">
<list>
<value>file:///d:/etc/services/pushExecuterService/pushExecuterServices.properties</value>
</list>
</property>
</bean>
However, I still get this error:
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'configuration.serviceId' in string value "${configuration.serviceId}"
at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:174)
I added a breakpoint in the PropertiesLoaderSupport class at this method:
public void setLocations(Resource... locations) {
this.locations = locations;
}
I paid attention that this method invoked multiple times and in one of them I noticed the locations param populated with:
URL [file:/d:/etc/services/pushExecuterService/pushExecuterServices.properties]
However, I am still getting this error.
I double checked in my project and I dont have any additional PropertyPlaceholderConfigurer beans(didnt check on external dependencies)
I ran my app with hard code the params inside the xml I can see within spring-boot logs:
2015-01-05 18:56:52.902 INFO 7016 --- [ main]
o.s.b.f.c.PropertyPlaceholderConfigurer: Loading properties file from
URL [file:/d:/etc/services/pushExecuterService/pushExecuterServices.properties]`
So I am not sure what's happening. any leads?
thank you.
Spring Boot favors Java-based configuration. In order to add configuration properties, we can use #PropertySource annotation together with #Configuration annotation.
The properties can be stored in any file. Property values can be injected directly into beans using the #Value annotation:
#Configuration
#PropertySource("classpath:mail.properties")
public class MailConfiguration {
#Value("${mail.protocol}")
private String protocol;
#Value("${mail.host}")
private String host;
}
#PropertySource's value attribute indicate the resource location(s) of the properties file to be loaded. For example, "classpath:/com/myco/app.properties" or "file:/path/to/file"
But Spring Boot provides an alternative method of working with properties that allows strongly typed beans to govern and validate the configuration of your application: #ConfigurationProperties
See this blog post with an example of using #ConfigurationProperties: http://blog.codeleak.pl/2014/09/using-configurationproperties-in-spring.html
For the #PropertySource example you can check this article: http://blog.codeleak.pl/2014/09/testing-mail-code-in-spring-boot.html

constructor-arg ref from properties in spring

I have bean which has to be binded at run time.
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg ref="${requiredBean:mysql}"/>
</bean>
<bean id="mysql" class="xxx.xxx.xxxxxx">
</bean>
<bean id="mongo" class="xxx.xxx.xxxxxx">
</bean>
In the property file I added the property
requiredBean=mongo
But due to some reason the requiredBean from the properties file is not picked up by the spring (The properties file is configured correctly and all other properties are loading properly except for this one).
I just want to know if the syntax that I used for declaring the arg for constructor aa ref is right or is there any other way to declare it.
Pls help me to resolve this.
Let me know if the question is not clear.
if you are sure (as you already mentioned in the content of .properties) that you are mentioning the right property(no spelling error), then problem is something else, and not the property itself. Try removing the default value . It must throw exception like :::: java.lang.IllegalArgumentException: Could not resolve placeholder 'XYZ' in string value "${XYZ}". If it does not throw this exception, issue is not related to this bean at all.

Property expansion with PropertiesFactoryBean

I wish to expose a Properties Spring bean whose values have been expanded via the typical property expansion mechanism. I'm using Spring 3.1. Let me digress.
Given the following properties file:
server.host=myhost.com
service.url=http://${server.host}/some/endpoint
And this portion of Spring XML config file:
<bean id="appProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="locations">
<list>
<value>classpath:default.properties</value>
</list>
</property>
</bean>
<context:property-placeholder properties-ref="appProperties" />
I can write the following working code:
#Component
public class MyComponent {
#Autowired
#Qualifier("appProperties")
private Properties appProperties;
#Value("${service.url}")
private String serviceUrl;
// remainder omitted
}
The only problem is that if I obtain the service.url value from appProperties I get http://${server.host}/some/endpoint - ie the value is unexpanded. However, if I get the value of service.url from serviceUrl, the value has been expanded: http://myhost.com/some/endpoint.
Does anyone know of a good way to expose a Properties instance as a Spring bean whose values have been expanded?
Alternatively, if anyone can point me to a Spring bean (must be Spring 3.1) that will do the expansion for me, I'll accept this too! (Interestingly, if you manually pull the property values from the Environment or PropertySource you'll find that these too are unexpanded.)
Thanks,
Muel.
I'm pretty late to this, but it's been viewed enough times that i figured it warranted a quick response. What you're seeing is an artifact of how Spring handles property expansion. When the need for property expansion is found, only previously loaded sources are checked, not the currently loading property source. When the file loads, there are no previous sources, so ${server.host} does not expand. When you later reference ${server.url} via the #Value annotation, the property file source is loaded and can be searched as you expected. This is why the #Value annotation gets full expansion but the result queried from the property file does not.

Categories