users@jersey.java.net

Re: Jersey 0.6 and Spring

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Tue, 19 Feb 2008 10:56:44 +0100

BTW what i really want to do is distribute a jersey-spring.jar with the
Jersey distribution that has common Jersey/Spring integration classes
(that have been documented and tested) so that Spring developers don't
keep having to write and maintain their own stuff.

However, i am maxed out and don't have the time to do this at the
moment. Any volunteers ? :-)

Paul.

Paul Sandoz wrote:
> Hi Tom,
>
> When you run your application and issue a request are you seeing some
> output like the following:
>
> Scanning for root resource and provider classes in the paths:
> <web app>/build/web/WEB-INF/lib
> <web app>/build/web/WEB-INF/classes
> Root resource classes found:
> class com.atlassian.crucible.spi.rpc.RestReviewService
>
> ? If so your ComponentProvider.getInstance method should be getting
> called with Scope.WebApplication and the root resource Class shown
> above. If not how are you configuring the web application ?
>
>
> I have attempted to improve the JavaDoc in the latest build. Currently
> the way it is implemented is Jersey will defer to the supplied
> ComponentProvider for all instances of components it needs to create
> (including infrastructure components). Note that root resource classes
> are just one type of component in Jersey. From the perspective of the
> ComponentProvider it does not care what the type of the component is but
> should care what the requested scope is.
>
> If the supplied ComponentProvider returns null (meaning that it does not
> support the the component) then Jersey will instantiate the component
> instead i.e. it is a sort of "keep on trucking" approach, which means
> one can mix Spring and non-Spring managed root resource classes as well
> as other types of component.
>
> This is why the example SpringComponentProvider does the following:
>
> private String getBeanName(Class c) {
> // Look up the bean names
> String names[] = springContext.getBeanNamesForType(c);
> if (names.length == 0) {
> // If not found return null
> return null;
> } else if (names.length > 1) {
> throw new RuntimeException(
> "Multiple configured beans for "
> + c.getName());
> }
> return names[0];
> }
>
> public Object getInstance(Scope scope, Class c)
> throws InstantiationException, IllegalAccessException {
> // look up the bean name from the class
> String beanName = getBeanName(c);
> // Cannot find the beanName for the class
> // return null and let Jersey be responsible for
> // managing that component
> if (beanName == null) return null;
>
> ...
> }
>
> I could restrict things such that the infrastructure components are
> instantiated and managed by Jersey without deferring to the
> ComponentProvider but application-defined components are deferred to the
> supplied ComponentProvider. For example if one wants application-defined
> message body readers/writers to be managed by Spring, then one could
> have this class:
>
> @Provider
> public class MyReader implements MessageBodyReader<MyType> {
> // inject some Spring stuff here
> ...
> }
>
> registered in the application context as a singleton. Jersey will defer
> to the ComponentProvider to instantiate this class and will ask the
> component provider that the life-cycle should be WebApplication
> (equivalent to singleton in Spring).
>
> I could probably better name the Scope enums, perhaps keep it the same
> as in Spring would be clearer?
>
> Hope this helps,
> Paul.
>
> Tom Davies wrote:
>> Hi,
>>
>> I'm trying to follow these instructions
>> http://blogs.sun.com/sandoz/entry/integrating_jersey_and_spring_take
>> for using Jersey and Spring.
>>
>> I'm finding that my Spring bean is not getting picked up by the
>> ComponentProvider.
>>
>> I'm suffering from a complete lack of understanding as to how the
>> ComponentProvider works: looking in the debugger I see that the
>> component provider is asked for beans implementing any of class
>> com.sun.ws.rest.impl.provider.entity.StringProvider, class
>> com.sun.ws.rest.impl.provider.entity.ByteArrayProvider, class
>> com.sun.ws.rest.impl.provider.entity.FileProvider, class
>> com.sun.ws.rest.impl.provider.entity.InputStreamProvider, class
>> com.sun.ws.rest.impl.provider.entity.DataSourceProvider, class
>> com.sun.ws.rest.impl.provider.entity.MimeMultipartProvider, class
>> com.sun.ws.rest.impl.provider.entity.FormURLEncodedProvider, class
>> com.sun.ws.rest.impl.provider.entity.XMLJAXBElementProvider.
>>
>> My bean class looks like:
>>
>> @Path("/review")
>> @Singleton
>> public class RestReviewService {
>> @Autowired
>> private ReviewService reviewService;
>>
>> @GET
>> @Path("reviews")
>> @ProduceMime("text/plain")
>> public List<ReviewData> getAllReviews() {
>> return reviewService.getAllReviews();
>> }
>> }
>>
>>
>> and its spring declaration like:
>> <bean id="restReviewService"
>> class="com.atlassian.crucible.spi.rpc.RestReviewService"
>> scope="singleton" autowire="autodetect"/>
>>
>> so I don't think it is going to implement any of those interfaces, and
>> so won't be seen.
>>
>> Can someone help to clear up my misconceptions?
>>
>> Thanks,
>> Tom
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>

-- 
| ? + ? = To question
----------------\
    Paul Sandoz
         x38109
+33-4-76188109