Re: Inconsistent and strange NPE when initializing Velocity
Nathan Bubna <[email protected]>
| Newsgroups | gmane.comp.jakarta.velocity.user |
|---|---|
| Message-ID | <CAFyaDjF+MD5OUpFS+tmRkE1DmzvFgGfLAoOgPQkaJUfYBkED9A@mail.gmail.com> |
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] >> >>