Java 关闭EmbeddedCassandraServerHelper时获取CancellationException
我正在编写一个使用cassandra单元的存储单元测试Java 关闭EmbeddedCassandraServerHelper时获取CancellationException,java,unit-testing,cassandra,Java,Unit Testing,Cassandra,我正在编写一个使用cassandra单元的存储单元测试 public class StoreTest { public void before() throws Exception { EmbeddedCassandraServerHelper.startEmbeddedCassandra(); DataLoader dataLoader = new DataLoader("mydata", "127.0.0.1:9171"); dataLoader.load(ne
public class StoreTest {
public void before() throws Exception {
EmbeddedCassandraServerHelper.startEmbeddedCassandra();
DataLoader dataLoader = new DataLoader("mydata", "127.0.0.1:9171");
dataLoader.load(new ClassPathJsonDataSet("cassandra.json"));
}
@After
public void after() throws Exception {
EmbeddedCassandraServerHelper.cleanEmbeddedCassandra();
}
@Test
public void testSomething() {
// test code
}
}
测试运行良好,能够连接到内存中的cassandra实例,并返回合理的结果。但是,当我关闭cassandra时,日志中出现以下异常
17:05:48.666 [StorageServiceShutdownHook] INFO o.a.cassandra.thrift.ThriftServer - Stop listening to thrift clients
17:05:48.667 [StorageServiceShutdownHook] INFO org.apache.cassandra.gms.Gossiper - Announcing shutdown
17:05:48.782 [GossipTasks:1] DEBUG o.a.c.c.DebuggableThreadPoolExecutor - Task cancelled
java.util.concurrent.CancellationException: null
at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:250) ~[na:1.7.0_21]
at java.util.concurrent.FutureTask.get(FutureTask.java:111) ~[na:1.7.0_21]
at org.apache.cassandra.concurrent.DebuggableThreadPoolExecutor.extractThrowable(DebuggableThreadPoolExecutor.java:230) [cassandra-all-1.2.0.jar:1.2.0]
at org.apache.cassandra.concurrent.DebuggableThreadPoolExecutor.logExceptionsAfterExecute(DebuggableThreadPoolExecutor.java:194) [cassandra-all-1.2.0.jar:1.2.0]
at org.apache.cassandra.concurrent.DebuggableScheduledThreadPoolExecutor.afterExecute(DebuggableScheduledThreadPoolExecutor.java:46) [cassandra-all-1.2.0.jar:1.2.0]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1153) [na:1.7.0_21]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_21]
at java.lang.Thread.run(Thread.java:722) [na:1.7.0_21]
17:05:49.667 [StorageServiceShutdownHook] INFO o.a.cassandra.net.MessagingService - Waiting for messaging service to quiesce
17:05:49.668 [ACCEPT-/27.0.0.1] INFO o.a.cassandra.net.MessagingService - MessagingService shutting down server thread.
这是从哪里来的?如何防止它发生?看起来停止方法有问题。我的猜测是,系统中仍在关闭的部分的工作线程在完成之前被中断。EmbeddedCassandraServerHelper代码不推荐stopEmbeddedCassandra方法,其注释是它不能完全工作 我们使用自己的代码将cassandra嵌入到单元测试中。我们不像EmbeddedCassandraServerHelper类那样使用activate()方法,而是使用Cassandrademon的init()和start()方法。stop()方法似乎可以工作。Cassandra并没有像预期的那样完美地嵌入
如果除了恼人的日志消息之外没有任何问题,我只会配置日志以抑制该类。否则,请尝试用init()/start()方法替换EmbeddedCassandraServerHelper中的active()方法调用。问题出在DebuggableThreadPoolExecutor.extractThrowable方法中。源代码是:
public static Throwable extractThrowable(Runnable runnable)
{
// Check for exceptions wrapped by FutureTask. We do this by calling get(), which will
// cause it to throw any saved exception.
//
// Complicating things, calling get() on a ScheduledFutureTask will block until the task
// is cancelled. Hence, the extra isDone check beforehand.
if ((runnable instanceof Future<?>) && ((Future<?>) runnable).isDone())
{
try
{
((Future<?>) runnable).get();
}
catch (InterruptedException e)
{
throw new AssertionError(e);
}
catch (CancellationException e)
{
logger.debug("Task cancelled", e);
}
catch (ExecutionException e)
{
return e.getCause();
}
}
return null;
}
publicstaticthrowable-extractThrowable(Runnable-Runnable)
{
//检查FutureTask包装的异常。我们通过调用get()来完成此操作,这将
//使其抛出任何已保存的异常。
//
//使事情复杂化的是,在ScheduledFutureTask上调用get()会一直阻塞,直到任务完成为止
//被取消。因此,额外的isDone检查提前。
if((未来的可运行实例)&((未来的)可运行.isDone())
{
尝试
{
((Future)runnable.get();
}
捕捉(中断异常e)
{
抛出新断言错误(e);
}
捕获(取消异常e)
{
调试(“任务取消”,e);
}
捕获(执行例外)
{
返回e.getCause();
}
}
返回null;
}
可以看到,它记录了带有调试警告的任务取消。我所做的是更改行logger.debug(“任务取消”,e)
到logger.debug(“任务已取消(请参阅DebuggableThreadPoolExecutor.extractThrowable)”代码>。这样可以记录事件,但不会用引起注意的堆栈跟踪污染日志