On 05.09.2005 17:05:48 Victor Mote wrote: > Jeremias Maerki wrote: > > > I got a little shock when I realized a problem I didn't think > > of when we discussed moving FOP components over to XML > > Graphics Commons. We said we would try to remove logging code > > from these basic components entirely. > > > > Now, I forgot to consider the decision to use FOrayFont made earlier. > > The external dependency on FOrayFont also would be a problem > > in itself because the Batik side has strong feelings against > > external dependencies. > > We need to think about what to do about this WRT the PDF and > > PS transcoders. Optimized text painting in these two > > transcoders depends a lot on the font subsystem. > > Well, the little change I just made removes entirely any dependency on > Avalon in any FOray code, except for the fact that Ant seems to need it for > logging (needed for creating hyphenation patterns and such). There is no > longer any Avalon code in FOrayFont. In fact, that was the primary > motivation for making the change. The Avalon Logger interface would have > been quite a sufficient solution for anything that FOray needs, and, since > it is an interface, adapters could be written from it to anything else, just > as Vincent and I have been discussing for the PseudoLogger interface.
Yeah, yet another generic logger abstraction interface. Sigh. > > Aside from that, a thought about the aXSL APIs: Being an > > ex-Avaloner SoC (separation of concerns) is a big concern to > > me. The functional API of a package should IMO actually not > > deal with (or rather expose) logging at all. It's a separate > > concern. I'm ever growing more cofident that > > developer-oriented logging should be done through a static > > logging facility (like Commons Logging) and that > > end-user-oriented logging needs to operate per processing run > > (like Avalon Logger) but not necessarily through a standard > > logging abstraction interface, but rather an > > application-specific one that provides exactly what the > > application needs to send feedback to the end-users. In that > > light, a PDF or font library shouldn't expose any logging > > facilities at all or at least to static logging that is > > externally configured. > > First, do you understand that the FOrayFont library does not "expose any > logging facilities" to the client, but instead asks the client to expose the > logging facilities to it? Yes. Sorry for the not quite accurate wording plus a typo. Let's try again: [a work interface] shouldn't expose any logging specifica (as they are a separate concern, see Avalon's LogEnabled interface or newer dependency injection systems). If developer-oriented logging is absolutely necessary I prefer static logging (like Commons Logging or Log4J) today. > A PseudoLogger is required (but can be passed > null) in the FontServer constructor That's an implementation detail and not a problem. It has nothing to do with the API. FontServer is an interface in the API and you are talking about the implementation of FontServer here, I assume. > and is required in a method in > FontConsumer. But FontConsumer is implemented on the client side, in which > the client application tells FOray about itself. This method getPseudoLogger() is what caught my purist's eye in the first place. It breaks IoC. > Second, why should FOray limit its clients to only use static logging? If > the client has to expose a static logging mechanism to FOray in order to get > static logging to work, what can possibly be wrong with exposing a > non-static logging mechanism to FOray? Right now, FOray doesn't care whether > static or non-static logging is used. Why should it? Exactly. Why should it? If you remove all logging concerns from the work interface you don't do any assumptions about how logging is done. The presence of getPseudoLogger(), though, produces a strong emphasis on non-static logging. > Third, lets define the "concern". <important>My understanding of Separation > of Concerns in this case is that FOrayFont owns the concern that a message > needs to be logged, and that the client application owns the concern of how > that logging should be accomplished.</important> > > In order to maintain that Separation of Concerns, one of two things must > happen: > 1. The client must tell the component how stuff should be logged. > 2. The server must tell the client what should be logged. > > This means some logging-related stuff will appear in the interface between > the two. Not IMO. It can be an implementation detail. See more below. > The design considerations are as follows: > 1. FOrayFont needs to be able to log messages. For whom? For the developer or for the end-user? Because that's what I've learned during the past months: That it should be well divided between the two audiences. The speciality is that the developer doesn't need a logger per processing run (i.e. non-static logging) and the end-user often needs more than just pure Strings through a generic logging interface. Note that this is not yet reality in FOP but I believe it will be soon. > 2. FOrayFont needs to be able to work with any client system, regardless of > their preferences on logging. Nobody challenges that. Due to input from Batik the question is raised whether such a library should do any logging at all. Don't get me wrong. I'm all for developer-oriented logging, even in basic libraries. It's just that I somehow need to find out how to accomodate everyone, like you intend, too. The complication here is that I needed to bring a new consideration into play. And we really need to pay attention what we are talking about: the aXSL API or the FOray implementation. If you read my message again I specifically talk about aXSL, not FOray. > I can keep all logging internal to the FOrayFont subsystem, which would mean > that the client application (FOP) has no control over the logging > whatsoever. Very bad. FOray has to guess what kind of logger to use, and it > will never be right. It's not true that it doesn't have control. It's just that (static) logging is controlled from elsewhere. > I can expose a logging interface that allows the client application to > handle logging its own way. This has been the approach used so far. > > The only other solution is a bit more complex, and IMO, quickly becomes > ugly. FOrayFont currently asks some client object to implement the > FontConsumer interface. Instead of having FontConsumer provide a > PseudoLogger, it could have a method instead that logs messages: > > /** > * @param level An integer describing the level at which this message > should be logged, > * that is, error, warning, debug, etc. > */ > public void logMessage(String message, int level) ; That would be worse, IMO. > The problem here is that I need to then create another interface that has > something similar that can pass itself to FontServer so that general (not > document-specific) logging messages can be handled. I also need to create > one for Graphics, Text, FOTree, etc. I will have 10 or 12 methods in various > interfaces that all do the same thing. This seems silly to me. This begs for > a type to do this, which the Avalon Logger interface provided and which > PseudoLogger provides as well. > > Further, does a logMessage() method still expose logging functionality in a > way that is objectionable to you and to Batik? Yes. IMO the API should not expose any aspect of logging, only pure work functionality. An implementation of the API, on the other side, will then expose any technical means (methods, config files...) to configure/control logging. Do you find logging aspects in APIs like DOM, JAXP, JDBC, EJB etc.? No, I don't think so. But any DOM implementation, or JDBC driver or Enterprise Java Bean is allowed to do logging of some sort and there are ways/approaches to configure it. Or take my JAXG. It doesn't care about how and if (developer-oriented) logging is done. Only the implementations define ways to control that if they support it. That is the key point! > > Now, I know this has the potential to spark a heated debate > > again and it raises question marks about the FOrayFont > > integration, but ATM I really don't know what to do about it > > right now. I just realized we have a problem here. I/we made > > promises on firstname.lastname@example.org to try to remove > > logging and other external dependencies (like Avalon) for the > > common components because that's something which is very > > important to the Batik side. > > So, then, how are those components supposed to log anything? Or, if they are > to log using their own static stuff, how can this be configured by the > client? Eventually such basic libraries shouldn't log anything anymore. That's the big dilemma I'm sitting in, the one I need to find a way out of. Anyway, ways to remove the necessity to log are: unit tests and stabilization. The problem is getting rid of something so extremely handy but actually completely unnecessary for something basic like a PDF or font library. But I'd never want to get rid of the ability to log in a complex system like a layout engine. > > Maybe we could have two different implementations of the > > PDFTextElementBridge so Batik can do native text rendering in > > a different way than FOP but there's still the PDF library > > that depends largely on the font subsystem. But maybe this > > could be handled in a similar way. I need to investigate that > > a little more. > > I'll be glad to help any way I can, and at this stage FOray can be flexible. > But I must admit that I don't follow the logic. I need for someone to do one > of the following: > 1. explain which of the two design considerations listed above you would > have your components abandon From my POV as a developer in general: none of them. From my POV as the one who pushes for XML Graphics Commons: both. See my problem? > 2. suggest a solution that allows *both* design considerations to be > retained, but does not have the client either doing the logging or telling > the component how to do the logging. Let logging be entirely an implementation detail, not a part of the functional API. > I still find myself learning new tricks, Me too! Me tooooo! > so perhaps there is some other > elegant alternative that I am simply too blind to yet see. We don't need a solution right now. I would just like you to think about removing logging as an aspect of the aXSL APIs. That would make things easier. But it's also just an aspect of my general view of API design. It actually doesn't have so much to do with Batik and XML Graphics Commons. I just needed to raise the overall concern about external dependencies because of what Thomas said in our discussion about XML Graphics Commons and because of the stuff we voted on. We don't have to find a solution today. I don't even have time for that right now. I can't continue with moving the main components to Commons right now anyway because I need to wait for what Vincent is doing. Furthermore, I want to get that first preview release out of the door and that can't happen with XML Graphics Commons. It's too late for that. > The deeper question here is whether it is really wise to avoid all external > dependencies. FOray is invested heavily in the idea that reusability is A > Good Thing. My sense is that FOP still struggles with this question. I usually don't use external dependencies without considering all the consequences. I'm all for reuse. The problem is that we found out that Batik and FOP have an extremely differing views on these things and we decided to start sharing (PDF lib etc.) and transferring (Transcoders) components inside the XML Graphics project. This has some consequences. As I said, I just wanted everyone to know that there are issues that will need to be dealt with someday but we don't have to do it right now. If there's an obvious solution, good, but I don't see it right now. Jeremias Maerki