groovy

Errors in templates syntax produce not so helpful error messages

Details

  • Type: Improvement Improvement
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Fixed
  • Affects Version/s: 1.1-beta-1
  • Fix Version/s: 1.5.2
  • Component/s: None
  • Labels:
    None
  • Number of attachments :
    0

Description

This code has a problem at least in the last <% %>:

class A {
   def static engine = new groovy.text.SimpleTemplateEngine()
   def static templt = engine.createTemplate('''
   <html>
   <body>
      <% if(a == 1) %>
         a == 1
      <% else %>
         a != 1
      <% %>
   </body>
   </html>
   ''')
}

a = new A()
println a.templt.make([a: 1])

it produces:

Caught: java.lang.ExceptionInInitializerError
        at t.class$(t.groovy)
        at t.run(t.groovy:16)
        at t.main(t.groovy)

which gives no clue that the problem is in the template body (I suppose I always have to use if-statement with curly brackets).
It is almost impossible to track this error in a real environment with big template sitting not even in the code but somewhere else.

If I replace the hole <bod...</body> with <body><%></body> the error is the same.
If I change template variable declaration to non-static, the error is a bit better but still not good:

Caught: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup
failed, Script1.groovy: 5: unexpected token: ; @ line 5, column 33.
1 error

        at A.<init>(t.groovy:3)
        at t.run(t.groovy:16)
        at t.main(t.groovy)

Where this Script1.groovy comes from? I have no ';' in my code ...

Activity

Hide
Yegor Bryukhov added a comment -

And when such code is used in Netbeans application, you can even see class not found exceptions which makes you think in a completely different direction.

Show
Yegor Bryukhov added a comment - And when such code is used in Netbeans application, you can even see class not found exceptions which makes you think in a completely different direction.
Hide
Yegor Bryukhov added a comment -

And I don't know why JIRA put 11 lines of code into one

Show
Yegor Bryukhov added a comment - And I don't know why JIRA put 11 lines of code into one
Hide
Yegor Bryukhov added a comment -

Here is another try to put the correctly formatted code, anyway line 16 in the exception is "a = new A()" and line 3 is [def templt = engine.createTemplate(''']:
--------
class A {
def static engine = new groovy.text.SimpleTemplateEngine()
def static templt = engine.createTemplate('''
<html>
<body>
<% if(a == 1) %>
a == 1
<% else %>
a != 1
<% %>
</body>
</html>
''')
}

a = new A()
println a.templt.make([a: 1])

Show
Yegor Bryukhov added a comment - Here is another try to put the correctly formatted code, anyway line 16 in the exception is "a = new A()" and line 3 is [def templt = engine.createTemplate(''']: -------- class A { def static engine = new groovy.text.SimpleTemplateEngine() def static templt = engine.createTemplate(''' <html> <body> <% if(a == 1) %> a == 1 <% else %> a != 1 <% %> </body> </html> ''') } a = new A() println a.templt.make([a: 1])
Hide
Paul King added a comment -

Add confluence code tags to description

Show
Paul King added a comment - Add confluence code tags to description
Hide
Paul King added a comment - - edited

As a workaround, I would remove the static modifiers for engine and templt as you are calling them from an instance anyway and also turn on the verbose flag in SimpleTemplateEngine like this:

class A {
   def engine = new groovy.text.SimpleTemplateEngine(true)
   def templt = engine.createTemplate('''
   <html>
   <body>
      <% if(a == 1) %>
         a == 1
      <% else %>
         a != 1
      <% %>
   </body>
   </html>
   ''')
}

a = new A()
println a.templt.make([a: 1])

This then shows you where the problem is:

-- script source --
/* Generated by SimpleTemplateEngine */
out.print("\n");
out.print("   <html>\n");
out.print("   <body>\n");
out.print("      "); if(a == 1) ;
out.print("\n");
out.print("         a == 1\n");
out.print("      "); else ;
out.print("\n");
out.print("         a != 1\n");
out.print("      "); ;
out.print("\n");
out.print("   </body>\n");
out.print("   </html>\n");
out.print("   ");

-- script end --

Caught: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed, Script1.groovy: 5: unexpected token: ; @ line 5, column 33.
1 error

	at A.<init>(testBits.groovy:1327)
	at testBits.run(testBits.groovy:1340)
	at testBits.main(testBits.groovy)

Which gives an indication that you need the curly braces as you have already surmised:

<% if(a == 1) { %>
         a == 1
      <% } else { %>
         a != 1
      <% } %>
Show
Paul King added a comment - - edited As a workaround, I would remove the static modifiers for engine and templt as you are calling them from an instance anyway and also turn on the verbose flag in SimpleTemplateEngine like this:
class A {
   def engine = new groovy.text.SimpleTemplateEngine(true)
   def templt = engine.createTemplate('''
   <html>
   <body>
      <% if(a == 1) %>
         a == 1
      <% else %>
         a != 1
      <% %>
   </body>
   </html>
   ''')
}

a = new A()
println a.templt.make([a: 1])
This then shows you where the problem is:
-- script source --
/* Generated by SimpleTemplateEngine */
out.print("\n");
out.print("   <html>\n");
out.print("   <body>\n");
out.print("      "); if(a == 1) ;
out.print("\n");
out.print("         a == 1\n");
out.print("      "); else ;
out.print("\n");
out.print("         a != 1\n");
out.print("      "); ;
out.print("\n");
out.print("   </body>\n");
out.print("   </html>\n");
out.print("   ");

-- script end --

Caught: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed, Script1.groovy: 5: unexpected token: ; @ line 5, column 33.
1 error

	at A.<init>(testBits.groovy:1327)
	at testBits.run(testBits.groovy:1340)
	at testBits.main(testBits.groovy)
Which gives an indication that you need the curly braces as you have already surmised:
<% if(a == 1) { %>
         a == 1
      <% } else { %>
         a != 1
      <% } %>
Hide
Paul King added a comment -

SimpleTemplateEngine, XmlTemplateEngine and GStringTemplateEngine now all produce somewhat more meaningful error messages when producing an incorrect template script. If you see the static initializer problem you can re-run the script using the '-d' argument on the command-line and you will see:

C:\temp>groovy -d Groovy2226.groovy
Caught: java.lang.ExceptionInInitializerError
java.lang.ExceptionInInitializerError
        at java.lang.Class.forName0(Native Method)
[...]
Caused by: groovy.lang.GroovyRuntimeException: Failed to parse template script (your template may contain an error or be trying to use expressions not currently supported): startup failed, SimpleTemplateScript1.groovy: 5: unexpected token:
; @ line 5, column 33.
1 error
        at groovy.text.SimpleTemplateEngine.createTemplate(SimpleTemplateEngine.java:75)
[...]
Show
Paul King added a comment - SimpleTemplateEngine, XmlTemplateEngine and GStringTemplateEngine now all produce somewhat more meaningful error messages when producing an incorrect template script. If you see the static initializer problem you can re-run the script using the '-d' argument on the command-line and you will see:
C:\temp>groovy -d Groovy2226.groovy
Caught: java.lang.ExceptionInInitializerError
java.lang.ExceptionInInitializerError
        at java.lang.Class.forName0(Native Method)
[...]
Caused by: groovy.lang.GroovyRuntimeException: Failed to parse template script (your template may contain an error or be trying to use expressions not currently supported): startup failed, SimpleTemplateScript1.groovy: 5: unexpected token:
; @ line 5, column 33.
1 error
        at groovy.text.SimpleTemplateEngine.createTemplate(SimpleTemplateEngine.java:75)
[...]
Hide
Paul King added a comment -

close off release 1.5.4

Show
Paul King added a comment - close off release 1.5.4

People

Vote (0)
Watch (0)

Dates

  • Created:
    Updated:
    Resolved: