-
Notifications
You must be signed in to change notification settings - Fork 75
Open
Labels
Description
Describe the bug
I've configured a basic Unleash
client in a Spring Boot application and when the hot reload triggers the background process crashes. The Configuration class is very simple and just setting the parameters (I'm using GitLab feature flags, so there is not api key needed).
I was able to stop the crashing by building our own UnleashScheduledExecutor
, but then we had multiple clients running in the background because they weren't being shutdown during the reload.
Steps to reproduce the bug
No response
Expected behavior
No response
Logs, error output, etc.
2025-07-18T05:41:11.031Z INFO 189 --- [example] [ restartedMain] i.g.repository.FeatureBackupHandlerFile : Unleash will try to load feature toggle states from temporary backup
2025-07-18T05:41:11.034Z ERROR 189 --- [example] [ restartedMain] i.g.util.UnleashScheduledExecutorImpl : Unleash background task crashed
java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask@70ae5d0a[Not completed, task = java.util.concurrent.Executors$RunnableAdapter@32432edc[Wrapped task = io.getunleash.repository.FeatureRepositoryImpl$$Lambda/0x000071686cb72198@344d5c9c]] rejected from java.util.concurrent.ScheduledThreadPoolExecutor@261362f3[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 1]
at java.base/java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2081) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:841) ~[na:na]
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute(ScheduledThreadPoolExecutor.java:340) ~[na:na]
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor.scheduleAtFixedRate(ScheduledThreadPoolExecutor.java:632) ~[na:na]
at io.getunleash.util.UnleashScheduledExecutorImpl.setInterval(UnleashScheduledExecutorImpl.java:43) ~[unleash-client-java-11.0.2.jar:11.0.2]
at io.getunleash.repository.FeatureRepositoryImpl.initCollections(FeatureRepositoryImpl.java:125) ~[unleash-client-java-11.0.2.jar:11.0.2]
at io.getunleash.repository.FeatureRepositoryImpl.<init>(FeatureRepositoryImpl.java:92) ~[unleash-client-java-11.0.2.jar:11.0.2]
at io.getunleash.repository.FeatureRepositoryImpl.<init>(FeatureRepositoryImpl.java:65) ~[unleash-client-java-11.0.2.jar:11.0.2]
at io.getunleash.repository.FeatureRepositoryImpl.<init>(FeatureRepositoryImpl.java:51) ~[unleash-client-java-11.0.2.jar:11.0.2]
at io.getunleash.repository.FeatureRepositoryImpl.<init>(FeatureRepositoryImpl.java:39) ~[unleash-client-java-11.0.2.jar:11.0.2]
at io.getunleash.repository.FeatureRepositoryImpl.<init>(FeatureRepositoryImpl.java:34) ~[unleash-client-java-11.0.2.jar:11.0.2]
at io.getunleash.EngineProxyImpl.<init>(EngineProxyImpl.java:38) ~[unleash-client-java-11.0.2.jar:11.0.2]
at io.getunleash.DefaultUnleash.defaultToggleRepository(DefaultUnleash.java:38) ~[unleash-client-java-11.0.2.jar:11.0.2]
at io.getunleash.DefaultUnleash.<init>(DefaultUnleash.java:42) ~[unleash-client-java-11.0.2.jar:11.0.2]
at com.example.config.UnleashConfiguration.unleash(UnleashConfiguration.java:39) ~[classes/:na]
at com.example.config.UnleashConfiguration$$SpringCGLIB$$0.CGLIB$unleash$0(<generated>) ~[classes/:na]
at com.example.config.UnleashConfiguration$$SpringCGLIB$$FastClass$$1.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:258) ~[spring-core-6.2.8.jar:6.2.8]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:400) ~[spring-context-6.2.8.jar:6.2.8]
at com.example.config.UnleashConfiguration$$SpringCGLIB$$0.unleash(<generated>) ~[classes/:na]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.lambda$instantiate$0(SimpleInstantiationStrategy.java:171) ~[spring-beans-6.2.8.jar:6.2.8]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiateWithFactoryMethod(SimpleInstantiationStrategy.java:88) ~[spring-beans-6.2.8.jar:6.2.8]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:168) ~[spring-beans-6.2.8.jar:6.2.8]
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653) ~[spring-beans-6.2.8.jar:6.2.8]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:489) ~[spring-beans-6.2.8.jar:6.2.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1375) ~[spring-beans-6.2.8.jar:6.2.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1205) ~[spring-beans-6.2.8.jar:6.2.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:569) ~[spring-beans-6.2.8.jar:6.2.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:529) ~[spring-beans-6.2.8.jar:6.2.8]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339) ~[spring-beans-6.2.8.jar:6.2.8]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:373) ~[spring-beans-6.2.8.jar:6.2.8]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337) ~[spring-beans-6.2.8.jar:6.2.8]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-6.2.8.jar:6.2.8]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1683) ~[spring-beans-6.2.8.jar:6.2.8]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1628) ~[spring-beans-6.2.8.jar:6.2.8]
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:913) ~[spring-beans-6.2.8.jar:6.2.8]
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ~[spring-beans-6.2.8.jar:6.2.8]
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:240) ~[spring-beans-6.2.8.jar:6.2.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1395) ~[spring-beans-6.2.8.jar:6.2.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1232) ~[spring-beans-6.2.8.jar:6.2.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:569) ~[spring-beans-6.2.8.jar:6.2.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:529) ~[spring-beans-6.2.8.jar:6.2.8]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:339) ~[spring-beans-6.2.8.jar:6.2.8]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:373) ~[spring-beans-6.2.8.jar:6.2.8]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:337) ~[spring-beans-6.2.8.jar:6.2.8]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-6.2.8.jar:6.2.8]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.instantiateSingleton(DefaultListableBeanFactory.java:1222) ~[spring-beans-6.2.8.jar:6.2.8]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingleton(DefaultListableBeanFactory.java:1188) ~[spring-beans-6.2.8.jar:6.2.8]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:1123) ~[spring-beans-6.2.8.jar:6.2.8]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:987) ~[spring-context-6.2.8.jar:6.2.8]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:627) ~[spring-context-6.2.8.jar:6.2.8]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.5.3.jar:3.5.3]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:752) ~[spring-boot-3.5.3.jar:3.5.3]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) ~[spring-boot-3.5.3.jar:3.5.3]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:318) ~[spring-boot-3.5.3.jar:3.5.3]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361) ~[spring-boot-3.5.3.jar:3.5.3]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350) ~[spring-boot-3.5.3.jar:3.5.3]
at com.example.Application.main(Application.java:10) ~[classes/:na]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:50) ~[spring-boot-devtools-3.5.3.jar:3.5.3]
Screenshots
No response
Additional context
package com.example.config;
import io.getunleash.DefaultUnleash;
import io.getunleash.util.UnleashConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@Slf4j
public class UnleashConfiguration {
@Value("${unleash.api-url}")
private String apiUrl;
@Value("${unleash.app-name}")
private String appName;
@Value("${unleash.instance-id}")
private String instanceId;
@Bean
public DefaultUnleash unleash() {
UnleashConfig config = UnleashConfig.builder()
.appName(appName)
.instanceId(instanceId)
.unleashAPI(apiUrl)
.synchronousFetchOnInitialisation(false)
.build();
return new DefaultUnleash(config);
}
}
Unleash version
GitLab feature flags feature - https://docs.gitlab.com/operations/feature_flags/
Subscription type
None
Hosting type
None
SDK information (language and version)
11.0.2
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
For later