Sanjay
Sanjay

Reputation: 29

HttpServletRequest field may not be static, final or have an Annotation type error with jersey 2

I have the following class for REST calls. Before I was using jersey 1.13 on which everything was working fine, now I have upgraded to jersey 2.27, I am getting the following error on any rest call to the given class

WARNING [http-nio-8080-exec-4] org.glassfish.jersey.internal.Errors.logErrors The following warnings have been detected: WARNING: HK2 service reification failed for [com.MyClass] with an exception: MultiException stack 1 of 2 java.lang.IllegalArgumentException: The field field(HttpServletRequest request in com..MyClass) may not be static, final or have an Annotation type

MultiException stack 2 of 2 java.lang.IllegalArgumentException: Errors were discovered while reifying SystemDescriptor( implementation=com.MyClass contracts={com.MyClass} scope=org.glassfish.jersey.process.internal.RequestScoped qualifiers={} descriptorType=CLASS descriptorVisibility=NORMAL metadata= rank=0 loader=null proxiable=null proxyForSameScope=null analysisName=null id=150 locatorId=0 identityHashCode=1270899559 reified=false)

@Path("/myclass")
public MyClass{
@Context
    static
    HttpServletRequest request;

    @Context
    HttpServletResponse response;

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @Path("/method1")
    public Response method1(PostObj postObj) {
        //implementation
   }

}

If I remove static keyword it works fine. But I want request to be kept static only. What is the issue with static keyword here ? How do I fix it ?

Upvotes: 1

Views: 1216

Answers (1)

Dezso Gabos
Dezso Gabos

Reputation: 2452

The JAX-RS API from the Java EE ecosystem of technologies provides the annotation @Context, to inject 12 object instances related to the context of HTTP requests. It behaves just like the @Inject and @Autowired annotations in Java EE and Spring respectively.

The object instances that it can inject are the following:

  • SecurityContext – Security context instance for the current HTTP request
  • Request – Used for setting precondition request processing
  • Application, Configuration, and Providers - Provide access to the JAX-RS application, configuration, and providers instances
  • ResourceContext – Resource context class instances
  • ServletConfig – The ServletConfig instance instance
  • ServletContext – The ServletContext instance
  • HttpServletRequest – The HttpServletRequest instance for the current request
  • HttpServletResponse – The HttpServletResponse instance for the current request
  • HttpHeaders – Maintains the HTTP header keys and values
  • UriInfo – Query parameters and path variables from the URI called

And here’s an example of injection into an instances field:

@Path("/")
public class EndpointResource {
    @Context
    private HttpHeaders httpHeaders;

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response getHeaders(){
        // Code here that uses httpHeaders
    }
}

Read up on injection, there is a reason why you can't inject static fields. Avoiding dependency injection on static fields and methods is a good practice, as it has the following restrictions and can be hard to debug.

  1. Static fields will be injected after the first object of the class was created via DI, which means no access to the static field in the constructor
  2. Static fields can not be marked as final, otherwise the compiler or the application complains at runtime about them
  3. Static methods are called only once after the first instance of the class was created

Upvotes: 2

Related Questions