Skip to content

Commit 7a857b1

Browse files
author
Vladimir Kotal
authored
fix ThreadLocal leaks in webapp (#2585)
* remove ThreadLocal data at the end of request processing fixes #1761
1 parent c8a9ebd commit 7a857b1

File tree

4 files changed

+56
-9
lines changed

4 files changed

+56
-9
lines changed

opengrok-indexer/src/main/java/org/opengrok/indexer/analysis/AnalyzerGuru.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,15 @@ public static FileAnalyzer getAnalyzer(InputStream in, String file) throws IOExc
506506
return factory.getAnalyzer();
507507
}
508508

509+
/**
510+
* Free resources associated with all registered analyzers.
511+
*/
512+
public static void returnAnalyzers() {
513+
for (FileAnalyzerFactory analyzer : factories) {
514+
analyzer.returnAnalyzer();
515+
}
516+
}
517+
509518
/**
510519
* Populate a Lucene document with the required fields.
511520
*

opengrok-indexer/src/main/java/org/opengrok/indexer/analysis/FileAnalyzerFactory.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,13 @@ public final FileAnalyzer getAnalyzer() {
205205
return fa;
206206
}
207207

208+
/**
209+
* Free thread-local data.
210+
*/
211+
public void returnAnalyzer() {
212+
cachedAnalyzer.remove();
213+
}
214+
208215
/**
209216
* Create a new analyzer.
210217
* @return an analyzer

opengrok-web/src/main/java/org/opengrok/web/WebappListener.java

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,24 +22,26 @@
2222
*/
2323
package org.opengrok.web;
2424

25-
import java.io.File;
26-
import java.io.IOException;
27-
import java.util.logging.Level;
28-
import java.util.logging.Logger;
29-
import javax.servlet.ServletContext;
30-
import javax.servlet.ServletContextEvent;
31-
import javax.servlet.ServletContextListener;
32-
import javax.servlet.ServletRequestEvent;
33-
import javax.servlet.ServletRequestListener;
3425
import org.json.simple.parser.ParseException;
3526
import org.opengrok.indexer.Info;
27+
import org.opengrok.indexer.analysis.AnalyzerGuru;
3628
import org.opengrok.indexer.authorization.AuthorizationFramework;
3729
import org.opengrok.indexer.configuration.RuntimeEnvironment;
3830
import org.opengrok.indexer.logger.LoggerFactory;
3931
import org.opengrok.indexer.web.PageConfig;
4032
import org.opengrok.indexer.web.SearchHelper;
4133
import org.opengrok.web.api.v1.suggester.provider.service.SuggesterServiceFactory;
4234

35+
import javax.servlet.ServletContext;
36+
import javax.servlet.ServletContextEvent;
37+
import javax.servlet.ServletContextListener;
38+
import javax.servlet.ServletRequestEvent;
39+
import javax.servlet.ServletRequestListener;
40+
import java.io.File;
41+
import java.io.IOException;
42+
import java.util.logging.Level;
43+
import java.util.logging.Logger;
44+
4345
import static org.opengrok.indexer.util.StatisticsUtils.loadStatistics;
4446
import static org.opengrok.indexer.util.StatisticsUtils.saveStatistics;
4547

@@ -135,6 +137,8 @@ public void requestDestroyed(ServletRequestEvent e) {
135137
if (sh != null) {
136138
sh.destroy();
137139
}
140+
141+
AnalyzerGuru.returnAnalyzers();
138142
}
139143

140144
/**
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package org.opengrok.web;
2+
3+
import org.junit.Test;
4+
5+
import javax.servlet.ServletContext;
6+
import javax.servlet.ServletRequestEvent;
7+
import javax.servlet.http.HttpServletRequest;
8+
9+
import static org.mockito.Mockito.mock;
10+
import static org.mockito.Mockito.when;
11+
12+
public class WebappListenerTest {
13+
/**
14+
* simple smoke test for WebappListener request handling
15+
*/
16+
@Test
17+
public void testRequest() {
18+
WebappListener wl = new WebappListener();
19+
final HttpServletRequest req = mock(HttpServletRequest.class);
20+
final ServletContext servletContext = mock(ServletContext.class);
21+
when(req.getServletContext()).thenReturn(servletContext);
22+
ServletRequestEvent event = new ServletRequestEvent(servletContext, req);
23+
24+
wl.requestInitialized(event);
25+
wl.requestDestroyed(event);
26+
}
27+
}

0 commit comments

Comments
 (0)