Spring configuration: long value out of a String property - spring

I am configuring a scheduler task in spring in this way:
<bean id="someSchedulerTask" class="org.springframework.scheduling.concurrent.ScheduledExecutorTask">
<!-- start after 60 seconds -->
<property name="delay" value="6000"/>
<!-- depends on the enviroment -->
<property name="period" value="${period}"/>
<property name="runnable" ref="myScheduler"/>
</bean>
The property period is set up in some configuration file, and it seems that the default type is String:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'someSchedulerTask' defined in class path resource [context.xml]: Initialization of b
ean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type 'java.lang.String' to required type 'long' for property 'period'; nested exception is ja
va.lang.NumberFormatException: For input string: "period"
How could I change in this step from Stirng to Long??
Thanks in advance
EDIT
There is no problem with the place holder configuration, I am using more values from this config file in another beans.
Declaration:
period=30000

There are two ways to do this:
1: Change your method to accept a java.lang.Long
2: Create a java.lang.Long yourself in spring:
<bean id="period" class="java.lang.Long">
<constructor-arg index="0" value="${period}"/>
</bean>
<bean id="someSchedulerTask" class="org.springframework.scheduling.concurrent.ScheduledExecutorTask">
<!-- start after 60 seconds -->
<property name="delay" value="6000"/>
<!-- depends on the enviroment -->
<property name="period" ref="period"/>
<property name="runnable" ref="myScheduler"/>
</bean>
or without the extra bean
<bean id="someSchedulerTask" class="org.springframework.scheduling.concurrent.ScheduledExecutorTask">
<!-- start after 60 seconds -->
<property name="delay" value="6000"/>
<!-- depends on the enviroment -->
<property name="period">
<bean class="java.lang.Long">
<constructor-arg index="0" value="${period}"/>
</bean>
</property>
<property name="runnable" ref="myScheduler"/>
</bean>

${period} is being read as a String instead of value of ${period} i.e period is being assigned with value ${period}.
For such properties to work, you need Property Placeholder. Add this to configuration
<context:property-placeholder location='period.properties'/>
// Edit location
Then you can have
<property name="period" value='${period}'/>

What is probably happening is you have misspelled the fully qualified name of the class which loads the properties file.Hence spring is trying the convert the place holder string i.e "${period}" to int hence the error....
I used to get the same error while using the code
There were typos in two places..

Related

Spring - merge lists

I have a factory bean that produces List. But I call this factory multiple times meaning I end up with a lot of beans of type List.
I have another bean that has a property of type List. Somehow I need to put all the List beans in to one single list and provide it as a property using Spring XML.
How do I do this?
<bean id="usefulBean" class="...">
<property name="listProperty" ref="listX1AndX2AndX3AndSoOn">
</bean>
<bean id="listX1" factory-bean="anInstanceFactory" factory-method="create">
...
</bean>
<bean id="listX2" factory-bean="anInstanceFactory" factory-method="create">
...
</bean>
<bean id="listX3" factory-bean="anInstanceFactory" factory-method="create">
...
</bean>

spring bean initializing instances differently via property wiring

I have the following properties in a property file:
context1.property1=value1
context1.property2=value2
context1.property3=value3
context2.property1=value4
context2.property2=value5
context2.property3=value6
I have a bean with the following structure:
class Bean {
private property1;
private property2;
private property3;
}
Is there any way better to initialize 2 instances of Bean without writing something like:
<bean id="bean1" class="com.test.Bean">
<property name="property1" value="${context1.value1}" />
<property name="property2" value="${context1.value2}" />
<property name="property3" value="${context1.value3}" />
</bean>
<bean id="bean2" class="com.test.Bean">
<property name="property1" value="${context2.value1}" />
<property name="property2" value="${context2.value2}" />
<property name="property3" value="${context2.value3}" />
</bean>
Thanks!
Have a look at PropertyOverrideConfigurer:
Property resource configurer that overrides bean property values in an application context definition. It pushes values from a properties file into bean definitions.
Configuration lines are expected to be of the following form:
beanName.property=value
Example properties file:
dataSource.driverClassName=com.mysql.jdbc.Driver
dataSource.url=jdbc:mysql:mydb
See also
Using PropertyOverrideConfigurer with Annotated Classes in Spring 3

#Resource dataSource mappedName - overriding to test in non JNDI env

I have an existing service bean which we deployed in Jboss. Unfortunatly it's dataSource reference is configured to inject the datasource reference via the "mappedName" lookup of the JNDI Service.
#Resource(name = "dataSource", mappedName = "java:/OracleDS")
private DataSource dataSource = null;
I want to test the bean in a non JNDI env. I expected to get this exception when i run in a non JNDI env.
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating
bean with name 'myService': Injection of resource fields failed; nested exception
is org.springframework.beans.factory.BeanDefinitionStoreException: Invalid bean
definition with name 'java:/OracleDS' defined in JNDI environment: JNDI lookup
failed; nested exception is javax.naming.NoInitialContextException: Need to
specify class name in environment or system property, or as an applet parameter,
or in an application resource file: java.naming.factory.initial
I realise the quickest way to fix this is to dropped the mappedName restriction, since then the production or test spring context can define the datasource. But in the case that i can't do this. Is there a way to define an InitialContext via a test spring context to avoid the exception above.
I did some more reading on SimpleNamingContextBuilder and came up with this context setup for my test case. The trick being to use the MethodInvokingFactoryBean to ensure the bind() method is called.
<bean id="jndiContext" class="org.springframework.mock.jndi.SimpleNamingContextBuilder" factory-method="emptyActivatedContextBuilder"/>
<bean id="invokingFactoryBean"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject">
<ref local="jndiContext" />
</property>
<property name="targetMethod">
<value>bind</value>
</property>
<property name="arguments">
<list>
<value>java:/OracleDS</value>
<ref bean="dataSource" />
</list>
</property>
</bean>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${datasource.driverClassName}" />
<property name="url" value="${datasource.url}" />
<property name="username" value="${datasource.username}" />
<property name="password" value="${datasource.password}" />
</bean>

spring: how to omit bean-name in a list?

Do I have to give ids to the elements of a list of Bars ?
<list value-type="foo.Bar">
<bean p:p1="someP1Value" p:p2="aP2Value" />
</list>
I get
Caused by: org.springframework.beans.factory.parsing.BeanDefinitionParsingException:
Configuration problem: Unnamed bean definition specifies neither 'class' nor 'parent'
nor 'factory-bean' - can't generate bean name
for this.
How can I omit the bean ids?
Well, the error message is pretty clear. When defining a <bean/> you must either specify class or parent attribute:
<list>
<bean class="foo.Bar" p:p1="someP1ValueA" p:p2="aP2ValueA"/>
<bean class="foo.Bar" p:p1="someP1ValueB" p:p2="aP2ValueB"/>
<bean class="foo.BarSubclass" p:p1="someP1ValueC" p:p2="aP2ValueC"/>
</list>
If you want to avoid exceesive use of class attribute, you can take advantage of parent feature:
<bean id="bar" abstract="true" class="foo.Bar"/>
<list value-type="foo.Bar">
<bean parent="bar" p:p1="someP1ValueA" p:p2="aP2ValueA"/>
<bean parent="bar" p:p1="someP1ValueB" p:p2="aP2ValueB"/>
<bean parent="bar" p:p1="someP1ValueC" p:p2="aP2ValueC" class="foo.BarSubclass"/>
</list>
What are the p:p1 and p:p2 namespaces?

BeanInstantiationException:Cannot convert type from java.lang.String to required type --- idref tag

I am new to spring and trying to understand the functionality of the idref tag
My config file is pasted here:
<bean id="AudioSystembean" class="com.springexample.AudioSystem">
<property name="price" value="200"/>
</bean>
<bean id="Vehicle1" class="com.SpringExample.Vehicle1">
<property name="vehicleType" value="CAR" />
<property name="audioSystem" >
<idref bean = "AudioSystembean" />
</property>
</bean>
When I am executing the code I am getting the error as : "BeanInstantiationException:Cannot convert type from java.lang.String to required type :com.SpringExampl.AudioSystem" [I dont remember the exact exception - I have the code at home]
If I use ref instead of idref it is working fine.
I tried google to understand about idref but could not get much information..
What am I doing wrong here?
In a Spring context, <idref> is used to pass the name of the referenced bean, rather than the bean itself (which is what <ref> does). So in your example:
<property name="audioSystem" >
<idref bean = "AudioSystembean" />
</property>
The audioSystem system property will be injected with the name of the AudioSystembean, i.e. the String "AudioSystembean".
This is not what you need here, though, you need the <ref> element, which passes a reference to the bean itself.

Resources