Announcement Announcement Module
Collapse
No announcement yet.
Factory method problem Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Factory method problem

    Using Spring 1.2 (not 1.2.x) I am getting the following exception:

    Code:
    2005-07-13 12:17:57,933 INFO [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Creating shared instance of singleton bean 'ResourceBundle'
    2005-07-13 12:17:57,933 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Creating instance of bean 'ResourceBundle' with merged definition [Root bean with class [java.util.ResourceBundle] defined in class path resource [com/isis/icapfe/applicationContext.xml]]
    2005-07-13 12:17:57,933 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Invoking BeanPostProcessors before instantiaion of bean 'ResourceBundle'
    2005-07-13 12:17:57,933 DEBUG [org.springframework.beans.BeanWrapperImpl] - Converting String to [class java.util.Locale] using property editor [org.springframework.beans.propertyeditors.LocaleEditor@198a455]
    2005-07-13 12:17:57,933 DEBUG [org.springframework.beans.factory.support.DefaultListableBeanFactory] - Ignoring factory method [public static java.util.ResourceBundle java.util.ResourceBundle.getBundle(java.lang.String,java.util.Locale,java.lang.ClassLoader)] of bean 'ResourceBundle': could not satisfy dependencies
    org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'ResourceBundle' defined in class path resource [com/isis/icapfe/applicationContext.xml]: Unsatisfied dependency expressed through constructor argument with index 2 of type [java.lang.ClassLoader]: Ambiguous constructor argument types - did you specify the correct bean references as generic constructor arguments?
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createArgumentArray(AbstractAutowireCapableBeanFactory.java:647)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:422)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:294)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:222)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:146)
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:277)
    	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:310)
    	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>&#40;ClassPathXmlApplicationContext.java&#58;80&#41;
    	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>&#40;ClassPathXmlApplicationContext.java&#58;65&#41;
    	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>&#40;ClassPathXmlApplicationContext.java&#58;56&#41;
    	at com.isis.icapfe.ApplicationServices.<clinit>&#40;ApplicationServices.java&#58;30&#41;
    	at com.isis.icapfe.delegates.TestDelegate.<clinit>&#40;TestDelegate.java&#58;25&#41;
    	at com.isis.icapfe.test.TestCorbaDelegates.testGetPin2&#40;TestCorbaDelegates.java&#58;43&#41;
    	at sun.reflect.NativeMethodAccessorImpl.invoke0&#40;Native Method&#41;
    	at sun.reflect.NativeMethodAccessorImpl.invoke&#40;NativeMethodAccessorImpl.java&#58;39&#41;
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke&#40;DelegatingMethodAccessorImpl.java&#58;25&#41;
    	at java.lang.reflect.Method.invoke&#40;Method.java&#58;324&#41;
    	at junit.framework.TestCase.runTest&#40;TestCase.java&#58;154&#41;
    	at junit.framework.TestCase.runBare&#40;TestCase.java&#58;127&#41;
    	at junit.framework.TestResult$1.protect&#40;TestResult.java&#58;106&#41;
    	at junit.framework.TestResult.runProtected&#40;TestResult.java&#58;124&#41;
    	at junit.framework.TestResult.run&#40;TestResult.java&#58;109&#41;
    	at junit.framework.TestCase.run&#40;TestCase.java&#58;118&#41;
    	at junit.framework.TestSuite.runTest&#40;TestSuite.java&#58;208&#41;
    	at junit.framework.TestSuite.run&#40;TestSuite.java&#58;203&#41;
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests&#40;RemoteTestRunner.java&#58;474&#41;
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run&#40;RemoteTestRunner.java&#58;342&#41;
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main&#40;RemoteTestRunner.java&#58;194&#41;
    Even though I get the above error, the resource bundle works! My applicationContext.xml has:

    Code:
    <bean id="propertyConfigurer"
    		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    		<property name="location">
    			<value>com/isis/icapfe/application.properties</value>
    		</property>
    	</bean>
    
    <bean id="ResourceBundle" factory-method="getBundle" class="java.util.ResourceBundle">
    		<constructor-arg index="0" value="com/isis/icapfe/MessageBundle" type="java.lang.String" />
    		<constructor-arg index="1" value="$&#123;language&#125;" type="java.util.Locale"/>
    	</bean>
    	
    	<bean id="WrappedResourceBundle" class="com.isis.icapfe.utils.ResourceBundleWrapper">
    		<constructor-arg index="0" ref="ResourceBundle" />
    	</bean>
    I don't understand why I am getting this error - surely Spring is clever enough to realise that I am using the factory method getBundle that takes two parameters (there are other overloaded methods that take 1 and 3 params). I even specify the types of the arguments to make it unambiguous. Any ideas?

    PS: My code gets the WrappedResourceBundle bean.

  • #2
    Hiya

    Your code is correct. The fact that the output log indicates an error (when no error is in fact encountered) is a side effect of some earlier refactorings of the codebase.

    When Spring is trying to resolve the arguments to the factory method, it uses the AbstractAutowireCapableBeanFactory.createArgumentA rray method. This method is also used to resolve plain vanilla constructor arguments. The message that is generated by the log could be better, since in the case of factory methods one is not using constructor arguments. The AbstractAutowireCapableBeanFactory.createArgumentA rray doesn't know this though (the code in the AbstractAutowireCapableBeanFactory.createArgumentA rray method used to be used purely for 'proper' constructor argument resolution back in days long past).

    So I guess the answer is... ignore it. I will clean up the logged message so that the exception-that-is-not-really-an-error is a lot clearer.

    Ciao
    Rick

    Comment


    • #3
      Ok

      Interesting. I don't mind an error message, but getting an exception worried me when it did seem to work. I assume that using the latest Spring 1.2.2 won't make a difference?

      Also, I noticed that in Eclipse 3.1M4 I have a validation error on the bean in question: "No contructor with 2 arguments defined in class 'java.util.ResourceBundle'". This is annoying since the xml is correct! Any way to get rid of it (besides specifying the dtd at the top of the document)?[/u]

      Comment


      • #4
        Hi

        The issue still exists in the source from the latest CVS HEAD. To wit...

        Code:
        try &#123;
        	args = createArgumentArray&#40;beanName, mergedBeanDefinition, resolvedValues, bw, argTypes&#41;;
        &#125;
        catch &#40;UnsatisfiedDependencyException ex&#41; &#123;
        	if &#40;logger.isDebugEnabled&#40;&#41;&#41; &#123;
        		// Rick &#58; the debug call must not pass along the 'swallowed' UnsatisfiedDependencyException in the message...
        		logger.debug&#40;"Ignoring factory method &#91;" + factoryMethod + "&#93; of bean '" + beanName +
        				"'&#58; could not satisfy dependencies", ex&#41;;
        	&#125;
        	if &#40;i == candidates.length - 1 && factoryMethodToUse == null&#41; &#123;
        		throw ex;
        	&#125;
        	else &#123;
        		// Swallow and try next overloaded factory method.
        		continue;
        	&#125;
        &#125;
        I have created a JIRA issue for this...

        http://opensource.atlassian.com/proj...rowse/SPR-1127

        Ciao
        Rick

        Comment

        Working...
        X