Defined bean to take enum construtor-arg - spring

A connection pool class used for all the data source connections. It has a static enum to indicate type of connection.
class ConnectionPool {
public static enum Type {
t1,
t2,
t3;
}
…
}
Another class does not have default contractor, the constructor takes the Type as contractor argument
class Update {
public Update(Type type) {
this.type = type;
}
...
}
In applicationContext.xml, defined a bean
<bean id="update" class="package.Update">
<contructor-arg type="package.ConnectionPool.Type">
<value>Type.t1</value>
</contructor-arg>
</bean>
But I got
Error creating bean with name 'update' defined in class path resource [applicationContext.xml]: Unsatisfied dependency expressed through constructor argument with index 0 of type [package.ConnectionPools$PoolType]: Ambiguous constructor argument types - did you specify the correct bean references as constructor arguments?

This should work:
<bean id="update" class="package.Update">
<contructor-arg type="package.ConnectionPool.Type">
<value>t1</value>
</contructor-arg>
</bean>
or even:
<bean id="update" class="package.Update">
<contructor-arg type="package.ConnectionPool.Type" value="t1"/>
</bean>
or my favorite:
#Configuration
public class Config {
#Bean
public Update update() {
return new Update(t1);
}
}

Related

Spring: two beans qualified different with the same name

Two beans qualidied different with the same name are getting me an exception.
Exception message:
***************************
APPLICATION FAILED TO START
***************************
Description:
The bean 'tipusFonsSql', defined in class path resource [net/gencat/clt/arxius/connector/config/SqlGiacTxtResourceLoader.class], could not be registered. A bean with that name has already been defined in class path resource [net/gencat/clt/arxius/connector/config/SqlGiacImgResourceLoader.class] and overriding is disabled.
It's telling me that class SqlGiacTxtResourceLoader and class SqlGiacImgResourceLoader are defining two beans with a same name.
Nevertheless, they are "#Qualified" different. I mean:
Into SqlGiacImgResourceLoader
#Bean
#GiacImg #TipusFonsQ
public String tipusFonsSql() {
//...
}
Into SqlGiacTxtResourceLoader
#Bean
#GiacTxt #TipusFonsQ
public String tipusFonsSql() {
//...
}
As you can see, one is "#aulified" with #GiacImg annotation and the other ony by #GiacTxt.
Any ideas?
You have to name them like this
#Bean(name = "GiacImg TipusFonsQ")
public String tipusFonsSql() {
//...
}
and
#Bean(name = "GiacTxt TipusFonsQ")
public String tipusFonsSql() {
//...
}
to avoid bean conflict
There is 2 way to resolve this issue ( haha there could be many but I know below 2 approach):------
1st Method
change the bean name:---
#Bean(name = "custome bean name")
2nd Method
write down the below key in the application.properties:--
spring.main.allow-bean-definition-overriding=true
NOTE:-in your case you can change method name also

Importing a OSGi service that is a singleton bean (that has a factory method)

How do I import the exported OSGi service that's a Singleton bean?
I end up getting the Exception as follows:
Unable to start blueprint container for bundle opaClient
org.osgi.service.blueprint.container.ComponentDefinitionException: Unable to find a matching constructor on class com.opa.gateway.OPAGateway for arguments [] when instantiating bean opaGateway
at org.apache.aries.blueprint.container.BeanRecipe.getInstance(BeanRecipe.java:336)
My Blueprint xml where the service is exported is as follows:
<bean id="opaGateway" class="com.opa.gateway.OPAGateway" factory-method="getInstance"/>
<service ref="opaGateway" interface="com.opa.gateway.IOPAGateway" />
And the service is referenced in another bundle as follows:
<reference interface="com.opa.gateway.OPAGateway" component-name="opaGateway" availability="mandatory" />
Is there a way to directly reference a singleton bean that's a OSGi service?
Yes, you can reference a singleton which is an OSGi service. Make sure (as #Balazs suggested) that your class has a static function/method getInstance() with no arguments.
Have a look at the blueprint below. Hope it gives you a clue... (If you need the complete sample I can try to post it.
<bean id="opaGateway"
class="org.test.OPAGateway" factory-method="getInstance">
</bean>
<bean id="opaClient"
class="org.test.client.OPAClient"
init-method="startup"
destroy-method="shutdown">
</bean>
<service ref="opaGateway" interface="org.test.IOPAGateway" />
<reference interface="org.test.IOPAGateway" availability="optional">
<reference-listener bind-method="setOPAGateway"
unbind-method="unsetOPAGateway">
<ref component-id="opaClient"/>
</reference-listener>
</reference>
bean opaGateway (org.test.OPAGateway). It is a class implementing org.test.IOPAGateway. It is instantiated by static method getInstance():
public class OPAGateway implements IOPAGateway {
private static OPAGateway instance = null;
public static OPAGateway getInstance () {
if(instance == null) {
instance = new OPAGateway();
}
return instance;
}
// A very simple method...
#Override
public String printMessage() {
return "I AM AN OPAGATEWAY";
}
}
bean: opaClient: It is just a consumer or the class that references the opaGateway:
public class OPAClient {
public void setOPAGateway(IOPAGateway c) {
if(c != null) {
System.out.println("Message: " + c.printMessage());
}
}
public void unsetOPAGateway(IOPAGateway c) {
}
}
The reference-listener: Injects the instance of opaGateway in the opaClient using the bind/unbind-method.
You can find more information here: http://www.ibm.com/developerworks/library/os-osgiblueprint/

Bean property 'iUserGeneratorInterface' is not writable or has an invalid setter method

I have a project structure as follows
[1]: http://i.stack.imgur.com/T1jvh.png
I have a class and interface defined in create-user
UserGeneratorInterface
package com.credit.userGenerator;
public interface UserGeneratorInterface {
public String userIdGenerator();
}
RandomUserGenerator.java
public class RandomUserGenerator implements UserGeneratorInterface {
public static enum Mode {
ALPHA, ALPHANUMERIC, NUMERIC
}
public static String generateRandomString(int length, Mode mode) throws Exception {
code logic
}
public String userIdGenerator(){
code logic
}
}
I have defined application context in da-web and wan to get service of RandomUserGenerator.java
public class ApplicationSignManager implements IApplicationSignInterface {
public UserGeneratorInterface iUserGeneratorInterface;
public UserGeneratorInterface getiUserGeneratorInterface() {
return iUserGeneratorInterface;
}
public void setiUserGeneratorInterface(
UserGeneratorInterface iUserGeneratorInterface) {
this.iUserGeneratorInterface = iUserGeneratorInterface;
}
}
AppContext.xml
<bean id="userGenerator" class="com.credit.userGenerator.RandomUserGenerator" ></bean>
<bean id="appSign" class="com.*****.service.ApplicationSignManager">
<description>List of Dao in ApplicationLogin Manager</description>
<property name="userGeneratorInterface" ref="userGenerator"/>
</bean>
But I am getting the following exception
Bean property 'iUserGeneratorInterface' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
As noticed in the comments, use setIUserGeneratorInterface() and getIUserGeneratorInterface() with capital 'I'.
Use 'property name="iUserGeneratorInterface" ref="userGenerator"' - note the leading 'i'.
Note that it is always advisable to use well-established practices when naming your classes and fields. In your case naming 'UserGeneratorInterface' simply 'UserGenerator' and naming the field 'iUserGeneratorInterface' simply 'userGenerator' would make more sense. Note also that you have declared this field public (although this has nothing to do with the errors).
Your bean id="userGenerator"
Use this "userGenerator" like (public UserGeneratorInterface userGenerator;) as same as the variable name.
And create getter, setter for this variable
then try

Bean property 'xxx' is not writable or has an invalid setter method

I have spring web application. I have defined the controller bean which takes the bean of service as property. Also service bean takes the Dao. Dao is tested and working fine. Now the problem with service. Actually i'd make sure about the setters there !
so what is the problem ?
Controller Bean :
<bean id="listTypeController" class="me.web.servlet.controller.ListTypeController">
<property name="typeService" ref="typeService" />
</bean>
Service Bean :
<bean id="typeService"class="me.general.service.impl.TypeServiceImpl">
<property name="genericDao" ref="genericDao" />
<property name="typeDao" ref="typeDao" />
</bean>
Service class:
public class TypeServiceImpl implements TypeService {
private TypeDao typeDao;
private GenericDao genericDao;
public TypeDao getTypeDao() {
return typeDao;
}
public GenericDao getGenericDao() {
return genericDao;
}
public void setTypeDao(TypeDao typeDao) {
this.typeDao = typeDao;
}
public void setGenericDao(GenericDao genericDao) {
this.genericDao = genericDao;
}
}
List Controller:
public class ListTypeController {
public static final String SEARCH_TYPE_FORM_ATTRIBUTE_NAME = "SearchTypeForm";
private TypeService typeService;
#ModelAttributeSEARCH_TYPE_FORM_ATTRIBUTE_NAME)
public SearchTypeForm createForm() {
SearchTypeForm form = new SearchTypeForm();
form.setPageSize(SystemConfiguration.getCurrentConfiguration().getDefaultPageSize());
form.setActive(Boolean.TRUE);
return form;
}
#RequestMapping("/administration/types")
public String listTypes(#ModelAttribute(SEARCH_TYPE_FORM_ATTRIBUTE_NAME) SearchTypeForm form,
Model model) {
Page<Type> all = typeService.findTypes(form);
model.addAttribute("all", all);
return "/master/general/List";
}
public void setTypeServic(TypeService typeService) {
this.typeService = typeService;
}
}
The Error :
Invalid property 'typeService' of bean class
[me.web.servlet.controller.ListTypeController]:
Bean property 'typeService' is not writable or has an invalid setter method.
Does the parameter type of the setter match the return type of the getter?
ListTypeController doesn't have a property of the appropriate type to receive the typeService bean, or else the setter for that property is malformed. Note that if you have some proxying going on and your ListTypeController specifies the type as TypeServiceImpl, then it may be because you should be referring to the bean by its interface type, TypeService. A proxy of your typeService would be a TypeService, but not a TypeServiceImpl.
Update: Based on your new code: setTypeServic should be setTypeService, or else your property name is actually typeServic.
In my case i named my propery as: isMyProperty and is in prefix caused an issue. I had to change the name to myProperty.
In my case it was because I had correct setter and getter but each with different type.
My setter took String and parsed it to target enum type and my getter returned directly the enum.
For some reason Spring (v3) got confused.

Spring: Bean property not writable or has an invalid setter method

I'm experimenting with Spring, I'm following the book: Spring: A developer's notebook. I'm getting this error:
"Bean property 'storeName' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?"
.. and I'm quite lost.
I have an ArrayListRentABike class which implements RentABike:
import java.util.*;
public class ArrayListRentABike implements RentABike {
private String storeName;
final List bikes = new ArrayList( );
public ArrayListRentABike( ) { initBikes( ); }
public ArrayListRentABike(String storeName) {
this.storeName = storeName;
initBikes( );
}
public void initBikes( ) {
bikes.add(new Bike("Shimano", "Roadmaster", 20, "11111", 15, "Fair"));
bikes.add(new Bike("Cannondale", "F2000 XTR", 18, "22222", 12, "Excellent"));
bikes.add(new Bike("Trek", "6000", 19, "33333", 12.4, "Fair"));
}
public String toString( ) { return "RentABike: " + storeName; }
public List getBikes( ) { return bikes; }
public Bike getBike(String serialNo) {
Iterator iter = bikes.iterator( );
while(iter.hasNext( )) {
Bike bike = (Bike)iter.next( );
if(serialNo.equals(bike.getSerialNo( ))) return bike;
}
return null;
}
}
And my RentABike-context.xml is this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="rentaBike" class="ArrayListRentABike">
<property name="storeName"><value>"Bruce's Bikes"</value></property>
</bean>
<bean id="commandLineView" class="CommandLineView">
<property name="rentaBike"><ref bean="rentaBike"/></property>
</bean>
</beans>
Any ideas please?
Thanks a lot!
Krt_Malta
You're using setter injection but don't have a setter defined for attribute storeName. Either add a setter/getter for storeName or use constructor injection.
Since you already have a constructor defined that takes storeName as input i'd say change your RentABike-context.xml to the following:
<bean id="rentaBike" class="ArrayListRentABike">
<constructor-arg index="0"><value>Bruce's Bikes</value></constructor-arg>
</bean>
Since the parameter passed to the constructor will initialize the storeName, you can use the constructor-arg element to set the storeName.
<bean id="rentaBike" class="ArrayListRentABike">
<constructor-arg value="Bruce's Bikes"/>
</bean>
The constructor-arg elements allow to pass parameters to the constructor (surprise, surprise) of your spring bean.
This error occurs because of storeName not defined for value solution is in:
<bean id="rentaBike" class="ArrayListRentABike">
<property name="storeName"><value>"Bruce's Bikes"</value></property>
</bean>

Resources