springapache-camelspring-beanblueprint-osgi

MethodInvokingFactoryBean returns itself instead of desired object


I am trying to use a MethodInvokingFactoryBean to get an instance of a com.amazonaws.regions.Region for use in configuring a com.amazonaws.services.kinesis.AmazonKinesisClient. I am doing this in Blueprint, Camel, Karaf.

<bean id="awsRegion" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetClass" value="com.amazonaws.regions.RegionUtils"/>
    <property name="targetMethod" value="getRegion"/>
    <property name="arguments">
        <list>
            <value>EU-WEST-1</value>
        </list>
    </property>
</bean>

<bean id="kinesisClient" class="com.amazonaws.services.kinesis.AmazonKinesisClient">
    <property name="region" ref="awsRegion"/>
</bean>

This seems like it should work, with the first bean creating a Region, and the second bean using it.

However, I get an error that makes it seem like the MethodInvokingFactoryBean is just returning an instance of itself instead of Region.

org.osgi.service.blueprint.container.ComponentDefinitionException: Error setting property: PropertyDescriptor <name: region, getter: null, setter: [class com.amazonaws.AmazonWebServiceClient.setRegion(class com.amazonaws.regions.Region)]
...
Caused by: java.lang.Exception: Unable to convert value org.springframework.beans.factory.config.MethodInvokingFactoryBean@2289c050 to type com.amazonaws.regions.Region

The method I'm invoking in RegionUtils should return a Region https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/regions/RegionUtils.html#getRegion-java.lang.String-

I came upon this way of getting the Region in the Client in this question, where the solution seemed to work for the asker.

Bind aws sqs region camel


Solution

  • At first , apache-camel tag is excess here. As second, you missed that asker is using spring context and you are using blueprint context. Try something like this:

    <bean id="awsRegion" class="com.amazonaws.regions.RegionUtils" factory-method="getRegion">
        <argument value="EU-WEST-1"/>
    </bean>
    
    <bean id="kinesisClient" class="com.amazonaws.services.kinesis.AmazonKinesisClient">
        <property name="region" ref="awsRegion"/>
    </bean>
    

    EDIT: just tested this example with latest aws-java-sdk and it is worked