users@jersey.java.net

Re: [Jersey] Simplifying Jersey life-cycle and IoC integration

From: Gili <cowwoc_at_bbs.darktech.org>
Date: Mon, 24 Nov 2008 12:00:24 -0800 (PST)

I just learned something useful by trying a concrete example. I invoked:

                System.out.println("uri=" +
UriBuilder.fromUri(uriInfo.getBaseUri()).path(getClass()).build());

and this exception is thrown:

java.lang.IllegalArgumentException: The class, class
adcaster.server.resources.TerminalsResource$$EnhancerByGuice$$13b1709e is
not annotated with @Path
        at
com.sun.jersey.api.uri.UriBuilderImpl.path(UriBuilderImpl.java:217)
        at
adcaster.server.resources.TerminalsResource.listTerminals(TerminalsResource.java:73)

Here are my assumptions:

1) For proxy by encapsulation, you need a method to return the unproxied
object: "Object getInjectableObject(Object proxy)". You can look up Jersey
annotations and inject fields directly into this object.

2) For proxy by extension, you need a method to return the class being
proxied: "Class<?> getInjectableClass(Class<?> proxy)". You must look up
Jersey annotations on that class (not the proxy) and inject fields into the
proxy object.

So here are my updated recommendations...

- Have IoC framework implement the following methods:

/**
 * Returns the object that fields should be injected into.
 *
 * @param o the object returned by getInstance()
 * @return the object that fields should be injected into
 */
public Object getInjectableObject(Object o);

/**
 * Returns the class to search for Jersey annotations.
 *
 * @param c a class passed to Jersey (may be a proxy)
 * @return the class to search for Jersey annotations
 */
public Class<?> getInjectableClass(Class<?> c);

- Then have UriBuilderImpl invoke getInjectableClass()
- There seems to be a typo in the exception message "class, class".

What do you think?

Gili


Gili wrote:
>
>
> Paul Sandoz wrote:
>>
>> The important point here is that the returned instance can be injected
>> on by Jersey correctly. That is why the method is called
>> getInjectableInstance. The single use-case that has been driving this
>> so far has been Spring-AOP, where proxy by encapsulation can occur
>> rather than proxy by extension (see snippet of Spring-based code at
>> end of email).
>>
>> Given an instance of Foo and an instance of Foo$$EnhancerByGuice$
>> $45c70c66 are the fields on the class Foo accessible and can those
>> fields be modified when given an instance of Foo$$EnhancerByGuice$
>> $45c70c66. If so then getInjectableInstance can just return the
>> instance that is passed in.
>>
>
> Unfortunately this won't work. I just fired up the debugger against Guice
> proxies and it seems I was right the first time around. Guice is using
> CGLIB to construct proxies that contain the data directly instead of
> redirecting method calls to an unproxied class.
>
> If I were to simply return o, Jersey wouldn't be able to find the @Path
> annotation because the proxy subclass does not contain it.
>
> I am suggesting the following:
>
> 1) Proxy by encapsulation (proxy methods redirect to unproxied object)
>
> Class<?> getInjectableClass(Object original)
> {
> return getInjectableObject(original).getClass();
> }
>
> Object getInjectableObject(Original original)
> {
> // return unproxied object
> }
>
> 2) Proxy by extension (proxy contains actual data)
>
> Class<?> getInjectableClass(Object original)
> {
> return original.getClass().getSuperclass();
> }
>
> Object getInjectableObject(Original original)
> {
> return original;
> }
>
> Jersey would then look up @Path and other annotations on the class
> returned by getInjectableClass() and inject into the object returned by
> getInjectableObject().
>
> The only thing I don't like about the above methods is that Spring's
> implementation of getInjectableClass() needs to invoke
> getInjectableObject() a second time. Ideally we want a single method that
> returns both Class and Object at the same time.
>
> Gili
>

-- 
View this message in context: http://n2.nabble.com/Simplifying-Jersey-life-cycle-and-IoC-integration-tp1367641p1573484.html
Sent from the Jersey mailing list archive at Nabble.com.