Все работает нормально при использовании учебника для начинающих, описанного в Справочнике CometD. Версии Spring, CometD и Jetty гармонируют друг с другом.
Теперь я (новичок с весенней загрузкой) хочу настроить веб-приложение Spring Boot (версия 1.5.4) с CometD (версия 3.1.2). И я также хочу выполнить настройку с помощью аннотаций без web.xml, как указано здесь.
Для этого я нашел проект github «Livechat», который предоставляет «Пример того, как подготовить WebsocketConfiguration» для CometD в проекте Spring Boot — мне не удалось его запустить.
Все мои попытки не смогли запустить простое загрузочное приложение Spring с аннотированной конфигурацией CometD.
Итак, я прошу помощи в настройке приложения Spring Boot:
- на основе версии 1.5.4
- CometD (версия 3.1.2)
- Работает на обоих: причал 9.x и tomcat (если возможно)
- Использование аннотаций вместо web.xml
Вот основное исключение, которое я получил во время своих тестов: 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
Веб-приложение.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 (как описано в «Справочнике CometD», глава «9.3.3.26. Конфигурация Spring на основе аннотаций»):
@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>
ServletContext
еще не доступен. Это отличается от обычного Spring (и документации CometD, на которую вы ссылаетесь), потому что вы обычно запускаете контейнер Servlet и, следовательно,ServletContext
before Spring. Я не знаю, есть ли способ сообщить Spring Boot разрешить bean-компоненты после запуска встроенного контейнера сервлетов. - person sbordet   schedule 06.07.2017web.xml
). - person sbordet   schedule 09.07.2017