On Tue, Apr 28, 2009 at 2:47 PM, Tatu Saloranta <tsaloranta_at_gmail.com> wrote:
> Hmmh. I think the problems are more due to my forgetting to add
>
> @Context Providers providers;
>
> injection, which is then to be used for locating actual things I need.
> That works with providers; I'll see how simple I can make it, starting
> from state that works. :)
Ok, second try. I don't know if this is a bug or not, but it seems suspicious.
So, given super-class like:
---
static abstract class SimpleResolver<T>
implements ContextResolver<T>
{
final T _context;
protected SimpleResolver(T ctxt) {
_context = ctxt;
}
public T getContext(Class<?> type) {
return _context;
}
}
---
following sub-class does NOT work wrt provider registration:
---
@Provider
static class ObjectMapperResolver
extends SimpleResolver<ObjectMapper>
{
public ObjectMapperResolver(ObjectMapper m) { super(m); }
}
---
however, adding 'implements' in there, like so:
---
@Provider
static class ObjectMapperResolver
extends SimpleResolver<ObjectMapper>
implements ContextResolver<ObjectMapper>
{
public ObjectMapperResolver(ObjectMapper m) { super(m); }
}
---
makes it click. I don't if that's due to introspection code not
following super-class hierarchy to find implemented interfaces (since
implemented super-interfaces are NOT included in Class information for
sub-class); or if it's that implemented interface is ContextResolver<T
== Object>,
or if it's compiler adding synthetic bridge methods. So many ways to
get it wrong. :)
If latter, it means that whereas super class basically has equivalent of:
public Object getContext(Class);
(due to type erasure etc)
compiler does synthesize method like:
public ObjectMapper getContext(Class)
for sub-class, to make things works; these are I think called "bridge" methods.
In the end, perhaps there should be an exception or warning if anyone
tries to register "ContextResolver<Object>" (or type variable)?
That seems like a common failure mode; and I can't think of a reason
to register resolver for Object.class.
-+ Tatu +-