Hi Sergey,

I can test the SNAPSHOT by tomorrow at the earliest because of our artifactory 
is not updating before tonight. I rebuild the code to reproduce the 
ClassCastException.

Looks like I remembered that message the wrong way. I am sorry. :-)

This is a ClassLoader issue:


WARNING: javax.ws.rs.WebApplicationException: java.lang.ClassCastException: 
class 
org.apache.cxf.jaxrs.impl.tl.ThreadLocalHttpServletRequest:foo.bar/cataloguefactory_...@com.sap.engine.boot.loader.ResourceMultiParentClassLoader@5125c637@alive
 incompatible with class 
com.sap.engine.services.servlets_jsp.server.runtime.client.HttpServletRequestFacadeWrapper:service:servlet_...@com.sap.engine.boot.loader.ResourceMultiParentClassLoader@477afcff@alive
at foo.bar.logon.web.jaxrs.impl.LogOnServiceImpl.logon(LogOnServiceImpl.java:70)

LogOnServiceImpl is the JAXRS service we are talking about the whole time. 
CatalogueFactory_ear has absolutely nothing to do with this service at this 
point and I have no idea, why this is even being mentioned here. 
LogOnServiceImpl is in another EAR. The issue is, that the 
HttpServletRequestFacadeWrapper for JSP pages provided by NetWeaver cannot be 
castet to the ThreadLocalHttpServletRequest of CXF, which makes sense.


Does this change the issue?


Best regards,
Marko
 
-----Ursprüngliche Nachricht-----
Von: Sergey Beryozkin [mailto:sberyoz...@gmail.com] 
Gesendet: Donnerstag, 9. April 2015 11:40
An: users@cxf.apache.org
Betreff: Re: AW: AW: AW: AW: How to forward requests to a JSP page when using 
CXFNonSpringJaxrsServlet

Hi,
sure, it is done, what I'd like to ask you though is to test a snapshot, The 
fix I did is basically about wrapping a returned RequestDispatcher and setting 
the property checked by CXF in a couple of places.

I'm actually not sure why you saw a class cast exception with Option 1 before 
my fix. Copying the relevant text here:

 >>>>>> 1.      I tried to implement the forwarding as it was already done
 >>>>>> by the old servlet using:
 >>>>>>
 >>>>>> @Context
 >>>>>> private ServletContext context;
 >>>>>>
 >>>>>> context.getRequestDispatcher(url).forward(request, response);  >>>>>>  
 >>>>>> >>>>>> But this does not work, because of a ClassCastException 
 >>>>>> happening.
 >>>>>> The exception message was like: The ThreadLocal instance for  >>>>>> 
 >>>>>> ServletContext could not be casted to the RequestDispatcher  >>>>>> 
 >>>>>> instance, which is provided by the server. (NetWeaver)  >>>>>>  >>>>>> 
 >>>>>> The ThreadLocal object is provided by CXF and the  >>>>>> 
 >>>>>> RequestDispatcher implementation is provided by NetWeaver. Of  >>>>>> 
 >>>>>> course, this will not work.

I'm not sure I understand to be honest. The thread local object provided by CXF 
keeps current ServletContext objects (created by NetWeaver I assume). So the 
runtime will do

threadLocal.put(currentServletContext)

and then

context.getRequestDispatcher(url)

is effectively

((ServletContext)threadLocal.get()).getRequestDispatcher(url)

so I'm not sure where ClassCastException is coming from...

Please investigate on your end by debugging the code...

Cheers, Sergey




On 09/04/15 07:24, Voss, Marko wrote:
> Hi Sergey,
>
> yes, we use a 2.7.x CXF version. I think, that is because of the old 
> NetWeaver server we have to use. Can you please fix this for 2.7.16 as 
> well? Thank you very much. :-)
>
>
> Best regards,
> Marko
>
> -----Ursprüngliche Nachricht-----
> Von: Sergey Beryozkin [mailto:sberyoz...@gmail.com]
> Gesendet: Mittwoch, 8. April 2015 18:59
> An: users@cxf.apache.org
> Betreff: Re: AW: AW: AW: How to forward requests to a JSP page when 
> using CXFNonSpringJaxrsServlet
>
> Hi Marko
>
> See https://issues.apache.org/jira/browse/CXF-6337
>
> Can you please test either 3.0.5-SNAPSHOT or 3.1.0-SNAPSHOT ?
> Do you need it for CXF 2.7.16 ?
>
> Sergey
>
> On 08/04/15 13:31, Sergey Beryozkin wrote:
>> Hi Marko
>>
>> That should be possible to get fixed.
>> As I said, the query parameters are passed along either way but if 
>> you can not modify JSP or these query parameters are actually 
>> representing some custom parameters, then yes, I can see why option 1 makes 
>> sense.
>>
>> By the way, RequestDispatcher supports dynamic resource paths set on 
>> the message context, so if you have CXF MessageContext injected then 
>> you'd set a property on it,
>>
>> "redirect.resource.path"="my.jsp?a=b"
>>
>> and it will work, but it is very much CXF specific....
>>
>> I'll try to get option 1 done before the releases...
>>
>> Cheers, Sergey
>>
>> On 08/04/15 13:13, Voss, Marko wrote:
>>> Hi Sergey,
>>>
>>> yes, it would be great, if variant 1 would work fine. (No
>>> ClassCastException)
>>>
>>> servletContext.getRequestDispatcher("my.jsp?a=b").forward()
>>>
>>>
>>> Is it possible to fix this?
>>>
>>>
>>> Best regards,
>>> Marko
>>>
>>>
>>> -----Ursprüngliche Nachricht-----
>>> Von: Sergey Beryozkin [mailto:sberyoz...@gmail.com]
>>> Gesendet: Mittwoch, 8. April 2015 14:07
>>> An: users@cxf.apache.org
>>> Betreff: Re: AW: AW: How to forward requests to a JSP page when 
>>> using CXFNonSpringJaxrsServlet
>>>
>>> Hi
>>>
>>> Not at the moment, how does it work in general, is it
>>>
>>> servletContext.getRequestDispatcher("my.jsp?a=b").forward() ?
>>>
>>> Note that RequestDispatcherProvider sets query parameters (as well 
>>> as path and other request properties) as HttpServletRequest 
>>> parameters, see
>>>
>>> https://fisheye6.atlassian.com/browse/cxf/rt/frontend/jaxrs/src/main
>>> /
>>> java/org/apache/cxf/jaxrs/provider/RequestDispatcherProvider.java?r=
>>> 3
>>> 309231e467225b18b24d90d77153a0c572a17e0#to342
>>>
>>>
>>> Cheers, Sergey
>>>
>>> On 08/04/15 12:37, Voss, Marko wrote:
>>>> Hi Sergey,
>>>>
>>>> can I somehow tell the RequestDispatcher to use the String of the 
>>>> Response Entity for redirection? Just saw, that there are also 
>>>> query parameters added to the JSP URL in some cases...
>>>>
>>>>
>>>> Thanks and best regards,
>>>> Marko
>>>>
>>>> -----Ursprüngliche Nachricht-----
>>>> Von: Sergey Beryozkin [mailto:sberyoz...@gmail.com]
>>>> Gesendet: Mittwoch, 8. April 2015 13:03
>>>> An: users@cxf.apache.org
>>>> Betreff: Re: AW: How to forward requests to a JSP page when using 
>>>> CXFNonSpringJaxrsServlet
>>>>
>>>> Hi Marko
>>>>
>>>> This is one way to do it, yes, does not even has to be on the same 
>>>> line, example, 
>>>> org.apache.cxf.jaxrs.provider.RequestDispatcherProvider
>>>> (
>>>> resource.Status.JSP1=/hello.jsp
>>>> resource.Status.JSP2=/foo.jsp
>>>> )
>>>>
>>>> Perhaps another alternative is to wrap an enum value into a bean 
>>>> class and redirect to a single JSP resource, which will get the 
>>>> bean, check the enum, delegate to specific JSPs...
>>>>
>>>> Cheers, Sergey
>>>>
>>>> On 08/04/15 06:47, Voss, Marko wrote:
>>>>> Hello Sergey,
>>>>>
>>>>> variant 2 was just an idea but is not really helpful, because of 
>>>>> we need to do some logic in order to decide, which JSP to call. So 
>>>>> we have to execute some code.
>>>>>
>>>>> So the idea I got is the following: The servlet does execute the 
>>>>> code and returns an enum value. Based on the enum value, the 
>>>>> RequestDispatcher decides, which JSP to call. This might look like
>>>>> this:
>>>>>
>>>>> org.apache.cxf.jaxrs.provider.RequestDispatcherProvider(resource.S
>>>>> t
>>>>> at
>>>>> u
>>>>> s.JSP1=/hello.jsp
>>>>> resource.Status.JSP2=/foo.jsp)
>>>>>
>>>>> The Response object gets the enum value as its entity.
>>>>>
>>>>> Is this correct?
>>>>>
>>>>>
>>>>> Thank you very much and best regards,
>>>>>
>>>>> Marko
>>>>>
>>>>> -----Ursprüngliche Nachricht-----
>>>>> Von: Sergey Beryozkin [mailto:sberyoz...@gmail.com]
>>>>> Gesendet: Dienstag, 7. April 2015 17:40
>>>>> An: users@cxf.apache.org
>>>>> Betreff: Re: How to forward requests to a JSP page when using 
>>>>> CXFNonSpringJaxrsServlet
>>>>>
>>>>> Hi,
>>>>>
>>>>> Please see comments below
>>>>> On 07/04/15 14:42, Voss, Marko wrote:
>>>>>> Hello,
>>>>>>
>>>>>> I do have the following situation:
>>>>>>
>>>>>> We have to use the CXFNonSpringJaxrsServlet for implementing the 
>>>>>> REST endpoints.
>>>>>>
>>>>>> The main servlet (old code to be replaced by the new REST
>>>>>> endpoints) of the application does implement internal forwarding to JSP 
>>>>>> pages.
>>>>>> (for example to a login page)
>>>>>>
>>>>>>
>>>>>> 1.      I tried to implement the forwarding as it was already done
>>>>>> by the old servlet using:
>>>>>>
>>>>>> @Context
>>>>>> private ServletContext context;
>>>>>>
>>>>>> context.getRequestDispatcher(url).forward(request, response);
>>>>>>
>>>>>> But this does not work, because of a ClassCastException happening.
>>>>>> The exception message was like: The ThreadLocal instance for 
>>>>>> ServletContext could not be casted to the RequestDispatcher 
>>>>>> instance, which is provided by the server. (NetWeaver)
>>>>>>
>>>>>> The ThreadLocal object is provided by CXF and the 
>>>>>> RequestDispatcher implementation is provided by NetWeaver. Of 
>>>>>> course, this will not work.
>>>>> Hmm, interesting, may make sense supporting this variation, I'll 
>>>>> have a look...
>>>>>
>>>>>>
>>>>>>
>>>>>> 2.       I was trying to use the RequestDispatcherProvider of CXF,
>>>>>> but how can you configure this provider using the 
>>>>>> CXFNonSpringJaxrsServlet?
>>>>>>
>>>>>> <servlet>
>>>>>>                   <servlet-name>RestfulApp</servlet-name>
>>>>>>
>>>>>> <servlet-class>org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServ
>>>>>> l
>>>>>> et</servlet-class>
>>>>>>
>>>>>>                   <init-param>
>>>>>>                          <param-name>jaxrs.serviceClasses</param-name>
>>>>>>                          <param-value>
>>>>>>                          ...
>>>>>>                          </param-value>
>>>>>>                   </init-param>
>>>>>>                   <init-param>
>>>>>>                          <param-name>jaxrs.providers</param-name>
>>>>>>                          <param-value>
>>>>>>
>>>>>> org.apache.cxf.jaxrs.provider.RequestDispatcherProvider
>>>>>>                          <!-- How to configure this one here??? -->
>>>>>>                          </param-value>
>>>>>>                   </init-param>
>>>>>>                   <load-on-startup>1</load-on-startup>
>>>>>>             </servlet>
>>>>>>
>>>>>
>>>>> The simplest way to do at a servlet level is to use redirect 
>>>>> parameters, see
>>>>>
>>>>> https://git-wip-us.apache.org/repos/asf?p=cxf.git;a=blob;f=systest
>>>>> s
>>>>> /j
>>>>> a
>>>>> xrs/src/test/resources/jaxrs_dispatch/WEB-INF/web.xml;h=a2212337bd
>>>>> 6
>>>>> a9
>>>>> e
>>>>> d7a212b21a6826850581601121;hb=HEAD
>>>>>
>>>>> or indeed you can directly configure this provider (and other
>>>>> providers) as a parameter, do something like
>>>>>
>>>>> org.apache.cxf.jaxrs.provider.RequestDispatcherProvider(resourcePa
>>>>> t
>>>>> h=
>>>>> /
>>>>> WEB-INF/jsp/test.jsp
>>>>> someotherproperty=somevalue)
>>>>>
>>>>>
>>>>>>
>>>>>> 3.       I was trying to implement a RequestHandler, which worked
>>>>>> but when the forwarding happens, I get spammed by error messages 
>>>>>> on server side, that the OutputStreams of the servlets are 
>>>>>> already taken by a getWriter() method. This spam should be avoided.
>>>>>> Example
>>>>>> Spam:
>>>>>>
>>>>>> WARNING: Interceptor for
>>>>>> {http://impl.jaxrs.web.foo.bar/}MyServiceImpl has thrown 
>>>>>> exception, unwinding now
>>>>>> com.sap.engine.services.servlets_jsp.server.exceptions.WebIllegalStateException:
>>>>>> The stream has already been taken by method [getWriter()].
>>>>>> at
>>>>>> com.sap.engine.services.servlets_jsp.server.runtime.client.HttpSe
>>>>>> r
>>>>>> vl
>>>>>> e
>>>>>> tResponseFacade.getOutputStream(HttpServletResponseFacade.java:24
>>>>>> 4
>>>>>> )
>>>>>>
>>>>>> This servlet is not in use at all at this point of the request 
>>>>>> and not after the request as well. So I wonder in general, why 
>>>>>> this exception occurs on this servlet. It is maybe a NetWeaver thing.
>>>>>>
>>>>>>
>>>>>> 4.       I was trying to implement an equivalent to the
>>>>>> RequestDispatcherProvider, doing things here by code. But even 
>>>>>> when this works, I still get the spam from above.
>>>>>>
>>>>> In both cases the outbound CXF JAX-RS interceptor and Http 
>>>>> transport need to know the request has been redirected, this can 
>>>>> be done by setting an "http.request.redirected" property on the 
>>>>> current message,
>>>>>
>>>>> message.put("http.request.redirected", true)
>>>>>
>>>>> But the option 2 is simpler, can you try it and let me know if it 
>>>>> works for you ?
>>>>>
>>>>> Thanks, Sergey
>>>>>
>>>>>>
>>>>>> Any help is much appreciated.
>>>>>>
>>>>>>
>>>>>> Best regards,
>>>>>>
>>>>>> Marko
>>>>>>
>>>>>
>>>>
>>>
>>
>
>
> --
> Sergey Beryozkin
>
> Talend Community Coders
> http://coders.talend.com/
>
> Blog: http://sberyozkin.blogspot.com
>

Reply via email to