Skip to content

Commit b56eef2

Browse files
committed
Close Reader used by MustacheViewResolver when compiling a Template
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 gh-4921
1 parent 681a866 commit b56eef2

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/mustache/web/MustacheViewResolver.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2015 the original author or authors.
2+
* Copyright 2012-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -106,7 +106,13 @@ private String getLocale(Locale locale) {
106106
}
107107

108108
private Template createTemplate(Resource resource) throws IOException {
109-
return this.compiler.compile(getReader(resource));
109+
Reader reader = getReader(resource);
110+
try {
111+
return this.compiler.compile(reader);
112+
}
113+
finally {
114+
reader.close();
115+
}
110116
}
111117

112118
private Reader getReader(Resource resource) throws IOException {

spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/mustache/web/MustacheViewResolverTests.java

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2015 the original author or authors.
2+
* Copyright 2012-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,11 +16,14 @@
1616

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

19+
import java.io.InputStream;
1920
import java.util.Locale;
2021

22+
import org.fusesource.hawtbuf.ByteArrayInputStream;
2123
import org.junit.Before;
2224
import org.junit.Test;
2325

26+
import org.springframework.core.io.Resource;
2427
import org.springframework.mock.web.MockServletContext;
2528
import org.springframework.web.context.support.StaticWebApplicationContext;
2629
import org.springframework.web.servlet.View;
@@ -29,11 +32,16 @@
2932
import static org.junit.Assert.assertNotNull;
3033
import static org.junit.Assert.assertNull;
3134
import static org.junit.Assert.assertThat;
35+
import static org.mockito.BDDMockito.given;
36+
import static org.mockito.Mockito.mock;
37+
import static org.mockito.Mockito.spy;
38+
import static org.mockito.Mockito.verify;
3239

3340
/**
3441
* Tests for {@link MustacheViewResolver}.
3542
*
3643
* @author Dave Syer
44+
* @author Andy Wilkinson
3745
*/
3846
public class MustacheViewResolverTests {
3947

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

8694
}
8795

96+
@Test
97+
public void templateResourceInputStreamIsClosed() throws Exception {
98+
final Resource resource = mock(Resource.class);
99+
given(resource.exists()).willReturn(true);
100+
InputStream inputStream = new ByteArrayInputStream(new byte[0]);
101+
InputStream spyInputStream = spy(inputStream);
102+
given(resource.getInputStream()).willReturn(spyInputStream);
103+
this.resolver = new MustacheViewResolver();
104+
this.resolver.setApplicationContext(new StaticWebApplicationContext() {
105+
106+
@Override
107+
public Resource getResource(String location) {
108+
return resource;
109+
}
110+
111+
});
112+
this.resolver.loadView("foo", null);
113+
verify(spyInputStream).close();
114+
}
115+
88116
}

0 commit comments

Comments
 (0)