Spring Instantiation exception with java.lang.String - java

What is wrong with the below bean? Using spring-beans-2.0 I'm getting below exception:
<bean id="logger" class="java.lang.String">
<constructor-arg value="logger"/>
</bean>
logger bean ibjecting to :
<bean id="loggerType" class="java.lang.String" scope="prototype">
<constructor-arg value="logger" />
</bean>
loggerbean injecting other bean that is correctly have argument as "java.lang.String".
Exception
Could not instantiate bean class [java.lang.String]: Illegal arguments for constructor;
nested exception is java.lang.IllegalArgumentException:
java.lang.ClassCastException#5083198c

If you are injecting another bean then use ref attribute instead of value attribute.
<bean id="loggerType" class="java.lang.String" scope="prototype">
<constructor-arg ref="logger" />
</bean>
Or use <ref/> tag with bean as attribute
<bean id="loggerType" class="java.lang.String" scope="prototype">
<constructor-arg>
<ref bean="logger"/>
</constructor-arg>
</bean>
For more info have a look at Spring documentation References to other beans (collaborators)
I suggest to move latest version of Spring - 4.0.6.RELEASE

String class has many one-argument constructors so Spring could choose wrong one, hence the exception.
I doubt it happens in newer versions of Spring. You said that you use Spring 2 and there is a bug related to this. But it seems to be fixed in newer versions.
The bug report says that it is fixed in version 3.0.3.

Related

Java Spring IOC bean creation value

I need a bean like this
<bean id="studentWithSchool" class="com.model.Student" scope="prototype">
<property name="school">
<bean class="com.model.School" scope="prototype"/>
</property>
</bean>
This is OK.
My problem is I have the student returning from a method from a different bean.
I usually load the bean like this when is a property.
<property name='beanProperty' value='#{anotherBean.getBeanProperty()}'/>
But in this case I need the new bean itself being set from the other bean method (School object is returned from another bean method).
This is what I try, and of course this is wrong:
<bean id="studentWithSchool" class="com.model.Student" scope="prototype" value='#{anotherBean.getBeanProperty()}'>
<property name="school">
<bean class="com.model.School" scope="prototype"/>
</property>
</bean>
Is there any workaround?
If I understand you correctly, the studentWithSchool is created and returned by a method in anotherBean. If that's the case, you can use a factory-method:
<bean id="studentWithSchool" factory-bean="anotherBean" factory-method="getBeanProperty" scope="prototype" />
I believe you are trying to use factory patter with Spring . For that you can use factory bean from spring.
<bean id="studentWithSchool" factory-bean="anotherBeanStaticFactory" factory- method="createBeanProperty" scope="prototype"
<property name="school">
<bean class="com.model.School" scope="prototype"/>
</property>
For more detail you can use below link :-
http://docs.spring.io/spring-framework/docs/2.5.6/api/org/springframework/beans/factory/BeanFactory.html

NamedParameterJdbcTemplate and CGlib in Spring AOP

Hi All in my Spring application i have used AutoWired NamedParameterJdbcTemplate.
#Autowired
NamedParameterJdbcTemplate namedParametersJdbcTemplate;
in my rest-servlet.xml
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/mylfrdb"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<constructor-arg ref="dataSource"/>
</bean>
<bean class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate" id="namedParameterJdbcTemplate">
<constructor-arg ref="jdbcTemplate"></constructor-arg>
</bean>
<bean class="org.springframework.jdbc.core.simple.SimpleJdbcCall" id="simpleJdbcCall">
<constructor-arg ref="dataSource"></constructor-arg>
</bean>
It working fine.
No i have to use performance intercepter with Spring AOP.
So i added following thing in my rest-servlet.xml
<aop:config >
<aop:pointcut expression="#target(org.springframework.stereotype.Service)" id="allServices"/>
<aop:advisor pointcut-ref="allServices" advice-ref="perfMonitor"/>
</aop:config>
So i got error like this.
Can not set org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate field com.lfr.dao.impl.FlatAdvertiseDaoImpl.namedParametersJdbcTemplate to com.sun.proxy.$Proxy15
So i refered this question and tried to implement 2nd solution give is by using CGLIB and
<aop:config proxy-target-class="true" >
No i am getting this error
Could not generate CGLIB subclass of class [class org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
I had the exact same error message. I was using Spring 3.2.5.RELEASE version. After debugging and trying to repeat the problem with PetClinic example came out it was matter of Spring version. This problem didn't occur in Spring 4.1.1. Try to upgrade, maybe it works.

Ambiguous setter methods causing issue with assigning property value

I am having a problem when setting a property of a bean that has ambiguous setter methods.
The issue is the hostConfiguration.host property of the HttpClient has 3 possible methods to use:
HostConfiguration.setHost(String host)
HostConfiguration.setHost(HttpHost host)
HostConfiguration.setHost(URI host)
Here is my bean definition:
<bean id="primaryClient" class="org.apache.commons.httpclient.HttpClient">
<property name="hostConfiguration.host">
<bean class="org.apache.commons.httpclient.HttpHost" >
<constructor-arg value="somelink.com"/>
<constructor-arg value="443"/>
<constructor-arg>
<bean class="org.apache.commons.httpclient.protocol.Protocol">
<constructor-arg value="https"/>
<constructor-arg ref="sslProtocolSocketFactory"/>
<constructor-arg value="443"/>
</bean>
</constructor-arg>
</bean>
</property>
</bean>
Here is the stack:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'primaryClient' defined in class path resource [spring/test-merchantlink-context.xml]: Error setting property values; nested exception is org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are:
PropertyAccessException 1: org.springframework.beans.TypeMismatchException: Failed to convert property value of type [org.apache.commons.httpclient.HttpHost] to required type [java.lang.String] for property 'hostConfiguration.host'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [org.apache.commons.httpclient.HttpHost] to required type [java.lang.String] for property 'host': no matching editors or conversion strategy found
How can I get around this? I'm using spring 2.5.6
Basically having overloaded setters violates the JavaBeans specification and is therefore not supported by spring. You can see https://jira.spring.io/browse/SPR-4931 for more details.
As you probably did not make the HttpClient and thus cannot change it, one solution would be the use of a factory bean. This would look something like this:
<bean id="httpClientFactory" class="my.package.HttpClientFactory"/>
<bean id="primaryClient" factory-bean="httpClientFactory" factory-method="create">
You would implement the create() method on my.package.HttpClientFactor to set-up and return your factory.
If there are specific parameters you want to set in the XML config rather than in code, you could add constructor arguments to my.package.HttpClientFactor.
You should avoid overloading property setters that you want to be able to wire using IoC. When you do need two setters for (logically) the same property, you should use different setter names ... and javadoc comments to explain what is going on.
There are same issues on http://forum.spring.io that describe your same problem and the better solution is the rename all methods.
Link1
Link2
Link3
It seems like you have to specify explicitly the expected class name to avoid ambiguity between the multiple setters available.
May be something like:
<bean id="primaryClient" class="org.apache.commons.httpclient.HttpClient">
<property name="hostConfiguration.host">
<bean class="org.apache.commons.httpclient.HttpHost" >
<constructor-arg type="java.lang.String">
<value>somelink.com</value>
</constructor-arg>
<constructor-arg type="int">
<value>443</value>
</constructor-arg>
<constructor-arg>
<bean class="org.apache.commons.httpclient.protocol.Protocol">
<constructor-arg value="https"/>
<constructor-arg ref="sslProtocolSocketFactory"/>
<constructor-arg value="443"/>
</bean>
</constructor-arg>
</bean>
</property>
</bean>

How to inject child dependency using byType autowiring?

I have two child classes(PermanentEmployee and ContractEmployee) of Employee class.
I want spring to inject the dependencies under TextEditor1 by type . Along with this i want to inject the PermanentEmployee depndency under TextEditor1.
similarily want to inject the contractEmployee dependency under TextEditor2. Rest should be injected
automatically by type?
<bean id="textEditor1" class="com.TextEditor" autowire="byType">
<property name="employee" ref="permanentEmployee" />
</bean>
<bean id="textEditor2" class="com.TextEditor" autowire="byType">
<property name="employee" ref="contractEmployee" />
</bean>
<bean id="permanentEmployee" class="com.PermanentEmployee" >
</bean>
<bean id="contractEmployee" class="com.ContractEmployee">
</bean>
But i get the error Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: saying two match are found ?
Update :- i also tried below but it didn't work either
<bean id="textEditor1" class="com.TextEditor" autowire="byType">
<qualifier type="permanentEmployee"/>
</bean>
I think that's because those two com.PermanentEmployee and com.ContractEmployee are implementing another interface like com.Employee?
That way, Spring will recognize those same type and can't choose which bean Spring have to auto-wire into the bean.
So you might need to add those byName, not byType in this case.
If you change those injection with #Autowired annotation or #Resource annotation, you can use #Qualifier( for Autowired ) or name property of Resource annotation to specify bean name.

constructor-arg and property together in bean definition

<bean id="cObject" scope="request" class="x.y.z.CClass"/>
<bean id="bObject" scope="request" class="x.y.z.BClass"/>
<bean id="aObject" scope="request" class="x.y.z.AClass">
<constructor-arg ref="bObject" />
<property name="cRef" ref="cObject" />
</bean>
aObject.cRef is not getting set for some reason. Note that constructor-arg and property are used in the same definition. I have not seen an example / post with similar feature.
On same sources my colleague discover:
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'service.MenuService#0'
defined in class path resource [spring-beans/integrator.xml]:
Could not resolve matching constructor (hint: specify index/type/name
arguments for simple parameters to avoid type ambiguities)
while my host, test and production servers have no such error.
With:
<bean class="service.MenuService">
<constructor-arg index="0" type="java.lang.String" value="#{user}"/>
<constructor-arg index="1" type="java.lang.String" value="#{password}"/>
<constructor-arg index="2" type="java.lang.String" value="#{uri}"/>
<property name="system" value="OPRT"/>
<property name="client" value="OPRT"/>
</bean>
while there are only one 3-args constructor in bean.
The reason to use constructor - it perform some additional actions on non-Spring library by invoking init() method. And set args as fields.
So I change spring-beans.xml to:
<bean class="service.MenuService" init-method="init">
<property name="login" value="#{user}"/>
<property name="password" value="#{password}"/>
<property name="httpsUrl" value="#{uri}"/>
<property name="system" value="OPRT" />
<property name="client" value="OPRT" />
</bean>
Take attention to init-method= part.
UPDATE After all I wrote simple XML config and step through Spring source code in debugger. Seems that with Spring 3.x it's possible to combine constructor-arg and property in XML bean definition (check doCreateBean in AbstractAutowireCapableBeanFactory.java, which call createBeanInstance and populateBean next).
See also https://softwareengineering.stackexchange.com/questions/149378/both-constructor-and-setter-injection-together-in-spring/
Mixing <constructor-arg> and <property> is generally a bad idea.
There is only one good reason for using <constructor-arg>, and that is to create immutable objects.
However, your objects are not immutable if you can set their properties. Don't use <constructor-arg>. Redesign the class, use an initializer method annotated with #PostConstruct if you need to apply some logic at bean creation time.

Categories