Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

using two servlets to create a JFreeChart

 
J. Kevin Robbins
Bartender
Pie
Posts: 1801
28
Chrome Eclipse IDE Firefox Browser jQuery Linux MySQL Database Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There has got to be a better way, but I'm having trouble stepping back and seeing the big picture.

I need to generate a graph using JFreeChart. The jsp page gets a couple of parameters and passes them to a servlet (we'll call it servlet A) which gets the records and stores them in the session. The JavaScript adds a link to the jsp that calls a second servlet (servlet B) which gets the data from the session and creates the chart. The chart is sent to the OutputStream, it does not create an image file. All this works on my local server setup. But when I move it to the test server, I get a broken image icon. It seems that servlet B is trying to fetch the data from the session before servlet A has finished generating it. My local machine is faster than our web server. Imagine that. Of course I realize that I should never rely on random timing to be successful; I need to control the flow of the app, not hope for the best or add sleep() code.

Okay, the JSP:

The JavaScript:

Servlet A:

And finally:

On the test server I get "records not found in session".
I have a feeling that I need to scrap all this and start over with a new design, but I'm not sure how. JFreeChart is a helluva package; the developers guide is almost 1,000 pages, so I've only scratched the surface. I've learned how to use this technique based on their demo code.

Any suggestions on how to make this reliable?
 
Bear Bibeault
Author and ninkuma
Marshal
Pie
Posts: 65338
97
IntelliJ IDE Java jQuery Mac Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Before diving into anything else, I strongly urge you to ditch creating charts on the server to send to the client as images. Investigate using a JS charting package such as HighCharts.

Not only does that mean that you only have to get the data to the UI, rather than all the handstands you are doing now, it also means that the charts are interactive without much (or any) work on your part.

Failing that, we can take a look at whatever's causing your race condition, but before doing that I, once again, strongly urge you to look at a client-side solution.

Creating charts and other UI on the server is so 2000.
 
J. Kevin Robbins
Bartender
Pie
Posts: 1801
28
Chrome Eclipse IDE Firefox Browser jQuery Linux MySQL Database Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I see your point. My problem is, HighCharts costs actual money which ain't gonna happen around here. I'm stuck with free solutions only. I'll look through the docs for JFreeChart and see if it has the capability to create an image file on the server.
 
J. Kevin Robbins
Bartender
Pie
Posts: 1801
28
Chrome Eclipse IDE Firefox Browser jQuery Linux MySQL Database Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ah, now I remember. There is this:
public static String saveChartAsPNG(JFreeChart chart, int width, int height,
ChartRenderingInfo info, HttpSession session) throws IOException;
Saves a chart to a PNG image file in the temporary directory and returns the fi le name used.
The fi le name is registered with a ChartDeleter instance that is linked to the specifi ed session - this
means the image fi le name will be deleted when the session expires. The info parameter should
be, if not null, a new instance of ChartRenderingInfo - it will be populated with information
about the chart as it is drawn for the PNG fi le (this information could be used to create an
HTML image map, for example). Note that the temporary fi le name prefi x can be set using
the setTempFilePrefix() method.


But when I first ventured into this package, I could never get the images to delete properly. It seems like there was also an issue with defining a "temp" directory that could be accessed by the client.

I'll take another look at this.
 
Bear Bibeault
Author and ninkuma
Marshal
Pie
Posts: 65338
97
IntelliJ IDE Java jQuery Mac Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There are many free charting packages as well (though they aren't as fully-featured or well-supported, of course). Flot charts, for example.

 
J. Kevin Robbins
Bartender
Pie
Posts: 1801
28
Chrome Eclipse IDE Firefox Browser jQuery Linux MySQL Database Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I've spent several days on this and got no where. I've given up on creating the chart as a local png file. There is just no way I can find to control the location of the file. And from what I've read on the jFreeChart forums, doing so is not the preferred way to serve the images as it breaks in a clustered environment. So I'm back to trying to use the OutputStream to send the graph.

But I'm still having a problem with this race condition. I've setup remote debugging on the test server, but it doesn't even hit the break point in the first servlet for some reason even though I can see the request in the Net panel. Again, it all works perfectly on the local server. It only fails when I move it to the test server.

So I'm looking at Deferreds in jQuery and trying to figure out if this will help me. I'm getting desperate. I've wasted way too much time on this page already.

First servlet:


Second servlet:


JS file:

The ajax function runs, but the first servlet hasn't yet set the parameters in the session when the second servlet (in the img link) tries to get data from the DAO, so no parameters are passed to the DAO. Can I use deferreds to control the flow of this JavaScript?

And....my day is almost done and I've just been informed that the A/C has failed in the data center. It looks like it's going to be a long night.
 
Bear Bibeault
Author and ninkuma
Marshal
Pie
Posts: 65338
97
IntelliJ IDE Java jQuery Mac Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I'm still unconvinced that a better approach isn't warranted, but let's deal with the race condition.

What I'd do is to make the first request using jQuery Ajax and wait until the returned promise is resolved (or use the success handler) to not make the 2nd request for the image until you're sure that the first request is done and has returned its response.

It looks as if you may have tried that approach at one point, but that code is commented out in your OP.
 
Tim Moores
Bartender
Posts: 3135
50
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you want to go the server-side route, I would suggest the cewolf library (on SourceForge). It has all the JSP tags one needs to create and manage images in a web app. I've used it before, and could give you some hints if you wanted to try it. The example web app has everything you need to get going.
 
J. Kevin Robbins
Bartender
Pie
Posts: 1801
28
Chrome Eclipse IDE Firefox Browser jQuery Linux MySQL Database Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
cewolf looks very interesting, but I can't see how I can pass parameters to it.

My app loads an initial page with some input fields, such as a date range. These parameters have to be passed to the server to create the chart. I don't see how I can do that with cewolf.
 
J. Kevin Robbins
Bartender
Pie
Posts: 1801
28
Chrome Eclipse IDE Firefox Browser jQuery Linux MySQL Database Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Bear Bibeault wrote:
What I'd do is to make the first request using jQuery Ajax and wait until the returned promise is resolved (or use the success handler) to not make the 2nd request for the image until you're sure that the first request is done and has returned its response.

I've tried "success", "complete", "ajaxComplete", and "done". Still have the same problem with each. That's why I started looking at deferred to see if that might offer a solution, but I've never used it so I'm not sure. Still reading.

The weird thing is, I've used this technique with other charts and it worked. Just luck?

I need to get my test server running. We had to shut it down yesterday because of the A/C issue. I'll take care of that issue and then get back to this.
 
Bear Bibeault
Author and ninkuma
Marshal
Pie
Posts: 65338
97
IntelliJ IDE Java jQuery Mac Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
J. Kevin Robbins wrote:. That's why I started looking at deferred to see if that might offer a solution, but I've never used it so I'm not sure. Still reading.

deferred will not do anything more for you than the other techniques I mentioned.

If marshaling the request so that they execute synchronously doesn't fix the problem, then there's more than a race condition between them going on.

I'm still somewhat mystified as to why this can't be done with a single request. Why does one request have to execute to put data into the session for the next request to fetch, versus respond with the image from the first request?
 
J. Kevin Robbins
Bartender
Pie
Posts: 1801
28
Chrome Eclipse IDE Firefox Browser jQuery Linux MySQL Database Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Bear Bibeault wrote:
I'm still somewhat mystified as to why this can't be done with a single request. Why does one request have to execute to put data into the session for the next request to fetch, versus respond with the image from the first request?

Lord knows I'm open to suggestions. I'm just working off the demo code from jFreeChart. This is only the second time I've used this library. The developers guide is 977 pages. I could make a career off this package if I ever figure out how to make it work properly.

It appears that the chart generator servlet (that writes to the OutputStream) has to be triggered from an img tag to control where the chart is created.

I think it's time to delete everything and start from scratch. Again.

[edit] This probably explains it better than I can. I know it's that "other" site. Sorry about that.
 
Bear Bibeault
Author and ninkuma
Marshal
Pie
Posts: 65338
97
IntelliJ IDE Java jQuery Mac Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
J. Kevin Robbins wrote:It appears that the chart generator servlet (that writes to the OutputStream) has to be triggered from an img tag to control where the chart is created.

Yes, if the chart is to appear on the page as an image. But what's the actual purpose of the first request? Why can't it also be accomplished in the image request?
 
J. Kevin Robbins
Bartender
Pie
Posts: 1801
28
Chrome Eclipse IDE Firefox Browser jQuery Linux MySQL Database Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I've been over-thinking this. I don't need the ajax request at all.

 
J. Kevin Robbins
Bartender
Pie
Posts: 1801
28
Chrome Eclipse IDE Firefox Browser jQuery Linux MySQL Database Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Which means that my first servlet doesn't do anything except setup the page for input. I should be able to do that in a single controller.

By George, I think I might be making progress here.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic