jersey
  1. jersey
  2. JERSEY-635

BeanNotOfRequiredTypeException when using spring annotation based proxies

    Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Affects Version/s: 1.5
    • Fix Version/s: 1.x-backlog
    • Component/s: extensions
    • Labels:
      None

      Description

      Hi,

      Using the following scenario, I get a BeanNotOfRequiredTypeException when retrieving the bean from the context.

      @Path("/service")
      public interface IJerseyTestService{
      @GET
      @Path("test")
      @PreAuthorize("hasRole('ROLE_USER')")
      public String test();
      }

      @Component
      public class JerseyTestService implements IJerseyTestService{
      public String test()

      { return "jersey test"; }

      }

      The problem is with SpringComponentProviderFactory.registerSpringBeans. this method checks if ResourceConfig.isRootResourceClass(type) but even if the annotation is defined in the interface, it adds concrete class (rc.getClasses().add(type)) to the ResourceConfig instead of the interface.

      Consequently, when the resource is invoked, the SpringManagedComponentProvider.getInstance will throw

      org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'jersey' must be of type [com.meridianp2p.stf.connector.http.JerseyTestService], but was actually of type [$Proxy69]

      because the bean is proxied.

      The solution is simply to change the SpringComponentProviderFactory.registerSpringBeans to something like:

      private void registerSpringBeans(final ResourceConfig rc) {

      String[] names = BeanFactoryUtils.beanNamesIncludingAncestors(springContext);

      for (String name : names) {
      Class<?> type = ClassUtils.getUserClass(springContext.getType(name));
      if (ResourceConfig.isProviderClass(type))

      { LOGGER.info("Registering Spring bean, " + name + ", of type " + type.getName() + " as a provider class"); rc.getClasses().add(type); }

      else if (ResourceConfig.isRootResourceClass(type)) {
      if (!type.isAnnotationPresent(Path.class)) {
      for (Class i : type.getInterfaces()){
      if (i.isAnnotationPresent(Path.class))

      { type = i; break; }

      }
      }
      LOGGER.info("Registering Spring bean, " + name +
      ", of type " + type.getName() +
      " as a root resource class");
      rc.getClasses().add(type);
      }
      }
      }

        Activity

        Hide
        tugando added a comment -

        I was facing the same issue. Thanks, this helped me solve it. When will this fix be implemented into a release? Anyone who wants to expose a Spring Java-Proxied bean as a Jersey resource, is bound to run into this issue.

        Show
        tugando added a comment - I was facing the same issue. Thanks, this helped me solve it. When will this fix be implemented into a release? Anyone who wants to expose a Spring Java-Proxied bean as a Jersey resource, is bound to run into this issue.

          People

          • Assignee:
            Unassigned
            Reporter:
            aledibe
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated: