Re: Inconsistent and strange NPE when initializing Velocity
Bradley Wagner <[email protected]>
| Newsgroups | gmane.comp.jakarta.velocity.user |
|---|---|
| Message-ID | <CAEbivYXYxG5-Qvk7-pUG40ciUO+E-aDOkYM5bC9kGraF5E4r2g@mail.gmail.com> |
So is the default behavior that once a macro is loaded it can't be overloaded by in another template? (basically, it's just defined once for the lifetime of the VelocityEngine) On Wed, Jun 27, 2012 at 4:41 PM, Nathan Bubna <[email protected]> wrote: > A VelocityEngine allows for global macros and template caching, both > configurable, of course. Context data is never cached or shared by > the engine, though you can yourself reuse a context across multiple > merges. > > On Wed, Jun 27, 2012 at 1:03 PM, Bradley Wagner > <[email protected]> wrote: > > Thanks, Nathan, I'll give that a shot. > > > > Offhand, is there anything else I need to be aware of that could be > > persisting across template renders (like velocimacros) since I'm now > using > > a single instance of engine? > > > > On Wed, Jun 27, 2012 at 3:51 PM, Nathan Bubna <[email protected]> wrote: > > > >> On Wed, Jun 27, 2012 at 11:04 AM, Bradley Wagner > >> <[email protected]> wrote: > >> > None explicitly specified. > >> > > >> > I looked at a default velocity properties that's in our project but > that > >> > we're not using: > >> > > >> > velocimacro.library = VM_global_library.vm > >> > velocimacro.permissions.allow.inline = true > >> > velocimacro.permissions.allow.inline.to.replace.global = false > >> > velocimacro.permissions.allow.inline.local.scope = false > >> > velocimacro.context.localscope = false > >> > > >> > I'm guessing this has something to do with these things being scoped > >> > globally by default or something? > >> > >> yeah, you should set > >> > >> velocimacro.permissions.allow.inline.local.scope = true > >> > >> > On Wed, Jun 27, 2012 at 12:39 PM, Nathan Bubna <[email protected]> > wrote: > >> > > >> >> What are the macro settings in your velocity.properties? > >> >> > >> >> On Mon, Jun 25, 2012 at 7:40 PM, Bradley Wagner > >> >> <[email protected]> wrote: > >> >> > We're noticing something now that may or may not be related to our > >> change > >> >> > to only use a single instance of the Velocity Engine. > >> >> > > >> >> > Macros that we define in one template seem to be sticking around > and > >> >> being > >> >> > used when we go to merge or evaluate a different template. > >> >> > > >> >> > Is this possible related and to be expected when using a single > >> instance > >> >> of > >> >> > the VelocityEngine? > >> >> > > >> >> > On Thu, Jun 7, 2012 at 5:28 PM, Bradley Wagner < > >> >> > [email protected]> wrote: > >> >> > > >> >> >> Thanks Will. We'll make sure to just initialize it once. > >> >> >> > >> >> >> > >> >> >> On Thu, Jun 7, 2012 at 3:36 PM, Will Glass-Husain < > >> >> [email protected]>wrote: > >> >> >> > >> >> >>> Hi, > >> >> >>> > >> >> >>> You should use either the Velocity static calls or the > >> VelocityEngine > >> >> but > >> >> >>> not both-- it's confusing. They don't technically interfere with > >> each > >> >> >>> other, but it'll be simpler and less error prone not to mix. > >> >> >>> > >> >> >>> It's also a performance hit to continually reinitialize Velocity. > >> >> There's > >> >> >>> no need to do this every time you process a page. Besides the > cost > >> of > >> >> >>> initialization, it also prevents you from doing any caching. > >> >> >>> > >> >> >>> Here's the general pattern > >> >> >>> * On app start up, initialize a VelocityEngine. Store it > somewhere. > >> >> >>> * Every time you need to process a template > >> >> >>> --> get the template > >> >> >>> --> create and populate a context > >> >> >>> --> using the velocity engine, merge the template (with the > >> >> context) > >> >> >>> > >> >> >>> WILL > >> >> >>> > >> >> >>> > >> >> >>> On Thu, Jun 7, 2012 at 8:26 AM, Bradley Wagner < > >> >> >>> [email protected]> wrote: > >> >> >>> > >> >> >>> > Thanks Will. > >> >> >>> > > >> >> >>> > So looking over the developer documentation about > initialization > >> and > >> >> our > >> >> >>> > code, it looks like we're using a mix of the Singleton Velocity > >> >> Engine > >> >> >>> and > >> >> >>> > Separate Instances in certain cases. However, in all these > cases, > >> >> we're > >> >> >>> > using the same set of properties. The documentation suggests > that > >> the > >> >> >>> > Separate Instance method is the newer way to do it, but you're > >> saying > >> >> >>> that > >> >> >>> > if we can get away with initializing Velocity one using > >> >> Velocity.init() > >> >> >>> we > >> >> >>> > should do that for better performance, yes? Are both mechanisms > >> for > >> >> >>> > evaluating templates thread-safe? > >> >> >>> > > >> >> >>> > In one place we're doing: > >> >> >>> > > >> >> >>> > VelocityContext context = new VelocityContext(contextMap) > >> >> >>> > Properties props = VelocityProperties.getProperties(); > >> >> >>> > Velocity.init(props); > >> >> >>> > String templatePath = > >> >> VelocityTemplates.getTemplatePath(templateName); > >> >> >>> > Template template = Velocity.getTemplate(templatePath); > >> >> >>> > StringWriter writer = new StringWriter(); > >> >> >>> > template.merge(context, writer); > >> >> >>> > return writer.toString(); > >> >> >>> > > >> >> >>> > and in another we're doing: > >> >> >>> > > >> >> >>> > VelocityEngine engine = new VelocityEngine(); > >> >> >>> > Properties velocityProps = VelocityProperties.getProperties(); > >> >> >>> > engine.init(velocityProps); > >> >> >>> > > >> >> >>> > // Get a template as stream. > >> >> >>> > StringWriter writer = new StringWriter(); > >> >> >>> > StringReader reader = new StringReader(template); > >> >> >>> > // create a temporary template name > >> >> >>> > String tempTemplateName = "velocityTransform-" + > >> >> >>> > System.currentTimeMillis(); > >> >> >>> > > >> >> >>> > // ask Velocity to evaluate it. > >> >> >>> > boolean result = engine.evaluate(context, writer, > >> tempTemplateName, > >> >> >>> > reader); > >> >> >>> > > >> >> >>> > String strResult = null; > >> >> >>> > if (result) > >> >> >>> > { > >> >> >>> > strResult = writer.getBuffer().toString(); > >> >> >>> > } > >> >> >>> > return strResult; > >> >> >>> > > >> >> >>> > Thanks a bunch for your help! > >> >> >>> > > >> >> >>> > On Wed, Jun 6, 2012 at 6:34 PM, Will Glass-Husain < > >> >> >>> [email protected]> > >> >> >>> > wrote: > >> >> >>> > > > >> >> >>> > > You only need to initialize Velocity once. Performance is > much > >> >> better > >> >> >>> > that > >> >> >>> > > way. > >> >> >>> > > > >> >> >>> > > WILL > >> >> >>> > > > >> >> >>> > > On Wed, Jun 6, 2012 at 2:37 PM, Bradley Wagner < > >> >> >>> > > [email protected]> wrote: > >> >> >>> > > > >> >> >>> > > > The odd part about that is that while I could see this > being a > >> >> race > >> >> >>> > > > condition... once Velocity gets into this state it doesn't > >> matter > >> >> >>> how > >> >> >>> > many > >> >> >>> > > > times we call Velocity.init, it returns the NPE every > time. I > >> >> guess > >> >> >>> I > >> >> >>> > > > should have mentioned that in the original post. Basically > >> once > >> >> it > >> >> >>> > starts > >> >> >>> > > > returning NPE our only recourse is to restart Tomcat, which > >> fixes > >> >> >>> the > >> >> >>> > > > problem, until it pops up again. > >> >> >>> > > > > >> >> >>> > > > On Wed, Jun 6, 2012 at 5:35 PM, Bradley Wagner < > >> >> >>> > > > [email protected]> wrote: > >> >> >>> > > > > >> >> >>> > > > > Ha, that's a good question. Yes, we're initializing > Velocity > >> >> LOTS > >> >> >>> of > >> >> >>> > > > > times. Basically every time we use it to create these > >> messages > >> >> in > >> >> >>> our > >> >> >>> > > > > message util. I'm guessing that's not recommended? > >> >> >>> > > > > > >> >> >>> > > > > > >> >> >>> > > > > On Wed, Jun 6, 2012 at 1:53 PM, Will Glass-Husain < > >> >> >>> > > > [email protected]>wrote: > >> >> >>> > > > > > >> >> >>> > > > >> Hi Bradley, > >> >> >>> > > > >> > >> >> >>> > > > >> Are you initializing Velocity multiple times? > >> >> >>> > > > >> > >> >> >>> > > > >> Though I haven't heard of this issue before, it sounds > >> like a > >> >> >>> race > >> >> >>> > > > >> condition, perhaps if the initialization is called > twice at > >> >> the > >> >> >>> same > >> >> >>> > > > time. > >> >> >>> > > > >> > >> >> >>> > > > >> WILL > >> >> >>> > > > >> > >> >> >>> > > > >> On Wed, Jun 6, 2012 at 8:37 AM, Bradley Wagner < > >> >> >>> > > > >> [email protected]> wrote: > >> >> >>> > > > >> > >> >> >>> > > > >> > Hi, > >> >> >>> > > > >> > > >> >> >>> > > > >> > I sent this message before I had subscribed to the > list > >> so I > >> >> >>> > wasn't > >> >> >>> > > > >> sure if > >> >> >>> > > > >> > the original made it. My apologies if this is a > >> duplicate. > >> >> >>> > > > >> > > >> >> >>> > > > >> > One of our clients running our software is > *occasionally* > >> >> >>> running > >> >> >>> > into > >> >> >>> > > > >> the > >> >> >>> > > > >> > stack trace at the bottom when Velocity is > initialized. A > >> >> >>> restart > >> >> >>> > > > tends > >> >> >>> > > > >> to > >> >> >>> > > > >> > fix this problem. But it pops back up after running > the > >> >> system > >> >> >>> for > >> >> >>> > a > >> >> >>> > > > >> while. > >> >> >>> > > > >> > > >> >> >>> > > > >> > They're running: > >> >> >>> > > > >> > > >> >> >>> > > > >> > - Velocity 1.7 > >> >> >>> > > > >> > - Tomcat 6.0.35 > >> >> >>> > > > >> > - Using the 3.2 of the Apache Commons Collections > >> library > >> >> >>> > > > >> > - Running Java 1.6.0_31 in Mac OS X 10.6.8 > >> >> >>> > > > >> > > >> >> >>> > > > >> > Unfortunately we don't have the ability to debug this > >> >> problem > >> >> >>> > > > remotely, > >> >> >>> > > > >> so > >> >> >>> > > > >> > we can't see exactly what's going on, but having > looked a > >> >> bit > >> >> >>> at > >> >> >>> > the > >> >> >>> > > > >> > Extended Properties class, it doesn't seem like it > >> should be > >> >> >>> > possible > >> >> >>> > > > to > >> >> >>> > > > >> > get an NPE at that line, because of the containsKey() > >> check > >> >> a > >> >> >>> few > >> >> >>> > > > lines > >> >> >>> > > > >> > before. > >> >> >>> > > > >> > > >> >> >>> > > > >> > java.lang.NullPointerException > >> >> >>> > > > >> > at > >> >> >>> > > > >> > > >> >> >>> > > > >> > >> >> >>> > > > > >> >> >>> > > >> >> >>> > > >> >> >>> > >> >> > >> > org.apache.commons.collections.ExtendedProperties.clearProperty(ExtendedProperties.java:797) > >> >> >>> > > > >> > at > >> >> >>> > > > >> > > >> >> >>> > > > >> > >> >> >>> > > > > >> >> >>> > > >> >> >>> > > >> >> >>> > >> >> > >> > org.apache.commons.collections.ExtendedProperties.setProperty(ExtendedProperties.java:722) > >> >> >>> > > > >> > at > >> >> >>> > > > >> > > >> >> >>> > > > >> > >> >> >>> > > > > >> >> >>> > > >> >> >>> > > >> >> >>> > >> >> > >> > org.apache.commons.collections.ExtendedProperties.combine(ExtendedProperties.java:783) > >> >> >>> > > > >> > at > >> >> >>> > > > >> > > >> >> >>> > > > >> > >> >> >>> > > > > >> >> >>> > > >> >> >>> > > >> >> >>> > >> >> > >> > org.apache.velocity.runtime.RuntimeInstance.setProperties(RuntimeInstance.java:657) > >> >> >>> > > > >> > at > >> >> >>> > > > >> > > >> >> >>> > > > >> > >> >> >>> > > > > >> >> >>> > > >> >> >>> > >> >> > >> > org.apache.velocity.runtime.RuntimeInstance.init(RuntimeInstance.java:645) > >> >> >>> > > > >> > at > >> >> >>> > > > >> > > >> >> >>> > > > >> > >> >> >>> > > > > >> >> >>> > > >> >> >>> > > >> >> >>> > >> >> > >> > org.apache.velocity.runtime.RuntimeSingleton.init(RuntimeSingleton.java:226) > >> >> >>> > > > >> > at > >> org.apache.velocity.app.Velocity.init(Velocity.java:97) > >> >> >>> > > > >> > at > >> >> >>> > > > >> > > >> >> >>> > > > >> > >> >> >>> > > > > >> >> >>> > > >> >> >>> > > >> >> >>> > >> >> > >> > com.hannonhill.cascade.velocity.VelocityEngineUtil.generateMessage(VelocityEngineUtil.java:66) > >> >> >>> > > > >> > > >> >> >>> > > > >> > Also, here's the code that's calling the > Velocity.init: > >> >> >>> > > > >> > > >> >> >>> > > > >> > Properties velocityProps = > >> >> >>> > VelocityProperties.getProperties(); > >> >> >>> > > > >> > > >> >> >>> > > > >> > Velocity.init(velocityProps); > >> >> >>> > > > >> > > >> >> >>> > > > >> > Velocity Properties are just loading the following > file > >> >> >>> contents > >> >> >>> > into > >> >> >>> > > > a > >> >> >>> > > > >> > properties object: > >> >> >>> > > > >> > > >> >> >>> > > > >> > > >> >> >>> > > > >> > > >> >> >>> > > > >> > >> >> >>> > > > > >> >> >>> > > >> >> >>> > > >> >> >>> > >> >> > >> > #---------------------------------------------------------------------------- > >> >> >>> > > > >> > # This controls if Runtime.error(), info() and warn() > >> >> messages > >> >> >>> > include > >> >> >>> > > > >> the > >> >> >>> > > > >> > # whole stack trace. The last property controls > whether > >> >> invalid > >> >> >>> > > > >> references > >> >> >>> > > > >> > # are logged. > >> >> >>> > > > >> > > >> >> >>> > > > >> > > >> >> >>> > > > >> > >> >> >>> > > > > >> >> >>> > > >> >> >>> > > >> >> >>> > >> >> > >> > #---------------------------------------------------------------------------- > >> >> >>> > > > >> > runtime.log.error.stacktrace = false > >> >> >>> > > > >> > runtime.log.warn.stacktrace = false > >> >> >>> > > > >> > runtime.log.info.stacktrace = false > >> >> >>> > > > >> > runtime.log.invalid.reference = true > >> >> >>> > > > >> > > >> >> >>> > > > >> > > >> >> >>> > > > >> > >> >> >>> > > > > >> >> >>> > > >> >> >>> > > >> >> >>> > >> >> > >> > #---------------------------------------------------------------------------- > >> >> >>> > > > >> > # Configuration for the Log4JLogSystem. > >> >> >>> > > > >> > # You must define the runtime.log.logsystem.class > >> property > >> >> to > >> >> >>> be: > >> >> >>> > > > >> > # org.apache.velocity.runtime.log.Log4JLogSystem > >> >> >>> > > > >> > # > >> >> >>> > > > >> > # You must also include Log4J's .jar files into your > >> >> classpath. > >> >> >>> > They > >> >> >>> > > > are > >> >> >>> > > > >> > # included with the Velocity distribution in the > >> build/lib > >> >> >>> > directory. > >> >> >>> > > > >> > # > >> >> >>> > > > >> > # There are several different options that you can > >> >> configure. > >> >> >>> > > > >> > # Uncomment the ones that you want and also define > their > >> >> >>> settings. > >> >> >>> > > > >> > > >> >> >>> > > > >> > > >> >> >>> > > > >> > >> >> >>> > > > > >> >> >>> > > >> >> >>> > > >> >> >>> > >> >> > >> > #---------------------------------------------------------------------------- > >> >> >>> > > > >> > > >> >> >>> > > > >> > > >> >> >>> > > > >> > >> >> >>> > > > > >> >> >>> > > >> >> >>> > > >> >> >>> > >> >> > >> > #---------------------------------------------------------------------------- > >> >> >>> > > > >> > # T E M P L A T E E N C O D I N G > >> >> >>> > > > >> > > >> >> >>> > > > >> > > >> >> >>> > > > >> > >> >> >>> > > > > >> >> >>> > > >> >> >>> > > >> >> >>> > >> >> > >> > #---------------------------------------------------------------------------- > >> >> >>> > > > >> > input.encoding=UTF-8 > >> >> >>> > > > >> > output.encoding=UTF-8 > >> >> >>> > > > >> > > >> >> >>> > > > >> > > >> >> >>> > > > >> > >> >> >>> > > > > >> >> >>> > > >> >> >>> > > >> >> >>> > >> >> > >> > #---------------------------------------------------------------------------- > >> >> >>> > > > >> > # F O R E A C H P R O P E R T I E S > >> >> >>> > > > >> > > >> >> >>> > > > >> > > >> >> >>> > > > >> > >> >> >>> > > > > >> >> >>> > > >> >> >>> > > >> >> >>> > >> >> > >> > #---------------------------------------------------------------------------- > >> >> >>> > > > >> > # These properties control how the counter is > accessed in > >> >> the > >> >> >>> > #foreach > >> >> >>> > > > >> > # directive. By default the reference $velocityCount > >> will be > >> >> >>> > available > >> >> >>> > > > >> > # in the body of the #foreach directive. The default > >> >> starting > >> >> >>> > value > >> >> >>> > > > >> > # for this reference is 1. > >> >> >>> > > > >> > > >> >> >>> > > > >> > > >> >> >>> > > > >> > >> >> >>> > > > > >> >> >>> > > >> >> >>> > > >> >> >>> > >> >> > >> > #---------------------------------------------------------------------------- > >> >> >>> > > > >> > directive.foreach.counter.name = velocityCount > >> >> >>> > > > >> > directive.foreach.counter.initial.value = 1 > >> >> >>> > > > >> > > >> >> >>> > > > >> > > >> >> >>> > > > >> > >> >> >>> > > > > >> >> >>> > > >> >> >>> > > >> >> >>> > >> >> > >> > #---------------------------------------------------------------------------- > >> >> >>> > > > >> > # T E M P L A T E L O A D E R S > >> >> >>> > > > >> > > >> >> >>> > > > >> > > >> >> >>> > > > >> > >> >> >>> > > > > >> >> >>> > > >> >> >>> > > >> >> >>> > >> >> > >> > #---------------------------------------------------------------------------- > >> >> >>> > > > >> > resource.loader = class > >> >> >>> > > > >> > class.resource.loader.description = Velocity Classpath > >> >> Resource > >> >> >>> > Loader > >> >> >>> > > > >> > class.resource.loader.class = > >> >> >>> > > > >> > > >> >> >>> > > >> org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader > >> >> >>> > > > >> > > >> >> >>> > > > >> > >> >> >>> > > > > > >> >> >>> > > > > > >> >> >>> > > > > >> >> >>> > > >> >> >>> > >> >> >> > >> >> >> > >> >> > >> >> --------------------------------------------------------------------- > >> >> To unsubscribe, e-mail: [email protected] > >> >> For additional commands, e-mail: [email protected] > >> >> > >> >> > >> > >> --------------------------------------------------------------------- > >> To unsubscribe, e-mail: [email protected] > >> For additional commands, e-mail: [email protected] > >> > >> > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [email protected] > For additional commands, e-mail: [email protected] > >