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.
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 bean in spring xml configuration file using c namespaces.
The bean which I'm trying to create has an empty constructor and one String parameter constructor (org.apache.activemq.command.ActiveMQQueue).
When I'm using the following code:
<bean id="queue"
class="org.apache.activemq.command.ActiveMQQueue"
c:_="spitter.queue" />
Intellij IDEA highlights c:_ in a red color saying:
Attribute c:_" is not allowed here
Does anybody know how to fix this?
You're not using the c namespace quite right. You should either use indexed arguments like:
<bean id="queue"
class="org.apache.activemq.command.ActiveMQQueue"
c:_0="spitter.queue" />
Or named arguments:
<bean id="queue"
class="org.apache.activemq.command.ActiveMQQueue"
c:name="spitter.queue" />
Checkout the Spring documentation for more information.
<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>
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.
I am trying to write a ValidatorFactory which will give me a validator based on its type
public Validator getNewValidator(ValidatorType type){
switch:
case a : new Validator1();
break;
case b : new Validator2();
break;
}
I want to write using spring xml beans definition
I can use method injection but it will let me create only one object and the method does
not take any arguments.
I don't want to use FactoryBean.. I am just looking whether we can do this using spring xml
bean definition.
you can do conditional bean injection with plain xml. The "ref" attribute can be triggered by property values from a property file and thus create conditional beans depending on property values. This feature is not documented but it works perfect.
<bean id="validatorFactory" class="ValidatorFactory">
<property name="validator" ref="${validatorType}" />
</bean>
<bean id="validatorTypeOne" class="Validator1" lazy-init="true" />
<bean id="validatorTypeTwo" class="Validator2" lazy-init="true" />
And the content of the property file would be:
validatorType=validatorTypeOne
To use the property file in your xml just add this context to the top of your spring config
<context:property-placeholder location="classpath:app.properties" />
For complex cases (more complex than the one exposed), Spring JavaConfig could be your friend.
If you are using annotation (#Autowired, #Qualifier etc) instead of xml, you are not able to make conditional beans work (at least at current version 3). This is due to #Qualifier does not support expression
#Qualifier(value="${validatorType}")
More information is at https://stackoverflow.com/a/7813228/418439
I had an slightly different requirements. In my case I wanted to have encoded password in production but plain text in development. Also, I didn't have access to parent bean parentEncoder. This is how I managed to achieve that:
<bean id="plainTextPassword" class="org.springframework.security.authentication.encoding.PlaintextPasswordEncoder"/>
<bean id="shaPassword" class="org.springframework.security.authentication.encoding.ShaPasswordEncoder">
<constructor-arg type="int" value="256"/>
</bean>
<bean id="parentEncoder" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="targetSource">
<bean class="org.springframework.aop.target.HotSwappableTargetSource">
<constructor-arg ref="${password.encoding}Password"/>
</bean>
</property>
</bean>
Of course, I defined password.encoding in a property file with possible values as sha or plainText.
You should be able to do this:
<bean id="myValidator" factory-bean="validatorFactory" factory-method="getNewValidator" scope="prototype">
<constructor-arg><ref bean="validatorType"/></constructor-arg>
</bean>
<bean id="validatorType" ... />
Of course, it uses an automatically configured FactoryBean underneath but you avoid any Spring dependency in your code.