【发布时间】:2015-01-20 15:39:14
【问题描述】:
我想用 Jetty9 和 Spring4 创建一个可运行的战争,并且仍然保持它作为可部署的战争(有点像Jenkins)
war 文件是使用 Maven 构建的,因此 maven-war-plugin 将主类 (WebAppRunner) 移动到文件树的顶部,覆盖 war 中的所有 jetty-* jar、javax* jar 和 spring-web.jar (可被主类访问)并在 META-INF/MANIFEST.MF 中设置主类。
主类像这样启动Jetty:
ProtectionDomain domain = WebAppRunner.class.getProtectionDomain();
URL location = domain.getCodeSource().getLocation();
WebAppContext context = new WebAppContext();
context.setContextPath( "/" );
context.setWar( location.toExternalForm() );
context.setParentLoaderPriority( true );
context.setConfigurations( new Configuration[] {
new AnnotationConfiguration(),
new WebInfConfiguration(),
new WebXmlConfiguration(),
new MetaInfConfiguration(),
new PlusConfiguration(),
new JettyWebXmlConfiguration()
} );
Server server = new Server( 8080 );
server.dumpStdErr();
server.setHandler( context );
try {
server.start();
server.join();
} catch ( Exception e ) {
LOG.warn( e );
}
Jetty 本身启动时没有问题,并且在启动期间 WebAppContext scans through WEB-INF/lib and WEB-INF/classes folders inside the war file 拾取 SpringServletContainerInitializer 作为 ServletContainerInitializer 的实现,这反过来应该启动 Web 应用程序。
但是AnnotationConfiguration.getNonExcludedInitializers 方法没有找到任何初始化器(ServiceLoader 返回空的可迭代对象)。
我在github 上创建了一个小型演示项目来演示这一点(它用 MyAnnotationConfiguration 覆盖 AnnotationConfiguration 只是为了添加日志条目)。您可以使用:
mvn clean compile war:exploded antrun:run war:war
并运行:
java -jar target/myapp.war
或获取更多日志记录:
java -Dorg.eclipse.jetty.LEVEL=DEBUG -jar target/myapp.war
【问题讨论】:
-
你看过Spring Boot吗?它使创建具有嵌入式 Jetty 或 Tomcat 的独立可运行应用程序变得容易,您还可以将应用程序打包为可以以传统方式部署的 WAR。
-
我做到了,我正在考虑将其作为最后的手段。
标签: java spring maven embedded-jetty