1

Background

I have a java.lang.Thread that runs inside an application on a web server (JBoss or WebSphere) at a specific time, without human interaction, and all it does is send out an email. The contents of the email are similar to the contents of a JSP (/jsp/Report.jsp) we use as a display in a web view.

Instead of duplicating the same work or changing the JSP to a static class both can access, I would like to grab the contents of the run of the JSP from inside the thread and place it in the email for sending.

I have the current ServletContext from using a listener in the "web.xml". My current JSP call in the thread is like:

servletContext.getRequestDispatcher("/jsp/Report.jsp").include(dummyRequest, dummyResponse);

And the request/response classes are basically created like this:

final HttpServletRequest dummyRequest = new HttpServletRequest() { .... }
final HttpServletResponse dummyResponse = new HttpServletResponse() { .... }

I was going to set additional attributes (Classes) to the JSP via the dummyRequest like "dummyRequest.setAttribute(name, value)".

Whenever I make the call, I get exceptions because the dummy request/response is an anonymous class of HttpServletResponse/HttpServletRequest.

WebSphere Application Server 7.0.0.17:

java.lang.RuntimeException: SRV.8.2: RequestWrapper objects must extend ServletRequestWrapper or HttpServletRequestWrapper

JBoss AS 7.1.1:

java.lang.ClassCastException: my.test.thread$1$2 incompatible with javax.servlet.ServletRequestWrapper

And I can't create a HttpServletResponseWrapper/HttpServletRequestWrapper without an original request/response.


Question

So.... Is it possible to grab the contents of a JSP from inside a Thread on a web application using the context?

If so, how do I go about doing it?


Update

Here is the code I am using for my test: link


Research

I've now started diving into the server's source code to try and get a clue what is going on.

JBoss

In ApplicationDispatcher, "forward" does nothing since the "DISPATCHER_TYPE" attribute isn't set in the request (seen in the method processRequest). This isn't required for "include".

The problem I get with "incude" about the incompatible type is inside "ApplicationFilterFactory.createFilterChain". The Request object isn't the right class it is looking for, which in JBoss' case is either "org.apache.catalina.connector.Request" or "org.apache.catalina.connector.RequestFacade". It won't continue at all unless the request matches one of these types.

So when I use the following request:

 final HttpServletRequest dummyRequest = new org.apache.catalina.connector.RequestFacade(new org.apache.catalina.connector.Request() { ... });

It successfully runs and returns the results of the JSP from inside the thread.

Websphere

I have not been able to produce the same results on Websphere.

Websphere requires an instance of "com.ibm.ws.webcontainer.srt.SRTConnectionContextImpl" and then manipulating the ServletContext to its original class "com.ibm.wsspi.webcontainer.facade.ServletContextFacade", but then I get stuck on an "access$200" null pointer exception inside "com.ibm.ws.webcontainer.srt.SRTServletRequest$SRTServletRequestHelper", which makes it seem like I am breaking Java somehow.

java.lang.NullPointerException at com.ibm.ws.webcontainer.srt.SRTServletRequest$SRTServletRequestHelper.access$200(SRTServletRequest.java:2629)

This is my current code:

SRTConnectionContext n = new SRTConnectionContextImpl();

(((SRTServletRequest) (n.getRequest())).getRequestContext())
.setCurrWebAppBoundary((WebApp) ((ServletContextFacade) context)
    .getIServletContext());

servletContext.getRequestDispatcher("/jsp/Report.jsp").include(n.getRequest(), n.getResponse());

The End

Hopefully someone can find a way to accomplish this on Websphere.

From my viewing of the source, unless there is a side method I am missing, you cannot run a include/forward without the server's own specific class files for the request. Even request wrappers are unwrapped to their base classes, and that is why I was always getting the Class Cast Exception with and without a wrapper.

If there isn't a cleaner, not server specific with server classes, method of getting the results of a JSP from inside a thread, than this may be the answer to my original question, regardless of how messy it seems.

rveach
  • 2,081
  • 15
  • 25
  • possible duplicate of [JSP as Email template](http://stackoverflow.com/questions/459624/jsp-as-email-template) – Smutje Jan 21 '15 at 22:02
  • @Smutje From his example [link](http://stackoverflow.com/questions/456148/suggestions-for-java-email-templating/20847683#20847683), it doesn't mention inside a thread and he seems to be using an already existing request object which doesn't exist in a thread. One of my problems was I was using "include" instead of "forward" so that removed the exception I got, but I am just getting a blank string as my JSP results. I am trying to look into what is wrong. – rveach Jan 21 '15 at 22:46

1 Answers1

0

because the dummy request/response is an anonymous class of HttpServletResponse/HttpServletRequest.

No. you get classcast exception b/c they are different container expects wrapper.. your code is providing request/response.

It is not very clear to us where exactly you are making call to create dummy HttpServletRequest/Response.. looks like from where you are calling... you actually need to instantiate ServletRequestWrapper/responseWapper object, set you request on it if you have a handle, and work with it.

May be this can help http://hc.apache.org/ to read the html out of your jsp/response and create email out of it.

Sendi_t
  • 617
  • 5
  • 13
  • I am creating the dummies before the call to "include". HttpServletRequestWrapper requires an initial HttpServletRequest and even if I use my dummyRequest, I still get the same ClassCastException. – rveach Jan 21 '15 at 23:13