Ad

ConversionNotSupportedException: Failed To Convert Property Value Of Type 'grails.spring.BeanBuilder' To Required Type 'java.lang.String'

- 1 answer

I'm working on this grails-aws plugin and get a strange error trying to run under Grails 2.3.4 and 2.3.5.

See travis build output where the tests pass for Grails 2.0.4 / 2.2.4, but fail for 2.3.4 / 2.3.5

Has something changed with grails 2.3.x in the area of reading values from config files?

Error creating bean with name 'credentialsHolder': Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'grails.spring.BeanBuilder' to required type 'java.lang.String' for property 'accessKey'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [grails.spring.BeanBuilder] to required type [java.lang.String] for property 'accessKey': no matching editors or conversion strategy found (NOTE: Stack trace has been filtered. Use --verbose to see entire trace.)

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'credentialsHolder': Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'grails.spring.BeanBuilder' to required type 'java.lang.String' for property 'accessKey'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [grails.spring.BeanBuilder] to required type [java.lang.String] for property 'accessKey': no matching editors or conversion strategy found
Ad

Answer

This is explained in this Grails JIRA - apparently the BeanBuilder invokes its closures with "delegate first" behaviour, but there was previously a bug in Groovy that meant calls that matched a static method of the containing scope ignored the resolve strategy setting and called the static method anyway. In other words the code you've previously been using only ever worked by accident. You should still be able to call the static method if you qualify it with the class name AwsPluginSupport.read(...).

Alternatively you could skip the gymnastics entirely - use literal '${....}' expressions for the bean properties and let the property placeholder mechanism pull the values out of the config for you. I.e. instead of

credentialsHolder(AWSCredentialsHolder) {
        accessKey  = readString("credentials.accessKey")
        secretKey  = readString("credentials.secretKey")
        properties = readString("credentials.properties")
}

use

credentialsHolder(AWSCredentialsHolder) {
        accessKey  = '${grails.plugin.aws.credentials.accessKey}'
        secretKey  = '${grails.plugin.aws.credentials.secretKey}'
        properties = '${grails.plugin.aws.credentials.properties}'
}

Note that it's important that these are single quoted strings (so the value is an expression including ${} that Spring can resolve) and not double quoted GStrings (which would [fail to] be resolved by Groovy at parse time).

Ad
source: stackoverflow.com
Ad