Jeremias Maerki wrote:

On 06.09.2004 22:31:24 Glen Mazza wrote:


Jeremias Maerki wrote:



Ok, the FOEventHandler is created in the FOTreeBuilder. One FO
TreeBuilder is instantiated per processing run. The FOEventHandler is
set on FONode's static variable during startDocument(). The
FOEventHandler keeps track of used fonts, number of pages, tracking IDs
etc. which are all relevant to one document run.




Incidentally, I'd like to get the fonts out of FOEventHandler, I think they should be declared only within those subclasses of FOEventHandler that need them. But we can take up that issue later.



Here you need to be more precise. Are you talking about the set of available fonts or the set of used fonts within the document/processing run? The former is not a problem in this matter, but the other is as are the other examples I mentioned. They are specific to the rendering run.



Let's leave this for now.  My thoughts on it aren't complete anyway.

Now imagine a situation where multiple processing runs occur and just
after the TreeBuilder sets the FOEventHandler on FONode in
startDocument() and continues layout, another thread starts another
processing run and runs through FOTreeBuilder.startDocument() before the
whole layout process of the first processing run is finished.




But that would be another instance of the application, so that would be another instance's FOEventHandler that would be altered. Statics are common to a running instance, not all running instances of the same application in general. Please continue to elaborate.



A static variable is unique within the same classloader. If you deploy FOP as a servlet there is one classloader loading the FOP classes and FONode's static foEventHandler variable is shared between all instances of the Fop class and therefore between rendering runs. Now Tomcat can initiate multiple FOP rendering runs in multiple threads and that's where the trouble begins.



I see now. This would indeed be a problem--we will probably need to revert my change.

What is an application in your terminology? I don't think there is such
a thing in Java. At least it's not a technical term but only a logical
one. If you deploy fop.jar using the boot classloader in Tomcat and
deploy two "applications" (each using a separate classloader for each
WAR file). Both webapps are using FOP in a different way, you still have
only one static foEventHandler variable which is shared between two
applications. That's probably a non-realistic approach for FOP, but
Xerces and Xalan are usually deployed this way.


OK, from what you're saying then, Xerces and Xalan should have no (or next to no) static variables because they are so heavily shared (i.e., stored in Tomcat /common or /shared directories). Correct?

A figure showing Tomcat's classloader hierarchy:
http://jakarta.apache.org/tomcat/tomcat-4.1-doc/class-loader-howto.html

I think in your view of the things you'd have to provide a classloader
for each instance of Fop to they don't bump into each other, but that's
not what you will want.



I agree--that would not be desirable.



Also, are you aware of why I switched to a static? To end the continuous recursion to the fo:root each time any of the child nodes need to call getFOEventHandler().startThisFormattingObject() and/or getFOEventHandler().endSomeFormattingObject().



Yes, I realize that. That's why I proposed looking at ThreadLocal after thinking some more about the problem. On the other side have you done speed checks to figure out if the recursion is really a problem? Java can optimize pretty well by itself and often it's not worth breaking your head. Also something I learned on this list.




Let me take a look at your two links first (Tomcat classloader and ThreadLocal). We'll get this reverted (to something) soon.

Jeremias Maerki (off to bed...)




At only 6pm?  ;-)  Anyway, thanks for the education today.

Glen



Reply via email to