ochs.tobi
ochs.tobi

Reputation: 3454

Groovy StreamingTemplateEngine IOException: mark() not supported

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?

Upvotes: 0

Views: 301

Answers (2)

ochs.tobi
ochs.tobi

Reputation: 3454

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"));

Upvotes: 0

Stephen C
Stephen C

Reputation: 718986

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");

Upvotes: 1

Related Questions