2012-10-06 66 views
0

情況: 我有一個靜態數據庫類,使用HSQLDB,我也想在其中使用Logging。Java java.util.logging記錄器與HSQLDB結合的奇怪行爲

我設置了記錄器,設置了所有的語句,但在使用特定的方法後,記錄器似乎不再工作了。沒有例外,只是似乎已經死了。

這是Logger類:

public class GLogger { 

    private static GFormatter formatterHTML; 
    private static FileHandler fileHTML; 
    private static boolean  isReady = false; 

public static void setup() throws IOException { 
    Logger logger = Logger.getLogger(""); 
    fileHTML = new FileHandler("conf/logging.html"); 
    formatterHTML = new GFormatter(); 
    fileHTML.setFormatter(formatterHTML); 
    logger.addHandler(fileHTML); 
    isReady = true; 
} 

public static boolean isReady() { 
    return isReady; 
} 
} 

這是數據庫類(部分):

public class Database { 

private static final Logger LOG = Logger.getLogger(Database.class.getName()); 
/** 
* The database server class 
*/ 
private static Server  hsqlServer; 

/** 
* The connection class. Used to manage request to the database. 
*/ 
private static Connection connection; 

/** 
* The name of the database 
*/ 
private static String  dbName; 

public Database(String databaseName, String fileName) { 

    LOG.setLevel(Level.FINEST); 

    hsqlServer = null; 
    connection = null; 

    dbName = databaseName; 

    // ###### LOGGER ###### 
    LOG.finest("Creating a new database server class"); 
    // #################### 
    hsqlServer = new Server(); 

    hsqlServer.setLogWriter(null); 
    hsqlServer.setSilent(true); 

    hsqlServer.setDatabaseName(0, dbName); 
    hsqlServer.setDatabasePath(0, "file:db/" + fileName); 
} 

/** 
* Start the new database class. 
*/ 
public static void start() { 

    // ###### LOGGER ###### 
    LOG.finest("Starting a new database class"); 
    // #################### 
    hsqlServer.start(); 
    connection = null; 
} 

/** 
* Start the new connection to the specified database, using the default username "sa" e no password 
*/ 
public static void connect() { 
    try { 
     // ###### LOGGER ###### 
     LOG.finest("Getting a connection to the newly started database"); 
     // #################### 
     Class.forName("org.hsqldb.jdbcDriver"); 
     // Default user of the HSQLDB is 'sa' with an empty password 
     connection = DriverManager.getConnection("jdbc:hsqldb:hsql://localhost/garby", "sa", ""); 
    } catch (ClassNotFoundException e) { 
     // ###### LOGGER ###### 
     LOG.severe("Impossible to connect to the database. ClassNotFound"); 
     // #################### 
    } catch (SQLException e) { 
     // ###### LOGGER ###### 
     LOG.finest("Impossible to connect to the database. " + e.getCause()); 
     // #################### 
    } 
} 
// ... more other stuff, not important and then the main method: 
public static void main(String[] args) { 
    if (!GLogger.isReady()) { 
     try { 
      GLogger.setup(); 
     } catch (Exception e) { 

     } 
    } 
    new Database("garby", "garbydb"); 
    Database.start(); 
    Database.connect(); 
    Database.tableStructureCreation(); 
    Database.populateFromFile("conf/populateServ.txt", "services"); 
    System.out.println(Database.listServices()); 
    Database.stop(); 
} 

我刪除那些不相關的我的問題,所有的方法和其他行動。

如果我運行該類,一切正常(!!數據庫添加了正確的結構和數據,用第二行「system.out」驗證)。記錄器不應該如何工作。我只能讀兩行,一個在構造函數中,另一個在start()方法中。

試了幾次後,我明白,這個問題是在該行

​​ 公共靜態無效的開始

();方法。實際上,如果主要移動Database.connect()之前的Database.start(),我可以讀取4條消息(1從構造函數中,2從連接[獲取conn ....不可能conn ...]和1從一開始),然後什麼也沒有。

如果我評論該行[hsqlServer.start()]我可以讀取所有日誌消息(顯然直到某處因爲缺少語句而拋出NullPointerException)。

我真的不明白爲什麼以及如何解決這個問題。這件事阻止了我所有的程序日誌消息,因爲顯然「數據庫」類幾乎在任何其他日誌消息之前啓動並阻止所有日誌消息。

任何想法?預先感謝您

[再次,對不起我的英語不好,我希望我可以理解] 編輯:我也刪除了Javadoc評論 - 沒有用。

+0

兩個建議 - 第一,我不知道你是否能取決於記錄程序在程序運行期間的任何特定時間刷新寫入日誌文件 - 是否在應用程序運行完成後嘗試查看日誌文件?其次 - 包括我自己在內的很多人都認爲java.util.logging只是比使用System.out更好 - 它有很多'問題'。要獲得更好的體驗,請查看Log4J或LogBack(LogBack是Log4J的更新版本)。 – GreyBeardedGeek

+0

該文件沒問題,它正確關閉,好像有些方法是關閉它的。 你能告訴我一個代碼如何從util.logging改爲你告訴我的代碼嗎?有沒有辦法改變?我有一個格式化程序可以準備我的html文件,我可以使用它,或者日誌格式化了嗎? – Gianmarco

+0

請參閱@fredt針對HSQLDB細節的答案。 Log4J和LogBack在操作上與lava.util.logging類似,但完整的處理超出了在這裏回答的範圍。這兩個圖書館非常受歡迎,以至於網絡上有很多信息。使用你最喜歡的搜索引擎。 – GreyBeardedGeek

回答

4

如果HSQLDB存在,HSQLDB將使用java.util.logging或Log4J。它重新配置日誌設置以使日誌正常工作。如果您自己配置日誌記錄,則必須包含系統屬性設置hsqldb.reconfig_logging = false。然後您需要配置您希望包含HSQLDB日誌消息的級別。請參閱指南:

設置系統屬性你啓動服務器前

http://hsqldb.org/doc/2.0/guide/management-chapt.html#mtc_jdc_logging

一種方法是這樣的:

System.setProperty("hsqldb.reconfig_logging", "false"); 
+0

是的,這是一個很好的答案,唯一的問題(正如我在先例問題中所說的)是我不知道如何設置這些屬性。 我添加以下行: LogManager.getLogManager()。readConfiguration(new FileInputStream(「conf/logger.properties」)); 但似乎沒有改變。我想我做錯了什麼。如果我從不給它提供LOG對象的引用,HSQLDB如何寫入日誌? – Gianmarco

+0

解決了。我不得不在「系統」屬性中插入那些屬性,而不是「記錄器」 – Gianmarco