0

Since now I used the SimpleTemplateEngine for processing my templates. I get the template files from a JarFile and create the template with a reader like this:

Reader reader = new InputStreamReader(jarFile.getInputStream(jarEntry), "UTF-8");
Template template = engine.createTemplate(reader);
String fileString = template.make(model).toString();

This was working fine, but now I need to create a template from a larger file and so the SimpleTemplateEngine can't handle this because it is limited to ~64K.

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: 5614: String too long. The given string is 298596 Unicode code units long, but only a maximum of 65535 is allowed.

In documentation it says SimpleTemplateEngine and StreamingTemplateEngine are working identical but for Strings > 64K. When I switch the Engine I get this error:

Edit stacktrace:

java.io.IOException: mark() not supported
        at java.io.Reader.mark(Reader.java:232) ~[na:1.8.0_181]
        at groovy.text.StreamingTemplateEngine$StreamingTemplate.handleEscaping(StreamingTemplateEngine.java:556) ~[groovy-templates-2.5.7.jar!/:2.5.7]
        at groovy.text.StreamingTemplateEngine$StreamingTemplate.<init>(StreamingTemplateEngine.java:460) ~[groovy-templates-2.5.7.jar!/:2.5.7]
        at groovy.text.StreamingTemplateEngine.createTemplate(StreamingTemplateEngine.java:215) ~[groovy-templates-2.5.7.jar!/:2.5.7]

Do I have to read the jarFile differently or how do I get rid of this error?

ochs.tobi
  • 3,214
  • 7
  • 31
  • 52

2 Answers2

1

Do I have to read the jarFile differently or how do I get rid of this error?

It looks like the InputStream that is returned by ZipFile::getInputStream does not implement mark / reset.

However, there is an easy fix. If you wrap the stream in a BufferedInputStream the latter will implement mark / reset for the data in the buffer. And you if you set the buffer to the size of the ZipEntry, you can buffer the entire stream; e.g.

int size = jarEntry.getSize();  // Might return -1.
BufferedInputStream bis = new BufferedInputStream(jarEntry.getInputStream(),
                                                  Math.max(size, 8192))
Reader reader = new InputStreamReader(bis, "UTF-8");
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • The `BufferedInputStream` is not the solution for me. After looking in the source files of `Reader` itself, I see that the `InputStreamReader` does not implement the `mark()` Method. The super class `Reader` has a method that only throws the `IOException`. – ochs.tobi Sep 05 '19 at 09:33
  • Thanks to your answer I got on the right track. I will add an answer with the solution for my problem. – ochs.tobi Sep 05 '19 at 09:43
0

The problem was the InputStreamReader. This reader does not implement the mark() method. I thought it was inherited from java.io.Reader. But after looking in the source of Reader I saw that there is a mark() method that only throws an exception. The InputStreamReader doesn't override it.

So I created a BufferedReader from the InputStreamReader like this and it works again:

Reader reader = new BufferedReader(new InputStreamReader(jarFile.getInputStream(jarEntry), "UTF-8"));
ochs.tobi
  • 3,214
  • 7
  • 31
  • 52