TestContainers、Couchbase 和 Spring Boot - ScheduledFutureTask 被 ScheduledThreadPoolExecutor 拒绝
TestContainers, Couchbase & Spring Boot - ScheduledFutureTask rejected from ScheduledThreadPoolExecutor
我们正在为我们的 Spring Boot 2.1.7.RELEASE
和 Couchbase
数据库创建集成测试。
我们正在使用 testcontainers 并且在测试完成后出现此错误 运行ning:
java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask@da0432 rejected from java.util.concurrent.ScheduledThreadPoolExecutor@238be2[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0]
在我们的 pom 中:
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>couchbase</artifactId>
<version>1.12.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>1.12.1</version>
<scope>test</scope>
</dependency>
在我们的 'Integration test config' class:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {MyApplication.class, IntegrationTestConfig.CouchbaseTestConfig.class},
webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public abstract class IntegrationTestConfig{
@ClassRule
public static CouchbaseContainer couchbaseContainer = new CouchbaseContainer()
.withIndex(true)
.withQuery(true)
.withClusterAdmin("clusterUser", "clusterPassword")
.withNewBucket(DefaultBucketSettings.builder()
.enableFlush(true)
.name("bucketName")
.password("bucketPassword")
.quota(100)
.replicas(0)
.type(BucketType.COUCHBASE)
.build());
@BeforeClass
public static void beforeClass() throws IOException{
log.debug("Starting containers...");
couchbaseContainer.start();
}
@AfterClass
public static void afterClass(){
log.debug("Stopping containers...");
couchbaseContainer.stop();
}
在我们的 IntegrationTest
class:
public class MyIntegrationTest extends IntegrationTestConfig{
@LocalServerPort
private int port;
@Test
public void testSomething(){
....
}
当尝试 运行 集成测试时,我们在控制台中看到:
ℹ︎ Checking the system...
✔ Docker version should be at least 1.6.0
✔ Docker environment should have more than 2GB free disk space
然后我们在控制台中得到这个一两秒钟:
DEBUG [IntegrationTestConfig] - Starting containers...
DEBUG [IntegrationTestConfig] - Stopping containers...
然后我们得到这个错误:
java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask@d87cbb rejected from java.util.concurrent.ScheduledThreadPoolExecutor@1486dd9[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0]
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830)
at java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute(ScheduledThreadPoolExecutor.java:326)
at java.util.concurrent.ScheduledThreadPoolExecutor.schedule(ScheduledThreadPoolExecutor.java:533)
at java.util.concurrent.ScheduledThreadPoolExecutor.submit(ScheduledThreadPoolExecutor.java:632)
at rx.internal.schedulers.NewThreadWorker.scheduleActual(NewThreadWorker.java:277)
at com.couchbase.client.core.env.CoreScheduler$EventLoopWorker.schedule(CoreScheduler.java:174)
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.schedule(OperatorObserveOn.java:188)
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.request(OperatorObserveOn.java:145)
at rx.Subscriber.setProducer(Subscriber.java:211)
at rx.internal.operators.OnSubscribeMap$MapSubscriber.setProducer(OnSubscribeMap.java:102)
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.init(OperatorObserveOn.java:139)
at rx.internal.operators.OperatorObserveOn.call(OperatorObserveOn.java:75)
at rx.internal.operators.OperatorObserveOn.call(OperatorObserveOn.java:40)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:44)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
at rx.Observable.unsafeSubscribe(Observable.java:10327)
at rx.internal.operators.OnSubscribeMap.call(OnSubscribeMap.java:48)
at rx.internal.operators.OnSubscribeMap.call(OnSubscribeMap.java:33)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
at rx.Observable.unsafeSubscribe(Observable.java:10327)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30)
at rx.Observable.unsafeSubscribe(Observable.java:10327)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30)
at rx.Observable.subscribe(Observable.java:10423)
at rx.Observable.subscribe(Observable.java:10390)
at com.couchbase.client.core.utils.Blocking.blockForSingle(Blocking.java:70)
at com.couchbase.client.java.CouchbaseCluster.disconnect(CouchbaseCluster.java:417)
at com.couchbase.client.java.CouchbaseCluster.disconnect(CouchbaseCluster.java:412)
at org.testcontainers.couchbase.CouchbaseContainer.stopCluster(CouchbaseContainer.java:198)
at org.testcontainers.couchbase.CouchbaseContainer.stop(CouchbaseContainer.java:193)
at org.testcontainers.containers.GenericContainer.finished(GenericContainer.java:829)
at org.testcontainers.containers.FailureDetectingExternalResource.evaluate(FailureDetectingExternalResource.java:36)
at org.testcontainers.containers.FailureDetectingExternalResource.evaluate(FailureDetectingExternalResource.java:30)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
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.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
因此,在为此浪费了令人沮丧的 2 天时间之后,结果发现问题出在以下函数中:
@AfterClass
public static void afterClass(){
log.debug("Stopping containers...");
couchbaseContainer.stop();
}
只需删除对
的调用
couchbaseContainer.stop();
问题解决了。
看起来即使 afterClass
正在停止 Couchbase
容器,其他东西也在尝试停止它,如堆栈跟踪中所示:
at org.testcontainers.couchbase.CouchbaseContainer.stopCluster(CouchbaseContainer.java:198)
at org.testcontainers.couchbase.CouchbaseContainer.stop(CouchbaseContainer.java:193)
所以实际上解决方案是从 afterClass
中删除 stop()
并让其他东西停止容器。
您可能需要 运行 您的数据库处于守护进程模式,这样它就不会自动停止:https://www.testcontainers.org/modules/databases/#running-container-in-daemon-mode
我们正在为我们的 Spring Boot 2.1.7.RELEASE
和 Couchbase
数据库创建集成测试。
我们正在使用 testcontainers 并且在测试完成后出现此错误 运行ning:
java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask@da0432 rejected from java.util.concurrent.ScheduledThreadPoolExecutor@238be2[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0]
在我们的 pom 中:
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>couchbase</artifactId>
<version>1.12.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>1.12.1</version>
<scope>test</scope>
</dependency>
在我们的 'Integration test config' class:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {MyApplication.class, IntegrationTestConfig.CouchbaseTestConfig.class},
webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public abstract class IntegrationTestConfig{
@ClassRule
public static CouchbaseContainer couchbaseContainer = new CouchbaseContainer()
.withIndex(true)
.withQuery(true)
.withClusterAdmin("clusterUser", "clusterPassword")
.withNewBucket(DefaultBucketSettings.builder()
.enableFlush(true)
.name("bucketName")
.password("bucketPassword")
.quota(100)
.replicas(0)
.type(BucketType.COUCHBASE)
.build());
@BeforeClass
public static void beforeClass() throws IOException{
log.debug("Starting containers...");
couchbaseContainer.start();
}
@AfterClass
public static void afterClass(){
log.debug("Stopping containers...");
couchbaseContainer.stop();
}
在我们的 IntegrationTest
class:
public class MyIntegrationTest extends IntegrationTestConfig{
@LocalServerPort
private int port;
@Test
public void testSomething(){
....
}
当尝试 运行 集成测试时,我们在控制台中看到:
ℹ︎ Checking the system...
✔ Docker version should be at least 1.6.0
✔ Docker environment should have more than 2GB free disk space
然后我们在控制台中得到这个一两秒钟:
DEBUG [IntegrationTestConfig] - Starting containers...
DEBUG [IntegrationTestConfig] - Stopping containers...
然后我们得到这个错误:
java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask@d87cbb rejected from java.util.concurrent.ScheduledThreadPoolExecutor@1486dd9[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 0]
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830)
at java.util.concurrent.ScheduledThreadPoolExecutor.delayedExecute(ScheduledThreadPoolExecutor.java:326)
at java.util.concurrent.ScheduledThreadPoolExecutor.schedule(ScheduledThreadPoolExecutor.java:533)
at java.util.concurrent.ScheduledThreadPoolExecutor.submit(ScheduledThreadPoolExecutor.java:632)
at rx.internal.schedulers.NewThreadWorker.scheduleActual(NewThreadWorker.java:277)
at com.couchbase.client.core.env.CoreScheduler$EventLoopWorker.schedule(CoreScheduler.java:174)
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.schedule(OperatorObserveOn.java:188)
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.request(OperatorObserveOn.java:145)
at rx.Subscriber.setProducer(Subscriber.java:211)
at rx.internal.operators.OnSubscribeMap$MapSubscriber.setProducer(OnSubscribeMap.java:102)
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.init(OperatorObserveOn.java:139)
at rx.internal.operators.OperatorObserveOn.call(OperatorObserveOn.java:75)
at rx.internal.operators.OperatorObserveOn.call(OperatorObserveOn.java:40)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:44)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
at rx.Observable.unsafeSubscribe(Observable.java:10327)
at rx.internal.operators.OnSubscribeMap.call(OnSubscribeMap.java:48)
at rx.internal.operators.OnSubscribeMap.call(OnSubscribeMap.java:33)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:48)
at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30)
at rx.Observable.unsafeSubscribe(Observable.java:10327)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30)
at rx.Observable.unsafeSubscribe(Observable.java:10327)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:41)
at rx.internal.operators.OnSubscribeDoOnEach.call(OnSubscribeDoOnEach.java:30)
at rx.Observable.subscribe(Observable.java:10423)
at rx.Observable.subscribe(Observable.java:10390)
at com.couchbase.client.core.utils.Blocking.blockForSingle(Blocking.java:70)
at com.couchbase.client.java.CouchbaseCluster.disconnect(CouchbaseCluster.java:417)
at com.couchbase.client.java.CouchbaseCluster.disconnect(CouchbaseCluster.java:412)
at org.testcontainers.couchbase.CouchbaseContainer.stopCluster(CouchbaseContainer.java:198)
at org.testcontainers.couchbase.CouchbaseContainer.stop(CouchbaseContainer.java:193)
at org.testcontainers.containers.GenericContainer.finished(GenericContainer.java:829)
at org.testcontainers.containers.FailureDetectingExternalResource.evaluate(FailureDetectingExternalResource.java:36)
at org.testcontainers.containers.FailureDetectingExternalResource.evaluate(FailureDetectingExternalResource.java:30)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
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.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
因此,在为此浪费了令人沮丧的 2 天时间之后,结果发现问题出在以下函数中:
@AfterClass
public static void afterClass(){
log.debug("Stopping containers...");
couchbaseContainer.stop();
}
只需删除对
的调用couchbaseContainer.stop();
问题解决了。
看起来即使 afterClass
正在停止 Couchbase
容器,其他东西也在尝试停止它,如堆栈跟踪中所示:
at org.testcontainers.couchbase.CouchbaseContainer.stopCluster(CouchbaseContainer.java:198)
at org.testcontainers.couchbase.CouchbaseContainer.stop(CouchbaseContainer.java:193)
所以实际上解决方案是从 afterClass
中删除 stop()
并让其他东西停止容器。
您可能需要 运行 您的数据库处于守护进程模式,这样它就不会自动停止:https://www.testcontainers.org/modules/databases/#running-container-in-daemon-mode