Forum How do I...?

How do I understand a HTTP 500 Error better?

nishantvarma
We run Prince over Apache Tomcat using the Java API mentioned here at http://www.princexml.com/doc/java/api/.

Our code snippet looks like:

final Prince prince = new Prince(context.getInitParameter("princexml.execpath"));
try {
prince.setHTML(true);
prince.convert(input, out);
} 
catch (IOException e) 
{
throw new WebApplicationException(Response.status(Status.BAD_REQUEST)
.entity("Error creating PDF from input." + " (" + e.getMessage() + ")").build());
}


However we get HTTP 500 Error for around 50 requests per 1000 requests. Our basic analysis shows that retrying it later on has resolved the issue for many PDF's. So it looks like its not the data that is causing the issue. I have seen Prince XML giving output for most HTML's.

How do I understand the HTTP 500 Error better? How do I get Prince to log the errors? Does Prince enable logging by default or do I have to specify it? If so how would I go about it? Something like this be fine?

prince.setDebug(true);
prince.setLog("/var/log/prince.log");
...
...
prince.convert(input,out);
mikeday
You may need to check the web server log to see why it is denying the request.
nishantvarma
Thanks Mike. A sample trace-back looks like the one below. So it looks like its not able to find "Status" class because of java version mismatch in war creation vs war deployment? However the exception seems to be raised from Prince and I wanted to see if we can get any reasons for that other than input HTML. Perhaps something like memory etc which you had indicated previously. Please let me know.

Wondering if setLog and debugLog will help us so that Prince can give more information on the IOError?

From localhost.2015-06-09.log
Jun 9, 2015 1:16:28 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [PDF Generation Service] in context with path [/com.print.pdfserver-0.1.1] threw exception [Servlet execution threw an exception] with root cause
java.lang.NoClassDefFoundError: com/sun/jersey/api/client/ClientResponse$Status
at com.print.pdfserver.ServiceImplementation$1.write(Unknown Source)
at com.sun.jersey.core.impl.provider.entity.StreamingOutputProvider.writeTo (StreamingOutputProvider.java:71)
at com.sun.jersey.core.impl.provider.entity.StreamingOutputProvider.writeTo (StreamingOutputProvider.java:57)
at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:306)
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest (WebApplicationImpl.java:1448)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest
(WebApplicationImpl.java:1360)
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest
(WebApplicationImpl.java:1350)
....
 

Edited by nishantvarma

mikeday
Is the input being passed to Prince a URL or the document in a string?

Is the exception coming from the server running Prince, or from the server returning the document to be converted by Prince?
nishantvarma
The Input is a HTML string and not a URL. We don't allow images getting inserted from Internet. Local Images are in Data URI format so that there are no callbacks to our app server to get the Image.

Here is our architecture. Linux Server with Prince and Apache Tomcat installed locally in the same machine. Prince path is a parameter read from the WAR XML. Hence both the server running Prince and Tomcat are the same.

I will again confirm these and let you know if there is any change but 99% this is the case.

Are you suspecting network issue in the event of a remote URL? Also would logging help us to get more details?

mikeday
Oh, originally I thought you were getting a 500 error from a remote server, but actually it is coming from the server that you are running Prince on. But the exception doesn't seem to have anything to do with Prince, which part of the code is it coming from?
nishantvarma
Yes. Our main app server and Prince (deployed using Tomcat on a single machine) are usually different two machines. [APP] -> [PRINCE/TOMCAT]
final Prince prince = new Prince(context.getInitParameter("princexml.execpath"));
try {
prince.setHTML(true);
prince.convert(input, out);
} 
catch (IOException e) 
{
throw new WebApplicationException(Response.status(Status.BAD_REQUEST)
.entity("Error creating PDF from input." + " (" + e.getMessage() + ")").build());
}

We are suspecting a problem in
prince.convert(input,out)
due to some environment factors raise an exception
new WebApplicationException(Response.status(Status.BAD_REQUEST)
which in-turn fails because Status Class doesn't exist in this machine due to Java version.
java.lang.NoClassDefFoundError: com/sun/jersey/api/client/ClientResponse$Status
If the latter didn't happen we should have got HTTP 400 with the original problem still existing.
However I should be fixing this status issue perhaps to atleast get e.getMessage() ? that will be a small detour from the original problem if I can get Prince to log it anyway.

That is our analysis. Please let me know if the analysis is wrong. I am wondering if I can force prince to log more details info. If I had some log information then I could atleast request them to switch servers and see which looks like my only try - but it needs some backing up.

Meanwhile I will also check Tomcat for any different error logs.

Edited by nishantvarma

mikeday
Calling SetLog() from Prince will help to see what is happening there, however it's possible that Prince is not even running. Capturing the original exception would be most useful.
nishantvarma
Thanks Mike. Only 5% PDF's fail so I think Prince is running just fine.

I was thinking when you do prince.convert(), it does a type of sub-process call from Java as I am from Python background. Or is like Prince runs in daemon(server) mode and it just connects to it?

Any case we will do a selLog and also see if we can switch servers.

Edited by nishantvarma

mikeday
It's a subprocess, calling Runtime.exec().