char[] to String Conversion in Spring configuration - spring

I have bean A that returns an attribute as char[] and another bean that expects an attribute as String and I would like to inject the attribute from bean A to bean B.
When I do this:
<bean id="B" class="....">
<property name="password" value="#{A.password}" />
</bean>
<bean id="A" class="...">
</bean>
The error I'm getting is:
Cannot convert value of type [char[]] to required type [java.lang.String] for property 'password': no matching editors or conversion strategy found
Any idea how to resolve this?
Perhaps by using an expression language syntax?
Perhaps by registering some sort of a converter like org.springframework.beans.propertyeditors.CharArrayPropertyEditor in the configuration before injecting the char[] attribute?

Looks like this will work:
<property name="password" value="#{new java.lang.String(A.password)}" />

Related

How to create multiple objects of same class , with different values , in Spring using xml config file?

appContextXmlAutowiring.xml
<bean id="emp" class="com.org.epam.Assignment.Spring.XmlAutowiring.Employee" >
<property name="name" value ="Vineet"/>
<property name="id" value ="100"/>
<property name="age" value ="28"/>
<property name="addressNew" ref="addressNew"/>
</bean>
<bean id="emp1" class="com.org.epam.Assignment.Spring.XmlAutowiring.Employee">
<property name="name" value ="Ashutosh"/>
<property name="id" value ="200"/>
<property name="age" value ="29"/>
<property name="addressNew" ref="addressNew1"/>
</bean>
<bean id="addressNew1" class="com.org.epam.Assignment.Spring.XmlAutowiring.Address" >
<property name="country" value ="India1"/>
<property name="state" value ="Maharashtra"/>
<property name="city" value ="Pune"/>
</bean>
<bean id="addressNew" class="com.org.epam.Assignment.Spring.XmlAutowiring.Address" >
<property name="country" value ="Ind"/>
<property name="state" value ="Mah"/>
<property name="city" value ="Punite"/>
</bean>
</beans>
Driver Main Class
public class DriverClass {
public static void main(String[] args) {
try{
ApplicationContext ac = new ClassPathXmlApplicationContext("appContextXmlAutowiring.xml");
Employee e = ac.getBean(Employee.class);
System.out.println(e.toString());
//System.out.println(e.getAddressNew().getCity());
}
catch (Exception e) {
e.printStackTrace();
}
}
}
Error Message
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.org.epam.Assignment.Spring.XmlAutowiring.Employee' available: expected single matching bean but found 2: emp,emp1
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1041)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:345)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:340)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1092)
at com.org.epam.Assignment.Spring.XmlAutowiring.DriverClass.main(DriverClass.java:12)
I am getting mentioned error when trying to create two different objects of same type i.e. Employee using Spring Application context.
Could anyone please help me in solving this error.
Also please mention how to create multiple objects of same class , with different values , in Spring using xml config file ?
Thanks
You are creating two beans with the same class and then retrieve the bean by class. The error says it doesn't know which bean to choose.
You should use the
applicationContext.getBean(name)
method instead
Your code is already creating multiple beans of same class as you defined in your xml config. That is not where the code is failing it is failing while retrieving the Employee bean from the application context. The reason behind this failure is pretty clear in the error message;
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No
qualifying bean of type
'com.org.epam.Assignment.Spring.XmlAutowiring.Employee' available:
expected single matching bean but found 2: emp,emp1
You need to retrieve the bean by its name in such situation as below;
Employee e = (Employee) ac.getBean("emp");
Employee e1 = (Employee) ac.getBean("emp1");

Spring - how to reference another property within the same bean?

I have the following definition in my configuration:
<bean class="com.project.TimerBean">
<property name="delay" value="30000" />
<property name="interval" value="60000" />
<property name="invokeThis" value="com.project.TargetClass" />
<property name="receiver" value="XYZ" />
<property name="args" value="#{interval}" />
</bean>
I would like to set the value of args to the same value as interval (in this case, 60000) without having to hard-code the value. However, the above snippet doesn't seem to work. How should I change this?
# syntax (Spel Expressions) are supposed to work the way you wrote it. You need to replace
#{interval} to #{beanId.interval}.
For example, if the id of the bean you are creating is timerBean, #{timerBean.interval} is supposed to work. You cannot refer to a property directly even if it is a part of the bean definition.
It only works if the property you are referring to is a part of another bean.
<bean id="beanA" class="org.BeanA">
<property name="prop1" value="1000" />
</bean>
<bean id="beanB" class="org.BeanB">
<property name="prop2" value = "#{beanA.prop1}" />
<property name="prop3" value = "#{beanB.prop2}" />
</bean>
In the above example, prop2 gets initialised from prop1 correctly. But prop3 gets initialised to null.
If you look at AbstractAutowireCapableBeanFactory class and method,
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs)
you can see that all the property values in a single bean definition are looped over and values are parsed. After all the values have been successfully parsed, only then they are set on the bean instance. In the above beanA and beanB example when prop3's value is getting parsed, spring looks for the value of prop2 on beanB which is not yet set and hence returns null.
AFAIK, there is no way around this except the way suggested by #Alex
PS: I am using spring version 4.1.6.RELEASE
Move interval value "60000" to the property file
yourVariableName = 60000
and change to:
<property name="interval" value="${yourVariableName}" />
<property name="args" value="${yourVariableName}" />

Dependency Injection returned results of bean init-method

I have two simple beans. In the first bean it calls a init-method and return string value.
Now I want to this returned string from first bean init-method , inject to my second bean
helloWorldBean3 property newKey. Please advise me on how to implement this requirement.
<bean id="helloWorldBean2" init-method="loadKey"
class="com.java.snippets.enterprise.services.HelloWorld2">
<property name="key" value="${key.supportiveFile}" />
<bean id="helloWorldBean3"
class="com.java.snippets.enterprise.services.HelloWorld">
<property name="newKey" ref="???" />
</bean>
Try using Spring EL like so:
<bean id="helloWorldBean3"
class="com.java.snippets.enterprise.services.HelloWorld">
<property name="newKey" value=""#{helloWorldBean2.loadKey()}"" />
</bean>

custom thymeleaf dialect registration causing exception

in applicationContext.xml
<bean id="templateEngine"
class="org.thymeleaf.spring3.SpringTemplateEngine">
<property name="templateResolver" ref="templateResolver" />
<property name="additionalDialects">
<set>
<bean class="org.test.custom.CustomDialact" />
</set>
</property>
</bean>
Stacktrace:
Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'additionalDialects' of bean class [org.thymeleaf.spring3.SpringTemplateEngine]: Bean property 'additionalDialects' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:1042)
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:902)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:75)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:57)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1424)
... 50 more
i don't know but it was fixed after restarting machine. but mean while i find another solution
by extend a custom class with HashSet and in constructor add custom dialect in it and declare it in xml. provide it reference to additionalDialects . thats it .it will start running . it think it is problem related to generics as spring sometimes supply empty type
like HashSet<V> .

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