Hatem
Hatem

Reputation: 589

Error creating bean

This is the error trace that am get :

 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'DefaultPG' defined in file [C:\Users\ali\workspace\tms-payment\PaymentGatewayConfigurations.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'paymentGatewayName' of bean class [me.tms.payment.common.DefaultPaymentGateway]: Bean property 'paymentGatewayName' 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.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1361)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1086)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1075)
at me.tms.payment.common.DefaultPaymentGateway.getPaymentGatewayName(DefaultPaymentGateway.java:12)
at me.tms.payment.test.DefaultPaymentGatewayTest.test(DefaultPaymentGatewayTest.java:16)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)
at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:87)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)
at org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:88)
at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'paymentGatewayName' of bean class [me.tms.payment.common.DefaultPaymentGateway]: Bean property 'paymentGatewayName' 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:1024)
at org.springframework.beans.BeanWrapperImpl.setPropertyValue(BeanWrapperImpl.java:900)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:76)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:58)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1358)
... 30 more

This is the class reported :

package me.tms.payment.common;

import me.tms.payment.configurations.ConfigurationsUtility;
import me.tms.payment.configurations.PaymentGatewayConfigurations;

 public class DefaultPaymentGateway {

private static String paymentGatewayName;

@SuppressWarnings("static-access")
public static String getPaymentGatewayName() {
    DefaultPaymentGateway defaultPaymentGateway = (DefaultPaymentGateway)ConfigurationsUtility.getBeanConfigurationContext(PaymentGatewayConfigurations.configurationsFile).getBean("DefaultPG");
     setPaymentGatewayName(defaultPaymentGateway.paymentGatewayName);
    return paymentGatewayName;
}

public static void setPaymentGatewayName(String paymentGatewayName) {
    DefaultPaymentGateway.paymentGatewayName = paymentGatewayName;
}

}

and this is the bean :

<!-- Default payment gateway properties -->
<bean id="DefaultPG" class="me.tms.payment.common.DefaultPaymentGateway" scope="prototype">
    <property name="paymentGatewayName" value="VPC"></property>
</bean> 

Whats the problem ?

Upvotes: 0

Views: 5588

Answers (4)

Hari Menon
Hari Menon

Reputation: 35405

Beans cannot be static classes. They need to be instantiated by Spring internally. And static classes obviously cannot be instantiated. Use this instead:

public class DefaultPaymentGateway {

    private static String paymentGatewayName = "VPN";

    public String getPaymentGatewayName() {
        return paymentGatewayName;
    }

    public void setPaymentGatewayName(String paymentGatewayName) {
        paymentGatewayName = paymentGatewayName;
    }

}

You should not be doing so much inside the getter/setter methods. Getter should just return the property and setter should just set it. Calling other getters/setters from them is recipe for trouble.

Upvotes: 1

Ajinkya
Ajinkya

Reputation: 22710

You cant inject static properties in bean thats the shortcoming of Spring.
Jira for the same https://jira.springsource.org/browse/SPR-3845

Workaround

  1. Create the static property of the class without any annotations
  2. Mark the class to have static properties injected with @Component so that the properties will be injected on Spring startup
  3. Create a non-static setter method that sets the static property
  4. Mark the setter method with @Autowired(required = true)

Source: http://www.connorgarvey.com/blog/?p=105 and Injecting values for static constants in Spring

Upvotes: 1

bluesman
bluesman

Reputation: 2260

Dont use static setters, remove the static keyword in your setter

Upvotes: 0

Subin Sebastian
Subin Sebastian

Reputation: 10997

Bean property 'paymentGatewayName' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?

Reason is paymentGatewayName is static . It is not propery of an Object, instead there is only one BeanName.paymentGatewayName in your jvm. You cant autowire a static bean property.

remove

<property name="paymentGatewayName" value="VPC"></property> and set it in your class itself.

private static String paymentGatewayName="VPC";

or make it non static.

Upvotes: 1

Related Questions