在 Apache James 中嵌入 Tomcat
Embedded Tomcat in Apache James
我正在尝试通过添加一些临时执行器 @RestController
s 来增强 apache-james 的 Spring 版本。
为此,我正在考虑启动一个嵌入式 Tomcat 9.x 服务器作为 sidecar,以便可以访问端点。
不幸的是,我得到一个 IllegalStateException: No ServletContext set
异常。
我目前的代码如下:
/**
* @author cdprete
* @since 09.06.21
*/
public class EmbeddedTomcat implements DisposableBean {
private final Tomcat tomcat;
public EmbeddedTomcat() throws LifecycleException {
String appBase = ".";
tomcat = new Tomcat();
tomcat.getConnector();
tomcat.getHost().setAppBase(appBase);
Context context = tomcat.addWebapp("", appBase);
// Don't scan MANIFESTs, otherwise lots of JARs will be reported as missing
((StandardJarScanner) context.getJarScanner()).setScanManifest(false);
tomcat.start();
}
@Override
public void destroy() throws Exception {
tomcat.destroy();
}
}
/**
* @author cdprete
* @since 08.06.21
*/
@EnableWebMvc
@Configuration
@Import({HealthConfiguration.class, DiskSpaceConfiguration.class, PingConfiguration.class, TraceConfiguration.class})
public class ActuatorConfiguration implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(ActuatorConfiguration.class);
ctx.setServletContext(servletContext);
servletContext.addListener(new ContextLoaderListener(ctx));
ServletRegistration.Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));
servlet.setLoadOnStartup(1);
servlet.addMapping("/");
}
}
并且在主 spring.xml
文件中:
<beans ...>
...
<!-- Embedded Tomcat -->
<bean class="ch.ti8m.channelsuite.james.actuator.EmbeddedTomcat" />
<!-- Actuator configuration -->
<bean class="ch.ti8m.channelsuite.james.actuator.ActuatorConfiguration" />
</beans>
如果我从 main
方法开始 Tomcat(例如,在 here 中),那么 Web 应用程序将按预期工作(至少是链接示例中的那个) .
我错过了什么?
如果实现 WebApplicationInitializer
接口的 class 在具有 @EnableWebMvc
的接口之前声明,一切都按预期工作。特别是,甚至没有必要将后者添加到上下文中,因为它已经在 WebApplicationInitializer
中启动的上下文中注册了
我正在尝试通过添加一些临时执行器 @RestController
s 来增强 apache-james 的 Spring 版本。
为此,我正在考虑启动一个嵌入式 Tomcat 9.x 服务器作为 sidecar,以便可以访问端点。
不幸的是,我得到一个 IllegalStateException: No ServletContext set
异常。
我目前的代码如下:
/**
* @author cdprete
* @since 09.06.21
*/
public class EmbeddedTomcat implements DisposableBean {
private final Tomcat tomcat;
public EmbeddedTomcat() throws LifecycleException {
String appBase = ".";
tomcat = new Tomcat();
tomcat.getConnector();
tomcat.getHost().setAppBase(appBase);
Context context = tomcat.addWebapp("", appBase);
// Don't scan MANIFESTs, otherwise lots of JARs will be reported as missing
((StandardJarScanner) context.getJarScanner()).setScanManifest(false);
tomcat.start();
}
@Override
public void destroy() throws Exception {
tomcat.destroy();
}
}
/**
* @author cdprete
* @since 08.06.21
*/
@EnableWebMvc
@Configuration
@Import({HealthConfiguration.class, DiskSpaceConfiguration.class, PingConfiguration.class, TraceConfiguration.class})
public class ActuatorConfiguration implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(ActuatorConfiguration.class);
ctx.setServletContext(servletContext);
servletContext.addListener(new ContextLoaderListener(ctx));
ServletRegistration.Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));
servlet.setLoadOnStartup(1);
servlet.addMapping("/");
}
}
并且在主 spring.xml
文件中:
<beans ...>
...
<!-- Embedded Tomcat -->
<bean class="ch.ti8m.channelsuite.james.actuator.EmbeddedTomcat" />
<!-- Actuator configuration -->
<bean class="ch.ti8m.channelsuite.james.actuator.ActuatorConfiguration" />
</beans>
如果我从 main
方法开始 Tomcat(例如,在 here 中),那么 Web 应用程序将按预期工作(至少是链接示例中的那个) .
我错过了什么?
如果实现 WebApplicationInitializer
接口的 class 在具有 @EnableWebMvc
的接口之前声明,一切都按预期工作。特别是,甚至没有必要将后者添加到上下文中,因为它已经在 WebApplicationInitializer