<context:property-placeholder
location="a.properties,b.properties"
ignore-unresolvable="true"/>
result: both properties file are loaded
<context:property-placeholder
location="${properties_location}"
ignore-unresolvable="true"/>
where properties_location is "a.properties,b.properties"
result: Exception in thread "main" org.springframework.beans.factory.BeanInitializationException: Could not load properties; nested exception is java.io.FileNotFoundException: class path resource [a.properties,b.properties] cannot be opened because it does not exist
edit: ${properties_location} is set the following way:
System.getProperties().setProperty("properties_location", "a.properties,b.properties");
ApplicationContext ctx = new GenericXmlApplicationContext("context.xml");
...
How can I initialize my application the 2nd way? to have all the properties file's path defined in a placeholder.
You have to change this to:
<context:property-placeholder
location="classpath:a.properties,
classpath:b.properties"
ignore-unresolvable="true"/>
From the source of the parser for the property-placeholder element.
String location = element.getAttribute("location");
if (StringUtils.hasLength(location)) {
String[] locations = StringUtils.commaDelimitedListToStringArray(location);
builder.addPropertyValue("locations", locations);
}
First the location is retrieved, if that has a value it is converted to a String[]. Springs conversion service takes care of replacing any placeholders in the String[]. But at that moment the properties_location placeholder is just a single element in the array and that gets resolved to a.properties,b.properties without further processing.
So at the moment this isn't possible with placeholders I'm afraid.
One thing that might work is using SpEL if it is always going to be a system property you can use #{systemProperties['properties_location']} to resolve the value. That should be resolved before anything else.
You cant use a property placeholder as a value in a placeholder placeholder resolver. Its like saying, "hey, resolve the placeholder for the location of the all the properties, and then you can start resolving properties!".
Logically it just dosent make sense. I was experimenting with spring property placeholder resolution recently, and stumbled upon this same question. I attempted to use two property placeholder configurers, one to resolve the location of the properties for the second, and the second to resolve the rest of the properties. Of course this dosent work due to the way in which spring initialises its beans.
Initialise bean post processors
Construct them
Construct all other beans
Since the property placeholder configurer is a bean post processor, if you have more than one of them, they get initialised and constructed at the same time, so know nothing of each others properties at construction
Edit
Given that the property location is a system property you could have:
System.getProperties().setProperty("properties_location_a", "classpath:/a.properties");
System.getProperties().setProperty("properties_location_b", "classpath:/b.properties");
And then in your spring content.xml:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true"/>
<property name="locations">
<list>
<value>${properties_location_a}</value>
<value>${properties_location_b}</value>
</list>
</property>
</bean>
Related
I am getting Circular reference error if my placeholder key starts with "database"
This config gives error.
<bean id="paymentTransactionLogMessageDecoratorDao"
class="com.gsicommerce.payment.dao.PaymentTransactionLogMessageDecoratorDao">
<constructor-arg ref="paymentTransactionLogMessageDao"/>
<constructor-arg value="${database.payments.logging.enabled}"/>
</bean>
Error: Circular placeholder reference
'database.payments.logging.enabled' in property definitions
When we change the key name like this,
<bean id="paymentTransactionLogMessageDecoratorDao"
class="com.gsicommerce.payment.dao.PaymentTransactionLogMessageDecoratorDao">
<constructor-arg ref="paymentTransactionLogMessageDao"/>
<constructor-arg value="${payments.database.logging.enabled}"/>
</bean>
this works. Do we have any reserve key words ("database") ?
As you can see, its a constructor injection and the property name is completely different.
public paymentTransactionLogMessageDecoratorDao(PaymentTransactionLogPersistenceServicetransactionLogMessageDao,
boolean databaseLoggingEnabled) {
this.transactionLogPersistenceService = transactionLogMessageDao;
this.databaseLoggingEnabled = databaseLoggingEnabled;
}
Probably your are using maven resource filtering: in this case, as detailed in this post, the keys of the property value to filter and it’s respective Spring property-placeholder cannot be the same.
I'm trying to create a MarshallingMessageConverter, here is my XML:
<bean id="marshallingMessageConverter" class="org.springframework.jms.support.converter.MarshallingMessageConverter">
<property name="marshaller" ref="marshaller" />
<property name="unmarshaller" ref="marshaller" />
<property name="marshalTo" value="MARSHAL_TO_TEXT_MESSAGE" />
</bean>
I am getting the following error:
Error setting property values; nested exception is
org.springframework.beans.NotWritablePropertyException:
Invalid property 'marshalTo' of bean class
[org.springframework.jms.support.converter.MarshallingMessageConverter]:
Bean property 'marshalTo' is not writable or has an invalid setter method.
Does the parameter type of the setter match the return type of the getter?
Is this because MarshallingMessageConverter doesn't have a getMarshalTo method, and so setting it in this way isn't working?
It looks like it should be possible, as I found https://jira.spring.io/browse/SWS-614, and someone else said they have the following config working:
<bean id="marshaller" class="org.springframework.oxm.xstream.XStreamMarshaller"/>
<bean id="xstream" class="org.springframework.oxm.support.MarshallingMessageConverter"
p:marshaller-ref="marshaller" p:unmarshaller-ref="marshaller" p:marshalTo="2"/>
<!--marshalTo=2 sets the marshaller to text message rather than bytes message-->
So I feel like maybe it's something I'm missing. I've tried using an int in the value, but that doesn't work either.
I want to use XML config because I'm using Spring Integration, and don't want to be pulling beans out of the app-context using Java.
I am using Spring version 3.2.1.RELEASE.
I was missing something... I was looking at the documentation for
org.springframework.oxm.support.MarshallingMessageConverter
but the one that I was using was
org.springframework.jms.support.converter.MarshallingMessageConverter
which has the method, toTargetType().
Not sure if I should delete my question or leave it here in case someone else does the same thing.
I have a simple Spring bean
public class Widget {
public Widget(File rootDir) { ... }
}
and in my application context XML I want to create an instance of Widget:
<bean id="widget" class="com.example.Widget">
<constructor-arg type="java.io.File" value="classpath:/someDir"/>
</bean>
When I run in from my IDE it works, the string is converted to a File and passed to the ctor.
When I run it with mvn exec:java the file cannot be found, I get all sorts of errors, but revolving around:
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name widget defined in class path
resource [META-INF/context.xml]: Could not resolve matching
constructor (hint: specify index/type/nam e arguments for simple
parameters to avoid type ambiguities)
So, how to I pass a classpath File (actually, directory) to a bean constructor in Spring?
I need a directory becasue then I want to scan it / list all files inside it.
So, how to I pass a classpath File (actually, directory) to a bean
constructor in Spring? I need a directory becasue then I want to scan
it / list all files inside it.
I don't know if that's possible but you can get all of the resources on the classpath that match a pattern using Spring. See PathMatchingResourcePatternResolver. See the docs on using Ant-style wildcards.
Try this for your constructor:
import org.springframework.core.io.Resource;
...
public Widget(Resource[] resources) { ... }
and in your XML, something like this (change the Ant pattern to match your use case):
<bean id="widget" class="com.example.Widget">
<constructor-arg>
<list>
<value>classpath:/someDir/*.foo</value>
</list>
</constructor-arg>
</bean>
Before using this, I recommend you take a look at the caveats related to non-filesystem resources mentioned in the PathMatchingResourcePatternResolver Javadocs.
I have a problem with the followingspring context configuration file:
...
<context:property-override location="classpath:query_1.properties" />
<bean
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations" value="classpath:query_2.properties" />
</bean>
....
The problem is that the properties in the file "query_2.properties" cannot be found. The exception I get ist he following one:
Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException. Could not resolve placeholder...
Now my question: is it possible that the combination of context:property-override and PropertyPlaceholderConfigurer does make no sense? Can anyone explain me in simple words what is the difference between both? Any help would be appreciated.
Thx. Horace
Property placeholders, normally defined using a <context:property-placeholder location=../> resolves the placeholders in bean definitions:
for eg.
<bean name="myclass" class="MyClass">
<property name="prop1" value="${prop1val}/>
</bean>
if the location specified with property placeholder has a property with name prop1val:
prop1val=aval
then it will be replaced in the bean myclass.
PrpertyOverrideConfigurer defined using <context:property-override location="classpath:query_1.properties" /> on the other is like a push mechanism, the property is of the form beanname.property and it would push this property into the bean with name beanname.
For eg. for the above case if the location had a property of:
myclass.prop1=aval
then it would inject in prop1 of myclass bean
The exception you are getting simply indicates that it is not able to find query_2.properties file, I doubt if it is any other configuration issue.
On which one will take effect if both are defined, I think the last one will the one to take effect.
Is it possible to set a Spring bean sub-property using dot notation? For instance:
<bean name="rememberMe" class="com.mydomain.security.RememberMeManager">
<property name="cookie.domain" value=".${webRoot}"/>
</bean>
Or do I need to also create an intermediary bean for the Cookie object stored in RememberMeManager.getCookie()?
My objective is to set cookies set by my site to ".mydomain.com" instead of "mydomain.com". I have a properties file with webRoot=mydomain.com in it.
Spring's PropertyPlaceholder will have no problem with replacing placeholders that are substrings of the property/value, such as ".${webRoot}", and according to the documentation, it will also fallback to the system properties if no property in the properties file is found.
Did you try this? Does it work or not?