users@jersey.java.net

[Jersey] Re: Jersey's limit with Spring injection

From: Michael-O <1983-01-06_at_gmx.net>
Date: Thu, 17 Apr 2014 09:31:14 +0200

Hi Vetle,

Am 2014-04-16 20:31, schrieb Vetle Leinonen-Roeim:
> Hi,
>
> The Spring injection has hopefully been changed for the better in Jersey
> 2.8 (master branch), which is still unreleased. If possible, try
> downloading it from Github, building it, and testing with that.

I have already noticed PL 74. I will downlad a tarball and try to build
and see whether it will work.

> Even so, your case seems very simple. I've used Spring and Jersey with
> success myself, and have only had minor issues (which are all fixed with
> the changes in Jersey 2.8). Perhaps you could provide a complete example
> that we can take a look at?

Yes, I can provide a minimal example. I will provide the modified
SpringComponentProvider which hopefully can be incorporated into the
master branch and will craft a minimal project depicting the context
heierarchy and nested injection. Unfortunately, I won't have access to
my source code at work before Wednesday next week, I will come back.

> To answer some of your questions; HK2 does the actual injection.
> AutowiredInjectResolver is called with information from HK2 on what is
> to be injected into, and it looks up the appropriate bean(s) in the
> Spring context. In Jersey 2.8, the way it looks up the beans has been
> changed, and should work better.

This means that the bridge is able to find the bean from the Spring
context but the AutowiredInjectResolver does it in a wrong fashion.

I will report in a week.

Thanks,

Michael


> On 04/16/2014 07:21 PM, Michael-O wrote:
>> Hi,
>>
>> I am examining Jersey's Spring module and is has a limitation as stated
>> in the user guide:
>>
>> "Spring beans can't be injected directly into JAX-RS classes by using
>> Spring XML configuration"
>>
>> I do not fully understand that and try to adapt that to my usecase. We
>> have Spring 4.0.x, Jersey 2.7 in evaluation right now.
>>
>> I have modified the SpringComponentProvider because I was not satisfied
>> with the way it interacts with Spring. The approach is now the same as
>> in the Spring DispatcherServlet:
>>
>> 1. The Spring ContextListener creates a root context
>> 2. The SpringComponentProvider retrieves this context and creates a
>> child context on top of that
>>
>> The root context has some common beans like services, which require
>> repositories and other stuff. The child context decares the resources
>> beans-
>>
>> All dependencies are annotated with @Autowired, context component scan
>> is not used but annotation config.
>>
>> Now my resource looks like this:
>>
>> // Located in the JAX-RS context, parent: root context
>> @Component
>> @Path(...)
>> public Resource {
>>
>> @Autowired
>> MyService service;
>>
>> @GET
>> public String hello() {
>> return service.hello();
>> }
>>
>> }
>>
>> and the service:
>>
>> // Located in the root context
>> public DefaultMyService implements MyService {
>>
>> @Autowired
>> MyRepository repository;
>>
>> public String hello() {
>> ...
>> return repository.hello();
>> }
>>
>> }
>>
>> As you can see, I have bean dependencies over two hierarchy levels.
>>
>> This approach works very well with the SpringWSServlet and JAX-WS Metro.
>> When I deploy the same setup with Jersey, service remains null and is
>> not wired. The AutowiredInjectResolver does not find the matching bean.
>> The weird issue is that,
>>
>> 1. if I swap @Autowired for @Inject, everything is fine,
>> 2. if I add "@Autowired Properties config" to Resource where the former
>> is located in the root context, the wiring works perfectly.
>>
>> The questions are:
>>
>> 1. Is that the limitation mention in the user guide?
>> 2. If not, who is cauesing that issue, the HK2 Spring Bridge, unable to
>> handle context and/or bean hierarchies of the Jersey Spring module?
>> 3. Why does @Inject work? More over, who is injecting, Spring or HK2?
>>
>> Help is very much appreciated,
>>
>> Michael
>>
>