Uploaded image for project: 'Spring Framework'
  1. Spring Framework
  2. SPR-16720

Inconsistent getTypeForFactoryMethod results for parameterized factory method

    XMLWordPrintable

    Details

    • Last commented by a User:
      true

      Description

      Hi,

      We were trying to upgrade Spring 4.2 to 4.3 version. And facing below issue while beans getting created.

      Class:
      @Component
      @RequiredArgsConstructor(onConstructor = @__(@Autowired))
      public class ClientFactory {
      public <T extends Client> T getRetryableServiceClient(final Class<T> clazz, final String qualifier) {
      }
      }

      package com.coral.client;
      public interface Client {
      }

      public class AdaptorFactory {
      @Autowired
      private NodeExecutionServiceClient nodeExecutionServiceClient;
      }

      Bean

      <bean id="nodeExecutionServiceClient" factory-bean="clientFactory"
      factory-method="getRetryableServiceClient">
      <constructor-arg index="0" value="com.nodeexecutionservice.NodeExecutionServiceClient" />
      <constructor-arg index="1" value="${NodeExecutionService.qualifier}"/>
      </bean>

      Bean creation of this was failing with error

      Exiting with throwable: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'adaptorFactory': Unsatisfied dependency expressed through field 'nodeExecutionServiceClient'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.nodeexecutionservice.NodeExecutionServiceClient' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations:

      {@org.springframework.beans.factory.annotation.Autowired(required=true)}

      I debugged into source code of spring and found issue

      Referring to this particular commit : https://github.com/spring-projects/spring-framework/commit/b9c4f1fa95a4b65e5baa6f507c0e2bfb4624b8af#diff-cc936e219ae3ea6fcf88f74629262bbd

      getTypeForFactoryMethod

      commonType comes as - com.nodeexecutionservice.NodeExecutionServiceClient
      uniqueCandidate comes as - com.coral.client.Client

      if (commonType != null)

      { // Clear return type found: all factory methods return same type. mbd.factoryMethodReturnType = (uniqueCandidate != null ? ResolvableType.forMethodReturnType(uniqueCandidate) : ResolvableType.forClass(commonType)); }

      return commonType;

      from the above code - ResolvableType of 'commonType' returned. But ResolvableType of 'uniqueCandidate' got saved in cache. My Generic question is ideally whatever we are returning, we should save that in cache as we are referring cache in the method call at the starting.

      In my case while resolving 'uniqueCandidate', '?' got saved in cache. It returned NodeExecutionServiceClient for the first call but for other subsequent calls, it's returning '?' which is causing issue.

      Why this is written like, return one resolvable type but same something else in cache which is ideally wrong ? And when 'commonType' is getting resolved correctly, rather than using why 'uniqueCandidate' is getting saved in cache ?

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              juergen.hoeller Juergen Hoeller
              Reporter:
              sandeep0940 Sandeep Donthula
              Last updater:
              Spring Issues Spring Issues
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved:
                Days since last comment:
                3 years, 24 weeks, 2 days ago