DI Florian Hackenberger created TAP5-2032:
---------------------------------------------

             Summary: GenericsUtils does not handle generics properly when 
extracting the actual type
                 Key: TAP5-2032
                 URL: https://issues.apache.org/jira/browse/TAP5-2032
             Project: Tapestry 5
          Issue Type: Bug
          Components: tapestry-ioc
    Affects Versions: 5.3.6
            Reporter: DI Florian Hackenberger


We have the following interfaces / classes

public interface IPersonWithRoleAssociation<A> extends 
IEntityAssociationWithInfo<A, Person> {
        PersonRole getRole();
        void setRole(PersonRole role);
}

public interface IEntityAssociationWithInfo<P, C> {
        P getParent();
        void setParent(P parent);

        C getChild();
        void setChild(C child);
}

public class Person implements Serializable {
        ....
        String name;
        public String getName() {
                return name;
        }
}

and the page:

public class EditPersonsWithRoles {
        @Property(write=false) IPersonWithRoleAssociation<A> personWithRole;
}

and the template snippet:

<t:textfield t:id="personSex" t:value="personWithRole.child.name"/>

Leads to the following exception:

Exception generating conduit for expression 'personWithRole.child.name': ...
...
Caused by: java.lang.ArrayIndexOutOfBoundsException: 1
        at 
org.apache.tapestry5.ioc.internal.util.GenericsUtils.resolve(GenericsUtils.java:388)
 ~[tapestry-ioc-5.3.6.jar:na]
        at 
org.apache.tapestry5.ioc.internal.util.GenericsUtils.resolve(GenericsUtils.java:128)
 ~[tapestry-ioc-5.3.6.jar:na]
        at 
org.apache.tapestry5.ioc.internal.util.GenericsUtils.extractActualType(GenericsUtils.java:74)
 ~[tapestry-ioc-5.3.6.jar:na]
        at 
org.apache.tapestry5.internal.services.PropertyConduitSourceImpl$PropertyConduitBuilder.buildGetterMethodAccessTerm(PropertyConduitSourceImpl.java:1119)
 ~[tapestry-core-5.3.6.jar:na]

At GenericsUtils.java:388 we have:
resolved = ((ParameterizedType) t).getActualTypeArguments()[i];
where:
i = 1
resolved = C
((ParameterizedType) t).getActualTypeArguments() = 
[org.topfive.entities.IPersonWithRoleAssociation<P>]

so the problem seems to be that the code assumes that it can find the type 
information for C as the second generic parameter for 
IPersonWithRoleAssociation, when in fact is is the second generic parameter for 
the superclass IEntityAssociationWithInfo which IPersonWithRoleAssociation 
extends and passes C explicitly (Person). Everything is fine, if I use a marker 
interface for Person (IPerson) and declare:

public interface IPersonWithRoleAssociation<A, P extends IPerson> extends 
IEntityAssociationWithInfo<A, P>

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to