Hi Paul,
That makes perfect sense. Indeed the exception mapper is a spring bean.
What do you mean by with jersey 1.0.1 and above it is no longer necessary to
register the spring beans explicitly?
Thanks.
On Thu, Feb 26, 2009 at 3:17 AM, Paul Sandoz <Paul.Sandoz_at_sun.com> wrote:
>
> 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.ErrorObjectToJSONMessageBodyWriter.resolveMessage(ErrorObjectToJSONMessageBodyWriter.java:113)
>>>>>>> at
>>>>>>> com.bps.iproject.jersey.entityproviders.errors.ErrorObjectToJSONMessageBodyWriter.buildJSONEntity(ErrorObjectToJSONMessageBodyWriter.java:83)
>>>>>>> at
>>>>>>> com.bps.iproject.jersey.entityproviders.errors.ErrorObjectToJSONMessageBodyWriter.writeTo(ErrorObjectToJSONMessageBodyWriter.java:72)
>>>>>>> at
>>>>>>> com.bps.iproject.jersey.entityproviders.errors.ErrorObjectToJSONMessageBodyWriter.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.TrustedSSOAuthenticationProcessingFilter.doFilter
>>>>>>> (TrustedSSOAuthenticationProcessingFilter.java:116)
>>>>>>> at
>>>>>>> org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:275)
>>>>>>> at
>>>>>>> org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(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.doFilterInternal(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
>>>>>>
>>>>>>
>>>>>
>>>>
>>>>
>>>
>>
>>
>
>