2014-11-20 114 views
1

我有一個具有websocket端點的Grails應用程序,它在開發過程中工作得非常好。我試圖部署到Tomcat,但由於某種原因,我每次部署時收到以下堆棧跟蹤從Tomcat:將Grails應用程序部署到Tomcat時發生javax.websocket.DeploymentException

SEVERE: Exception sending context initialized event to listener instance of class my.package.MyServletChatListenerAnnotated 
javax.websocket.DeploymentException: Multiple Endpoints may not be deployed to the same path [/chatroomServerEndpoint] 
    at org.apache.tomcat.websocket.server.WsServerContainer.addEndpoint(WsServerContainer.java:207) 
    at org.apache.tomcat.websocket.server.WsServerContainer.addEndpoint(WsServerContainer.java:271) 
    at javax.websocket.server.ServerContainer$addEndpoint.call(Unknown Source) 
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45) 
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108) 
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116) 
    at grails.websocket.example.MyServletChatListenerAnnotated.contextInitialized(MyServletChatListenerAnnotated.groovy:36) 
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4994) 
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5492) 
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) 
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901) 
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877) 
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:649) 
    at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1081) 
    at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:553) 
    at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1668) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:606) 
    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:301) 
    at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:819) 
    at com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:801) 
    at org.apache.catalina.manager.ManagerServlet.check(ManagerServlet.java:1480) 
    at org.apache.catalina.manager.HTMLManagerServlet.upload(HTMLManagerServlet.java:286) 
    at org.apache.catalina.manager.HTMLManagerServlet.doPost(HTMLManagerServlet.java:206) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:646) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
    at org.apache.catalina.filters.CsrfPreventionFilter.doFilter(CsrfPreventionFilter.java:213) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
    at org.apache.catalina.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:108) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:612) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) 
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421) 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611) 
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1736) 
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1695) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
    at java.lang.Thread.run(Thread.java:745) 

我沒有多個端點,因爲這是我部署的唯一WAR文件。這裏是我的類的結構如下圖所示:我已經註冊了偵聽器在我web.xml文件

@WebListener 
@ServerEndpoint("/chatroomServerEndpoint") 
public class MyServletChatListenerAnnotated implements ServletContextListener { 

    private final Logger log = LoggerFactory.getLogger(getClass().name) 

    @Override 
    public void contextInitialized(ServletContextEvent sce) { 
    ServletContext servletContext = sce.servletContext 
    ServerContainer serverContainer = (ServerContainer) servletContext.getAttribute("javax.websocket.server.ServerContainer") 
    try { 
     serverContainer.addEndpoint(MyServletChatListenerAnnotated) 
     ApplicationContext ctx = (ApplicationContext) servletContext.getAttribute(GA.APPLICATION_CONTEXT) 
     GrailsApplication grailsApplication = ctx.grailsApplication 
     ConfigObject config = grailsApplication.config 
     Integer defaultMaxSessionIdleTimeout = config.myservlet.timeout ?: 0 
     serverContainer.defaultMaxSessionIdleTimeout = defaultMaxSessionIdleTimeout 
    } catch (IOException e) { 
     log.error(e.message, e) 
    } 
    } 

    @Override 
    public void contextDestroyed(ServletContextEvent servletContextEvent) { 
    // ... 
    } 

    @OnOpen 
    public void handleOpen(Session userSession) { 
    // ... 
    } 

    @OnMessage 
    public String handleMessage(String message, Session userSession) throws IOException { 
    // ... 
    } 

    @OnClose 
    public void handleClose(Session userSession) { 
    // ... 
    } 

    @OnError 
    public void handleError(Throwable t) { 
    log.error("An error occurred.", t) 
    } 
} 

<listener> 
    <listener-class>my.package.MyServletChatListenerAnnotated</listener-class> 
</listener> 

我使用Grails 2.4.4,Tomcat的7.0.57上Ubuntu 14.04和Java 7u72,所有這些的最新版本。

我也試着部署這個例子(也可以工作在開發中): https://github.com/vahidhedayati/grails-websocket-example

我收到完全相同的錯誤。有誰知道爲什麼會發生這種情況?我顯然不想嘗試部署多個端點。

回答

2

我解決了這個問題。的contextInitialized第四行:

serverContainer.addEndpoint(MyServletChatListenerAnnotated) 

試圖添加端點第二次。似乎Grails在開發中需要添加該端點,但Tomcat會根據@ServerEndpoint註釋添加端點。將此行包裝在:

if (Environment.current == Environment.DEVELOPMENT) { 
    serverContainer.addEndpoint(MyServletChatListenerAnnotated) 
} 

解決開發和生產中的問題。

+0

我遇到了'spring-mvc'應用程序的類似問題。什麼軟件包包含'Environment'類? – bachr 2014-11-30 13:09:13

+0

['Environment'](http://grails.org/doc/2.4.x/api/grails/util/Environment.html)類特定於Grails。我相信Spring雖然具有環境配置文件形式的一些類似功能。 – Casey 2014-11-30 13:54:48