"Missing ServletContext" in CometD configuration (version 3.1.2) using Spring Boot Web Application (version 1.5.4)

Viewed 581

Everything works fine when using the primer described in the CometD Reference Book. The versions of Spring, CometD and Jetty harmonizing together.

Now, I (a spring boot newbie) want to setup a Spring Boot Web Application (version 1.5.4) with CometD (version 3.1.2). And I also want to do the configuration via annotations without web.xml as mentioned here.

For that I found the github project "Livechat" which provides an "Example how to prepare the WebsocketConfiguration" for CometD in a Spring Boot project - I wasn't able to get it running.

All my attempts failed to get a simple spring boot application running with an annotated CometD configuration.

So, I ask for help, to setup a Spring Boot Application:

  • based on version 1.5.4
  • CometD (version 3.1.2)
  • Working on both: jetty 9.x and tomcat (if possible)
  • Using annotations instead of web.xml

Here is the main exception I got during my tests: Missing ServletContext

Caused by: java.lang.IllegalArgumentException: Missing ServletContext
at org.cometd.websocket.server.WebSocketTransport.init(WebSocketTransport.java:60) ~[cometd-java-websocket-javax-server-3.1.2.jar:na]
at org.cometd.server.BayeuxServerImpl.initializeServerTransports(BayeuxServerImpl.java:255) ~[cometd-java-server-3.1.2.jar:na]
at org.cometd.server.BayeuxServerImpl.doStart(BayeuxServerImpl.java:135) ~[cometd-java-server-3.1.2.jar:na]
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68) ~[jetty-util-9.4.6.v20170531.jar:9.4.6.v20170531]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_121]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_121]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_121]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_121]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeCustomInitMethod(AbstractAutowireCapableBeanFactory.java:1758) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1695) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624) ~[spring-beans-4.3.9.RELEASE.jar:4.3.9.RELEASE]
... 29 common frames omitted

WebApplication.java:

@ComponentScan
@SpringBootApplication
@EnableScheduling
public class WebApplication extends SpringBootServletInitializer implements WebApplicationInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(WebApplication.class);
    }

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

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        super.onStartup(servletContext);
    }
}

CometDConfiguration.java (as described in the "CometD Reference Book" chapter "9.3.3.26. Annotation Based Spring Configuration":

@Component
public class CometDConfiguration implements DestructionAwareBeanPostProcessor, ServletContextAware {
    private BayeuxServer bayeuxServer;
    private ServerAnnotationProcessor processor;

    @Inject
    private void setBayeuxServer(BayeuxServer bayeuxServer) {
        this.bayeuxServer = bayeuxServer;
    }

    @PostConstruct
    private void init() {
        this.processor = new ServerAnnotationProcessor(bayeuxServer);
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
        processor.processDependencies(bean);
        processor.processConfigurations(bean);
        processor.processCallbacks(bean);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String name) throws BeansException {
        return bean;
    }

    @Override
    public boolean requiresDestruction(Object bean) {
        return true;
    }

    @Override
    public void postProcessBeforeDestruction(Object bean, String name) throws BeansException {
        processor.deprocessCallbacks(bean);
    }

    @Bean(initMethod = "start", destroyMethod = "stop")
    public BayeuxServer bayeuxServer() {
        BayeuxServerImpl bean = new BayeuxServerImpl();
//        bean.setOption(BayeuxServerImpl.LOG_LEVEL, "3");
        return bean;
    }

    @Override
    public void setServletContext(ServletContext servletContext) {
        servletContext.setAttribute(BayeuxServer.ATTRIBUTE, bayeuxServer);
    }
}

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.4.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <cometd-version>3.1.2</cometd-version>
        <jetty-version>9.4.6.v20170531</jetty-version>
    </properties>

    <dependencies>

        <!-- Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- JSP and JSTL SUPPORT -->
        <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>jstl</artifactId>
                <scope>provided</scope>
        </dependency>

        <!-- Cometd dependencies -->
        <dependency>
            <groupId>org.cometd.java</groupId>
            <artifactId>bayeux-api</artifactId>
            <version>${cometd-version}</version>
        </dependency>
        <dependency>
            <groupId>org.cometd.javascript</groupId>
            <artifactId>cometd-javascript-jquery</artifactId>
            <version>${cometd-version}</version>
            <type>war</type>
        </dependency>
        <dependency>
            <groupId>org.cometd.java</groupId>
            <artifactId>cometd-java-server</artifactId>
            <version>${cometd-version}</version>
        </dependency>
        <dependency>
            <groupId>org.cometd.java</groupId>
            <artifactId>cometd-java-websocket-javax-server</artifactId>
            <version>${cometd-version}</version>
        </dependency>
        <dependency>
            <groupId>org.cometd.java</groupId>
            <artifactId>cometd-java-annotations</artifactId>
            <version>${cometd-version}</version>
        </dependency>
        <dependency>
            <groupId>org.cometd.java</groupId>
            <artifactId>cometd-java-oort</artifactId>
            <version>${cometd-version}</version>
        </dependency>

        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-util</artifactId>
            <version>${jetty-version}</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-util-ajax</artifactId>
            <version>${jetty-version}</version>
        </dependency>

        <dependency>
          <groupId>org.eclipse.jetty</groupId>
          <artifactId>apache-jstl</artifactId>
          <version>${jetty-version}</version>
          <type>pom</type>
        </dependency>
        <dependency>
          <groupId>org.eclipse.jetty</groupId>
          <artifactId>apache-jsp</artifactId>
          <version>${jetty-version}</version>
          <type>jar</type>
    </dependency>       

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.25</version>
        </dependency>


    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>

                <configuration>
                    <scanIntervalSeconds>10</scanIntervalSeconds>
                    <webAppConfig>
                        <contextPath>/cometd-primer</contextPath>
                    </webAppConfig>
                </configuration>
            </plugin>
        </plugins>
    </build>


</project>
0 Answers
Related