Announcement Announcement Module
Collapse
No announcement yet.
Groovy property setting error Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Groovy property setting error

    Hi,

    I have simple description

    <lang:groovy id="messenger" script-source="classpath:org/springframework/scripting/groovy/Messenger.groovy">
    <langroperty name="message" value="Hello World!"/>
    </lang:groovy>

    but I get error:

    Exception in thread "main" org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'setup' defined in class path resource [myrsik1.xml]: Cannot resolve reference to bean 'messenger' while setting constructor argument with key [0]; nested exception is

    org.springframework.beans.factory.BeanCreationExce ption:
    Error creating bean with name 'messenger': Error setting property values;
    nested exception is org.springframework.beans.NotWritablePropertyExcep tion: Invalid property 'message' of bean class [org.springframework.scripting.groovy.GroovyScriptF actory]:
    Bean property 'message' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?

    Caused by: org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'messenger': Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyExcep tion: Invalid property 'message' of bean class [org.springframework.scripting.groovy.GroovyScriptF actory]: Bean property 'message' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
    Caused by: org.springframework.beans.NotWritablePropertyExcep tion: Invalid property 'message' of bean class [org.springframework.scripting.groovy.GroovyScriptF actory]: Bean property 'message' 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.setPrope rtyValue(BeanWrapperImpl.java:699)
    at org.springframework.beans.BeanWrapperImpl.setPrope rtyValue(BeanWrapperImpl.java:575)
    at org.springframework.beans.AbstractPropertyAccessor .setPropertyValue(AbstractPropertyAccessor.java:49 )
    at org.springframework.beans.AbstractPropertyAccessor .setPropertyValues(AbstractPropertyAccessor.java:6 8)
    at org.springframework.beans.AbstractPropertyAccessor .setPropertyValues(AbstractPropertyAccessor.java:5 7)
    at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.applyPropertyValues(Abs tractAutowireCapableBeanFactory.java:813)
    at org.springframework.beans.factory.support.Abstract AutowireCapableBeanFactory.populateBean(AbstractAu towireCapableBeanFactory.java:589)


    Why property is not writable?
    Groovy doesn't need setter method?


    Please help


    Thanks
    tom

  • #2
    Hi Tom

    Odd. The 'message' property is failing to be set because there is no 'message' property on the GroovyScriptFactory class. WHich is as I say odd because you are not setting the property value on the GroovyScriptFactory, you are setting it on your Messenger.

    I am at a loss to address this without seeing more of your configuration and your Groovy script itself (I daresay that it is the same as the one that ships with Spring). Post them please.

    Cheers
    Rick

    Comment


    • #3
      I made simplified test case.

      beans.xml
      ----------------
      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:lang="http://www.springframework.org/schema/lang"
      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schem...ring-beans.xsd
      http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd">

      <!-- this is the bean definition for the Groovy-backed Messenger implementation -->
      <lang:groovy id="messenger" script-source="classpath:org/springframework/scripting/groovy/Messenger.groovy">
      <langroperty name="message" value="I Can Do The Frug" />
      </lang:groovy>

      </beans>

      Messanger.groovy
      ----------------------

      package org.springframework.scripting.groovy;

      class GroovyMessenger {

      @Property String message;
      }

      Attached please find groman project files and
      workspace picture.

      Thanks, Rick!

      Comment


      • #4
        Hi Tom

        Short answer: use an ApplicationContext implementation, and not a simple BeanFactory. To wit:

        Code:
        package man;
        
        import org.springframework.context.ApplicationContext;
        import org.springframework.context.support.ClassPathXmlApplicationContext;
        
        public class Groman {
        
            public static void main(String[] args) {
                // ClassPathResource res = new ClassPathResource("beans.xml");
                // XmlBeanFactory factory = new XmlBeanFactory(res);
        
                ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
                Object obj = ctx.getBean("messenger");
                System.out.println(obj);
                
                // prints something like 'org.springframework.scripting.groovy.GroovyMessenger@d3c65d'
            }
        }
        (You will also need to have the following libraries on your project classpath in addition to Spring, Commons Logging, and Groovy: antlr-2.7.6.jar and asm-2.2.2.jar. I have already added sidebars to the dynamic languages chapter documenting the libraries required for each supported dynamic language.)

        Long(ish) answer: use an ApplicationContext implementation, and not a simple BeanFactory, because the scripting support utilises a BeanPostProcessor implementation (ScriptFactoryPostProcessor) to transparently replace dynamic language bean definitions with AOP proxies so that everything works correctly.

        The reference documentation is not explicit about this, so I will go back and make some (small) changes in light of your post. Thanks for spotting this prior to the final release.

        Also, you will really also want to have your Groovy class declaration implement an interface. In the case of your example, be sure to implement the Messenger interface like so:

        Code:
        package org.springframework.scripting.groovy;
        
        class GroovyMessenger implements Messenger {
        
            @Property String message;
        
        }
        Cheers
        Rick

        Comment


        • #5
          Catch fatal exception during invalid script loading

          Hi Rick

          Problem solved, Thanks!!

          Sorry to bother you again,
          Spring is great but learning takes some time

          I have dynamic data flow router implemented in Groovy.
          I want to use 'refreshable bean' feature.

          I understand what script must be tested before usage but still itís possible what script is invalid.
          Any exceptions relating to refreshing the script (such as encountering a compilation error, or finding that the script file has been deleted) will result in a fatal exception being propagated to the calling code.

          Loading script (and compilation error) occurs then router receives incoming message.
          Due to compilation error incoming message is lost.

          Actually router itself is fully functional (using previous error-free Groovy script) and next messages are handled correctly.

          So the only bad thing is lost message during invalid Groovy script loading.
          Is where any possibility to change behavior?
          Catch fatal exception and still let router execute previous correct Groovy code?

          Tom

          Comment

          Working...
          X