Skip to content

[Feature]: Implement Spring Lifecyle #428

@AndreKoepke

Description

@AndreKoepke

Feature Description

It would be great, when this repository implements Spring Lifecycle for its beans.

The lifecycle-interface looks like

public interface Lifecycle {
    void start();

    void stop();

    boolean isRunning();
}

and allows to start and stop beans at runtime. This is important for CRaC.

Use Case

We tried to use CRaC and noticed that the creation of a checkpoint failed, because the sockets to Solace are still open.

See the stracktrace to identify places.

An exception during a checkpoint operation:
jdk.internal.crac.mirror.CheckpointException
	Suppressed: sun.nio.ch.EPollSelectorImpl$BusySelectorException: Selector sun.nio.ch.EPollSelectorImpl@7534785a has registered keys from channels: [java.nio.channels.SocketChannel[connected local=/192.168.5.1:53678 remote=broker.solace.cloud/10.241.78.37:55443]]
		at java.base/sun.nio.ch.EPollSelectorImpl.beforeCheckpoint(EPollSelectorImpl.java:411)
		at java.base/jdk.internal.crac.mirror.impl.AbstractContext.invokeBeforeCheckpoint(AbstractContext.java:43)
		at java.base/jdk.internal.crac.mirror.impl.AbstractContext.beforeCheckpoint(AbstractContext.java:58)
		at java.base/jdk.internal.crac.mirror.impl.BlockingOrderedContext.beforeCheckpoint(BlockingOrderedContext.java:64)
		at java.base/jdk.internal.crac.mirror.impl.AbstractContext.invokeBeforeCheckpoint(AbstractContext.java:43)
		at java.base/jdk.internal.crac.mirror.impl.AbstractContext.beforeCheckpoint(AbstractContext.java:58)
		at java.base/jdk.internal.crac.mirror.Core.checkpointRestore1(Core.java:154)
		at java.base/jdk.internal.crac.mirror.Core.checkpointRestore(Core.java:313)
		at java.base/jdk.internal.crac.mirror.Core.checkpointRestoreInternal(Core.java:326)
	Suppressed: jdk.internal.crac.mirror.impl.CheckpointOpenSocketException: EPoll FD 8 left open in sun.nio.ch.EPollSelectorImpl@7534785a with registered keys.
		at java.base/sun.nio.ch.EPollSelectorImpl.lambda$claimFd$0(EPollSelectorImpl.java:423)
		at java.base/jdk.internal.crac.mirror.Core.checkpointRestore1(Core.java:170)
		at java.base/jdk.internal.crac.mirror.Core.checkpointRestore(Core.java:313)
		at java.base/jdk.internal.crac.mirror.Core.checkpointRestoreInternal(Core.java:326)
	Suppressed: jdk.internal.crac.mirror.impl.CheckpointOpenSocketException: EPoll Event FD 9 left open in sun.nio.ch.EPollSelectorImpl@7534785a with registered keys.
		at java.base/sun.nio.ch.EPollSelectorImpl.lambda$claimFd$0(EPollSelectorImpl.java:423)
		at java.base/jdk.internal.crac.mirror.Core.checkpointRestore1(Core.java:170)
		at java.base/jdk.internal.crac.mirror.Core.checkpointRestore(Core.java:313)
		at java.base/jdk.internal.crac.mirror.Core.checkpointRestoreInternal(Core.java:326)
	Suppressed: jdk.internal.crac.mirror.impl.CheckpointOpenSocketException: java.nio.channels.SocketChannel[connected local=/192.168.5.1:53678 remote=broker.solace.cloud/10.241.78.37:55443]
		at java.base/jdk.internal.crac.JDKSocketResourceBase.lambda$beforeCheckpoint$0(JDKSocketResourceBase.java:69)
		at java.base/jdk.internal.crac.mirror.Core.checkpointRestore1(Core.java:170)
		at java.base/jdk.internal.crac.mirror.Core.checkpointRestore(Core.java:313)
		at java.base/jdk.internal.crac.mirror.Core.checkpointRestoreInternal(Core.java:326)
	Caused by: java.lang.Exception: This file descriptor was created by main at epoch:1763472339057 here
		at java.base/jdk.internal.crac.JDKFdResource.<init>(JDKFdResource.java:65)
		at java.base/jdk.internal.crac.JDKSocketResourceBase.<init>(JDKSocketResourceBase.java:45)
		at java.base/jdk.internal.crac.JDKSocketResource.<init>(JDKSocketResource.java:40)
		at java.base/sun.nio.ch.SocketChannelImpl$Resource.<init>(SocketChannelImpl.java:1551)
		at java.base/sun.nio.ch.SocketChannelImpl.<init>(SocketChannelImpl.java:85)
		at java.base/sun.nio.ch.SocketChannelImpl.<init>(SocketChannelImpl.java:138)
		at java.base/sun.nio.ch.SelectorProviderImpl.openSocketChannel(SelectorProviderImpl.java:77)
		at io.netty.channel.socket.nio.NioSocketChannel.newChannel(NioSocketChannel.java:71)
		at io.netty.channel.socket.nio.NioSocketChannel.<init>(NioSocketChannel.java:95)
		at io.netty.channel.socket.nio.NioSocketChannel.<init>(NioSocketChannel.java:88)
		at io.netty.channel.socket.nio.NioSocketChannel.<init>(NioSocketChannel.java:81)
		at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
		at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
		at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
		at io.netty.channel.ReflectiveChannelFactory.newChannel(ReflectiveChannelFactory.java:44)
		at io.netty.bootstrap.AbstractBootstrap.initAndRegister(AbstractBootstrap.java:326)
		at io.netty.bootstrap.Bootstrap.doResolveAndConnect(Bootstrap.java:164)
		at io.netty.bootstrap.Bootstrap.connect(Bootstrap.java:125)
		at com.solace.transport.impl.netty.NettySolTransport.open(NettySolTransport.java:333)
		at com.solacesystems.jcsmp.protocol.smf.SimpleSmfClient.createOpenTransportAdapter(SimpleSmfClient.java:1373)
		at com.solacesystems.jcsmp.protocol.smf.SimpleSmfClient.open(SimpleSmfClient.java:853)
		at com.solacesystems.jcsmp.protocol.smf.SimpleSmfClient.sendLoginRequestAwaitForResponse(SimpleSmfClient.java:295)
		at com.solacesystems.jcsmp.protocol.impl.TcpChannel.sendLoginRequestWaitForLoginResponse(TcpChannel.java:198)
		at com.solacesystems.jcsmp.protocol.impl.ChannelOpStrategyClient.performOpen(ChannelOpStrategyClient.java:98)
		at com.solacesystems.jcsmp.protocol.impl.TcpClientChannel.performOpenSingle(TcpClientChannel.java:397)
		at com.solacesystems.jcsmp.protocol.impl.TcpClientChannel.access$1000(TcpClientChannel.java:132)
		at com.solacesystems.jcsmp.protocol.impl.TcpClientChannel$ClientChannelConnect.call(TcpClientChannel.java:2672)
		at com.solacesystems.jcsmp.protocol.impl.TcpClientChannel.open(TcpClientChannel.java:376)
		at com.solacesystems.jcsmp.impl.JCSMPBasicSession.sniffRouter(JCSMPBasicSession.java:442)
		at com.solacesystems.jcsmp.impl.JCSMPBasicSession.connect(JCSMPBasicSession.java:1307)
		at com.solace.spring.cloud.stream.binder.config.SolaceMessageChannelBinderConfiguration.initSession(SolaceMessageChannelBinderConfiguration.java:77)
		at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
		at java.base/java.lang.reflect.Method.invoke(Method.java:580)
		at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMethod.invoke(InitDestroyAnnotationBeanPostProcessor.java:457)
		at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:401)
		at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:219)
		at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:429)
		at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1818)
		at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:607)
		at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:529)
		at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339)
		at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:373)
		at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337)
		at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
		at org.springframework.beans.factory.support.DefaultListableBeanFactory.instantiateSingleton(DefaultListableBeanFactory.java:1228)
		at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingleton(DefaultListableBeanFactory.java:1194)
		at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:1130)
		at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:990)
		at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:627)
		at org.springframework.cloud.stream.binder.DefaultBinderFactory.initializeBinderContextSimple(DefaultBinderFactory.java:534)
		at org.springframework.cloud.stream.binder.DefaultBinderFactory.getBinderInstance(DefaultBinderFactory.java:384)
		at org.springframework.cloud.stream.binder.DefaultBinderFactory.doGetBinderConventional(DefaultBinderFactory.java:325)
		at org.springframework.cloud.stream.binder.DefaultBinderFactory.doGetBinder(DefaultBinderFactory.java:214)
		at org.springframework.cloud.stream.binder.DefaultBinderFactory.getBinder(DefaultBinderFactory.java:197)
		at org.springframework.cloud.stream.binding.BindingService.getBinder(BindingService.java:422)
		at org.springframework.cloud.stream.binding.BindingService.bindConsumer(BindingService.java:110)
		at org.springframework.cloud.stream.binding.AbstractBindableProxyFactory.createAndBindInputs(AbstractBindableProxyFactory.java:99)
		at org.springframework.cloud.stream.binding.InputBindingLifecycle.doStartWithBindable(InputBindingLifecycle.java:59)
		at java.base/java.util.LinkedHashMap$LinkedValues.forEach(LinkedHashMap.java:833)
		at org.springframework.cloud.stream.binding.AbstractBindingLifecycle.start(AbstractBindingLifecycle.java:60)
		at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:405)
		at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:394)
		at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:586)
		at java.base/java.lang.Iterable.forEach(Iterable.java:75)
		at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:364)
		at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:310)
		at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:1009)
		at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:630)
		at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
		at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752)
		at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439)
		at org.springframework.boot.SpringApplication.run(SpringApplication.java:318)
		at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361)
		at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350)
		at com.example.spring_boot_crac_solace.SpringBootCracSolaceApplication.main(SpringBootCracSolaceApplication.java:10)
		at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
		at java.base/java.lang.reflect.Method.invoke(Method.java:580)
		at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:106)
		at org.springframework.boot.loader.launch.Launcher.launch(Launcher.java:64)
		at org.springframework.boot.loader.launch.JarLauncher.main(JarLauncher.java:40)

Seems to be related to #3062, but only for Solace.

To Reproduce
We created a Demo-Project (thanks @tuxmatta).

  1. Checkout https://github.com/tuxmatta/spring-boot-crac-solace
  2. Configure a Solace-Broker in docker-compose.yml.
  3. Run do_example.sh

Proposed Solution

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions