Quantcast

CDI Injection into JAX-RS 2 Filter

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

CDI Injection into JAX-RS 2 Filter

algermissen1971-2
Hi all,

I am again struggling with the question of how to enable CDI for JAX-RS 2 filter classes.

Marek (IIRC) has pointed me the solution based on AbstractBinder:

Suppose I want to inject in a filter the instance of MyToBeInjectedSingleton.class like so:

class MyFilter .... {

        @Inject
        MyToBeInjectedSingleton mySingleton;

}

I was told to extend AbstratBinder:

public class MyBinder extends AbstractBinder {
       
        @Override
        protected void configure() {

                bindAsContract(MyToBeInjectedSingleton.class).in(Singleton.class);
       
        }


}

and then register the Binder in a Feature:

public class MyFeature implements Feature {

        @Override
        public boolean configure(FeatureContext featureContext) {
            featureContext.register(new MyBinder());
                return true;
        }
}

Worked fine, but it seems the API of jersey-common changed and AbstractBinder is gone. Now, I could pull in
the older jersey-common, but as the code is to run in GF4 (which comes with the new version), I guess this would lead to serious conflicts somewhere.

Hence the question: what do I need to do in the new jersey-common to register an instance for injection?


Besides that, I still cannot really understand that one needs to go through this kind of trouble (with changing APIs) just because I want to inject something in a JAX-RS component. Isn't there a better way? Maybe I am just too stupid or blind to see the light.



Jan














Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: CDI Injection into JAX-RS 2 Filter

japod
Hi Jan,

AbstractBinder has been moved to HK2 (See [1]),
the API should be more-less the same. So you can stick with
current jersey-common.

Otherwise CDI injection should be working for just fine in GF.
I am wondering why you need a custom binder. Could you please
provide some more details on your use case. Maybe this is a bug in Jersey.

Thanks,

~Jakub



On Aug 1, 2013, at 3:38 PM, algermissen1971 <[hidden email]> wrote:

Hi all,

I am again struggling with the question of how to enable CDI for JAX-RS 2 filter classes.

Marek (IIRC) has pointed me the solution based on AbstractBinder:

Suppose I want to inject in a filter the instance of MyToBeInjectedSingleton.class like so:

class MyFilter .... {

@Inject
MyToBeInjectedSingleton mySingleton;

}

I was told to extend AbstratBinder:

public class MyBinder extends AbstractBinder {

@Override
protected void configure() {

bindAsContract(MyToBeInjectedSingleton.class).in(Singleton.class);

}


}

and then register the Binder in a Feature:

public class MyFeature implements Feature {

@Override
public boolean configure(FeatureContext featureContext) {
   featureContext.register(new MyBinder());
return true;
}
}

Worked fine, but it seems the API of jersey-common changed and AbstractBinder is gone. Now, I could pull in
the older jersey-common, but as the code is to run in GF4 (which comes with the new version), I guess this would lead to serious conflicts somewhere.

Hence the question: what do I need to do in the new jersey-common to register an instance for injection?


Besides that, I still cannot really understand that one needs to go through this kind of trouble (with changing APIs) just because I want to inject something in a JAX-RS component. Isn't there a better way? Maybe I am just too stupid or blind to see the light.



Jan















Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: CDI Injection into JAX-RS 2 Filter

algermissen1971-2
Jakub,

On 01.08.2013, at 16:01, Jakub Podlesak <[hidden email]> wrote:

Hi Jan,

AbstractBinder has been moved to HK2 (See [1]),
the API should be more-less the same. So you can stick with
current jersey-common.

Ah, thanks. Still, seems odd I'd have to just know such a thing when maintaining a 'normal' application. (But see below).


Otherwise CDI injection should be working for just fine in GF.
I am wondering why you need a custom binder. Could you please
provide some more details on your use case. Maybe this is a bug in Jersey.

No idea. I have been struggeling with this issue ever since. I'll give out-of-the-box CDI another try and report back. Maybe it *was* just a bug in Jersey/GF and it has gone away.

Meanwhile, thanks.

Jan



Thanks,

~Jakub



On Aug 1, 2013, at 3:38 PM, algermissen1971 <[hidden email]> wrote:

Hi all,

I am again struggling with the question of how to enable CDI for JAX-RS 2 filter classes.

Marek (IIRC) has pointed me the solution based on AbstractBinder:

Suppose I want to inject in a filter the instance of MyToBeInjectedSingleton.class like so:

class MyFilter .... {

@Inject
MyToBeInjectedSingleton mySingleton;

}

I was told to extend AbstratBinder:

public class MyBinder extends AbstractBinder {

@Override
protected void configure() {

bindAsContract(MyToBeInjectedSingleton.class).in(Singleton.class);

}


}

and then register the Binder in a Feature:

public class MyFeature implements Feature {

@Override
public boolean configure(FeatureContext featureContext) {
   featureContext.register(new MyBinder());
return true;
}
}

Worked fine, but it seems the API of jersey-common changed and AbstractBinder is gone. Now, I could pull in
the older jersey-common, but as the code is to run in GF4 (which comes with the new version), I guess this would lead to serious conflicts somewhere.

Hence the question: what do I need to do in the new jersey-common to register an instance for injection?


Besides that, I still cannot really understand that one needs to go through this kind of trouble (with changing APIs) just because I want to inject something in a JAX-RS component. Isn't there a better way? Maybe I am just too stupid or blind to see the light.



Jan
















Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: CDI Injection into JAX-RS 2 Filter

algermissen1971-2
In reply to this post by japod

On 01.08.2013, at 16:01, Jakub Podlesak <[hidden email]> wrote:


Otherwise CDI injection should be working for just fine in GF.

Question:

I have an EJB singleton and want to inject that into a jax-rs2 filter.

How would you do that? Injection into filter does not happen - I think I need to annotate the filter, but with what?

I know that @RequestScoped does the trick on resource classes, but filters are application scoped - mostly.

Any idea?

Jan




I am wondering why you need a custom binder. Could you please
provide some more details on your use case. Maybe this is a bug in Jersey.

Thanks,

~Jakub



On Aug 1, 2013, at 3:38 PM, algermissen1971 <[hidden email]> wrote:

Hi all,

I am again struggling with the question of how to enable CDI for JAX-RS 2 filter classes.

Marek (IIRC) has pointed me the solution based on AbstractBinder:

Suppose I want to inject in a filter the instance of MyToBeInjectedSingleton.class like so:

class MyFilter .... {

@Inject
MyToBeInjectedSingleton mySingleton;

}

I was told to extend AbstratBinder:

public class MyBinder extends AbstractBinder {

@Override
protected void configure() {

bindAsContract(MyToBeInjectedSingleton.class).in(Singleton.class);

}


}

and then register the Binder in a Feature:

public class MyFeature implements Feature {

@Override
public boolean configure(FeatureContext featureContext) {
   featureContext.register(new MyBinder());
return true;
}
}

Worked fine, but it seems the API of jersey-common changed and AbstractBinder is gone. Now, I could pull in
the older jersey-common, but as the code is to run in GF4 (which comes with the new version), I guess this would lead to serious conflicts somewhere.

Hence the question: what do I need to do in the new jersey-common to register an instance for injection?


Besides that, I still cannot really understand that one needs to go through this kind of trouble (with changing APIs) just because I want to inject something in a JAX-RS component. Isn't there a better way? Maybe I am just too stupid or blind to see the light.



Jan
















Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: CDI Injection into JAX-RS 2 Filter

algermissen1971-2

On 01.08.2013, at 17:34, algermissen1971 <[hidden email]> wrote:


On 01.08.2013, at 16:01, Jakub Podlesak <[hidden email]> wrote:


Otherwise CDI injection should be working for just fine in GF.

Question:

I have an EJB singleton and want to inject that into a jax-rs2 filter.

How would you do that? Injection into filter does not happen - I think I need to annotate the filter, but with what?

I know that @RequestScoped does the trick on

Sorry - meant to write @Stateless.

Jan


resource classes, but filters are application scoped - mostly.

Any idea?

Jan




I am wondering why you need a custom binder. Could you please
provide some more details on your use case. Maybe this is a bug in Jersey.

Thanks,

~Jakub



On Aug 1, 2013, at 3:38 PM, algermissen1971 <[hidden email]> wrote:

Hi all,

I am again struggling with the question of how to enable CDI for JAX-RS 2 filter classes.

Marek (IIRC) has pointed me the solution based on AbstractBinder:

Suppose I want to inject in a filter the instance of MyToBeInjectedSingleton.class like so:

class MyFilter .... {

@Inject
MyToBeInjectedSingleton mySingleton;

}

I was told to extend AbstratBinder:

public class MyBinder extends AbstractBinder {

@Override
protected void configure() {

bindAsContract(MyToBeInjectedSingleton.class).in(Singleton.class);

}


}

and then register the Binder in a Feature:

public class MyFeature implements Feature {

@Override
public boolean configure(FeatureContext featureContext) {
   featureContext.register(new MyBinder());
return true;
}
}

Worked fine, but it seems the API of jersey-common changed and AbstractBinder is gone. Now, I could pull in
the older jersey-common, but as the code is to run in GF4 (which comes with the new version), I guess this would lead to serious conflicts somewhere.

Hence the question: what do I need to do in the new jersey-common to register an instance for injection?


Besides that, I still cannot really understand that one needs to go through this kind of trouble (with changing APIs) just because I want to inject something in a JAX-RS component. Isn't there a better way? Maybe I am just too stupid or blind to see the light.



Jan

















Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: CDI Injection into JAX-RS 2 Filter

japod
@javax.ejb.Singleton should do the trick. Does it? Is that fine for you?

~Jakub


On Aug 1, 2013, at 5:35 PM, algermissen1971 <[hidden email]> wrote:


On 01.08.2013, at 17:34, algermissen1971 <[hidden email]> wrote:


On 01.08.2013, at 16:01, Jakub Podlesak <[hidden email]> wrote:


Otherwise CDI injection should be working for just fine in GF.

Question:

I have an EJB singleton and want to inject that into a jax-rs2 filter.

How would you do that? Injection into filter does not happen - I think I need to annotate the filter, but with what?

I know that @RequestScoped does the trick on

Sorry - meant to write @Stateless.

Jan


resource classes, but filters are application scoped - mostly.

Any idea?

Jan




I am wondering why you need a custom binder. Could you please
provide some more details on your use case. Maybe this is a bug in Jersey.

Thanks,

~Jakub



On Aug 1, 2013, at 3:38 PM, algermissen1971 <[hidden email]> wrote:

Hi all,

I am again struggling with the question of how to enable CDI for JAX-RS 2 filter classes.

Marek (IIRC) has pointed me the solution based on AbstractBinder:

Suppose I want to inject in a filter the instance of MyToBeInjectedSingleton.class like so:

class MyFilter .... {

@Inject
MyToBeInjectedSingleton mySingleton;

}

I was told to extend AbstratBinder:

public class MyBinder extends AbstractBinder {

@Override
protected void configure() {

bindAsContract(MyToBeInjectedSingleton.class).in(Singleton.class);

}


}

and then register the Binder in a Feature:

public class MyFeature implements Feature {

@Override
public boolean configure(FeatureContext featureContext) {
   featureContext.register(new MyBinder());
return true;
}
}

Worked fine, but it seems the API of jersey-common changed and AbstractBinder is gone. Now, I could pull in
the older jersey-common, but as the code is to run in GF4 (which comes with the new version), I guess this would lead to serious conflicts somewhere.

Hence the question: what do I need to do in the new jersey-common to register an instance for injection?


Besides that, I still cannot really understand that one needs to go through this kind of trouble (with changing APIs) just because I want to inject something in a JAX-RS component. Isn't there a better way? Maybe I am just too stupid or blind to see the light.



Jan


















Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: CDI Injection into JAX-RS 2 Filter

algermissen1971-2

On 01.08.2013, at 18:11, Jakub Podlesak <[hidden email]> wrote:

@javax.ejb.Singleton should do the trick. Does it? Is that fine for you?

Trying this:

Injecting EJB @Singleton into resource class which is annotated with @Stateless:

- @Inject: works
- @EJB: Works

Injecting EJB @Singleton into filter class which is annotated with EJB @Singleton, as you suggest:

- @Inject: fails - not even constructor of filter is called before the exception[1] occurs
- @EJB: failse - not even constructor of filter is called before the exception[1] occurs

When I annotate the filter with @Startup, filter ctor is called, @PostConstruct method is called injection fails, but not with the exception above, just silently and the dependency is null.

I do not have the time right now for doring an example project, but this seems totally strange - maybe you get a clue anyhow. (There isn't much in the project besides the injection stuff anyhow).

Jan

[1] The exception the runtime throws *before* even instantiating the filter class I want to inject into is sth like this:

[2013-08-01T18:49:59.034+0200] [glassfish 4.0] [SEVERE] [] [javax.enterprise.web] [tid: _ThreadID=21 _ThreadName=http-lis
  WebModule[/pms]StandardWrapper.Throwable
MultiException stack 1 of 3
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at Injectee(requiredTyp
        at org.jvnet.hk2.internal.ThreeThirtyResolver.resolve(ThreeThirtyResolver.java:74)
        at org.jvnet.hk2.internal.ClazzCreator.resolve(ClazzCreator.java:191)
        at org.jvnet.hk2.internal.ClazzCreator.resolveAllDependencies(ClazzCreator.java:214)
        at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:311)
        at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:448)
        at org.jvnet.hk2.internal.SingletonContext.findOrCreate(SingletonContext.java:118)
        at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2204)
        at org.jvnet.hk2.internal.ServiceHandleImpl.getService(ServiceHandleImpl.java:93)
        at org.glassfish.jersey.internal.inject.Providers.getAllRankedProviders(Providers.java:234)
        at org.glassfish.jersey.server.ApplicationHandler.getProcessingProviders(ApplicationHandler.java:568)
        at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:393)
        at org.glassfish.jersey.server.ApplicationHandler.access$500(ApplicationHandler.java:157)
        at org.glassfish.jersey.server.ApplicationHandler$3.run(ApplicationHandler.java:280)
        at org.glassfish.jersey.internal.Errors$2.call(Errors.java:289)
        at org.glassfish.jersey.internal.Errors$2.call(Errors.java:286)
        at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
        at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
        at org.glassfish.jersey.internal.Errors.processWithException(Errors.java:286)
        at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:277)
        at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:262)
        at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:167)
        at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:349)
        at javax.servlet.GenericServlet.init(GenericServlet.java:244)
        at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1583)










~Jakub


On Aug 1, 2013, at 5:35 PM, algermissen1971 <[hidden email]> wrote:


On 01.08.2013, at 17:34, algermissen1971 <[hidden email]> wrote:


On 01.08.2013, at 16:01, Jakub Podlesak <[hidden email]> wrote:


Otherwise CDI injection should be working for just fine in GF.

Question:

I have an EJB singleton and want to inject that into a jax-rs2 filter.

How would you do that? Injection into filter does not happen - I think I need to annotate the filter, but with what?

I know that @RequestScoped does the trick on

Sorry - meant to write @Stateless.

Jan


resource classes, but filters are application scoped - mostly.

Any idea?

Jan




I am wondering why you need a custom binder. Could you please
provide some more details on your use case. Maybe this is a bug in Jersey.

Thanks,

~Jakub



On Aug 1, 2013, at 3:38 PM, algermissen1971 <[hidden email]> wrote:

Hi all,

I am again struggling with the question of how to enable CDI for JAX-RS 2 filter classes.

Marek (IIRC) has pointed me the solution based on AbstractBinder:

Suppose I want to inject in a filter the instance of MyToBeInjectedSingleton.class like so:

class MyFilter .... {

@Inject
MyToBeInjectedSingleton mySingleton;

}

I was told to extend AbstratBinder:

public class MyBinder extends AbstractBinder {

@Override
protected void configure() {

bindAsContract(MyToBeInjectedSingleton.class).in(Singleton.class);

}


}

and then register the Binder in a Feature:

public class MyFeature implements Feature {

@Override
public boolean configure(FeatureContext featureContext) {
   featureContext.register(new MyBinder());
return true;
}
}

Worked fine, but it seems the API of jersey-common changed and AbstractBinder is gone. Now, I could pull in
the older jersey-common, but as the code is to run in GF4 (which comes with the new version), I guess this would lead to serious conflicts somewhere.

Hence the question: what do I need to do in the new jersey-common to register an instance for injection?


Besides that, I still cannot really understand that one needs to go through this kind of trouble (with changing APIs) just because I want to inject something in a JAX-RS component. Isn't there a better way? Maybe I am just too stupid or blind to see the light.



Jan



















Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: CDI Injection into JAX-RS 2 Filter

japod
Hi Jan,

i have just put together a quick test, and it turns out there is a bug in Jersey,
that only makes it possible for resource classes to take part
in EJB/CDI integration.


I will make sure this gets fixed in the next Jersey release,
that should come out sometime this month.

~Jakub


On Aug 1, 2013, at 7:13 PM, algermissen1971 <[hidden email]> wrote:


On 01.08.2013, at 18:11, Jakub Podlesak <[hidden email]> wrote:

@javax.ejb.Singleton should do the trick. Does it? Is that fine for you?

Trying this:

Injecting EJB @Singleton into resource class which is annotated with @Stateless:

- @Inject: works
- @EJB: Works

Injecting EJB @Singleton into filter class which is annotated with EJB @Singleton, as you suggest:

- @Inject: fails - not even constructor of filter is called before the exception[1] occurs
- @EJB: failse - not even constructor of filter is called before the exception[1] occurs

When I annotate the filter with @Startup, filter ctor is called, @PostConstruct method is called injection fails, but not with the exception above, just silently and the dependency is null.

I do not have the time right now for doring an example project, but this seems totally strange - maybe you get a clue anyhow. (There isn't much in the project besides the injection stuff anyhow).

Jan

[1] The exception the runtime throws *before* even instantiating the filter class I want to inject into is sth like this:

[2013-08-01T18:49:59.034+0200] [glassfish 4.0] [SEVERE] [] [javax.enterprise.web] [tid: _ThreadID=21 _ThreadName=http-lis
  WebModule[/pms]StandardWrapper.Throwable
MultiException stack 1 of 3
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at Injectee(requiredTyp
        at org.jvnet.hk2.internal.ThreeThirtyResolver.resolve(ThreeThirtyResolver.java:74)
        at org.jvnet.hk2.internal.ClazzCreator.resolve(ClazzCreator.java:191)
        at org.jvnet.hk2.internal.ClazzCreator.resolveAllDependencies(ClazzCreator.java:214)
        at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:311)
        at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:448)
        at org.jvnet.hk2.internal.SingletonContext.findOrCreate(SingletonContext.java:118)
        at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2204)
        at org.jvnet.hk2.internal.ServiceHandleImpl.getService(ServiceHandleImpl.java:93)
        at org.glassfish.jersey.internal.inject.Providers.getAllRankedProviders(Providers.java:234)
        at org.glassfish.jersey.server.ApplicationHandler.getProcessingProviders(ApplicationHandler.java:568)
        at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:393)
        at org.glassfish.jersey.server.ApplicationHandler.access$500(ApplicationHandler.java:157)
        at org.glassfish.jersey.server.ApplicationHandler$3.run(ApplicationHandler.java:280)
        at org.glassfish.jersey.internal.Errors$2.call(Errors.java:289)
        at org.glassfish.jersey.internal.Errors$2.call(Errors.java:286)
        at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
        at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
        at org.glassfish.jersey.internal.Errors.processWithException(Errors.java:286)
        at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:277)
        at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:262)
        at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:167)
        at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:349)
        at javax.servlet.GenericServlet.init(GenericServlet.java:244)
        at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1583)










~Jakub


On Aug 1, 2013, at 5:35 PM, algermissen1971 <[hidden email]> wrote:


On 01.08.2013, at 17:34, algermissen1971 <[hidden email]> wrote:


On 01.08.2013, at 16:01, Jakub Podlesak <[hidden email]> wrote:


Otherwise CDI injection should be working for just fine in GF.

Question:

I have an EJB singleton and want to inject that into a jax-rs2 filter.

How would you do that? Injection into filter does not happen - I think I need to annotate the filter, but with what?

I know that @RequestScoped does the trick on

Sorry - meant to write @Stateless.

Jan


resource classes, but filters are application scoped - mostly.

Any idea?

Jan




I am wondering why you need a custom binder. Could you please
provide some more details on your use case. Maybe this is a bug in Jersey.

Thanks,

~Jakub



On Aug 1, 2013, at 3:38 PM, algermissen1971 <[hidden email]> wrote:

Hi all,

I am again struggling with the question of how to enable CDI for JAX-RS 2 filter classes.

Marek (IIRC) has pointed me the solution based on AbstractBinder:

Suppose I want to inject in a filter the instance of MyToBeInjectedSingleton.class like so:

class MyFilter .... {

@Inject
MyToBeInjectedSingleton mySingleton;

}

I was told to extend AbstratBinder:

public class MyBinder extends AbstractBinder {

@Override
protected void configure() {

bindAsContract(MyToBeInjectedSingleton.class).in(Singleton.class);

}


}

and then register the Binder in a Feature:

public class MyFeature implements Feature {

@Override
public boolean configure(FeatureContext featureContext) {
   featureContext.register(new MyBinder());
return true;
}
}

Worked fine, but it seems the API of jersey-common changed and AbstractBinder is gone. Now, I could pull in
the older jersey-common, but as the code is to run in GF4 (which comes with the new version), I guess this would lead to serious conflicts somewhere.

Hence the question: what do I need to do in the new jersey-common to register an instance for injection?


Besides that, I still cannot really understand that one needs to go through this kind of trouble (with changing APIs) just because I want to inject something in a JAX-RS component. Isn't there a better way? Maybe I am just too stupid or blind to see the light.



Jan




















Loading...