Details
-
Bug
-
Status: Open
-
Major
-
Resolution: Unresolved
-
1.0
-
None
-
None
Description
Initializing a property with a "ref" element fails with complex generics
public interface EndpointHandler {}
public interface EndpointServer <H extends EndpointHandler>{}
public interface HandlerFactory <S> {}
public abstract class AbstractFactory <H extends EndpointHandler, S extends EndpointServer<H>>{ HandlerFactory<S> handlerFactory = null; public HandlerFactory<S> getHandlerFactory() { return handlerFactory; } public void setHandlerFactory(HandlerFactory<S> handlerFactory) { this.handlerFactory = handlerFactory; } }
public class ConcreteFactory extends AbstractFactory<MyHandler, MyServer<MyHandler>> { }
public class ConcreteHandlerFactory implements HandlerFactory<MyServer<MyHandler>> {}
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:ext="http://aries.apache.org/blueprint/xmlns/blueprint-ext/v1.2.0"> <bean id="concreteHandlerFactory" class="bugtest.ConcreteHandlerFactory" /> <bean id="concreteFactory" class="bugtest.ConcreteFactory"> <property name="handlerFactory" ref="concreteHandlerFactory" /> </bean> </blueprint>
The problem manifests in
if (from.equals(to)) { return true; } if (from.getRawClass() == to.getRawClass()) { if (to.size() == 0) { return true; } if (from.size() == to.size()) { boolean ok = true; for (int i = 0; i < from.size(); i++) { ReifiedType tf = from.getActualTypeArgument(i); ReifiedType tt = to.getActualTypeArgument(i); if (!isWildcardCompatible(tf, tt)) { <<================= HERE ok = false; break; } } if (ok) { return true; } } } else { ReifiedType t = getExactSuperType(from, to.getRawClass()); if (t != null) { return isTypeAssignable(t, to); } } return false; }
ReifiedType tt has the correct generic class EndpointServer but has 0 parameters. So the assignment fails.
Hacking this with a property of type"Object" and a cast works. The type structure and assignment also work in rather ancient spring-dm