Uploaded image for project: 'Causeway'
  1. Causeway
  2. CAUSEWAY-2575

PanelAbstract found to be suspectious generic by the IDE because of erasure clash.



    • Improvement
    • Status: Closed
    • Minor
    • Resolution: Fixed
    • 2.0.0-M3, 2.0.0-M4
    • 2.0.0-M5
    • Viewer Wicket
    • None


      Due to the generic handling of Wicket and Isis, there is an annoying error message in IDE (IntelliJ (IntelliJ IDEA 2020.3.2 (Ultimate Edition) Build #IU-203.7148.57) and Eclipse as well):

      'setDefaultModel(IModel model)' in 'org.apache.wicket.MarkupContainer' clashes with 'setDefaultModel(IModel model)' in 'org.apache.wicket.IGenericComponent'; both methods have same erasure yet neither overrides the other

      It is displayed on every class which is PanelAbstract descendant. The root cause is the generic-raw-generic inheritance tree branch: PanelAbstract is a generic parametrized by IModel, and its ancestor, PanelBase is originally  a generic parametrized by the content of the IModel.  Basically PanelAbstract should be declared as 

      class PanelAbstract<U, T extends IModel<U>> extends PanelBase<U>  ...

      Of course, this is inconvenient and repetitive, but Java can't infer U from T. 


      So it is fair cause to use raw type in-the-middle to change, "unbox" the parameter. But this cause a huge mess in the IDE. Two ancestors of PanelAbstract  has the same method: setDefaultModel in IGenericComponent<T, GenericPanel<T>> (which is generic, and the method is default) and MarkupContainer (which is NOT a generic) won't match any more, although their erasure won't be different: the compiler complains.

      There is a comment in PanelAbstract about this solution describing it suspectious.

      My suggestion to solve this problem:

      Simply make the PanelBase to be raw, using Panel instead of GenericPanel<T>:

      public class PanelBase extends Panel implements HasCommonContext {



      This simply solves the problem, and removes the generic-raw-generic ancestor tree mess (Panel and its ancestors are raw types), makes the inheritance cleaner.

      There are some places where PanelBase is used directly, but these can be solve easily as most of them are PanelBase<Void>.


      Other solution is to keep the generic:

      public abstract class PanelAbstract<T extends IModel<?>> 
      extends PanelBase<Object>

      but getModel will return IModel<Object> which is not compatible to T of course, so we need another method, for example getPanelModel() which returns T. This need more refactoring, so I suggest the first.



      It is a minor problem, but very annoying to develop new PanelAbstract descendant, so I would be happy to see a solution.


      Some links, in connection with this problem:






            hobrom Andi Huber
            gyorfimi Miklós Győrfi
            0 Vote for this issue
            3 Start watching this issue