users@jersey.java.net

Re: [Jersey] Error resolving locale.

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Thu, 26 Feb 2009 09:17:27 +0100

On Feb 25, 2009, at 3:31 PM, Erick Dovale wrote:

> Paul,
> We are in the middle of a release now but I have already planned
> for upgrading jersey to 1.0.2.
> Will let you know once I do it.
> See below for comments.
>
> On Wed, Feb 25, 2009 at 2:53 AM, Paul Sandoz <Paul.Sandoz_at_sun.com>
> wrote:
>
> On Feb 24, 2009, at 10:55 PM, Erick Dovale wrote:
>
>> Paul,
>> The problem seems to be related to the fact that we have two
>> jersey applications going on at the same time (read two
>> SpringServlets mapped to different paths scanning different
>> packages for resources but the same packages for entity providers
>> and exception mappers.)
>
> How have you configured that? as two separate servlet declarations
> in the web.xml ?
> Yes
>


Ah! a light comes on. Is the exception mapper a Spring bean? if they
are then i assume that there will only be one instance per the web
application. The Jersey servlet, incorrectly in such cases, assumes
one per servlet instance.

So if servlet A injects its thread local proxy into the exception
mapper, then that proxy will get used when servlet B processes a
request that results in the use of the exception mapper. Thus if
there is no request in scope for servlet A, but there is for Servlet
B and it uses the exception mapper an illegal state exception will
result.

Hmm.... upgrading to 1.0.2 will not help in this respect. I need to
think about this some more. We might need to introduce a Jersey
specific context for such cases. Ugh! It may be nice to be able to
have multiple servlets handing separate areas for certain
configuration operations e.g. different filters, authentication, but
not in other cases. However, given that Jersey has a flexible
filtering mechanisms per resource it may not be so pressing to have
multiple servlets.


Note that Spring support in 1.0.1 and above has changed so it is no
longer necessary to explicitly register the spring beans.

So for now i recommend, as you have done already, to stick to using
just one SpringServlet for now.

Paul.

>
> Are you using static fields in your provider implementations?
> No
>
>>
>> If I merge them both under the same jersey app the problem goes
>> away. The actual reason why this is happening I don't know.
>> Do you have any idea?
>>
>
> No yet, need more information.
>
> If you declare two Jersey spring servlets then the applications
> should be completely isolated (with on exception, see later) with
> separate instances of the provider classes.
>
> The exception is related to default JAXB contexts for classes. This
> should work fine and multiple applications can share this information.
>
> Can you try upgrading to 1.0.1 or 1.0.2 and see if the problem
> resolves itself?
>
> Paul.
>
>
>> Thanks.
>>
>> On Tue, Feb 24, 2009 at 10:43 AM, Erick Dovale <edovale_at_gmail.com>
>> wrote:
>> Paul,
>> I'll try to figure it out my self sometime this week and will let
>> you know.
>>
>> Thanks a lot.
>>
>>
>> On Tue, Feb 24, 2009 at 10:40 AM, Paul Sandoz
>> <Paul.Sandoz_at_sun.com> wrote:
>>
>> On Feb 24, 2009, at 4:20 PM, Erick Dovale wrote:
>>
>>> Sorry, I am on jersey 1.0
>>>
>>
>> OK.
>>
>>
>>> On Tue, Feb 24, 2009 at 10:20 AM, Erick Dovale
>>> <edovale_at_gmail.com> wrote:
>>> Paul,
>>> I am on jersey 1.0.1.
>>> The ErrorObjectToJSONMessageBodyWriter message body writer that
>>> writes error objects into the response.
>>> The ErrorObject is usually created by an exception mapper and put
>>> as entity in the response to be later processed by the body
>>> writer for the appropriate content type.
>>> Make sense?
>>>
>>
>> Yes, although i still do not understand how the thread local value
>> is being set to null because of that.
>>
>> For the case of mapping exceptions the thread local context is
>> only set to null if the exception cannot be mapped and if that is
>> the case an exception is thrown so your
>> ErrorObjectToJSONMessageBodyWriter would never get invoked.
>>
>> I modified the hello world sample from the latest 1.0.3-SNAPSHOT
>> [1] (see code below) to reproduce the same steps you describe, but
>> i cannot reproduce the issue you observe.
>>
>> Paul.
>>
>> [1] http://download.java.net/maven/2/com/sun/jersey/samples/
>> helloworld/1.0.3-SNAPSHOT/helloworld-1.0.3-SNAPSHOT-project.zip
>>
>> @Path("/helloworld")
>> public class HelloWorldResource {
>>
>> public static class MyException extends RuntimeException {}
>>
>> public static class MyType {}
>>
>> @Provider
>> public static class MyExceptionMapper implements
>> ExceptionMapper<MyException> {
>>
>> public Response toResponse(MyException exception) {
>> return Response.ok().entity(new MyType()).build();
>> }
>> }
>>
>> @Provider
>> public static class MyMessageBodyWriter implements
>> MessageBodyWriter<MyType> {
>>
>> @Context UriInfo ui;
>>
>> @Context HttpHeaders h;
>>
>> public boolean isWriteable(Class<?> type, Type
>> genericType, Annotation[] annotations, MediaType mediaType) {
>> return type == MyType.class;
>> }
>>
>> public long getSize(MyType t, Class<?> type, Type
>> genericType, Annotation[] annotations, MediaType mediaType) {
>> return -1;
>> }
>>
>> public void writeTo(MyType t, Class<?> type, Type
>> genericType, Annotation[] annotations, MediaType mediaType,
>> MultivaluedMap<String, Object> httpHeaders, OutputStream
>> entityStream) throws IOException, WebApplicationException {
>> ui.getRequestUri();
>> h.getLanguage();
>> entityStream.write("Hello World".getBytes());
>> }
>>
>> }
>>
>>
>> // The Java method will process HTTP GET requests
>> @GET
>> // The Java method will produce content identified by the MIME
>> Media
>> // type "text/plain"
>> @Produces("text/plain")
>> public String getClichedMessage() {
>> throw new MyException();
>> }
>> }
>>
>>> Thanks.
>>>
>>>
>>> On Tue, Feb 24, 2009 at 10:10 AM, Paul Sandoz
>>> <Paul.Sandoz_at_sun.com> wrote:
>>>
>>> On Feb 24, 2009, at 3:42 PM, Erick Dovale wrote:
>>>
>>> Folks,
>>> Have any of you experienced this before?
>>>
>>>
>>> What version of Jersey are you using? I suspect it is 1.0 from
>>> looking at the package names.
>>>
>>> The IllegalStateExeption is thrown when a method is called on
>>> HttpContext for which there is no HTTP request, and thus no
>>> HttpContext, in scope.
>>>
>>> I looked at the 1.0 code for WebApplicationImpl [1] and i cannot
>>> see how this can manifest itself since the thread local context
>>> value is set to null after the ContainerResponse.write method is
>>> called.
>>>
>>> Can you describe a bit more the function of
>>> ErrorObjectToJSONMessageBodyWriter? is the "error object"
>>> returned from a resource method?
>>>
>>> Can you try using Jersey 1.0.1 or 1.0.2 and see if the same error
>>> occurs?
>>>
>>> Thanks,
>>> Paul.
>>>
>>> [1] https://jersey.dev.java.net/source/browse/*checkout*/jersey/
>>> tags/jersey-1.0/jersey/jersey-server/src/main/java/com/sun/jersey/
>>> impl/application/WebApplicationImpl.java?rev=1602
>>>
>>> public void handleRequest(ContainerRequest request,
>>> ContainerResponse response) throws IOException {
>>> try {
>>> final WebApplicationContext localContext = new
>>> WebApplicationContext(this, request, response);
>>> context.set(localContext);
>>>
>>> /**
>>> * The matching algorithm currently works from an
>>> absolute path.
>>> * The path is required to be in encoded form.
>>> */
>>> StringBuilder path = new StringBuilder();
>>> path.append("/").append(localContext.getPath(false));
>>>
>>> if (!resourceConfig.getFeature
>>> (ResourceConfig.FEATURE_MATCH_MATRIX_PARAMS)) {
>>> path = stripMatrixParams(path);
>>> }
>>>
>>> // TODO convert to filter
>>> // If there are URI conneg extensions for media and
>>> language
>>> if (!resourceConfig.getMediaTypeMappings().isEmpty() ||
>>> !resourceConfig.getLanguageMappings().isEmpty
>>> ()) {
>>> uriConneg(path, request);
>>> }
>>>
>>> for (ContainerRequestFilter f : requestFilters)
>>> request = f.filter(request);
>>>
>>> if (!rootsRule.accept(path, null, localContext)) {
>>> throw new NotFoundException();
>>> }
>>> } catch (WebApplicationException e) {
>>> mapWebApplicationException(e, response);
>>> } catch (ContainerCheckedException e) {
>>> if (!mapException(e.getCause(), response)) {
>>> context.set(null);
>>> throw e;
>>> }
>>> } catch (RuntimeException e) {
>>> if (!mapException(e, response)) {
>>> context.set(null);
>>> throw e;
>>> }
>>> }
>>>
>>> try {
>>> for (ContainerResponseFilter f : responseFilters)
>>> response = f.filter(request, response);
>>> } catch (WebApplicationException e) {
>>> mapWebApplicationException(e, response);
>>> } catch (RuntimeException e) {
>>> if (!mapException(e, response)) {
>>> context.set(null);
>>> throw e;
>>> }
>>> }
>>>
>>> try {
>>> response.write();
>>> } catch (WebApplicationException e) {
>>> if (response.isCommitted()) {
>>> throw e;
>>> } else {
>>> mapWebApplicationException(e, response);
>>> response.write();
>>> }
>>> } finally {
>>> context.set(null);
>>>
>>> }
>>> }
>>>
>>>
>>> Thanks.
>>>
>>> java.lang.IllegalStateException
>>> at com.sun.jersey.impl.ThreadLocalHttpContext.getRequest
>>> (ThreadLocalHttpContext.java:75)
>>> at com.sun.jersey.impl.application.WebApplicationImpl
>>> $1.invoke(WebApplicationImpl.java:179)
>>> at $Proxy195.getLanguage(Unknown Source)
>>> at
>>> com.bps.iproject.jersey.entityproviders.errors.ErrorObjectToJSONMess
>>> ageBodyWriter.resolveMessage
>>> (ErrorObjectToJSONMessageBodyWriter.java:113)
>>> at
>>> com.bps.iproject.jersey.entityproviders.errors.ErrorObjectToJSONMess
>>> ageBodyWriter.buildJSONEntity
>>> (ErrorObjectToJSONMessageBodyWriter.java:83)
>>> at
>>> com.bps.iproject.jersey.entityproviders.errors.ErrorObjectToJSONMess
>>> ageBodyWriter.writeTo(ErrorObjectToJSONMessageBodyWriter.java:72)
>>> at
>>> com.bps.iproject.jersey.entityproviders.errors.ErrorObjectToJSONMess
>>> ageBodyWriter.writeTo(ErrorObjectToJSONMessageBodyWriter.java:1)
>>> at com.sun.jersey.spi.container.ContainerResponse.write
>>> (ContainerResponse.java:251)
>>> at
>>> com.sun.jersey.impl.application.WebApplicationImpl.handleRequest
>>> (WebApplicationImpl.java:752)
>>> at
>>> com.sun.jersey.impl.application.WebApplicationImpl.handleRequest
>>> (WebApplicationImpl.java:692)
>>> at
>>> com.sun.jersey.spi.container.servlet.ServletContainer.service
>>> (ServletContainer.java:344)
>>> at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
>>> at
>>> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter
>>> (ApplicationFilterChain.java:269)
>>> at org.apache.catalina.core.ApplicationFilterChain.doFilter
>>> (ApplicationFilterChain.java:188)
>>> at
>>> com.opensymphony.module.sitemesh.filter.PageFilter.parsePage
>>> (PageFilter.java:119)
>>> at
>>> com.opensymphony.module.sitemesh.filter.PageFilter.doFilter
>>> (PageFilter.java:55)
>>> at
>>> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter
>>> (ApplicationFilterChain.java:215)
>>> at org.apache.catalina.core.ApplicationFilterChain.doFilter
>>> (ApplicationFilterChain.java:188)
>>> at
>>> com.bps.iproject.web.filter.CleanupBPSThreadLocalFilter.doFilter
>>> (CleanupBPSThreadLocalFilter.java:47)
>>> at org.acegisecurity.util.FilterToBeanProxy.doFilter
>>> (FilterToBeanProxy.java:98)
>>> at
>>> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter
>>> (ApplicationFilterChain.java:215)
>>> at org.apache.catalina.core.ApplicationFilterChain.doFilter
>>> (ApplicationFilterChain.java:188)
>>> at org.acegisecurity.util.FilterChainProxy
>>> $VirtualFilterChain.doFilter(FilterChainProxy.java:265)
>>> at
>>> org.acegisecurity.intercept.web.FilterSecurityInterceptor.invoke
>>> (FilterSecurityInterceptor.java:107)
>>> at
>>> org.acegisecurity.intercept.web.FilterSecurityInterceptor.doFilter
>>> (FilterSecurityInterceptor.java:72)
>>> at org.acegisecurity.util.FilterChainProxy
>>> $VirtualFilterChain.doFilter(FilterChainProxy.java:275)
>>> at org.acegisecurity.ui.ExceptionTranslationFilter.doFilter
>>> (ExceptionTranslationFilter.java:110)
>>> at org.acegisecurity.util.FilterChainProxy
>>> $VirtualFilterChain.doFilter(FilterChainProxy.java:275)
>>> at
>>> org.acegisecurity.ui.basicauth.BasicProcessingFilter.doFilter
>>> (BasicProcessingFilter.java:175)
>>> at org.acegisecurity.util.FilterChainProxy
>>> $VirtualFilterChain.doFilter(FilterChainProxy.java:275)
>>> at org.acegisecurity.ui.AbstractProcessingFilter.doFilter
>>> (AbstractProcessingFilter.java:229)
>>> at org.acegisecurity.util.FilterChainProxy
>>> $VirtualFilterChain.doFilter(FilterChainProxy.java:275)
>>> at
>>> com.bps.iproject.web.security.TrustedSSOAuthenticationProcessingFilt
>>> er.doFilter(TrustedSSOAuthenticationProcessingFilter.java:116)
>>> at org.acegisecurity.util.FilterChainProxy
>>> $VirtualFilterChain.doFilter(FilterChainProxy.java:275)
>>> at
>>> org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilt
>>> er(HttpSessionContextIntegrationFilter.java:286)
>>> at org.acegisecurity.util.FilterChainProxy
>>> $VirtualFilterChain.doFilter(FilterChainProxy.java:275)
>>> at org.acegisecurity.util.FilterChainProxy.doFilter
>>> (FilterChainProxy.java:149)
>>> at org.acegisecurity.util.FilterToBeanProxy.doFilter
>>> (FilterToBeanProxy.java:98)
>>> at
>>> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter
>>> (ApplicationFilterChain.java:215)
>>> at org.apache.catalina.core.ApplicationFilterChain.doFilter
>>> (ApplicationFilterChain.java:188)
>>> at
>>> org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.d
>>> oFilterInternal(OpenSessionInViewFilter.java:198)
>>> at
>>> org.springframework.web.filter.OncePerRequestFilter.doFilter
>>> (OncePerRequestFilter.java:76)
>>> at
>>> org.apache.catalina.core.ApplicationFilterChain.internalDoFilter
>>> (ApplicationFilterChain.java:215)
>>> at org.apache.catalina.core.ApplicationFilterChain.doFilter
>>> (ApplicationFilterChain.java:188)
>>> at org.apache.catalina.core.StandardWrapperValve.invoke
>>> (StandardWrapperValve.java:213)
>>> at org.apache.catalina.core.StandardContextValve.invoke
>>> (StandardContextValve.java:174)
>>> at org.apache.catalina.core.StandardHostValve.invoke
>>> (StandardHostValve.java:127)
>>> at org.apache.catalina.valves.ErrorReportValve.invoke
>>> (ErrorReportValve.java:117)
>>> at org.apache.catalina.core.StandardEngineValve.invoke
>>> (StandardEngineValve.java:108)
>>> at org.apache.catalina.connector.CoyoteAdapter.service
>>> (CoyoteAdapter.java:174)
>>> at org.apache.coyote.http11.Http11Processor.process
>>> (Http11Processor.java:874)
>>> at org.apache.coyote.http11.Http11BaseProtocol
>>> $Http11ConnectionHandler.processConnection
>>> (Http11BaseProtocol.java:665)
>>> at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket
>>> (PoolTcpEndpoint.java:528)
>>> at
>>> org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt
>>> (LeaderFollowerWorkerThread.java:81)
>>> at org.apache.tomcat.util.threads.ThreadPool
>>> $ControlRunnable.run(ThreadPool.java:689)
>>> at java.lang.Thread.run(Unknown Source)
>>>
>>>
>>>
>>> --------------------------------------------------------------------
>>> -
>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>
>>>
>>>
>>
>>
>>
>
>