2014-02-10 66 views
1

成功运行Spring getting started guide for WebSocket后,我想拼命地将此应用程序构建为WAR并将其部署到Tomcat中。我已尽了最大努力修改该项目以构建WAR文件,方法是遵循Spring getting started guide for converting a Spring Boot JAR to a WAR,但是当我部署生成的WAR时,Tomcat会引发异常。LifecycleException将Spring Boot WebSocket示例部署到Tomcat中

我正在开发使用Gradle 1.10的STS 3.4.0(在使用Eclipse中的Maven构建时,我以前没有成功部署后切换到此)。摇篮报告一个成功构建WAR文件,但是当我试图将其部署到Tomcat,以下异常被抛出:

09-Feb-2014 17:30:27.537 SEVERE [localhost-startStop-3] org.apache.catalina.core.ContainerBase.addChildInternal ContainerBase.addChild: start: 
org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/gs-messaging-stomp-websocket-0.1.0]] 
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154) 
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:726) 
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:702) 
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:699) 
    at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:977) 
    at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1763) 
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:262) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
    at java.lang.Thread.run(Thread.java:744) 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tomcatEmbeddedServletContainerFactory' defined in class path resource [org/springframework/boot/autoconfigure/websocket/WebSocketAutoConfiguration$TomcatWebSocketConfiguration.class]: Initialization of bean failed; nested exception is java.lang.ArrayStoreException: org.apache.catalina.valves.RemoteIpValve 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:547) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:700) 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760) 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482) 
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:124) 
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:658) 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:355) 
    at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:129) 
    at org.springframework.boot.web.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:90) 
    at org.springframework.boot.web.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:53) 
    at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:181) 
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5237) 
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) 
    ... 10 more 
Caused by: java.lang.ArrayStoreException: org.apache.catalina.valves.RemoteIpValve 
    at org.springframework.boot.autoconfigure.web.ServerProperties$Tomcat.customizeTomcat(ServerProperties.java:212) 
    at org.springframework.boot.autoconfigure.web.ServerProperties.customize(ServerProperties.java:117) 
    at org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizerBeanPostProcessor.postProcessBeforeInitialization(EmbeddedServletContainerCustomizerBeanPostProcessor.java:68) 
    at org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizerBeanPostProcessor.postProcessBeforeInitialization(EmbeddedServletContainerCustomizerBeanPostProcessor.java:54) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:407) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1545) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539) 
    ... 27 more 

我在Windows 8.1中的64位运行Tomcat 8.0.0-RC10。我相信相关的应用程序文件是这些:

Application.java:

包你好;

import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 
import org.springframework.context.annotation.ComponentScan; 
import org.springframework.context.annotation.Configuration; 

@Configuration 
@EnableAutoConfiguration 
@ComponentScan 
public class Application { 

    public static void main(String[] args) { 
     SpringApplication.run(Application.class, args); 
    } 
} 

HelloWebXml.java(代替实际的web.xml):

package hello; 

import org.springframework.boot.builder.SpringApplicationBuilder; 
import org.springframework.boot.web.SpringBootServletInitializer; 

public class HelloWebXml extends SpringBootServletInitializer { 

    @Override 
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { 
     return application.sources(Application.class); 
    } 

} 

,最后的build.gradle:

buildscript { 
    repositories { 
     maven { url "http://repo.spring.io/libs-snapshot" } 
     mavenLocal() 
    } 
    dependencies { 
     classpath("org.springframework.boot:spring-boot-gradle-plugin:1.0.0.RC1") 
    } 
} 

apply plugin: 'java' 
apply plugin: 'eclipse' 
apply plugin: 'idea' 
apply plugin: 'spring-boot' 
apply plugin: 'war' 

war { 
    baseName = 'gs-messaging-stomp-websocket' 
    version = '0.1.0' 
} 

repositories { 
    mavenCentral() 
    maven { url "http://repo.spring.io/libs-snapshot" } 
} 

dependencies { 
    compile("org.springframework.boot:spring-boot-starter-web:0.5.0.BUILD-SNAPSHOT") 
    compile("org.springframework.boot:spring-boot-starter-websocket:0.5.0.BUILD-SNAPSHOT") 
    compile("org.springframework:spring-messaging:4.0.0.RELEASE") 
    compile("com.fasterxml.jackson.core:jackson-databind") 
    testCompile("junit:junit:4.11") 
} 

task wrapper(type: Wrapper) { 
    gradleVersion = '1.10' 
} 

我必须说,我觉得很讽刺而且这个问题似乎与tomcatEmbeddedServletContainerFactory有关。因此,一个功能的唯一目的(我相信)是允许应用程序在servlet容器的外部运行---这是我完全没有兴趣的一项功能---阻止我正确地将应用程序部署到servlet容器中。

所有帮助将不胜感激。

回答

3

在Syer先生的回答(对不起,我试图upvote,但我太新来这个论坛),以及从this post关于如何标记资源为'提供'的信息,我终于得到这座大楼是我可以在Tomcat中成功部署的一场战争。

有点实验后,似乎有什么需要的是进行以下修改我的build.gradle:

configurations { 
    provided 
} 

sourceSets { 
    main.compileClasspath += configurations.provided 
    test.compileClasspath += configurations.provided 
    test.runtimeClasspath += configurations.provided 
} 

eclipse.classpath.plusConfigurations += configurations.provided 

dependencies { 
    compile("org.springframework.boot:spring-boot-starter-web:0.5.0.BUILD-SNAPSHOT") { 
     exclude module: 'spring-boot-starter-tomcat' 
    } 
    compile("org.springframework.boot:spring-boot-starter-websocket:0.5.0.BUILD-SNAPSHOT") { 
     exclude module: 'spring-boot-starter-tomcat' 
    } 

    provided group: 'org.springframework.boot', name: 'spring-boot-starter-tomcat', version: '0.5.0.BUILD-SNAPSHOT' 

    compile("org.springframework:spring-messaging:4.0.0.RELEASE") 
    compile("com.fasterxml.jackson.core:jackson-databind") 
    testCompile("junit:junit:4.11") 
} 

当我只引用了“排除模块”的变化,我得到了一个编译时间错误,抱怨说“没有找到javax.servlet.ServletException的类文件” - 这让我感到困惑,因为我相信这是我的Java 7 JDK的一部分。

当我仅应用“提供的组”更改时,实际上并没有从我的战争中删除spring-boot-starter-tomcat jar。

1

您需要使“提供”嵌入式tomcat依赖(现在,您在“编译”配置中具有spring-boot-starter-tomcat,可以通过spring-boot-starter-web传递)。如果你真的没有使用嵌入式服务器,你可以完全删除它。 Gradle具有标准的习惯用法,用于排除传递依赖关系,并将它们添加到不同的配置中,我相信。