• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

using two servlets to create a JFreeChart

 
Bartender
Posts: 1810
28
jQuery Netbeans IDE Eclipse IDE Firefox Browser MySQL Database Chrome Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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?
 
Sheriff
Posts: 67746
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
Posts: 1810
28
jQuery Netbeans IDE Eclipse IDE Firefox Browser MySQL Database Chrome Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
Posts: 1810
28
jQuery Netbeans IDE Eclipse IDE Firefox Browser MySQL Database Chrome Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
Sheriff
Posts: 67746
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
Posts: 1810
28
jQuery Netbeans IDE Eclipse IDE Firefox Browser MySQL Database Chrome Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
Sheriff
Posts: 67746
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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.
 
Saloon Keeper
Posts: 7582
176
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
Posts: 1810
28
jQuery Netbeans IDE Eclipse IDE Firefox Browser MySQL Database Chrome Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
Posts: 1810
28
jQuery Netbeans IDE Eclipse IDE Firefox Browser MySQL Database Chrome Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
Sheriff
Posts: 67746
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
Posts: 1810
28
jQuery Netbeans IDE Eclipse IDE Firefox Browser MySQL Database Chrome Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
Sheriff
Posts: 67746
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
Posts: 1810
28
jQuery Netbeans IDE Eclipse IDE Firefox Browser MySQL Database Chrome Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I've been over-thinking this. I don't need the ajax request at all.

 
J. Kevin Robbins
Bartender
Posts: 1810
28
jQuery Netbeans IDE Eclipse IDE Firefox Browser MySQL Database Chrome Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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.
 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic