AQ and Spring Integration - java.lang.IllegalStateException: No 'defaultDestination' or 'defaultDestinationName' specified - spring-boot

When trying to run an Spring Integration application on Weblogic and connect to AQ I am getting the following error:
2016-11-08 18:07:53.677 ERROR 12864 --- [ask-scheduler-7] o.s.integration.handler.LoggingHandler : java.lang.IllegalStateException: No 'defaultDestination' or 'defaultDestinationName' specified. Check configuration of JmsTe
mplate.
at org.springframework.jms.core.JmsTemplate.getRequiredDefaultDestinationName(JmsTemplate.java:216)
at org.springframework.jms.core.JmsTemplate.receiveSelected(JmsTemplate.java:738)
at org.springframework.integration.jms.JmsDestinationPollingSource.doReceiveJmsMessage(JmsDestinationPollingSource.java:141)
at org.springframework.integration.jms.JmsDestinationPollingSource.receive(JmsDestinationPollingSource.java:111)
at org.springframework.integration.endpoint.SourcePollingChannelAdapter.receiveMessage(SourcePollingChannelAdapter.java:209)
at org.springframework.integration.endpoint.AbstractPollingEndpoint.doPoll(AbstractPollingEndpoint.java:245)
at org.springframework.integration.endpoint.AbstractPollingEndpoint.access$000(AbstractPollingEndpoint.java:58)
at org.springframework.integration.endpoint.AbstractPollingEndpoint$1.call(AbstractPollingEndpoint.java:190)
at org.springframework.integration.endpoint.AbstractPollingEndpoint$1.call(AbstractPollingEndpoint.java:186)
at org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller$1.run(AbstractPollingEndpoint.java:353)
at org.springframework.integration.util.ErrorHandlingTaskExecutor$1.run(ErrorHandlingTaskExecutor.java:55)
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
at org.springframework.integration.util.ErrorHandlingTaskExecutor.execute(ErrorHandlingTaskExecutor.java:51)
at org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller.run(AbstractPollingEndpoint.java:344)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
This is my code:
#SpringBootApplication
#EnableIntegration
#IntegrationComponentScan
public class AQMessageProcessorApplication extends SpringBootServletInitializer implements WebApplicationInitializer {
private static final String DATAFLOW_ACDR = "urn:xeu:ec:fisheries:flux-bl:FLUX_ACDR_OtherReport:1:1";
private static final Logger logger = LoggerFactory.getLogger(AQMessageProcessorApplication.class);
#Autowired
private ConnectionFactory aqConnectionFactory;
#Autowired
private Destination aqAcdrQueue;
public static void main(String[] args) {
SpringApplication.run(AQMessageProcessorApplication.class, args);
}
#Bean
public IntegrationFlow aqAcdrInboundFlow() {
return IntegrationFlows
.from(
Jms.inboundAdapter(this.aqConnectionFactory)
.destination(aqQueue),
e -> e.poller( Pollers.fixedRate(100, TimeUnit.MILLISECONDS).maxMessagesPerPoll(100))
)
.enrich(e -> e
.requestPayload(Message::getPayload)
.shouldClonePayload(false)
)
.transform( message-> message )
.channel("entrypoint")
.get();
}
#Bean
public ConnectionFactory aqConnectionFactory() {
ConnectionFactory factory = null;
JndiTemplate jndi = new JndiTemplate();
try {
factory = (ConnectionFactory) jndi.lookup("jms/QCF");
} catch (NamingException e) {
logger.error("NamingException for jms/QCF", e);
}
return factory;
}
#Bean
public Destination aqWeblogicQueue() {
Destination destination = null;
JndiTemplate jndi = new JndiTemplate();
try {
destination = (Destination) jndi.lookup("jms/Q_TEST");
} catch (NamingException e) {
logger.error("NamingException for jms/Q_TEST ", e);
}
return destination;
}
}
I have tried this code with WebLogic queues and it worked no problem.
What silly thing am I missing here?
Regards!

Related

kafkaendpointlistenerregistry.start() throws null pointer exception

I have a requirement where I want to start Kakfa consumer manually.
Code :
class Dummy implements
ConsumerSeekAware
{
#Autowired
KafkaListenerEndpointRegistry registry;
CountDownLatch latch;
#Autowired
ConcurrentKafkaListenerContainerFactory factory;
onIdleEvent(){
latch.countdown()
}
#KafkaListener(id="myContainer",
topics="mytopic",
autoStartup="false")
public void listen() {}
#Scheduled(cron=" some time ")
void do_some_consumption(){
latch = new CountDownLatch(1);
this.registry.getListenerContainer("myContainer").start();
latch.await();
do processing
this.registry.getListenerContainer("myContainer").stop()
}
}
I have made the bean of
ConcurrentKafkaListenerContainerFactory with all props in my other Config class which I am Autowiring here.
However, I get a null pointer exception when I start my container
using this.registry.getListenerContainer("myContainer").start()
java.lang.NullPointerException: null
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:93)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
I just copied your code into a Spring Boot app (which auto configures the factories); and everything works perfectly as expected...
#SpringBootApplication
#EnableScheduling
public class So62412316Application {
public static void main(String[] args) {
SpringApplication.run(So62412316Application.class, args);
}
#Bean
public ApplicationRunner runner(KafkaTemplate<String, String> template) {
return args -> {
template.send("mytopic", "foo");
};
}
#Bean
public NewTopic topic() {
return TopicBuilder.name("mytopic").partitions(1).replicas(1).build();
}
}
#Component
class Dummy implements ConsumerSeekAware {
#Autowired
KafkaListenerEndpointRegistry registry;
CountDownLatch latch;
#Autowired
ConcurrentKafkaListenerContainerFactory factory;
#EventListener
public void onIdleEvent(ListenerContainerIdleEvent event) {
System.out.println(event);
latch.countDown();
}
#KafkaListener(id = "myContainer", topics = "mytopic", autoStartup = "false")
public void listen(String in) {
System.out.println(in);
}
#Scheduled(initialDelay = 5_000, fixedDelay = 60_000)
void do_some_consumption() throws InterruptedException {
latch = new CountDownLatch(1);
this.registry.getListenerContainer("myContainer").start();
latch.await();
this.registry.getListenerContainer("myContainer").stop();
}
}
spring.kafka.consumer.auto-offset-reset=earliest
spring.kafka.listener.idle-event-interval=5000

RSocketRequester doesn't consider datamimeType

Trying to use Protobuf with RSocket, Requester doesn't consider dataMimeType set to application/protobuf or application/vnd.google.protobuf. I get error No decoder
Client Application
#SpringBootApplication
#Slf4j
public class PersonServiceClientApplication {
#Bean
RSocketRequester rSocketRequester(RSocketStrategies rSocketStrategies) {
return RSocketRequester.builder()
.rsocketFactory(
factory -> factory.dataMimeType("application/protobuf").frameDecoder(PayloadDecoder.ZERO_COPY))
.rsocketStrategies(rSocketStrategies).connectTcp("localhost", 9080).retry().block();
}
#Bean
public RSocketStrategiesCustomizer protobufRSocketStrategyCustomizer() {
return (strategy) -> {
strategy.decoder(new ProtobufDecoder());
strategy.encoder(new ProtobufEncoder());
};
}
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(PersonServiceClientApplication.class, args);
RSocketRequester req = context.getBean(RSocketRequester.class);
req.route("io.github.kprasad99.person.get3").retrieveMono(Person.class)
.doOnNext(e -> log.info(e.getFirstName())).block(Duration.ofSeconds(30));
}
}
Stacktrace
Exception in thread "restartedMain" java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: java.lang.IllegalArgumentException: No decoder for io.github.kprasad.person.proto.PersonProto$Person
at org.springframework.messaging.rsocket.RSocketStrategies.decoder(RSocketStrategies.java:92)
at org.springframework.messaging.rsocket.DefaultRSocketRequester$DefaultRequestSpec.retrieveMono(DefaultRSocketRequester.java:274)
at org.springframework.messaging.rsocket.DefaultRSocketRequester$DefaultRequestSpec.retrieveMono(DefaultRSocketRequester.java:258)
at io.github.kprasad99.person.PersonServiceClientApplication.main(PersonServiceClientApplication.java:69)
... 5 more
However if I explicitly disable RSocketStrategiesAutoConfiguration, and recreate RSocketStrategies bean, it works.
SpringBootApplication(exclude = { RSocketStrategiesAutoConfiguration.class })
#Slf4j
public class PersonServiceClientApplication {
private static final String PATHPATTERN_ROUTEMATCHER_CLASS = "org.springframework.web.util.pattern.PathPatternRouteMatcher";
#Bean
public RSocketStrategies rSocketStrategies(ObjectProvider<RSocketStrategiesCustomizer> customizers) {
RSocketStrategies.Builder builder = RSocketStrategies.builder();
if (ClassUtils.isPresent(PATHPATTERN_ROUTEMATCHER_CLASS, null)) {
builder.routeMatcher(new PathPatternRouteMatcher());
}
customizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
return builder.build();
}
#Bean
RSocketRequester rSocketRequester(RSocketStrategies rSocketStrategies) {
return RSocketRequester.builder()
.rsocketFactory(
factory -> factory.dataMimeType("application/protobuf").frameDecoder(PayloadDecoder.ZERO_COPY))
.rsocketStrategies(rSocketStrategies).connectTcp("localhost", 9080).retry().block();
}
#Bean
public RSocketStrategiesCustomizer protobufRSocketStrategyCustomizer() {
return (strategy) -> {
strategy.decoder(new ProtobufDecoder());
strategy.encoder(new ProtobufEncoder());
};
}
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(PersonServiceClientApplication.class, args);
RSocketRequester req = context.getBean(RSocketRequester.class);
req.route("io.github.kprasad99.person.get3").retrieveMono(Person.class)
.doOnNext(e -> log.info(e.getFirstName())).block(Duration.ofSeconds(30));
}
}
Why neither dataMimeType nor protobufRSocketStrategyCustomizer bean considered why decoding.
Able to solve this, needed use application/x-protobuf. Below is the beans created for client.
#Bean
public Mono<RSocketRequester> rSocketRequester(
RSocketRequester.Builder rsocketRequesterBuilder, ClientTransport clientTransport,
RSocketStrategies strategies) {
Mono<RSocketRequester> rsocketRequester = rsocketRequesterBuilder.rsocketStrategies(strategies)
.dataMimeType(new MimeType("application", "x-protobuf"))
.connect(clientTransport).log();
return rsocketRequester;
}
#Bean
public RSocketStrategiesCustomizer protobufRSocketStrategyCustomizer() {
return (strategy) -> {
strategy.decoder(new ProtobufDecoder());
strategy.encoder(new ProtobufEncoder());
};
}

Introducing Spring Batch fails Dao-Test

I am using Spring Batch in a Spring Boot application as below. Spring Batch and the application seem to work fine with that configuration.
However, with that configuration for a simple Dao-Test (not for Spring Batch) I get the following exception. Without the Spring Batch configuration the test is running fine. Update: The problem appears if I configure to use an own JobRepository with a transaction manager (below in class MyBatchConfigurer).
I tried to provide another transaction manager for Spring Batch but I am running from exception to exception.
org.springframework.dao.InvalidDataAccessApiUsageException: no transaction is in progress; nested exception is javax.persistence.TransactionRequiredException: no transaction is in progress
Caused by: javax.persistence.TransactionRequiredException: no transaction is in progress
at org.hibernate.internal.SessionImpl.checkTransactionNeeded(SessionImpl.java:3505)
at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1427)
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1423)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:350)
at com.sun.proxy.$Proxy165.flush(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:305)
at com.sun.proxy.$Proxy165.flush(Unknown Source)
at com.foo.dao.GenericDao.save(GenericDao.java:60)
at com.foo.dao.GenericDao$$FastClassBySpringCGLIB$$71a0996b.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:746)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
... 37 more
Test Setup
#SpringBootTest
#RunWith(SpringRunner.class)
#EntityScan(basePackages = "com.foo.entity")
#DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
#TestPropertySource("/mytest.properties")
#Sql(executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD, scripts = "classpath:/testdata.sql")
public class MyTest {
#Inject
private OrderDao sut;
#Test
public void test_findByAnotherFieldId() {
final Order order = // build an order ...
sut.save(order);
final Order result = sut.findByAnotherFieldId("valueOfOtherField");
assertThat(result).isEqualTo(order);
}
}
Spring Batch Job configuration
#Configuration
#EnableBatchProcessing
#Import(OracleDatabaseConfig.class)
#ComponentScan(basePackageClasses = MyBatchConfigurer.class)
public class BatchJobConfig {
// Injects...
#Qualifier("analyseOrdersJob")
#Bean
public Job analyseOrdersJob() {
return jobBuilderFactory.get("analyseOrdersJob").start(analyseOrdersStep()).build();
}
#Bean
public Step analyseOrdersStep() {
return stepBuilderFactory.get("analyseOrdersStep").<Order, String>chunk(4)
.reader(orderItemReader) //
.processor(orderItemProcessor) //
.writer(orderItemWriter) //
.build();
}
}
Spring Batch configuration
#Component
public class MyBatchConfigurer extends DefaultBatchConfigurer {
#Inject
private DataSource dataSource;
#Override
public JobRepository getJobRepository() {
try {
return extractJobRepository();
} catch (final Exception e) {
throw new BatchConfigurationException(e);
}
}
private JobRepository extractJobRepository() throws Exception {
final JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
factory.setDataSource(dataSource);
factory.setTransactionManager(getTransactionManager());
factory.afterPropertiesSet();
return factory.getObject();
}
}
ItemReader
#Component
#StepScope
public class OrderItemReader implements ItemReader<Order> {
#Inject
private OrderDao orderdao;
private int nextOrderIndex;
private List<Order> orders;
#PostConstruct
public void postConstruct() {
orders = orderdao.findAll();
}
#Override
public Order read() {
if (nextOrderIndex < orders.size()) {
final Order order = orders.get(nextOrderIndex);
nextOrderIndex++;
return order;
}
return null;
}
}
ItemWriter and ItemProcessor are similarly configured.

WebSocket issue : Multiple Endpoints may not be deployed to the same path

i am building project in spring boot and i want to implement chat application logic into my project i am using websockets and here is my code
#SpringBootApplication
public class SamepinchApplication extends SpringBootServletInitializer{
#Bean
public EchoEndpoint echoEndpoint() {
return new EchoEndpoint();
}
#Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
#Bean
public ServletContextAware endpointExporterInitializer(final ApplicationContext applicationContext) {
return new ServletContextAware() {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(SamepinchApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(SamepinchApplication.class, args);
}
}
and EchoEndpoint
#ServerEndpoint(value = "/api/v1/chat/{username}")
public class EchoEndpoint {
private static final Logger log = LoggerFactory.getLogger(EchoEndpoint.class);
private static final Set<Session> sessionsSet = Collections.synchronizedSet(new HashSet<Session>());
private static final ConcurrentHashMap<String, Object> sessions = new ConcurrentHashMap<String, Object>();
#OnOpen
public void onWebSocketConnect(Session session, #PathParam("username") String uname) throws IOException {
session.getBasicRemote().sendText("Connection established with session id "+session.getId());
sessionsSet.add(session);
sessions.put(uname, session);
System.out.println("Connected with: " + session.getId());
log.info("Connected with: " + session.getId());
}
#OnMessage
public void onWebSocketMessage(Session session, String message) throws IOException {
System.out.println("getting message......");
System.out.println(message.substring(message.indexOf(":",0)+1));
String[] mesgArray = message.split(":");
System.out.println(mesgArray[0]);
Session sess = (Session) sessions.get(mesgArray[0]);
if(sess != null)
sess.getBasicRemote().sendText(message.substring(message.indexOf(":",0)+1));
// sendMessageToAll(message);
}
#OnClose
public void onWebSocketClose(Session session) {
System.out.println("Closed: " + session.getId());
log.info("Closed: " + session.getId());
}
#OnError
public void onWebSocketError(Session session, Throwable error) {
System.out.println("Error (from " + session.getId() + "): " + error.getMessage());
log.info("Error (from " + session.getId() + "): " + error.getMessage());
}
private void sendMessageToAll(String message){
for(Session s : sessionsSet){
try {
log.info("send from qasim siddiqui");
log.info(s.getId());
s.getBasicRemote().sendText(message);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
this code is working fine when i am running code in ecllipse but when i deployed it to tomcat it gives me this exception
SEVERE: ContainerBase.addChild: start:
org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/samepinch-0.0.1-SNAPSHOT]]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
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:652)
at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1095)
at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1930)
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:745)
Caused by: java.lang.IllegalStateException: Failed to register #ServerEndpoint class: class com.samepinch.socket.EchoEndpoint
at org.springframework.web.socket.server.standard.ServerEndpointExporter.registerEndpoint(ServerEndpointExporter.java:148)
at org.springframework.web.socket.server.standard.ServerEndpointExporter.registerEndpoints(ServerEndpointExporter.java:129)
at org.springframework.web.socket.server.standard.ServerEndpointExporter.afterSingletonsInstantiated(ServerEndpointExporter.java:107)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:775)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
at org.springframework.boot.context.web.SpringBootServletInitializer.run(SpringBootServletInitializer.java:117)
at org.springframework.boot.context.web.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:108)
at org.springframework.boot.context.web.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:68)
at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:175)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5517)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
... 10 more
Caused by: javax.websocket.DeploymentException: Multiple Endpoints may not be deployed to the same path [/api/v1/chat/{username}]
at org.apache.tomcat.websocket.server.WsServerContainer.addEndpoint(WsServerContainer.java:199)
at org.apache.tomcat.websocket.server.WsServerContainer.addEndpoint(WsServerContainer.java:271)
at org.springframework.web.socket.server.standard.ServerEndpointExporter.registerEndpoint(ServerEndpointExporter.java:145)
... 24 more
on tomcat it tries to create multiple endpoints and i am not getting any solution . Can anybody help me!
i am using this dependency for websocket
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
you remove
#Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
Tomcat not need this
You are creating multiple end points in production,you should need echo end point in development not in production..so configure according to the environment
if (Environment.current == Environment.DEVELOPMENT) {
// then create echo point
}

Injecting a bean at startup in Spring

I have a class RunBackgroundServices which runs some background services at startup. I need a new object BackgroundServices in it. So I am using WebApplicationContext to get the bean. But it's not working.
RunBackgroundServices.java
#WebListener
public class RunBackgroundServices implements ServletContextListener {
private ExecutorService executor;
public void contextInitialized(ServletContextEvent event) {
final WebApplicationContext springContext = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
BackgroundServices backgroundServices = springContext.getBean(BackgroundServices.class);
executor = Executors.newSingleThreadExecutor();
executor.submit(backgroundServices); // Task should implement Runnable.
}
public void contextDestroyed(ServletContextEvent event) {
executor.shutdown();
}
}
BackgroundServices.java
#Service
public class BackgroundServices extends Thread {
#Autowired
ServerListener serverListener;
#Autowired
ClientListener clientListener;
private static final Logger logger = LoggerFactory
.getLogger(BackgroundServices.class);
public void run() {
logger.debug("BackgroundServices :: run");
try {
serverListener.start();
} catch (InterruptedException e) {
logger.error(e.getStackTrace().toString());
}
try {
clientListener.start();
} catch (InterruptedException e) {
logger.error(e.getStackTrace().toString());
}
}
}
I am getting the following error -
Exception sending context initialized event to listener instance of class com.emc.hl7.common.RunBackgroundServices
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.emc.hl7.common.BackgroundServices] is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:295)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1125)
at com.emc.hl7.common.RunBackgroundServices.contextInitialized(RunBackgroundServices.java:20)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4961)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5455)
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:634)
at org.apache.catalina.startup.HostConfig.deployDescriptor(HostConfig.java:671)
at org.apache.catalina.startup.HostConfig$DeployDescriptor.run(HostConfig.java:1840)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
There is an easier way to perform bootstraping operations using Spring.
All you have to do is have Spring bean that implements ApplicationListener<ContextRefreshedEvent>
Your code would look like:
#Component
public class ContextStartupListener implements ApplicationListener<ContextRefreshedEvent> {
private final BackgroundServices backgroundServices;
private ExecutorService executor;
#Autowired
public ContextStartupListener(BackgroundServices backgroundServices) {
this.backgroundServices= backgroundServices;
}
#Override
public void onApplicationEvent(ContextRefreshedEvent event) {
if(!isRootApplicationContext(event)) {
return;
}
executor = Executors.newSingleThreadExecutor();
executor.submit(backgroundServices);
}
private boolean isRootApplicationContext(ContextRefreshedEvent event) {
return null == event.getApplicationContext().getParent();
}
}
Note the use of isRootApplicationContext. It is needed if you have multiple application contexts and do no want to run the bootstrapping operation on each one.
Using the above code you are bootstrapping using Spring's events, not the Servlet container's events.

Resources