@Override
    public void open() throws InterruptedException, JournalException {
        // Open a new journal database or get last existing one as current journal database
        List<Long> dbNames;
        JournalException exception = null;
        for (int i = 0; i < RETRY_TIME; i++) {
            try {
                // sleep for retry
                if (i > 0) {
                    Thread.sleep(SLEEP_INTERVAL_SEC * 1000L);
                }

                dbNames = bdbEnvironment.getDatabaseNamesWithPrefix(prefix);
                if (dbNames == null) {  // bdb environment is closing
                    throw new JournalException("fail to get dbNames while open bdbje journal. will exit");
                }
                String dbName;
                if (dbNames.isEmpty()) {
                    /*
                     *  This is the very first time to open. Usually, we will open a new database named "1".
                     *  But when we start cluster with an image file copied from other cluster,
                     *  here we should open database with name image max journal id + 1.
                     *  (default GlobalStateMgr.getCurrentState().getReplayedJournalId() is 0)
                     */
                    if (prefix.isEmpty()) {
                        dbName = getFullDatabaseName(GlobalStateMgr.getCurrentState().getReplayedJournalId() + 1);
                    } else {
                        dbName = getFullDatabaseName(StarMgrServer.getCurrentState().getReplayId() + 1);
                    }
                    LOG.info("the very first time to open bdb, dbname is {}", dbName);
                } else {
                    // get last database as current journal database
                    dbName = getFullDatabaseName(dbNames.get(dbNames.size() - 1));
                }

                if (currentJournalDB != null) {
                    currentJournalDB.close();
                }
                currentJournalDB = bdbEnvironment.openDatabase(dbName);
                if (currentJournalDB == null) {
                    LOG.warn("fail to open database {}. retried {} times", dbName, i);
                    continue;
                }
                return;
            } catch (DatabaseException e) {
                String errMsg = String.format("catch exception after retried %d times", i + 1);
                LOG.warn(errMsg, e);
                exception = new JournalException(errMsg);
                exception.initCause(e);
            }
        }

        // failed after retry
        throw exception;
    }
@Test(expected = JournalException.class)
    public void testOpenGetNamesFails(@Mocked BDBEnvironment environment) throws Exception {
        new Expectations(environment) {
            {
                environment.getDatabaseNamesWithPrefix("");
                times = 1;
                result = null;
            }
        };

        BDBJEJournal journal = new BDBJEJournal(environment);
        journal.open();
        Assert.fail();
    }