Skip to content

Commit

Permalink
Close Reader used by MustacheViewResolver when compiling a Template
Browse files Browse the repository at this point in the history
Previously, MustacheViewResolver would create an InputStreamReader
that wraps the template Resource's InputStream but would fail to close
the Reader. When the InputStream was a FileInputStream, this caused
the resolver to leak file handles.

This commit updates the resolver to close the Reader once the Template
has been compiled, thereby allowing any underlying resources to be
cleaned up immediately, rather than having to wait for the JVM to exit.

Closes spring-projectsgh-4921
  • Loading branch information
wilkinsona committed Jan 15, 2016
1 parent 681a866 commit b56eef2
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -106,7 +106,13 @@ private String getLocale(Locale locale) {
}

private Template createTemplate(Resource resource) throws IOException {
return this.compiler.compile(getReader(resource));
Reader reader = getReader(resource);
try {
return this.compiler.compile(reader);
}
finally {
reader.close();
}
}

private Reader getReader(Resource resource) throws IOException {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,11 +16,14 @@

package org.springframework.boot.autoconfigure.mustache.web;

import java.io.InputStream;
import java.util.Locale;

import org.fusesource.hawtbuf.ByteArrayInputStream;
import org.junit.Before;
import org.junit.Test;

import org.springframework.core.io.Resource;
import org.springframework.mock.web.MockServletContext;
import org.springframework.web.context.support.StaticWebApplicationContext;
import org.springframework.web.servlet.View;
Expand All @@ -29,11 +32,16 @@
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;

/**
* Tests for {@link MustacheViewResolver}.
*
* @author Dave Syer
* @author Andy Wilkinson
*/
public class MustacheViewResolverTests {

Expand Down Expand Up @@ -85,4 +93,24 @@ public void setsContentType() throws Exception {

}

@Test
public void templateResourceInputStreamIsClosed() throws Exception {
final Resource resource = mock(Resource.class);
given(resource.exists()).willReturn(true);
InputStream inputStream = new ByteArrayInputStream(new byte[0]);
InputStream spyInputStream = spy(inputStream);
given(resource.getInputStream()).willReturn(spyInputStream);
this.resolver = new MustacheViewResolver();
this.resolver.setApplicationContext(new StaticWebApplicationContext() {

@Override
public Resource getResource(String location) {
return resource;
}

});
this.resolver.loadView("foo", null);
verify(spyInputStream).close();
}

}

0 comments on commit b56eef2

Please sign in to comment.