cxf-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sergey Beryozkin <sberyoz...@gmail.com>
Subject Re: Configuration and Constructor Context Injection problem when using CXF
Date Wed, 20 Aug 2014 13:55:41 GMT
Hi,

Thanks for sharing these results, let me comment, please see below
On 20/08/14 07:13, jordan wrote:
> Hi dear all,
>
> We would like to use JAXRS-2.0 and CXF in our project.
>
> And we would like use some @Context injection in our test.
>
> But I found the Configuration and Singleton Constructor @Context injection
> don't work. I also searched cxf and test project, but didn't find any
> related test and usage.
>
> I'm not sure do you have any related test or work, and could your please
> give some suggestion?
>
> Appreciate it! :)
>
> *1, Configuration injection doesn't work in both Resource and Filter:*
>
Right, see
https://issues.apache.org/jira/browse/CXF-5899

I've never been sure how would the application class would use it, but, 
I guess I can imagine how a filter would use, especially a client filter 
may be (check the properties, etc). It's supported all right directly in 
the Client API, but not on the server side. The preliminary TCK 
available to Apache did not have any issues with it so it kind of fell 
of my radar, supporting the actual injection. Several people have 
pointed out to it. Time to get it fixed :-)
> Here is one my test resource:
>
>      private UriInfo uriInfo1;
>
>      @Context
>      private UriInfo uriInfo2;
>
>     private Configuration config1;
>
>      @Context
>      private Configuration config2;
>
>      @Context
>      public void setUriInfo(UriInfo ui) {
>          uriInfo1 = ui;
>      }
>
>      @Context
>      public void setConfiguration (Configuration co) {
>          config1= co;
>      }
>
>      @GET
>      @Path("/" + ContextUtil.URIINFONAME1)
>      @Produces("text/plain")
>      public String listQueryParamNames1() {
>      	if(config1 == null || config1.equals(null)){
>      		System.out.println("CXF config test: config1 is null");
>      	} else{
>      		System.out.println("CXF config test: config1 is not null: " +
> config1.toString());
>      	}
>      	
>      	if(config2 == null || config2.equals(null)){
>      		System.out.println("CXF config test: config2 is null");
>      	} else{
>      		System.out.println("CXF config test: config2 is not null: " +
> config2.toString());
>      	}
>      	
>          return ContextUtil.URIINFONAME1 + ": " +
> ContextUtil.testUriInfo(uriInfo1);
>      }
>
> All other @context injection work fine, such as uriinfo, request,
> httpheaders and so on...
> But only Configuration doesn't work
>
> My test report:
> CXF config test: config1 is null
> CXF config test: config2 is null
>
> Sometime, I also see this error:
> Caused by: java.lang.NullPointerException: javax.ws.rs.core.Configuration
> context class has not been injected. Check if ContextProvider supporting
> this class is registered
>

This is to do with a fact CXF is lax with accepting custom interfaces 
(and given it does not support the injection of Configuration it comes 
up as a custom interface). So what happens a thread local proxy is 
injected but at the runtime, if it is accessed, NPE will be reported if 
an actual (custom) ContextProvider is available, see

https://issues.apache.org/jira/browse/CXF-5803,

we agreed with Andrey who reported the issue originally that if a custom 
context resolver is not available then a thread local proxy should not 
even be created - another issue to take care of. We do not have a 
resource leak but it would simply be cleaner and more optimal.

>
> *2, Does @Context work/available in Application class?*
>
> I write some injection in Application like this:
>
> @ApplicationPath("/context")
> public class DemoApplication extends javax.ws.rs.core.Application {
>
>      @Context
>      private UriInfo ui;
>
>      @Context
>      private HttpHeaders hh;
>
>      @Context
>      private Request re;
>
>      @Context
>      private Application ap;
>
>      @Context
>      private ResourceContext rc;
>
>      @Context
>      private Providers pr;
>
> But I cannot use them in anywhere in Application code, all report null. is
> this work as design?
>
> And I see the standard, we could use @Context for Constructor.
>
> If we cannot use @Context in Application, how can we new Resource for
> Singleton?
>
> Such as, here is my resource Constructor :
>
>      public AbstractRestService(@Context UriInfo ui, @Context HttpHeaders hh,
> @Context Request r, @Context Providers p) {
>          this.uriInfo3 = ui;
>          this.httpheaders3 = hh;
>          this.request3 = r;
>          this.providers3 = p;
>      }
>
> When init, getClasses() works fine because we don't need write Constructor.
> But getSingletons() doesn't work, because I need provide @context in
> Application:
>
>      @Override
>      public Set<Class&lt;?>> getClasses() {
>          Set<Class&lt;?>> classes = new HashSet<Class&lt;?>>();
>          classes.add(ClassesRestService.class);
>          classes.add(ClassesRestService2.class);
>          classes.add(ContextRequestFilter1.class);
>          classes.add(ContextRequestFilter2.class);
>          classes.add(ContextRequestFilter3.class);
>          classes.add(ContextRequestFilter4.class);
>          classes.add(JordanExceptionMapProvider.class);
>          return classes;
>      }
>
>      @Override
>      public Set getSingletons() {
>          Set objs = new HashSet();
> *        objs.add(new SingletonsRestService(ui, hh, re, pr));*
>          objs.add(new SingletonsRestService2(rc));
>          objs.add(new ContextRequestFilter1());
>          objs.add(new ContextRequestFilter2());
> //        objs.add(new ContextRequestFilter3(ui, ap, pr));
>          objs.add(new ContextRequestFilter4());
>          objs.add(new JordanExceptionMapProvider());
>          return objs;
>      }
>
> I have tested  by using CXF, they all don't work, and I didn't see any
> related test in CXF project.
>
Hmm... Application itself can definitely be injected as a Context into 
providers/resource classes.
I have to admit, the use case you've described above is entirely new to 
me. Right, the constructor injection in getClasses() would indeed work, 
but not in getSingletons()...

By the way, where exactly do you see that contexts can be injected into 
Application ? Actually, here:

"9.2
Context Types
This section describes the types of context available to resource 
classes, providers and Application sub-
classes."

Yes, will be fixed asap.

> Could you please help take a look?
>
> Thanks all and have a good day~ :)
>
Thanks for the detailed analysis, appreciated

Cheers. Sergey
>
>
> --
> View this message in context: http://cxf.547215.n5.nabble.com/Configuration-and-Constructor-Context-Injection-problem-when-using-CXF-tp5747973.html
> Sent from the cxf-dev mailing list archive at Nabble.com.
>



Mime
View raw message