Uploaded image for project: 'Wicket'
  1. Wicket
  2. WICKET-7086

Injecting Spring bean may cause ClassCastException

Attach filesAttach ScreenshotVotersWatch issueWatchersCreate sub-taskLinkCloneUpdate Comment AuthorReplace String in CommentUpdate Comment VisibilityDelete Comments
    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Minor
    • Resolution: Fixed
    • 9.15.0
    • 10.0.0, 9.17.0
    • wicket-spring
    • None

    Description

      Issue Summary:

      The getBeanNameOfClass() method used for injecting Spring beans into Wicket components has a limitation when dealing with generic collection fields. The method is designed to look up a bean name based on the raw type of the collection (e.g., List). However, in scenarios where there are beans with more specific generic types (e.g., List<SomeClass>), the method incorrectly resolves and injects the bean, leading to potential ClassCastException issues at runtime.

      Problem Details:

      When the field class is a generic collection (e.g., List<AnyClass>), the getBeanNameOfClass() method resolves a bean with the type of the raw collection (e.g., List). This behavior generally works as intended. However, when there are beans with more specific generic types (e.g., List<SomeClass>), the method incorrectly identifies and injects the bean, even if the generic types (SomeClass and AnyClass) do not match. This results in unexpected behavior and may cause ClassCastException errors later in the application.

      Reproduction Scenario:

      This issue becomes apparent when using Apache Causeway in conjunction with Spring Data REST.  There is a bean named defaultMessageConverters (wich is a List) is inserted into CausewayWicketApplication within the applicationInitializers field, it is erroneously resolved based on the raw type, leading to improper injection.

      Proposed Solution:

      Review and enhance the getBeanNameOfClass() method to consider generic types more accurately, ensuring that beans are resolved based on compatibility with the field's specific generic type. 

      Problem is here:

       

      List<String> names = new ArrayList<>(
          Arrays.asList(BeanFactoryUtils.beanNamesForTypeIncludingAncestors(ctx, clazz)));
       

       

      It uses the clazz, without generic.

      Possible solution:

       

      ResolvableType resolvableType = generic != null ? ResolvableType.forClassWithGenerics(clazz, generic) : ResolvableType.forClass(clazz);
      List<String> names = new ArrayList<>(
          Arrays.asList(BeanFactoryUtils.beanNamesForTypeIncludingAncestors(ctx, resolvableType)));
       

       

      It is compatible with Spring from 4.2. 

       

      Additional Context:

      This problem affects scenarios where generic collections are used in Spring-Wicket integration, and it becomes particularly prominent when Apache Causeway is utilized alongside Spring Data REST.

       

      Attachments

        Activity

          This comment will be Viewable by All Users Viewable by All Users
          Cancel

          People

            mgrigorov Martin Tzvetanov Grigorov
            gyorfimi Miklós Győrfi
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Slack

                Issue deployment