velocity-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dan Finkelstein <>
Subject Re: To Singleton, or not to Singlton, that is the question...
Date Thu, 19 Jul 2001 17:05:30 GMT
Hi --

We have now successfully modified our application to take advantage of the 
multiple engine support that Geir has now incorporated into velocity.

I'm really pleased with the implementation and functionality. It solves 
what were some very tricky problems for us -- and our code is cleaner to boot.

Our architecture is a bit unusual, basically with two variations of 
velocity usage:

* We have normal servlets, which use templates for specifying the html 
pages. For this I'm using the static Velocity singleton.

* Then we have a publishing capability, where a lot of munging, or 
preprocessing, is taking place. Each of these publish processes may have 
differing characteristics so we instantiate a new velocity engine at the 
beginning of each process. And guess what? This is the WWW so we need to 
handle multiple publishes simultaneously.

The multiple engine support allows us to implement our design in a natural 
fashion -- we already use velocity on our live site and this new feature 
strongly reinforces our decision to go with this enabling technology.

And a special word of thanks to Geir -- who came through in record time 
with fixes for ancillary bugs, so that I could test this feature.  Thanks 
so much for your help and support!

As you might imagine, my vote is to fold this new feature into the source !!!


At 12:03 PM 7/17/01 -0700, you wrote:
>Hi Geir,
>This morning I tried to integrate the new multiple engine feature into our 
>system.  Unfortunately, I came to a stop because a bug that I reported to 
>you earlier doesn't seem to have been fixed.
>The bug was this:
>         The resource loader is unable to find #include files which 
> Velocity 1.1 when running
>         with Velocity.evaluate(). It works ok if I were to use 
> template.merge().
>         And it also works ok with Velocity 1.0.
>(see emails with subject "template load problem with evaluate()in Vel 1.1").
>Anyway, as you might imagine, I'm dying to try this out, but our system 
>relies heavily on the Velocity.evaluate() method.  Help!
>Thanks a lot,
>At 11:45 PM 7/15/01 -0400, you wrote:
>>Once Brian finishes the CVS migration (Thanks, Brian!) to the new
>>server, I will put into whiteboard/geir a new jar, source tgz and
>>example proggie that is a successful attempt to convert Velocity to
>>allow multiple concurrent instances of the template engine in a given
>>I won't commit changes to CVS until people agree this is a good way to
>>go.  I don't want to have to back this change out :)  It's very broad
>>and touches most if not all parts of Velocity.
>>You now have the option of how you want to use the Velocity template
>>engine in your applications :
>>1) The current model of using the Velocity class to access the singlton
>>pattern is still valid - this jar should drop in and work anywhere the
>>exsting production or nightly jars work.
>>2) There is a new class that can
>>be used in the way you suspect
>>VelocityEngine ve = new VelocityEngine();
>>and VelocityEngine currently has the same interface as Velocity, so
>>everything you can do now with the singleton will work with the
>>The basic idea is that all parts of velocity depended upon Runtime for
>>core services in that they would call things like  Runtime.error( msg )
>>to log, for example.  So, the class Runtime was renamed RuntimeInstance,
>>a new interface RuntimeServices was created (that has most of the old
>>Runtime methods), and a referece to RuntimeInstance (which implements
>>RuntimeServices) is passed into the various subcomponents of Velocity
>>for use to replace using the singleton for services.  To do this, any
>>other singleton classes are now instance classes (ResourceManager, for
>>example) as well, and a few things had to be slightly modified to break
>>singleton assumptions.
>>So, the meta API of Velocity is :
>>VelocityEngine : new class that is a new-able class to provide separate
>>instances, delegates all calls to a RuntimeInstance.  With it you can :
>>VelocityEngine ve1 = new VelocityEngine();
>>VelocityEngine ve2 = new VelocityEngine();
>>and then configure and init() each separately, as you would hope for...
>>Velocity : the old Singleton application helper class. Nothing has
>>changed. Delegates calls to the RuntimeSingleton class.  You can and
>>should continue to use this for the Singleton model.
>>RuntimeSingleton : renamed Runtime class, this is the static class for
>>Singleton usage.
>>Runtime : new deprecated wrapper class, delegates to RuntimeSingleton.
>>I want to get rid of this if we go forward as I think that
>>RuntimeSingleton is a more descriptive class name.  Anyway, you
>>shouldn't be accessing the class directly in your applications - that's
>>what Velocity is for.
>>The nice thing is that you can continue to use the Singleton model, or
>>even use both models concurrently.
>>I converted Anakia to use an instance, but the structure of Texen
>>requires more work than I cared to do at the time, so it still requires
>>the singleton model.  This can be converted later, or left as is.  It's
>>up to the Texen tribe.  I will note that the failures we have been
>>seeing from Gump lately are due to a new classloader scheme in Ant that
>>Sam is trying which I believe could be solved by converting Texen to the
>>new instance model.
>>The only real change is that anything implementing LogSystem must now
>>add an init( RuntimeServices) method, as the logger factory made this
>>necessary to pass the RuntimeServices.  I don't think this will be
>>something that affects many people at all.  It would only affect you if
>>you created your own personal logger class that is instantiated.  If you
>>have a logger class that you pass to Velocity as a living instance (yes,
>>you can do that - see the logger test and examples), all is ok.  We can
>>discuss this - if it's too large a burden, we can try to redo, but I
>>think that it would be counter productive in the long run.
>>So, take a look at the code, and more importantly, test it out in
>>existing apps to make sure all is still healthy, and in new apps that
>>you were planning. There has been more and more interest in seeing this
>>solution, so lets give this a try.
>>Note that there is no performance penalty for this (it actually sped up
>>as I found some spurious initialization of the syntax tree when going
>>through this :)
>>Also, the example program is called InstanceExample, and is very very
>>simple. It was inspired by the needs of Turbine (or what I understand
>>their needs to be...) in that you setup two engines, and give each a
>>different template path, and then ask for the same template from each -
>>so you can have a default top level template index.vm for each of your
>>webapps, and don't really have to worry other than at setup time where
>>the templates are - you can make the same request into any engine...
>>Geir Magnusson Jr.                 
>>System and Software Consulting
>>Developing for the web?  See
>>You have a genius for suggesting things I've come a cropper with!
>Dan Finkelstein
>Senior Architect, Instructional Tools & Technology
>eMind LLC
>Northern California Annex
>1250 Addison St, Suite #210
>Berkeley, CA 94702-1700
>Tel: (510) 486-2740
>Fax: (510)486-2843
>Visit us at <>
>This email message is for the sole use of the intended recipient(s) and may
>contain confidential and privileged information. Any unauthorized review,
>use, disclosure or distribution is prohibited. If you are not the intended
>recipient, please contact the sender by reply email and destroy all copies
>of the original message.

Dan Finkelstein
Senior Architect, Instructional Tools & Technology
eMind LLC
Northern California Annex
1250 Addison St, Suite #210
Berkeley, CA 94702-1700
Tel: (510) 486-2740
Fax: (510)486-2843

Visit us at <>

This email message is for the sole use of the intended recipient(s) and may
contain confidential and privileged information. Any unauthorized review,
use, disclosure or distribution is prohibited. If you are not the intended
recipient, please contact the sender by reply email and destroy all copies
of the original message.

View raw message