JeeWiz Home  
The Model-Driven System Builder

JeeWiz Architect's Guide
 
Contents  >   8.  Templates and Velocity Features
 


8.9 Trouble-shooting Velocity Scripts

If you hit problems writing Velocity scripts, try the following...

 8.9.1  Syntax Problems
 8.9.2  Big Trouble
 8.9.3  Drilling Down

8.9.1  Syntax Problems
  1. Use the formal syntax - '${x}' - rather than the informal '$x' - for Velocity substitutions.
  2. Generating double quotes and other special characters Velocity allows you to use single or double quotes in #set. This means that you can create a simple string containing double-quote characters simply by using the '...' form of a string. However, the single quotes version does not evaluate $ substitutions within the string. This means there is no simple mechanism for generating double-quote characters in a string with substitutions.
    Note that the '\' character does not work as it does in Java. In Velocity, the only situation where it functions as an escape character is before '$' - not before '"'.
    The mechanism we use in generation systems to generate difficult characters in strings is to define special characters in the base system.properties file - see jeewiz/resources/base/control/system.properties. (The base template directory is normally included as the lowest-priority template directory in a generation stack.) This system.properties file has the following character definitions, which depend on the Java properties file convention of using \u to introduce a 16-bit unicode character:
    cr  : \u000D       -- cr  is for carriage-return
    lf  : \u000A       -- lf  is for line-feed
    tab : \u0009
    backspace : \u0008
    q   : "            -- q   is for (double) quote
    a   : '            -- a   is for apostrophe (single quote)
    d   : \u0024       -- d   is for dollar
    h   : #            -- h   is for hash
    amp : &            -- amp is for ampersand
    eq  : =            -- eq  is for equals (=) 
    sc  : \u003B       -- sc  is for semicolon (;)
    
    To construct a string with awkward characters, use the double-quote literal string in the assignment and one of the above variables. For example, to generate a double-quote character, use substitution of the $q variable. If x=="XXX", then
    #set( $v = "log.debug( ${q}${x} = ${q} + ${x} );" )
    
    will set $v to
    log.debug( "XXX = " + XXX );
    
  3. If you get an error "Encountered "\r\n" location = ...", it is probably due to an unclosed parenthesis or quote. There should be a file and line-number/character-position in the error message indicating where the unclosed character is. But note ... the character position does not take account of tabbing, so this may be out by a few characters.

8.9.2  Big Trouble
There are so many aspects to JeeWiz, it is sometimes difficult to track down whether or not a template or pattern was executed ... and if not, why not. There are a number of techniques for diagnosing problems in this area - where coordination amongst the aspects of JeeWiz programs is the issue.

Experience shows that it is normally quicker and less tiring to debug problems of this nature by adding the diagnostics than to puzzle over the logic, spelling and configuration linkages.

  1. The first thing to do - although it does take time to run - is to get a verbose (or even debug) trace. This can be done in jwcall and jwrun style builds using the following command lines
    ant -v           >redirectOutput.txt 2>&1
    ant -Dpass=-v  >redirectOutput.txt 2>&1
    
    (If you want the debug-level diagnostics, which is many times bigger, use '-d' instead of '-v'.) This produces a higly detailed and lengthy build. This logs the template directories and properties defined to start the build, the macros read in, the objects created in reading in the object model, the operation of patterns (which may cause more objects to be read in and patterns to be fired), and the logs from the per-object build files which run templates to produce output files and also run processors (e.g. compilers) to generate binary files.

    This output tries to log the expressions, files and outputs behind the steps of the operation.
  2. If overriding of patterns and templates might be an issue, get a 'dump' and use the calling hierarchy at the end of the output to check that the patterns and templates being used are the ones you intended. Some of the bugs in renderings come from another file overriding the one you wanted to be run. This can be done in Windows using the following command line
    ant "-Dpass=-Ddump=aggregate.xml" >redirectOutput.txt 2>&1
    
    Change 'aggregate.xml' to a filename of your choice. See here for details.
  3. If you are interested in whether one particular template or pattern is being executed, put a #trace() directive at the start of the file. (Doing this is also a good idea when you have coded a new routine with a significant amount of logic in it, to quickly follow the logic through.)

8.9.3  Drilling Down
This section covers the remaining diagnostic techniques, for drilling down in particular situations.
  1. If you are having problems getting Velocity to recognise a method on a particular object, you will get a ReferenceException. If this happens, try the following:
    • Check the exact case. The only case conversion that Velocity does is to capitalise the call to get a property. In other words, '$prop' will try to find 'getProp()', using the JavaBeans convention. Any other case in the method name in the call must exactly match the case in the definition.
    • If you are expecting a Velocity method, use the dump facility. This has a list, by meta-class, of the Velocity methods and the number of arguments.
    • If you expecting a Java method, first check the case, number of arguments and whether the object is public.
    • Next, check that the arguments are not null - Velocity sometimes does not find the Java method you expect if an argument is null. If this is the problem, the invocation of the call will get a ReferenceException on the argument.
    • Dump the class name of the object you're invoking the method on: $this.log( $class.name ).
    • If you are expecting a method in a superclass of the object to be invoked, you can check the inheritance chain using the getSuperclasses() method: $this.log( $superclasses ). The 'getSuperclasses()' method on a model object returns an ArrayList of for the complete inheritance chain, down to Object.
    • Finally, dump all the methodsavailable on an object: $this.log( $this.dumpObject( $object.availableMethods ) ). This will dump all the public methods down the inheritance chain. This dump is in precedence order, so you can search down the list to find the first applicable member.
    • If the member is there and still not being called, then it is time to check that the arguments are compatible with the call. Remember that Velocity converts to/from Strings and between intj's and long's - but that is all. Other arguments in the call must match the type of the corresponding paratemers.
  2. If you are not sure which files were involved in producing a particular output file, you can trace the "#parse" calls in Velocity scripts.

    To turn on tracing of #parse in templates (this doesn't work in patterns), set the trace build property.

  3. Methods for particular situations:
  4. Sometimes there are many times an template or patter is executed, but only one or two of these occurrences have a probelm In this case, put debugging comments into the generated file. In other words, don't use $this.log() - put what you would have logged into a comment for the target language. For example, put '//...' comments into Java, or '<!-- comments -->' into templates that create XML files.
  5. For patterns, adding XML comments to the output, as suggested in the previous tip, is not helpful because XML comments are thrown away when JeeWiz reads the pattern output. However, you can achieve the same 'commenting' results by adding <debug> - or whatever element tag you fancy - elements into the generated XML and then get a dump of the total (post-patterns) XML.
 


Copyright (c) 2001-2008 New Technology/enterprise Ltd.