|
40 | 40 | import java.util.Date;
|
41 | 41 | import java.util.EnumSet;
|
42 | 42 | import java.util.HashMap;
|
| 43 | +import java.util.HashSet; |
43 | 44 | import java.util.LinkedHashMap;
|
44 | 45 | import java.util.List;
|
45 | 46 | import java.util.Locale;
|
|
65 | 66 | import jakarta.servlet.FilterChain;
|
66 | 67 | import jakarta.servlet.FilterConfig;
|
67 | 68 | import jakarta.servlet.GenericServlet;
|
| 69 | +import jakarta.servlet.ServletConfig; |
68 | 70 | import jakarta.servlet.ServletContext;
|
69 | 71 | import jakarta.servlet.ServletContextEvent;
|
70 | 72 | import jakarta.servlet.ServletContextListener;
|
@@ -1366,6 +1368,26 @@ void startedLogMessageWithMultiplePorts() {
|
1366 | 1368 | + " \\(http(/1.1)?\\), [0-9]+ \\(http(/1.1)?\\) with context path '/'");
|
1367 | 1369 | }
|
1368 | 1370 |
|
| 1371 | + @Test |
| 1372 | + void servletComponentsAreInitializedWithTheSameThreadContextClassLoader() { |
| 1373 | + AbstractServletWebServerFactory factory = getFactory(); |
| 1374 | + ThreadContextClassLoaderCapturingServlet servlet = new ThreadContextClassLoaderCapturingServlet(); |
| 1375 | + ThreadContextClassLoaderCapturingFilter filter = new ThreadContextClassLoaderCapturingFilter(); |
| 1376 | + ThreadContextClassLoaderCapturingListener listener = new ThreadContextClassLoaderCapturingListener(); |
| 1377 | + this.webServer = factory.getWebServer((context) -> { |
| 1378 | + context.addServlet("tcclCapturingServlet", servlet).setLoadOnStartup(0); |
| 1379 | + context.addFilter("tcclCapturingFilter", filter); |
| 1380 | + context.addListener(listener); |
| 1381 | + }); |
| 1382 | + this.webServer.start(); |
| 1383 | + assertThat(servlet.contextClassLoader).isNotNull(); |
| 1384 | + assertThat(filter.contextClassLoader).isNotNull(); |
| 1385 | + assertThat(listener.contextClassLoader).isNotNull(); |
| 1386 | + assertThat(new HashSet<>( |
| 1387 | + Arrays.asList(servlet.contextClassLoader, filter.contextClassLoader, listener.contextClassLoader))) |
| 1388 | + .hasSize(1); |
| 1389 | + } |
| 1390 | + |
1369 | 1391 | protected Future<Object> initiateGetRequest(int port, String path) {
|
1370 | 1392 | return initiateGetRequest(HttpClients.createMinimal(), port, path);
|
1371 | 1393 | }
|
@@ -1822,4 +1844,43 @@ public boolean isTrusted(X509Certificate[] chain, String authType) {
|
1822 | 1844 |
|
1823 | 1845 | }
|
1824 | 1846 |
|
| 1847 | + static class ThreadContextClassLoaderCapturingServlet extends HttpServlet { |
| 1848 | + |
| 1849 | + private ClassLoader contextClassLoader; |
| 1850 | + |
| 1851 | + @Override |
| 1852 | + public void init(ServletConfig config) throws ServletException { |
| 1853 | + this.contextClassLoader = Thread.currentThread().getContextClassLoader(); |
| 1854 | + } |
| 1855 | + |
| 1856 | + } |
| 1857 | + |
| 1858 | + static class ThreadContextClassLoaderCapturingListener implements ServletContextListener { |
| 1859 | + |
| 1860 | + private ClassLoader contextClassLoader; |
| 1861 | + |
| 1862 | + @Override |
| 1863 | + public void contextInitialized(ServletContextEvent sce) { |
| 1864 | + this.contextClassLoader = Thread.currentThread().getContextClassLoader(); |
| 1865 | + } |
| 1866 | + |
| 1867 | + } |
| 1868 | + |
| 1869 | + static class ThreadContextClassLoaderCapturingFilter implements Filter { |
| 1870 | + |
| 1871 | + private ClassLoader contextClassLoader; |
| 1872 | + |
| 1873 | + @Override |
| 1874 | + public void init(FilterConfig filterConfig) throws ServletException { |
| 1875 | + this.contextClassLoader = Thread.currentThread().getContextClassLoader(); |
| 1876 | + } |
| 1877 | + |
| 1878 | + @Override |
| 1879 | + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) |
| 1880 | + throws IOException, ServletException { |
| 1881 | + chain.doFilter(request, response); |
| 1882 | + } |
| 1883 | + |
| 1884 | + } |
| 1885 | + |
1825 | 1886 | }
|
0 commit comments