EL and covariant return types

2019-07-05 23:39发布

问题:

i have these classes

public abstract class Unit
{
    public abstract UnitType getType();

    ...
}

public class Item extends Unit
{
    protected ItemType type;

    @Override
    public ItemType getType()
    {
        return type;
    }

    public void setType(ItemType type)
    {
        this.type = type;
    }

    ...
}

and obvoiusly ItemType extends UnitType.

and i get:

javax.el.PropertyNotWritableException: /WEB-INF/facelets/general.xhtml @23,165 value="#{bean.item.type}": The class 'com.example.Item' does not have a writable property 'type'.

i can understand that covariant return type can confuse EL (2.2), so is this a bug?

i can workaround this using

  1. generics
  2. change setType signature to public void setType(UnitType type) and check instanceof inside
  3. change method name to avoid override

is there a REAL solution instead of workarounds?

回答1:

Seems like java.beans.Introspector is responsible. There were a lot of relevant bugs in Java: 7092744, 7122138, 6528714, 6794807, 6788525. Problems manifest with covariant return types and generics due to synthetic bridge methods. With some Java 7 updates (45, 51, 67, 71) problems manifest not right way but after running the server for some time - this is probably related to softly/weakly referenced caches in the Introspector and related classes.

All these problems seem to be fixed in Java 1.7.0_80 (tested with Mojarra 2.2.8 and Wildfly 8.2.0.Final).