2

我正在编写一个使用 cassandra-unit 的商店单元测试。

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.

这是从哪里来的,我该如何防止它发生?

4

2 回答 2

0

看起来停止方法有问题。我的猜测是,仍在关闭的系统的一部分的工作线程在完成之前就被中断了。最新的EmbeddedCassandraServerHelper 代码弃用了 stopEmbeddedCassandra 方法,并指出它不能完全工作。

我们使用自己的代码将 cassandra 嵌入到我们的单元测试中。我们不像 EmbeddedCassandraServerHelper 类那样使用 activate() 方法,而是使用 CassandraDaemon 的 init() 和 start() 方法。stop() 方法似乎可以工作。Cassandra 没有完美嵌入,因为它期望在jsvc下执行。

如果除了烦人的日志消息之外没有任何问题,我只需配置日志记录以禁止该类。否则,请尝试将 EmbeddedCassandraServerHelper 中的 active() 方法调用替换为 init()/start() 方法。

于 2013-06-10T21:50:25.937 回答
0

问题位于方法 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;
}

正如人们所看到的,它记录了带有调试警告的任务取消。我所做的是将线路更改logger.debug("Task cancelled", e);logger.debug("Task cancelled (see DebuggableThreadPoolExecutor.extractThrowable)");. 通过这种方式记录事件,但不会使用引起注意的堆栈跟踪污染日志。

于 2015-04-30T07:53:33.550 回答