Dynamic PNG Servlet concurrency problem
Dynamic PNG Servlet concurrency problem
Hello. I am following the developer's manual to get a dynamic chart with jfreechart. It worked fine in tomcat for simple graphics, but now that I have to access a jdbc source and plot 3 concurrent graphics (all of them are the same servlet run with different post parameters) it doesn't work at all. It yields weird errors, like "Broken Pipe". Well, I simplified it the most I could: I made a simple html file like that:
<html>
<head>
<title>Teste
</title>
</head>
<body bgcolor=red>
<center>
<img src=http://localhost:8080/nrpt/MyServlet?pa ... &type=M><p>
</center>
</body>
</html>
And it worked fine. But if I do more than one invocation of the same picture, it simply doesn't work; it keeps locked, loading, never outputting images. It doesn't well if it's like that:
<html>
<head>
<title>Teste
</title>
</head>
<body bgcolor=red>
<center>
<img src=http://localhost:8080/nrpt/MyServlet?pa ... &type=M><p>
<img src=http://localhost:8080/nrpt/MyServlet?pa ... &type=D><p>
<img src=http://localhost:8080/nrpt/MyServlet?pa ... &type=A><p>
</center>
</body>
</html>
SOMETIMES - not too often - some graphics appears. Most times, however, it just keeps waiting and waiting forever. If I try the direct URL (like http://localhost:8080/nrpt/MyServlet?pa ... 3=B&type=M) it always works fine. It looks like a concurrency/synchronization/threading problem.
the methods I am using to export the chart to png are those:
response.setContentType("image/png");
response.setHeader("Content-Disposition", "inline; filename=\"" + name + ".png\"");
ChartUtilities.writeChartAsPNG(out, mychart, 448, 200);
out.flush();
response.flushBuffer();
How could I fix that and which should I look first? I am thinking about using
something other than CharUtilities to write the PNG Stream. Please, I desperately
need any advice!
<html>
<head>
<title>Teste
</title>
</head>
<body bgcolor=red>
<center>
<img src=http://localhost:8080/nrpt/MyServlet?pa ... &type=M><p>
</center>
</body>
</html>
And it worked fine. But if I do more than one invocation of the same picture, it simply doesn't work; it keeps locked, loading, never outputting images. It doesn't well if it's like that:
<html>
<head>
<title>Teste
</title>
</head>
<body bgcolor=red>
<center>
<img src=http://localhost:8080/nrpt/MyServlet?pa ... &type=M><p>
<img src=http://localhost:8080/nrpt/MyServlet?pa ... &type=D><p>
<img src=http://localhost:8080/nrpt/MyServlet?pa ... &type=A><p>
</center>
</body>
</html>
SOMETIMES - not too often - some graphics appears. Most times, however, it just keeps waiting and waiting forever. If I try the direct URL (like http://localhost:8080/nrpt/MyServlet?pa ... 3=B&type=M) it always works fine. It looks like a concurrency/synchronization/threading problem.
the methods I am using to export the chart to png are those:
response.setContentType("image/png");
response.setHeader("Content-Disposition", "inline; filename=\"" + name + ".png\"");
ChartUtilities.writeChartAsPNG(out, mychart, 448, 200);
out.flush();
response.flushBuffer();
How could I fix that and which should I look first? I am thinking about using
something other than CharUtilities to write the PNG Stream. Please, I desperately
need any advice!
Re: Dynamic PNG Servlet concurrency problem
Maybe I should give more data:
sun j2sdkee 1.3.1
sun j2sdk 1.4.1_01
eclipse 2.0
tomcat 4.0.4
jfreechart 0.9.4
Conectiva Linux with kernel 2.4.18-8cl (it's just like RedHat).
sun j2sdkee 1.3.1
sun j2sdk 1.4.1_01
eclipse 2.0
tomcat 4.0.4
jfreechart 0.9.4
Conectiva Linux with kernel 2.4.18-8cl (it's just like RedHat).
Still more data
I made a test: I broke the streaming servlet into 3 almost identical ones and then tried that. It worked. Well, but I wasn't really going to use that; I was going to insert these pictures in an iText document. I was able to insert one graphic with static data before, but when I try to insert these charts, I get this error message:
java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
at org.apache.catalina.connector.ResponseBase.flushBuffer(ResponseBase.java:674)
at org.apache.catalina.connector.HttpResponseBase.flushBuffer(HttpResponseBase.java:764)
at org.apache.catalina.connector.ResponseBase.write(ResponseBase.java:647)
at org.apache.catalina.connector.ResponseBase.write(ResponseBase.java:656)
at org.apache.catalina.connector.ResponseStream.write(ResponseStream.java:312)
at org.apache.catalina.connector.http.HttpResponseStream.write(HttpResponseStream.java:182)
at org.apache.catalina.connector.ResponseStream.write(ResponseStream.java:286)
at com.jrefinery.chart.ChartUtilities.writeBufferedImageAsPNG(Unknown Source)
at com.jrefinery.chart.ChartUtilities.writeChartAsPNG(Unknown Source)
at com.jrefinery.chart.ChartUtilities.writeChartAsPNG(Unknown Source)
at br.com.ymf.NetReport.Servlets.PerformanceComparativaImagemM.doGet(PerformanceComparativaImagemM.java:178)
at javax.servlet.http.HttpServlet.service(HttpServlet.java)
at javax.servlet.http.HttpServlet.service(HttpServlet.java)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
at br.com.ymf.NetReport.Filtros.FiltroAutenticadorCliente.doFilter(FiltroAutenticadorCliente.java:56)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:213)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:243)
at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:566)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:472)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:190)
at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:566)
at org.apache.catalina.valves.CertificatesValve.invoke(CertificatesValve.java:246)
at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:564)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:472)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943)
at org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2347)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:180)
at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:566)
at org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.java:170)
at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:564)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:170)
at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:564)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:468)
at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:564)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:472)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:174)
at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:566)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:472)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943)
at org.apache.catalina.connector.http.HttpProcessor.process(HttpProcessor.java:1027)
at org.apache.catalina.connector.http.HttpProcessor.run(HttpProcessor.java:1125)
at java.lang.Thread.run(Thread.java:536)
br.com.ymf.NetReport.Servlets.PerformanceComparativaImagemM.doGet(PerformanceComparativaImagemM.java:178)
is that line:
response.setContentType("image/png");
response.setHeader("Content-Disposition", "inline; filename=\"" + relatorio + periodicidade.substring(0,1) + ".png\"");
ChartUtilities.writeChartAsPNG(out, grafico, 448, 200);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
out.flush();
still no clue of what to do =(
java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
at org.apache.catalina.connector.ResponseBase.flushBuffer(ResponseBase.java:674)
at org.apache.catalina.connector.HttpResponseBase.flushBuffer(HttpResponseBase.java:764)
at org.apache.catalina.connector.ResponseBase.write(ResponseBase.java:647)
at org.apache.catalina.connector.ResponseBase.write(ResponseBase.java:656)
at org.apache.catalina.connector.ResponseStream.write(ResponseStream.java:312)
at org.apache.catalina.connector.http.HttpResponseStream.write(HttpResponseStream.java:182)
at org.apache.catalina.connector.ResponseStream.write(ResponseStream.java:286)
at com.jrefinery.chart.ChartUtilities.writeBufferedImageAsPNG(Unknown Source)
at com.jrefinery.chart.ChartUtilities.writeChartAsPNG(Unknown Source)
at com.jrefinery.chart.ChartUtilities.writeChartAsPNG(Unknown Source)
at br.com.ymf.NetReport.Servlets.PerformanceComparativaImagemM.doGet(PerformanceComparativaImagemM.java:178)
at javax.servlet.http.HttpServlet.service(HttpServlet.java)
at javax.servlet.http.HttpServlet.service(HttpServlet.java)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
at br.com.ymf.NetReport.Filtros.FiltroAutenticadorCliente.doFilter(FiltroAutenticadorCliente.java:56)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:213)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:243)
at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:566)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:472)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:190)
at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:566)
at org.apache.catalina.valves.CertificatesValve.invoke(CertificatesValve.java:246)
at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:564)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:472)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943)
at org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2347)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:180)
at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:566)
at org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.java:170)
at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:564)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:170)
at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:564)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:468)
at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:564)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:472)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:174)
at org.apache.catalina.core.StandardPipeline.invokeNext(StandardPipeline.java:566)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:472)
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:943)
at org.apache.catalina.connector.http.HttpProcessor.process(HttpProcessor.java:1027)
at org.apache.catalina.connector.http.HttpProcessor.run(HttpProcessor.java:1125)
at java.lang.Thread.run(Thread.java:536)
br.com.ymf.NetReport.Servlets.PerformanceComparativaImagemM.doGet(PerformanceComparativaImagemM.java:178)
is that line:
response.setContentType("image/png");
response.setHeader("Content-Disposition", "inline; filename=\"" + relatorio + periodicidade.substring(0,1) + ".png\"");
ChartUtilities.writeChartAsPNG(out, grafico, 448, 200);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
out.flush();
still no clue of what to do =(
Re: Dynamic PNG Servlet concurrency problem
Try the writeChartAsJPEG method, just to see if it is a problem with the PNG encoder.
Regards,
DG
Regards,
DG
Re: Dynamic PNG Servlet concurrency problem
I doubt it is a problem with the PNG encoder as I have a number of sites where I produce multiple graphs on a single page based of different parameters. I would suspect that it is a threading issue within your servlet. If you post the code for your servlet it will not take long to check.
Regards,
Richard...
Regards,
Richard...
Re: Dynamic PNG Servlet concurrency problem
Hello Mr. GIlbert! I tried with writeChartAsJPEG too, setting the content-type to jpeg and so on, but it worked the same way.
The code for my servlet is the following:
----------------------------------------------------------
<imports omitted>
public class PerformanceComparativaImagemM extends SQLServlet {
private static final String STORED_PROCEDURE = "my_stored_procedure";
private PreparedStatement ps1, ps2;
private ResultSet rs1, rs2;
private ConfiguracaoBean configuracaoBean;
private String relatorio, dataInicial, tipoRelatorio, periodicidade;
Double [][] valores;
String [] series;
String [] categorias;
String titulo;
int numberOfRows, contador;
CategoryPlot plot;
NumberAxis eixo;
Legend legenda;
static SimpleDateFormat dmy = new SimpleDateFormat("dd/MM/yyyy");
static SimpleDateFormat ymd = new SimpleDateFormat("yyyyMMdd");
/**
* Processes a GET request.
*
* @param request The request.
* @param response The response.
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ServletOutputStream out = response.getOutputStream();
relatorio = request.getParameter("relatorio");
dataInicial = request.getParameter("dataInicial");
tipoRelatorio = request.getParameter ("tipoRelatorio");
periodicidade = "M";
if (relatorio==null||dataInicial==null||tipoRelatorio==null||periodicidade==null) {
System.err.println("Invalid data.");
return;
}
if (!loadJDBCDriver())
{
throw new ServletException("Can't load JDBC drivers!");
}
if (!connectToDatabase())
{
throw new ServletException("Can't connect to database!");
}
try
{
ps1 =
con.prepareCall("{call NETBOOK.dbo." + STORED_PROCEDURE + " (?,?,?,?)}");
ps1.setString(1, relatorio);
ps1.setString(2, dataInicial);
ps1.setString(3, tipoRelatorio);
ps1.setString(4, periodicidade);
rs1 = ps1.executeQuery();
numberOfRows = 0;
while (rs1.next()) {
numberOfRows++;
} // Change later - inefficient code
if (numberOfRows==0)
{
disconnectFromDatabase();
throw new ServletException(
"no occurrences ");
}
rs1 = ps1.executeQuery();
valores = new Double[numberOfRows][1];
series = new String[numberOfRows];
try {
contador=0;
while (rs1.next()) {
valores[contador][0] = new Double(rs1.getDouble("VL"));
if (rs1.getString("DS_ITEM").trim().equalsIgnoreCase(relatorio)) {
series[contador] = "Carteira";
} else {
series[contador] = rs1.getString("DS_ITEM");
}
contador++;
}
categorias = new String[] {dmy.format(ymd.parse(dataInicial)) };
DefaultCategoryDataset ds = new DefaultCategoryDataset(series, categorias, valores); // construÃmos os valores para o gráfico
switch (periodicidade.charAt(0)) {
case 'M':
titulo = "Monthly";
break;
case 'A':
titulo = "Yearly";
break;
case '1':
titulo = "Last 12 months";
break;
default:
titulo = "Unknown type: " + periodicidade;
}
JFreeChart grafico = ChartFactory.createVerticalBarChart(titulo,"","",ds,true);
grafico.setBackgroundPaint(Color.white);
plot = grafico.getCategoryPlot();
plot.setBackgroundPaint(Color.white);
plot.setVerticalLabels(true);
eixo = (NumberAxis)plot.getRangeAxis();
eixo.setStandardTickUnits(TickUnits.createIntegerTickUnits());
legenda = grafico.getLegend();
legenda.setAnchor(Legend.EAST);
response.setContentType("image/png");
response.setHeader("Content-Disposition", "inline; filename=\"" + relatorio + periodicidade.substring(0,1) + ".png\"");
ChartUtilities.writeChartAsPNG(out, grafico, 448, 200);
out.flush();
response.flushBuffer();
out.close();
}
catch (Exception e) {
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
}
finally {
try
{
out.close();
} catch (IOException e)
{
System.err.println("Can't close");
}
}
} catch (SQLException e)
{
System.err.println("SQL Error: " + e.getMessage());
}
}
}
--------------------------------------------------------------------------------
BTW, it is called by another servlet which actually renderizes the HTML (or PDF) via
iText. The relevant code (the actual code is thousands of line) is here:
-------------------------------------------------------------------------
...
private Cell incluiCelula(String frase, FonteNrpt fonte, String comprimento, char alinhamento)
throws BadElementException
{
Cell celltmp;
celltmp =
new Cell(
new Phrase(
frase,
FontFactory.getFont(
fonte.getFonte(),
fonte.getTamanho(),
fonte.getAtributo(),
new Color(fonte.getCorR(), fonte.getCorG(), fonte.getCorB()))));
if (comprimento != null)
celltmp.setWidth(comprimento);
switch (alinhamento)
{
case 'L' :
case 'l' :
celltmp.setHorizontalAlignment(Element.ALIGN_LEFT);
break;
case 'M' :
case 'm' :
celltmp.setHorizontalAlignment(Element.ALIGN_CENTER);
break;
case 'R' :
case 'r' :
celltmp.setHorizontalAlignment(Element.ALIGN_RIGHT);
default :
break;
}
celltmp.setBorderWidth(0.0f);
return celltmp;
}
...
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException
{
...
com.lowagie.text.Image performanceImg1 =
com.lowagie.text.Image.getInstance(
new java.net.URL(
request.getScheme()
+ "://"
+ request.getServerName()
+ ":"
+ request.getServerPort()
+ request.getContextPath()
+ "/rpt/PerformanceComparativaImagem"
+ per[ii]
+ "?relatorio="
+ configuracaoBean.getCarteira().trim()
+ "&dataInicial="
+ sdfamdonly
.format(configuracaoBean.getDataInicial())
.trim()
+ "&tipoRelatorio="
+ "B"));
performanceImg1.setMarkupAttribute("border", "0");
Chunk performanceChunk1 = new Chunk(performanceImg1, 0.0f, 0.0f);
cell = new Cell(performanceChunk1);
cell.setWidth("60");
cell.setColspan(2);
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setBorderWidth(0.0f);
ytabela.addCell(cell);
...
----------------------------------------------------------------------------
The code for my servlet is the following:
----------------------------------------------------------
<imports omitted>
public class PerformanceComparativaImagemM extends SQLServlet {
private static final String STORED_PROCEDURE = "my_stored_procedure";
private PreparedStatement ps1, ps2;
private ResultSet rs1, rs2;
private ConfiguracaoBean configuracaoBean;
private String relatorio, dataInicial, tipoRelatorio, periodicidade;
Double [][] valores;
String [] series;
String [] categorias;
String titulo;
int numberOfRows, contador;
CategoryPlot plot;
NumberAxis eixo;
Legend legenda;
static SimpleDateFormat dmy = new SimpleDateFormat("dd/MM/yyyy");
static SimpleDateFormat ymd = new SimpleDateFormat("yyyyMMdd");
/**
* Processes a GET request.
*
* @param request The request.
* @param response The response.
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ServletOutputStream out = response.getOutputStream();
relatorio = request.getParameter("relatorio");
dataInicial = request.getParameter("dataInicial");
tipoRelatorio = request.getParameter ("tipoRelatorio");
periodicidade = "M";
if (relatorio==null||dataInicial==null||tipoRelatorio==null||periodicidade==null) {
System.err.println("Invalid data.");
return;
}
if (!loadJDBCDriver())
{
throw new ServletException("Can't load JDBC drivers!");
}
if (!connectToDatabase())
{
throw new ServletException("Can't connect to database!");
}
try
{
ps1 =
con.prepareCall("{call NETBOOK.dbo." + STORED_PROCEDURE + " (?,?,?,?)}");
ps1.setString(1, relatorio);
ps1.setString(2, dataInicial);
ps1.setString(3, tipoRelatorio);
ps1.setString(4, periodicidade);
rs1 = ps1.executeQuery();
numberOfRows = 0;
while (rs1.next()) {
numberOfRows++;
} // Change later - inefficient code
if (numberOfRows==0)
{
disconnectFromDatabase();
throw new ServletException(
"no occurrences ");
}
rs1 = ps1.executeQuery();
valores = new Double[numberOfRows][1];
series = new String[numberOfRows];
try {
contador=0;
while (rs1.next()) {
valores[contador][0] = new Double(rs1.getDouble("VL"));
if (rs1.getString("DS_ITEM").trim().equalsIgnoreCase(relatorio)) {
series[contador] = "Carteira";
} else {
series[contador] = rs1.getString("DS_ITEM");
}
contador++;
}
categorias = new String[] {dmy.format(ymd.parse(dataInicial)) };
DefaultCategoryDataset ds = new DefaultCategoryDataset(series, categorias, valores); // construÃmos os valores para o gráfico
switch (periodicidade.charAt(0)) {
case 'M':
titulo = "Monthly";
break;
case 'A':
titulo = "Yearly";
break;
case '1':
titulo = "Last 12 months";
break;
default:
titulo = "Unknown type: " + periodicidade;
}
JFreeChart grafico = ChartFactory.createVerticalBarChart(titulo,"","",ds,true);
grafico.setBackgroundPaint(Color.white);
plot = grafico.getCategoryPlot();
plot.setBackgroundPaint(Color.white);
plot.setVerticalLabels(true);
eixo = (NumberAxis)plot.getRangeAxis();
eixo.setStandardTickUnits(TickUnits.createIntegerTickUnits());
legenda = grafico.getLegend();
legenda.setAnchor(Legend.EAST);
response.setContentType("image/png");
response.setHeader("Content-Disposition", "inline; filename=\"" + relatorio + periodicidade.substring(0,1) + ".png\"");
ChartUtilities.writeChartAsPNG(out, grafico, 448, 200);
out.flush();
response.flushBuffer();
out.close();
}
catch (Exception e) {
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
}
finally {
try
{
out.close();
} catch (IOException e)
{
System.err.println("Can't close");
}
}
} catch (SQLException e)
{
System.err.println("SQL Error: " + e.getMessage());
}
}
}
--------------------------------------------------------------------------------
BTW, it is called by another servlet which actually renderizes the HTML (or PDF) via
iText. The relevant code (the actual code is thousands of line) is here:
-------------------------------------------------------------------------
...
private Cell incluiCelula(String frase, FonteNrpt fonte, String comprimento, char alinhamento)
throws BadElementException
{
Cell celltmp;
celltmp =
new Cell(
new Phrase(
frase,
FontFactory.getFont(
fonte.getFonte(),
fonte.getTamanho(),
fonte.getAtributo(),
new Color(fonte.getCorR(), fonte.getCorG(), fonte.getCorB()))));
if (comprimento != null)
celltmp.setWidth(comprimento);
switch (alinhamento)
{
case 'L' :
case 'l' :
celltmp.setHorizontalAlignment(Element.ALIGN_LEFT);
break;
case 'M' :
case 'm' :
celltmp.setHorizontalAlignment(Element.ALIGN_CENTER);
break;
case 'R' :
case 'r' :
celltmp.setHorizontalAlignment(Element.ALIGN_RIGHT);
default :
break;
}
celltmp.setBorderWidth(0.0f);
return celltmp;
}
...
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException
{
...
com.lowagie.text.Image performanceImg1 =
com.lowagie.text.Image.getInstance(
new java.net.URL(
request.getScheme()
+ "://"
+ request.getServerName()
+ ":"
+ request.getServerPort()
+ request.getContextPath()
+ "/rpt/PerformanceComparativaImagem"
+ per[ii]
+ "?relatorio="
+ configuracaoBean.getCarteira().trim()
+ "&dataInicial="
+ sdfamdonly
.format(configuracaoBean.getDataInicial())
.trim()
+ "&tipoRelatorio="
+ "B"));
performanceImg1.setMarkupAttribute("border", "0");
Chunk performanceChunk1 = new Chunk(performanceImg1, 0.0f, 0.0f);
cell = new Cell(performanceChunk1);
cell.setWidth("60");
cell.setColspan(2);
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setBorderWidth(0.0f);
ytabela.addCell(cell);
...
----------------------------------------------------------------------------
Re: Dynamic PNG Servlet concurrency problem
Yes, it is a threading problem in your servlet. I would suggest you buy a book on servlets. In summary, all your member variables in your servlet are going to be shared between requests including your PreparedStatement and your ResultSets. Consequently any concurrent access is going to result in a disaster. You would be better off abstracting your data access to a JavaBean which can then be declared within your doGet(...) method to prevent concurrency issues.
Regards,
Richard...
Regards,
Richard...
Re: Dynamic PNG Servlet concurrency problem
Sorry for my lameness!! I am reading a very large book about servlets and I was aware of concurrency problems, but I really forgot about that. Actually a java bean modelled for data access wouldn't fit well within the code, so I just removed all the member variables declaration and made the servlet work via dynamic allocations of variables in the doGet() method.
That seemed to have solved the concurrency problem. iText however is still not accepting my chart. I'll have to work it out, but anyway the jfreechart part is solved now.
Thank you.
That seemed to have solved the concurrency problem. iText however is still not accepting my chart. I'll have to work it out, but anyway the jfreechart part is solved now.
Thank you.
Re: Dynamic PNG Servlet concurrency problem
I think I still have a problem with JFreeChart.
I reduced the problem to a single servlet which doesn't even access the database. Now there isn't any chance of being a multithreading problem - it is even called just one time. If i call it alone, it works ok. It also works if I call it with the 'wget' command. But if I call it through iText, it does not work. Normal pngs do work.
The actual code is the following:
------------------------------------------------------------------------
<imports ommitted>
public class Imagem extends HttpServlet {
static SimpleDateFormat dmy = new SimpleDateFormat("dd/MM/yyyy");
static SimpleDateFormat ymd = new SimpleDateFormat("yyyyMMdd");
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ServletOutputStream out = response.getOutputStream();
System.out.println("Executando PerformanceComparativaBrutaImagem...");
try
{
double [][] dados = new double [][] { {1.0} , {-2.0}, {3.0}, {-4.0}, {5.0}, {-6.0 } };
String [] series = new String [] { "Bananas", "Apples", "Oranges", "Pineapples", "Lasagnas", "Lemons" };
String [] categorias = new String[] { "" };
DefaultCategoryDataset ds = new DefaultCategoryDataset (dados);
ds.setSeriesNames(series);
ds.setCategories(categorias);
JFreeChart grafico = ChartFactory.createVerticalBarChart("teste","","",ds,true);
grafico.setBackgroundPaint(Color.white);
CategoryPlot plot = grafico.getCategoryPlot();
plot.setBackgroundPaint(Color.white);
plot.setVerticalLabels(true);
NumberAxis eixo = (NumberAxis)plot.getRangeAxis();
eixo.setStandardTickUnits(TickUnits.createIntegerTickUnits()); // Deixamos o eixo Y apenas com valores inteiros
Legend legenda = grafico.getLegend();
legenda.setAnchor(Legend.EAST);
response.setContentType("image/png");
response.setHeader("Content-Disposition", "inline; filename=\"" + "teste.png\"");
ChartUtilities.writeBufferedImageAsPNG(out, grafico.createBufferedImage(448,200));
out.close();
response.flushBuffer();
}
catch (Exception e) {
e.printStackTrace();
}
finally {
try
{
out.close();
} catch (IOException e)
{
System.err.println("Can't close!");
}
}
}
}
---------------------------------------------------------------------
when run, it yields these errors:
java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
at org.apache.catalina.connector.ResponseBase.flushBuffer(ResponseBase.java:674)
at org.apache.catalina.connector.HttpResponseBase.flushBuffer(HttpResponseBase.java:764)
at org.apache.catalina.connector.ResponseBase.write(ResponseBase.java:647)
at org.apache.catalina.connector.ResponseBase.write(ResponseBase.java:656)
at org.apache.catalina.connector.ResponseStream.write(ResponseStream.java:312)
at org.apache.catalina.connector.http.HttpResponseStream.write(HttpResponseStream.java:182)
at org.apache.catalina.connector.ResponseStream.write(ResponseStream.java:286)
at com.jrefinery.chart.ChartUtilities.writeBufferedImageAsPNG(Unknown Source)
at com.jrefinery.chart.ChartUtilities.writeBufferedImageAsPNG(Unknown Source)
at br.com.ymf.NetReport.Servlets.Imagem.doGet(Imagem.java:93)
at javax.servlet.http.HttpServlet.service(HttpServlet.java)
at javax.servlet.http.HttpServlet.service(HttpServlet.java)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
at br.com.ymf.NetReport.Filtros.FiltroAutenticadorCliente.doFilter(FiltroAutenticado
I reduced the problem to a single servlet which doesn't even access the database. Now there isn't any chance of being a multithreading problem - it is even called just one time. If i call it alone, it works ok. It also works if I call it with the 'wget' command. But if I call it through iText, it does not work. Normal pngs do work.
The actual code is the following:
------------------------------------------------------------------------
<imports ommitted>
public class Imagem extends HttpServlet {
static SimpleDateFormat dmy = new SimpleDateFormat("dd/MM/yyyy");
static SimpleDateFormat ymd = new SimpleDateFormat("yyyyMMdd");
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ServletOutputStream out = response.getOutputStream();
System.out.println("Executando PerformanceComparativaBrutaImagem...");
try
{
double [][] dados = new double [][] { {1.0} , {-2.0}, {3.0}, {-4.0}, {5.0}, {-6.0 } };
String [] series = new String [] { "Bananas", "Apples", "Oranges", "Pineapples", "Lasagnas", "Lemons" };
String [] categorias = new String[] { "" };
DefaultCategoryDataset ds = new DefaultCategoryDataset (dados);
ds.setSeriesNames(series);
ds.setCategories(categorias);
JFreeChart grafico = ChartFactory.createVerticalBarChart("teste","","",ds,true);
grafico.setBackgroundPaint(Color.white);
CategoryPlot plot = grafico.getCategoryPlot();
plot.setBackgroundPaint(Color.white);
plot.setVerticalLabels(true);
NumberAxis eixo = (NumberAxis)plot.getRangeAxis();
eixo.setStandardTickUnits(TickUnits.createIntegerTickUnits()); // Deixamos o eixo Y apenas com valores inteiros
Legend legenda = grafico.getLegend();
legenda.setAnchor(Legend.EAST);
response.setContentType("image/png");
response.setHeader("Content-Disposition", "inline; filename=\"" + "teste.png\"");
ChartUtilities.writeBufferedImageAsPNG(out, grafico.createBufferedImage(448,200));
out.close();
response.flushBuffer();
}
catch (Exception e) {
e.printStackTrace();
}
finally {
try
{
out.close();
} catch (IOException e)
{
System.err.println("Can't close!");
}
}
}
}
---------------------------------------------------------------------
when run, it yields these errors:
java.net.SocketException: Broken pipe
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
at org.apache.catalina.connector.ResponseBase.flushBuffer(ResponseBase.java:674)
at org.apache.catalina.connector.HttpResponseBase.flushBuffer(HttpResponseBase.java:764)
at org.apache.catalina.connector.ResponseBase.write(ResponseBase.java:647)
at org.apache.catalina.connector.ResponseBase.write(ResponseBase.java:656)
at org.apache.catalina.connector.ResponseStream.write(ResponseStream.java:312)
at org.apache.catalina.connector.http.HttpResponseStream.write(HttpResponseStream.java:182)
at org.apache.catalina.connector.ResponseStream.write(ResponseStream.java:286)
at com.jrefinery.chart.ChartUtilities.writeBufferedImageAsPNG(Unknown Source)
at com.jrefinery.chart.ChartUtilities.writeBufferedImageAsPNG(Unknown Source)
at br.com.ymf.NetReport.Servlets.Imagem.doGet(Imagem.java:93)
at javax.servlet.http.HttpServlet.service(HttpServlet.java)
at javax.servlet.http.HttpServlet.service(HttpServlet.java)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
at br.com.ymf.NetReport.Filtros.FiltroAutenticadorCliente.doFilter(FiltroAutenticado
Re: Dynamic PNG Servlet concurrency problem
Please ignore that. I fixed it. My mistake.
Re: Dynamic PNG Servlet concurrency problem
Try
+ out.flush();
out.close();
- response.flushBuffer();
Regards,
Richard...
+ out.flush();
out.close();
- response.flushBuffer();
Regards,
Richard...