[ 
https://issues.apache.org/jira/browse/VELOCITY-669?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12665565#action_12665565
 ] 

Byron Foster commented on VELOCITY-669:
---------------------------------------

<qoute> 
For instance in Parser.jjt you added that macroNames HashMap. Now 
escapedDirective method does not ask RuntimeServices anymore if some string is 
a macro or not. Instead it takes a look at macroNames. I think this is not the 
same thing since it is not guaranteed that the Parser instance knows about all 
macros. 
</qoute>

That's true, I've changed it so that it work exactly as it did before, so that 
escapedDirectives includes globals.  On a side note however, this whole 
mechanism supports the escaping of macros which is fundamentally broken as 
discussed in VELOCITY-454 and VELOCITY-670 (And in 670 I only outline one of 
the cases).  And, I plan to address.

<qoute> 
You also removed Macro.processAndRegister and changed so that macro is 
registered late at init and it feels a bit out of place. This may have some 
side effects (unnecessary reparsing of macros etc)?
</qoute>

I think that registering the macro in init, right after it is initialized is 
exactly right.  I think there are three clear phases to a template:  Parse, 
Init, Render.  As it stands now, these three phases are cleanly delineated such 
that no phase overlaps into another.  Further,  both Parse and Init are done 
only once, with one thread, and initialization is done in a predictable depth 
first traversal of the entire AST tree instead of initializing fragments of the 
tree in some other order.  I think this delineation contributes to the overall 
maintainability of the code.  Before these changes initialization was being 
done during Render,  and it was being done more then once, and you could have 
potentially multiple threads in an init method. 

<qoute>
 Is it certain that the Node argument passed to init is the same argument 
passed to processAndRegister (the macro body?). 
</qoute>

As far as I can tell.

<qoute>
I tested that by simply adding "nodeTree.init(null, rsvc);" to the last line of 
VelocimacroManager.MacroEntry constructor fixes this bug. Context can be null 
for init calls since init isn't (and should not be) context dependent. The only 
AST element that refers Context is ASTStringLiteral which can be changed to 
call super.getTemplateName() instead of getting it from the Context.
</qoute>

Even though I do agree with your premiss that initialization should not be 
context dependent, I don't believe this will work.  Not just the SimpleNodes 
are initialized with the context, but also Directives.  Just taking a cursory 
glance I see that BlockMacro and Define use the context.  I did not look at the 
other Directives. This does not include user defined directives which may or 
may not assume that the context can be null.

Calling init from MacroEntry results in initialization taking place during 
Parse, and creates the situation in which macros are initialized at least 
twice, and maybe more.  Referring back to the points I made about delineating 
the phases I think the solution as it stands is cleaner.



> Concurrency bug introduced in 1.7-dev
> -------------------------------------
>
>                 Key: VELOCITY-669
>                 URL: https://issues.apache.org/jira/browse/VELOCITY-669
>             Project: Velocity
>          Issue Type: Bug
>    Affects Versions: 1.7
>            Reporter: Jarkko Viinamäki
>            Priority: Blocker
>
> Warning: current SVN head is broken - it fails under heavy load. I don't have 
> time to investigate right now but 1.6.1 release version does not have this 
> bug (1.6.2 release candidate may have it! - I'm not sure what's included 
> there). However, current SVN head fails consistently with my load testing 
> suite when I run it under JRat profiling:
> -------------------------------------------------------------------------------
> Test set: org.apache.velocity.test.load.Velocity24LoadTest
> -------------------------------------------------------------------------------
> Tests run: 250, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 71.032 sec 
> <<< FAILURE!
> testRendering(org.apache.velocity.test.load.Velocity24Test)  Time elapsed: 
> 0.125 sec  <<< ERROR!
> java.lang.NullPointerException
>       at java.io.Writer.write(Writer.java:110)
>       at 
> org.apache.velocity.runtime.parser.node.ASTText.render_$jrat(ASTText.java:83)
>       at org.apache.velocity.runtime.parser.node.ASTText.render(ASTText.java)
>       at 
> org.apache.velocity.runtime.parser.node.ASTBlock.render_$jrat(ASTBlock.java:72)
>       at 
> org.apache.velocity.runtime.parser.node.ASTBlock.render(ASTBlock.java)
>       at 
> org.apache.velocity.runtime.directive.VelocimacroProxy.render_$jrat(VelocimacroProxy.java:222)
>       at 
> org.apache.velocity.runtime.directive.VelocimacroProxy.render(VelocimacroProxy.java)
>       at 
> org.apache.velocity.runtime.directive.RuntimeMacro.render_$jrat(RuntimeMacro.java:295)
>       at 
> org.apache.velocity.runtime.directive.RuntimeMacro.render(RuntimeMacro.java)
>       at 
> org.apache.velocity.runtime.directive.RuntimeMacro.render_$jrat(RuntimeMacro.java:215)
>       at 
> org.apache.velocity.runtime.directive.RuntimeMacro.render(RuntimeMacro.java)
>       at 
> org.apache.velocity.runtime.parser.node.ASTDirective.render_$jrat(ASTDirective.java:198)
>       at 
> org.apache.velocity.runtime.parser.node.ASTDirective.render(ASTDirective.java)
>       at 
> org.apache.velocity.runtime.parser.node.SimpleNode.render_$jrat(SimpleNode.java:342)
>       at 
> org.apache.velocity.runtime.parser.node.SimpleNode.render(SimpleNode.java)
>       at org.apache.velocity.Template.merge_$jrat(Template.java:340)
>       at org.apache.velocity.Template.merge(Template.java)
>       at org.apache.velocity.Template.merge_$jrat(Template.java:248)
>       at org.apache.velocity.Template.merge(Template.java)
>       at 
> org.apache.velocity.test.load.Velocity24Test.testRendering_$jrat(Velocity24Test.java:52)
>       at 
> org.apache.velocity.test.load.Velocity24Test.testRendering(Velocity24Test.java)
> Although I'm not sure, I strongly suspect that this has got something to do 
> with refactoring done (2009-01-11) for VelocimacroProxy.init. In 1.6.1 the 
> init function initializes the nodeTree variable but if I'm not mistaken, in 
> current SVN head this does not happen(!). It seems that under certain 
> conditions the engine tries to render an ASTText node that has not been 
> initialized (char array is null) which causes this exception. 

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to