You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@xalan.apache.org by Sc...@lotus.com on 2001/07/09 12:38:21 UTC

Re: Transparent caching with JAXP/TrAX

Morten Jorgensen <mo...@sun.com> wrote:
> and
> we don't want to compile such classes more often than we have
> to, and this is the reason why we want cache translets.

My position is that the XSLT processor should not be doing caching.  I have
said this many times and I will continue to say it.

> Please let me first make a
> distinction between caching javax.xml.transform.Transformer
> objects and caching Translet classes.

What I don't hear you talking about is the javax.xml.transform.Templates
class.  I can't find where this object is implemented in the XSLTC source,
which surprises me.

In my mind:

The Templates implementation object is a very thin wrapper around a
Translet *class*.  It probably just contains the Class object.
The Transformer is an instance of a Translet class (which it is now, so
this much is done).

Here's how it should work in my opinion:

org.apache.xalan.xsltc.compiler.XSLTC should implement javax.xml.transform.
TransformerFactory.
org.apache.xalan.xsltc.compiler.XSLTC#newTemplates(Source source) should
compile the source object into a Translets, and create a small wrapper
class, org.apache.xalan.xslt.TemplatesImpl that contains the Class object,
or perhaps just the class name (or, perhaps you get fancier than that and
it holds the actual bytecodes... dunno).

Everytime the caller calls TransformerFactory#newTemplates(Source source),
org.apache.xalan.xsltc.compiler.XSLTC#newTemplates(Source source) will
compile a new Translet, period.  Caching that object is the responsibility
of the caller, which can use whatever mechanisms are suitible.

org.apache.xalan.xslt.TemplatesImpl#newTransformer() should simply call
Class#newInstance() on the the contained Translet class object.

This seems really simple to me.  Applications that are already caching
Templates objects then start caching XSLTC translets automatically, with
the same mechanism.

> Our main concern is where to store the translets (a simple Java
> property file pointing to a directory may do)

Does the class have to be put on disk?  (A question... I simply don't
know).  If it does, I guess I would use a system property to indicate the
storage directory.

> and how to
> make sure that a translet in the cache is still valid

This is one of the reasons you really shouldn't muck with caching.
Whatever you do will cause somebody problems.  Put this responsibility at
the application level where it belongs.

-scott




                                                                                                                      
                    Morten Jorgensen                                                                                  
                    <morten.jorgense        To:     xalan dev <xa...@xml.apache.org>                              
                    n@sun.com>              cc:     (bcc: Scott Boag/CAM/Lotus)                                       
                    Sent by:                Subject:     Transparent caching with JAXP/TrAX                           
                    Morten.Jorgensen                                                                                  
                    @sun.com                                                                                          
                                                                                                                      
                                                                                                                      
                    07/09/01 12:24                                                                                    
                    PM                                                                                                
                    Please respond                                                                                    
                    to xalan-dev                                                                                      
                                                                                                                      
                                                                                                                      




Tom/Dick/Harry/anybody,

We are trying to come up with a decent design for transparent
translet caching with JAXP/TrAX. Please let me first make a
distinction between caching javax.xml.transform.Transformer
objects and caching Translet classes. A Transformer object can
be instanciated (using a factory class) and then kept in
memory (ie. cached) for a sequence of similar transformations.

A translet is a Java class and not an instance of a class, and
we don't want to compile such classes more often than we have
to, and this is the reason why we want cache translets. The
best way of doing this using JAXP is to make the XSL->translet
compilation transparent, similar to the way JSPs are compiled
into servlets. This could be done by having the Transformer
object check for the existance (and validity) of an already
compiled translet, and then either use the existing translet
or create a new one if needed, and then run the transformation
using this translet:

                 +-------------+    +----------+
                 |    XSLTC    | -> | Translet |
                 |  compiler   |    |  storage |
                 +-------------+    +----------+
                        ^                 |
                        |                 v
       xsl/xml   +-------------+    +----------+
JAXP ----------> |  JAXP/TrAX  | -> |  XSLTC   |
user <---------- | Transformer | <- | Translet |
         *ml     +-------------+    +-----------

Our main concern is where to store the translets (a simple Java
property file pointing to a directory may do) and how to
make sure that a translet in the cache is still valid (the
Source interface does not give much info on the XSL source).

Any suggestions are welcome!

Thanks
Morten





Re: Transparent caching with JAXP/TrAX

Posted by Padraig O'hIceadha <pa...@gradient.ie>.
Hi Scott,

Scott_Boag@lotus.com wrote:

>Morten Jorgensen <mo...@sun.com> wrote:
>
>>and
>>we don't want to compile such classes more often than we have
>>to, and this is the reason why we want cache translets.
>>
>
>My position is that the XSLT processor should not be doing caching.  I have
>said this many times and I will continue to say it.
>
>>Please let me first make a
>>distinction between caching javax.xml.transform.Transformer
>>objects and caching Translet classes.
>>
>
>What I don't hear you talking about is the javax.xml.transform.Templates
>class.  I can't find where this object is implemented in the XSLTC source,
>which surprises me.
>
    This is documented here : 
http://xml.apache.org/xalan-j/xsltc/xsltc_trax.html#templatescreation as 
sems to fit your model.

>
>
>In my mind:
>
>The Templates implementation object is a very thin wrapper around a
>Translet *class*.  It probably just contains the Class object.
>The Transformer is an instance of a Translet class (which it is now, so
>this much is done).
>
>Here's how it should work in my opinion:
>
>org.apache.xalan.xsltc.compiler.XSLTC should implement javax.xml.transform.
>TransformerFactory.
>org.apache.xalan.xsltc.compiler.XSLTC#newTemplates(Source source) should
>compile the source object into a Translets, and create a small wrapper
>class, org.apache.xalan.xslt.TemplatesImpl that contains the Class object,
>or perhaps just the class name (or, perhaps you get fancier than that and
>it holds the actual bytecodes... dunno).
>
>Everytime the caller calls TransformerFactory#newTemplates(Source source),
>org.apache.xalan.xsltc.compiler.XSLTC#newTemplates(Source source) will
>compile a new Translet, period.  Caching that object is the responsibility
>of the caller, which can use whatever mechanisms are suitible.
>
    The current implementation from the docs above is

public class TransformerFactoryImpl extends SAXTransformerFactory {
...
  public Templates newTemplates(Source stylesheet) throws
    TransformerConfigurationException
  {
    Transformer translet = newTransformer(stylesheet);
    return new TransletTemplates(translet);
  }
}


If XSLTC added support for a newTemplatesHandler() method which uses a 
TemplatesHandlerFactory and added a corresponding method to set a 
TemplatesHandlerFactory then an app could call newTemplatesHandler to 
get the default handler, then set a factory of their own (which also 
stores the default handler) which tries to determine by a means useful 
for that app if the stylesheet has changed and if not use 
Class.forName/newInstance etc to retrieve a cached Translet and then 
returns 'new TransletTemplates(translet);'. If the stylesheet has 
changed it could chain to it's stored templatesHandler.

    This means that an app could implement it's own caching mechanism 
for Templates/translets.

    Does this make sense ?

        Regards,

            Padraig

>
>
>org.apache.xalan.xslt.TemplatesImpl#newTransformer() should simply call
>Class#newInstance() on the the contained Translet class object.
>
>This seems really simple to me.  Applications that are already caching
>Templates objects then start caching XSLTC translets automatically, with
>the same mechanism.
>
>>Our main concern is where to store the translets (a simple Java
>>property file pointing to a directory may do)
>>
>
>Does the class have to be put on disk?  (A question... I simply don't
>know).  If it does, I guess I would use a system property to indicate the
>storage directory.
>
>>and how to
>>make sure that a translet in the cache is still valid
>>
>
>This is one of the reasons you really shouldn't muck with caching.
>Whatever you do will cause somebody problems.  Put this responsibility at
>the application level where it belongs.
>
>-scott
>
>
>
>
>                                                                                                                      
>                    Morten Jorgensen                                                                                  
>                    <morten.jorgense        To:     xalan dev <xa...@xml.apache.org>                              
>                    n@sun.com>              cc:     (bcc: Scott Boag/CAM/Lotus)                                       
>                    Sent by:                Subject:     Transparent caching with JAXP/TrAX                           
>                    Morten.Jorgensen                                                                                  
>                    @sun.com                                                                                          
>                                                                                                                      
>                                                                                                                      
>                    07/09/01 12:24                                                                                    
>                    PM                                                                                                
>                    Please respond                                                                                    
>                    to xalan-dev                                                                                      
>                                                                                                                      
>                                                                                                                      
>
>
>
>
>Tom/Dick/Harry/anybody,
>
>We are trying to come up with a decent design for transparent
>translet caching with JAXP/TrAX. Please let me first make a
>distinction between caching javax.xml.transform.Transformer
>objects and caching Translet classes. A Transformer object can
>be instanciated (using a factory class) and then kept in
>memory (ie. cached) for a sequence of similar transformations.
>
>A translet is a Java class and not an instance of a class, and
>we don't want to compile such classes more often than we have
>to, and this is the reason why we want cache translets. The
>best way of doing this using JAXP is to make the XSL->translet
>compilation transparent, similar to the way JSPs are compiled
>into servlets. This could be done by having the Transformer
>object check for the existance (and validity) of an already
>compiled translet, and then either use the existing translet
>or create a new one if needed, and then run the transformation
>using this translet:
>
>                 +-------------+    +----------+
>                 |    XSLTC    | -> | Translet |
>                 |  compiler   |    |  storage |
>                 +-------------+    +----------+
>                        ^                 |
>                        |                 v
>       xsl/xml   +-------------+    +----------+
>JAXP ----------> |  JAXP/TrAX  | -> |  XSLTC   |
>user <---------- | Transformer | <- | Translet |
>         *ml     +-------------+    +-----------
>
>Our main concern is where to store the translets (a simple Java
>property file pointing to a directory may do) and how to
>make sure that a translet in the cache is still valid (the
>Source interface does not give much info on the XSL source).
>
>Any suggestions are welcome!
>
>Thanks
>Morten
>
>
>
>
>
>




Re: Transparent caching with JAXP/TrAX

Posted by Morten Jorgensen <mo...@sun.com>.
Gary L Peskin wrote:
> I may be missing something here and I'm sure Scott will jump in but here
> is my understanding of things.  I don't really think that TRaX has "...
> loads of crap ... that most users will never bother even looking at" but
> I could be wrong there too.

"Crap" is a badly chosen word. Apologies for that. But, as we started our
initial TrAX implementation we found ourselves adding loads of methods and
code that most users probably will not find necessary. This is why I think
we should separate the TrAX code and the core XSLTC stuff.

>   Templates <==> Translet class
>   Transfomer <==> Translet object/instance
>
>   ........
>
>   TransformerFactory.newTransformer(Source)
> -and-
>   TransformerFactory.newTemplates(Source) -followed by-
>   Templates.newTransformer()

Grand. But I still don't think that every call to newTemplates() should
necessarily require re-compilation - we should at least offer the option
of caching between sessions. Caching templates in memory (ie. leaving
class definitions in memory) will speed up transformations as long as the
templates (class definitions) can be kept in memory over long time.

Why does TransformerFactory.newTemplates() have to compile the input
stylesheet if there is already a stored class definition for the translet?
The idea behind TrAX is having a common API for XSL transformations. This
API will not be broken if we transparently cache translet class files in
the Templates implementation. If we decide to use a simple property to
point to a translet pool, we can take any value of this property as a
clear indication that the user knows that his XSLT processor is XSLTC and
that he/she wants to use translet caching.

Morten

Re: Transparent caching with JAXP/TrAX

Posted by Padraig O'hIceadha <pa...@gradient.ie>.
Hi,

    I made the changes described below to move the compilation from 
TransletTemplates#newTransformer() into 
TransformerFactoryInpl#newTemplates() and I find that where the 
Templates object is created once and Transformers created from the 
Templates as required it was about twice as fast.

    I'm attaching the files. If you think it is a useful change I'll 
make patch files.

        Regards,

            Padraig

Padraig O'hIceadha wrote:

> Hi Gary, Morten,
>
>     We were looking at caching a Templates object for reuse with XSLTC 
> but were a little confused in that it is the newTransformer that does 
> the compilation. The class compiled (the translet) seems to be a 
> Transformer. So caching the Template object is not much use.
>
>     One critical aspect of Templates is that they are thread safe. I 
> presume Translets are not ?
>
>     Is it safe as a workaround to :
>
>    1. after calling newTransformer for the first time cast the result
>       back to AbstractTranslet and cache the result of
>       getTransletName() and the result of
>       calling Class.forName(transletName);
>    2. then while the cache is not dirty instead of calling
>       newTransformer again do
>          1. Class transletClass = <read Class from cache (or do the
>             Class.forName again)>
>          2. translet = (Translet)transletClass.newInstance();
>          3. ((AbstractTranslet)translet).setTransletName(<read name
>             from cache>);
>
>     Is it likely that Xsltc will change so that the Translet class is 
> not a Transformer ?
>
>     Or is it likely that the compilation will move soon to 
> newTemplates with the TransletTemplates class retaining the Class 
> object and the class name and TransletTemplates#newTransformer change 
> to doing a newInstance on the stored Class and then setting the 
> translet name ? All the code exists for this, it would just need to be 
> re-organised a little.
>
>     Two new instance variables (transletName, transletClass) could be 
> added to store the Classs and its name. The first half of 
> TransletTemplates#newTransformer() could  move to the constructor with 
> the only change being that transletName would no longer be local it 
> would be one of the instance variables.
>
>     The second half of that method would stay where it is with the 
> changes that it also would use this.tansletName and this.transletClass 
> rather than doing a classForName.
>
>     TransformerFactoryInpl#newTransformer(Source source) would then be 
> something like
>
>     Templates tmpl=newTemplates( source );
>     if( tmpl==null ) return null;
>     return tmpl.newTransformer();
>
>     Does this make sense ?
>
>         Regards,
>
>             Padraig
>
> Gary L Peskin wrote:
>
>>Morten --
>>
>>I may be missing something here and I'm sure Scott will jump in but here
>>is my understanding of things.  I don't really think that TRaX has "...
>>loads of crap ... that most users will never bother even looking at" but
>>I could be wrong there too.
>>
>>Basically, 
>>
>>  Templates <==> Translet class
>>  Transfomer <==> Translet object/instance
>>
>>You say that "the current code wraps the translet (or actually the
>>translet base class) inside a transformer object."  In TRaX terms, this
>>should really be in a Templates object.  Once inside the Templates
>>object, the user can cache this to his or her content.  Switching to a
>>TRAX-conformant XSLTC will allow the user to use the caching strategy
>>already in place.
>>
>>Now, when a transform is desired, the user creates a Transformer from
>>the Templates object by calling Templates.newTransformer().  This is
>>just creating a newInstance() of the Translet embodied in the Templates
>>object.  This should be a lightweight operation, not requiring a
>>recompilation like the current Transformer generation but just a new
>>instance of the translet.
>>
>>I think that part of the confusion stems from the fact that there are
>>two ways to get a transformer in TRaX:
>>
>>  TransformerFactory.newTransformer(Source)
>>-and-
>>  TransformerFactory.newTemplates(Source) -followed by-
>>  Templates.newTransformer()
>>
>>The first method is good for one-shot prototypes or other applications
>>where there is no need to maintain the translet -class- for multiple
>>invocations.  The second method is used for industrial strength
>>applications where we compile once and then execute instances lots of
>>times.
>>
>>It sounds like you're currently doing your compiling in
>>Templates.newTransformer() but that is not where it should be
>>happening.  It should be happening in
>>TransformerFactor.newTemplates(Source).
>>
>>If you already realized this, then I've completely misunderstood
>>everyone's point and I'll just go away.  Otherwise, please come back
>>with any questions.
>>
>>Thanks,
>>Gary
>>
>>Morten Jorgensen wrote:
>>
>>>Scott_Boag@lotus.com <ma...@lotus.com> wrote:
>>>
>>>>Morten Jorgensen <mo...@sun.com> <ma...@sun.com> wrote:
>>>>
>>>>>and we don't want to compile such classes more often
>>>>>than we have to, and this is the reason why we want
>>>>>cache translets.
>>>>>
>>>>My position is that the XSLT processor should not be doing caching.
>>>>I have said this many times and I will continue to say it.
>>>>
>>>Why would anyone bother to use compiled stylesheets if they have to
>>>be compiled for every transformation (or sequence of transformations)?
>>>There is not reason at all to use XSLTC if translets are not pre-
>>>compiled and stored. XSLTC spends ca. 4 times as long to compile a
>>>translet as any other XSLT processor uses on a transformation. If our
>>>JAXP implementation forces a compilation for each time a translet is
>>>loaded we would make XSLTC the slowest XSLT processor on the market.
>>>If XSLTC is made the slowest JAXP compliant processor there is, then
>>>I don't think many people will bother use it - except for those that
>>>are still using its native APIs - and there would be no reason to
>>>add JAXP support at all.
>>>
>>>>Here's how it should work in my opinion:
>>>>
>>>>org.apache.xalan.xsltc.compiler.XSLTC should implement javax.xml.transform.
>>>>TransformerFactory.
>>>>org.apache.xalan.xsltc.compiler.XSLTC#newTemplates(Source source) should
>>>>compile the source object into a Translets, and create a small wrapper
>>>>class, org.apache.xalan.xslt.TemplatesImpl that contains the Class object,
>>>>or perhaps just the class name (or, perhaps you get fancier than that and
>>>>it holds the actual bytecodes... dunno).
>>>>
>>>There are still loads of people that prefer to use the native APIs of XSLTC.
>>>Many of these users stick to XSLTC because of its small footprint, and not
>>>so much for performance reasons. I would like to separate the JAXP/TrAX
>>>wrappers from the existing XSLTC source tree (leaving the existing code
>>>untouched - for now) and putting all TrAX wrappers in a separate directory:
>>>
>>> a) org.apache.xalan.xsltc.runtime - existing code
>>> b) org.apache.xalan.xsltc.dom     - internal DOM
>>> c) org.apache.xalan.xsltc.trax    - TrAX wrappers/etc.
>>>
>>>There is loads of crap in TrAX that most users will never bother even looking
>>>at. I don't want to force this stuff upon those users that are more than
>>>happy to use just a) and b) above (this is the case for those that are using
>>>XSLTC in applets). I know that the current code wraps the translet (or actually
>>>the translet base class) inside a transformer object. Nowmatter how fancy this
>>>looks on a design diagram it is not desireably/practical for many users.
>>>
>>>>Everytime the caller calls TransformerFactory#newTemplates(Source source),
>>>>org.apache.xalan.xsltc.compiler.XSLTC#newTemplates(Source source) will
>>>>compile a new Translet, period.  Caching that object is the responsibility
>>>>of the caller, which can use whatever mechanisms are suitible.
>>>>
>>>>org.apache.xalan.xslt.TemplatesImpl#newTransformer() should simply call
>>>>Class#newInstance() on the the contained Translet class object.
>>>>
>>>>This seems really simple to me.  Applications that are already caching
>>>>Templates objects then start caching XSLTC translets automatically, with
>>>>the same mechanism.
>>>>
>>>Sure, users can cache Template instances as much as they want to nomatter
>>>what is wrapped in inside the Template. But, this means that the stylesheet
>>>is compiled every time the user wants to instanciate a translet _object_.
>>>This, again, undermines the whole idea of compiling stylesheets.
>>>
>>>Most of the software I use is open-source and is distributed as source code.
>>>I compile this software once, store it as binaries and load it into memory
>>>when I need it. I do not compile it every time I run it and then keep it
>>>memory for as long as I can. This is mainly for two reasons:
>>>
>>> a) I don't want to wait for it to compile every time I load it
>>> b) I do not have enough memory on my PC to keep it in memory at all times
>>>
>>>This holds for translets too. A web server that uses XSLTC would proably
>>>not be able to keep Template/Transformer objects for all stylesheets in
>>>memory at all times. Neither would it be preferrable to compile stylesheets
>>>every time a new Transformer/Template object is instanciated.
>>>
>>>>>Our main concern is where to store the translets (a simple Java
>>>>>property file pointing to a directory may do)
>>>>>
>>>>Does the class have to be put on disk?  (A question... I simply don't
>>>>know).  If it does, I guess I would use a system property to indicate the
>>>>storage directory.
>>>>
>>>Yes, we absolutely, definately need to be able to store translet
>>>_classes_ somewhere. A simple property could be used. If the property we
>>>use is set, then translets can be cached in the directory (or whatever)
>>>the property points to, otherwise caching is turned off.
>>>
>>>>>and how to make sure that a translet in the cache is still valid
>>>>>
>>>>This is one of the reasons you really shouldn't muck with caching.
>>>>Whatever you do will cause somebody problems.  Put this responsibility at
>>>>the application level where it belongs.
>>>>
>>>Template/Transformer caching definately belongs at the application level.
>>>How these objects are created is our responsibility. And we want to create
>>>them as efficiently as we can.
>>>
>>>Morten
>>>
>>
>>
>
>



Re: Transparent caching with JAXP/TrAX

Posted by Gary L Peskin <ga...@firstech.com>.
Morten --

I may be missing something here and I'm sure Scott will jump in but here
is my understanding of things.  I don't really think that TRaX has "...
loads of crap ... that most users will never bother even looking at" but
I could be wrong there too.

Basically, 

  Templates <==> Translet class
  Transfomer <==> Translet object/instance

You say that "the current code wraps the translet (or actually the
translet base class) inside a transformer object."  In TRaX terms, this
should really be in a Templates object.  Once inside the Templates
object, the user can cache this to his or her content.  Switching to a
TRAX-conformant XSLTC will allow the user to use the caching strategy
already in place.

Now, when a transform is desired, the user creates a Transformer from
the Templates object by calling Templates.newTransformer().  This is
just creating a newInstance() of the Translet embodied in the Templates
object.  This should be a lightweight operation, not requiring a
recompilation like the current Transformer generation but just a new
instance of the translet.

I think that part of the confusion stems from the fact that there are
two ways to get a transformer in TRaX:

  TransformerFactory.newTransformer(Source)
-and-
  TransformerFactory.newTemplates(Source) -followed by-
  Templates.newTransformer()

The first method is good for one-shot prototypes or other applications
where there is no need to maintain the translet -class- for multiple
invocations.  The second method is used for industrial strength
applications where we compile once and then execute instances lots of
times.

It sounds like you're currently doing your compiling in
Templates.newTransformer() but that is not where it should be
happening.  It should be happening in
TransformerFactor.newTemplates(Source).

If you already realized this, then I've completely misunderstood
everyone's point and I'll just go away.  Otherwise, please come back
with any questions.

Thanks,
Gary

Morten Jorgensen wrote:
> 
> Scott_Boag@lotus.com wrote:
> >
> > Morten Jorgensen <mo...@sun.com> wrote:
> > > and we don't want to compile such classes more often
> > > than we have to, and this is the reason why we want
> > > cache translets.
> >
> > My position is that the XSLT processor should not be doing caching.
> > I have said this many times and I will continue to say it.
> 
> Why would anyone bother to use compiled stylesheets if they have to
> be compiled for every transformation (or sequence of transformations)?
> There is not reason at all to use XSLTC if translets are not pre-
> compiled and stored. XSLTC spends ca. 4 times as long to compile a
> translet as any other XSLT processor uses on a transformation. If our
> JAXP implementation forces a compilation for each time a translet is
> loaded we would make XSLTC the slowest XSLT processor on the market.
> If XSLTC is made the slowest JAXP compliant processor there is, then
> I don't think many people will bother use it - except for those that
> are still using its native APIs - and there would be no reason to
> add JAXP support at all.
> 
> > Here's how it should work in my opinion:
> >
> > org.apache.xalan.xsltc.compiler.XSLTC should implement javax.xml.transform.
> > TransformerFactory.
> > org.apache.xalan.xsltc.compiler.XSLTC#newTemplates(Source source) should
> > compile the source object into a Translets, and create a small wrapper
> > class, org.apache.xalan.xslt.TemplatesImpl that contains the Class object,
> > or perhaps just the class name (or, perhaps you get fancier than that and
> > it holds the actual bytecodes... dunno).
> 
> There are still loads of people that prefer to use the native APIs of XSLTC.
> Many of these users stick to XSLTC because of its small footprint, and not
> so much for performance reasons. I would like to separate the JAXP/TrAX
> wrappers from the existing XSLTC source tree (leaving the existing code
> untouched - for now) and putting all TrAX wrappers in a separate directory:
> 
>  a) org.apache.xalan.xsltc.runtime - existing code
>  b) org.apache.xalan.xsltc.dom     - internal DOM
>  c) org.apache.xalan.xsltc.trax    - TrAX wrappers/etc.
> 
> There is loads of crap in TrAX that most users will never bother even looking
> at. I don't want to force this stuff upon those users that are more than
> happy to use just a) and b) above (this is the case for those that are using
> XSLTC in applets). I know that the current code wraps the translet (or actually
> the translet base class) inside a transformer object. Nowmatter how fancy this
> looks on a design diagram it is not desireably/practical for many users.
> 
> > Everytime the caller calls TransformerFactory#newTemplates(Source source),
> > org.apache.xalan.xsltc.compiler.XSLTC#newTemplates(Source source) will
> > compile a new Translet, period.  Caching that object is the responsibility
> > of the caller, which can use whatever mechanisms are suitible.
> >
> > org.apache.xalan.xslt.TemplatesImpl#newTransformer() should simply call
> > Class#newInstance() on the the contained Translet class object.
> >
> > This seems really simple to me.  Applications that are already caching
> > Templates objects then start caching XSLTC translets automatically, with
> > the same mechanism.
> 
> Sure, users can cache Template instances as much as they want to nomatter
> what is wrapped in inside the Template. But, this means that the stylesheet
> is compiled every time the user wants to instanciate a translet _object_.
> This, again, undermines the whole idea of compiling stylesheets.
> 
> Most of the software I use is open-source and is distributed as source code.
> I compile this software once, store it as binaries and load it into memory
> when I need it. I do not compile it every time I run it and then keep it
> memory for as long as I can. This is mainly for two reasons:
> 
>  a) I don't want to wait for it to compile every time I load it
>  b) I do not have enough memory on my PC to keep it in memory at all times
> 
> This holds for translets too. A web server that uses XSLTC would proably
> not be able to keep Template/Transformer objects for all stylesheets in
> memory at all times. Neither would it be preferrable to compile stylesheets
> every time a new Transformer/Template object is instanciated.
> 
> > > Our main concern is where to store the translets (a simple Java
> > > property file pointing to a directory may do)
> >
> > Does the class have to be put on disk?  (A question... I simply don't
> > know).  If it does, I guess I would use a system property to indicate the
> > storage directory.
> 
> Yes, we absolutely, definately need to be able to store translet
> _classes_ somewhere. A simple property could be used. If the property we
> use is set, then translets can be cached in the directory (or whatever)
> the property points to, otherwise caching is turned off.
> 
> > > and how to make sure that a translet in the cache is still valid
> >
> > This is one of the reasons you really shouldn't muck with caching.
> > Whatever you do will cause somebody problems.  Put this responsibility at
> > the application level where it belongs.
> 
> Template/Transformer caching definately belongs at the application level.
> How these objects are created is our responsibility. And we want to create
> them as efficiently as we can.
> 
> Morten

Re: Transparent caching with JAXP/TrAX

Posted by Morten Jorgensen <mo...@sun.com>.
Scott_Boag@lotus.com wrote:
> 
> Morten Jorgensen <mo...@sun.com> wrote:
> > and we don't want to compile such classes more often
> > than we have to, and this is the reason why we want
> > cache translets.
> 
> My position is that the XSLT processor should not be doing caching.
> I have said this many times and I will continue to say it.

Why would anyone bother to use compiled stylesheets if they have to
be compiled for every transformation (or sequence of transformations)?
There is not reason at all to use XSLTC if translets are not pre-
compiled and stored. XSLTC spends ca. 4 times as long to compile a
translet as any other XSLT processor uses on a transformation. If our
JAXP implementation forces a compilation for each time a translet is
loaded we would make XSLTC the slowest XSLT processor on the market.
If XSLTC is made the slowest JAXP compliant processor there is, then
I don't think many people will bother use it - except for those that
are still using its native APIs - and there would be no reason to
add JAXP support at all.

> Here's how it should work in my opinion:
> 
> org.apache.xalan.xsltc.compiler.XSLTC should implement javax.xml.transform.
> TransformerFactory.
> org.apache.xalan.xsltc.compiler.XSLTC#newTemplates(Source source) should
> compile the source object into a Translets, and create a small wrapper
> class, org.apache.xalan.xslt.TemplatesImpl that contains the Class object,
> or perhaps just the class name (or, perhaps you get fancier than that and
> it holds the actual bytecodes... dunno).

There are still loads of people that prefer to use the native APIs of XSLTC.
Many of these users stick to XSLTC because of its small footprint, and not
so much for performance reasons. I would like to separate the JAXP/TrAX
wrappers from the existing XSLTC source tree (leaving the existing code
untouched - for now) and putting all TrAX wrappers in a separate directory:

 a) org.apache.xalan.xsltc.runtime - existing code
 b) org.apache.xalan.xsltc.dom     - internal DOM
 c) org.apache.xalan.xsltc.trax    - TrAX wrappers/etc.

There is loads of crap in TrAX that most users will never bother even looking
at. I don't want to force this stuff upon those users that are more than
happy to use just a) and b) above (this is the case for those that are using
XSLTC in applets). I know that the current code wraps the translet (or actually
the translet base class) inside a transformer object. Nowmatter how fancy this
looks on a design diagram it is not desireably/practical for many users.

> Everytime the caller calls TransformerFactory#newTemplates(Source source),
> org.apache.xalan.xsltc.compiler.XSLTC#newTemplates(Source source) will
> compile a new Translet, period.  Caching that object is the responsibility
> of the caller, which can use whatever mechanisms are suitible.
>
> org.apache.xalan.xslt.TemplatesImpl#newTransformer() should simply call
> Class#newInstance() on the the contained Translet class object.
> 
> This seems really simple to me.  Applications that are already caching
> Templates objects then start caching XSLTC translets automatically, with
> the same mechanism.

Sure, users can cache Template instances as much as they want to nomatter
what is wrapped in inside the Template. But, this means that the stylesheet
is compiled every time the user wants to instanciate a translet _object_.
This, again, undermines the whole idea of compiling stylesheets.

Most of the software I use is open-source and is distributed as source code.
I compile this software once, store it as binaries and load it into memory
when I need it. I do not compile it every time I run it and then keep it
memory for as long as I can. This is mainly for two reasons:

 a) I don't want to wait for it to compile every time I load it
 b) I do not have enough memory on my PC to keep it in memory at all times

This holds for translets too. A web server that uses XSLTC would proably
not be able to keep Template/Transformer objects for all stylesheets in
memory at all times. Neither would it be preferrable to compile stylesheets
every time a new Transformer/Template object is instanciated.

> > Our main concern is where to store the translets (a simple Java
> > property file pointing to a directory may do)
> 
> Does the class have to be put on disk?  (A question... I simply don't
> know).  If it does, I guess I would use a system property to indicate the
> storage directory.

Yes, we absolutely, definately need to be able to store translet
_classes_ somewhere. A simple property could be used. If the property we
use is set, then translets can be cached in the directory (or whatever)
the property points to, otherwise caching is turned off.
 
> > and how to make sure that a translet in the cache is still valid
> 
> This is one of the reasons you really shouldn't muck with caching.
> Whatever you do will cause somebody problems.  Put this responsibility at
> the application level where it belongs.

Template/Transformer caching definately belongs at the application level.
How these objects are created is our responsibility. And we want to create
them as efficiently as we can.

Morten