On 03/13/2012 02:45 PM, Thorsten Scherler wrote:
On 03/13/2012 01:22 PM, Thorsten Scherler wrote:
Hi all,
as I mentioned in another thread I am ATM extracting various code
from our main c3 block into separate ones. The extraction works fine
for i18n and some general pipes. However we use a activemq queue and
when I try to invoke a java pipeline from within a
javax.jms.MessageListener I get a NPE in invoking pipe.execute().
I use something like:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Pipeline<SAXPipelineComponent> emailPipe =
this.applicationContext.getBean("emailPipe", Pipeline.class);
emailPipe.setup(baos, parameters);
emailPipe.execute(); -> here we get NPE
I debugged the whole thing and found out that we never enter in the
execute() method of the pipeline because before the
CallStackCollectorDataStore.set is called.
public void set(String key, Object value) {
CallStack.getCurrentFrame().setAttribute(key, value);
}
This provokes the following:
java.lang.NullPointerException
at
org.apache.cocoon.servlet.collector.CallStackCollectorDataStore.set(CallStackCollectorDataStore.java:28)
at
org.apache.cocoon.servlet.collector.ResponseHeaderCollector.setModifiedResponse(ResponseHeaderCollector.java:200)
at
org.apache.cocoon.servlet.collector.ResponseHeaderCollector.interceptInvoke(ResponseHeaderCollector.java:49)
Now finally I found that CallStack.getCurrentFrame() is NULL,
because in CallStack
public static CallFrame getCurrentFrame() {
final Stack stack = (Stack) callStack.get();
...
the stack is null and then the method is returning null provoking
this very ugly NPE (which took me ages to track down).
Now my question is how can it be that the stack is null and how can I
prevent it from happening? Further I would strongly vote to refactor
CallStack.getCurrentFrame().setAttribute to something like
CallFrame frame = CallStack.getCurrentFrame();
if(null!=frame){
frame.setAttribute(key, value);
}else{
// should we throw here an exception or is there an alternative?
}
Any ideas are welcome.
Ok, getting closer to the underlying problem. I did
ServletContext xXx = CallStackHelper.getCurrentServletContext();
and surprise surprise "xXx = null"
...now how can I attach the context to my jms listener again?
Answering my own question for the archives.
I found a way even if it feels like a hack, but seems to work. Before
you start the pipeline you need to create your own context and do not
forget to leave it again.
ServletContext mainContext = new ServletServiceContext();
ServletServiceRequest request = new ServletServiceRequest(new
URI("dummy"), null);
ServletServiceResponse response = new ServletServiceResponse();
CallStackHelper.enterServlet(mainContext, request, response);
// business logic now
CallStackHelper.leaveServlet(); //now leave the dummy context again
Hope that can be useful to somebody some day. ;)
salu2
--
Thorsten Scherler<scherler.at.gmail.com>
codeBusters S.L. - web based systems
<consulting, training and solutions>
http://www.codebusters.es/