21

I'm a Spring newbie with a seemingly simple Spring problem. I worked on this for hours without luck. Here is the exception, followed by the code (thank you in advance):

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'graphiteWriterSession' defined in file [/home/user/resources/jmxtrans.graphite.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'host' of bean class [com.example.ExampleClass]: Bean property 'host' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?

My bean definitions:

<bean id="graphiteWriterSession" class="com.example.ExampleClass">
    <property name="host" value="host.example.com" />
    <property name="port" value="2023" />
    <property name="namespacePrefix" value="apps.foo.bar" />
    <property name="debug" value="true" />
</bean>

<bean id="jmxtransSession" class="com.example.MainMethodClass" factory-method="getInstance">
    <property name="graphiteWriterSession" ref="graphiteWriterSession" />
</bean>

The code snippet:

package com.example.ExampleClass;
import com.googlecode.jmxtrans.model.output.GraphiteWriter;

public class ExampleClass {

   private static final long   serialVersionUID = 1L;
   private String              host;
   private int                 port;
   private GraphiteWriter      gw;

  public ExampleClass() {
  }

  public GraphiteWriter getWriter() {
    gw = new GraphiteWriter();
    gw.addSetting(GraphiteWriter.PORT, port);
    gw.addSetting(GraphiteWriter.HOST, host);
    return gw;
  }

  // =====================================================
  // set/get methods for Carbon host.
  // Plugged into Spring application-context file.
  // =====================================================
  public void setCarbonHost( String host ) {
       this.host = host;
  }

  public String getCarbonHost() {
       return host;
  }
  // =====================================================


  // =====================================================
  // set/get methods for Carbon port.
  // Plugged into Spring application-context file.
  // =====================================================
  public void setCarbonPort( int port ) {
      this.port = port;
  }

  public int getCarbonPort() {
      return port;
  }
  // =====================================================
}

I didn't include the driver (main method containing) class here. Although that driver class depends on the above class, the driver class itself does not have a problem (I don't believe).

The error above shows the 'host' property as having the problem but, as you might expect, the 'port' property has the same issue (it's just so happens that the 'host' property is evaluated first).

Can anyone tell me where I'm going wrong? Feel free to explain if you wish, as I'm not a Spring person, per se. Thank you.

NYCeyes
  • 5,215
  • 6
  • 57
  • 64

4 Answers4

21

1) For host you should define public getHost() and setHost(String s)
methods, similarly for port you need getPort() and setPort(int v) methods.

This is what Spring needs to initialize your bean.

I think it needs the setter in particular (in this case).

Or ...

2) You can rename the properties in your XML file to

carbonHost and carbonPort. This should do it too.

peter.petrov
  • 38,363
  • 16
  • 94
  • 159
  • Thank you Peter. It worked, and can I tell you that, on a hunch, I actually tried that a few hours ago. It didn't then, but you know how debugging goes -- I might have momentarily changed something else which still gave rise to the same issue. For my understanding: I had assumed that Spring (which I've only used for two days) matched property "name" to the method it finds that sets it. But I guess there could be any number of methods that sets a property value. So: if name = "fooBar", then your setter/getter names should be setFooBar() and getFooBar()? – NYCeyes Feb 06 '14 at 21:05
  • 1
    "So: if name = "fooBar", then your setter/getter names should be setFooBar() and getFooBar()?" Exactly, it looks for this naming convention. And ... So if your property is someName, the getter/setter should be setSomeName, getSomeName. You may define more getters/setters but Spring looks for these two. – peter.petrov Feb 06 '14 at 21:13
  • 1
    also please note the case sensitivity, as in my case I had mentioned name="FooBar" which is wrong – shabby Jun 10 '15 at 12:23
8

The problem is that you are using <property name="port" value="2023" /> in your bean configuration, but the corresponding method in the ExampleClass is called setCarbonPort(int port).

Solution: update either the xml to <property name="carbonPort" value="2023" /> or the method to setPort(int port).

matsev
  • 32,104
  • 16
  • 121
  • 156
2

The getters and setters must be public, any other access level will cause the error.

RancidVess
  • 21
  • 1
-1

Property elements correspond to JavaBean setter methods exposed by the bean classes.

The setters and getters of dependency in the bean has to be in accordance with the property element's name attribute.

Therefore, in your case the property has name attribute value as "host" then the setter has to be "setHost()" instead of "setCarbonHost()". However if you want your method to be named as "setCarbonHost()" only then property needs name attribute value to be as "carbonHost".