2011-11-10 23 views
3

我正在開發一個項目,這個項目經歷了多次手忙腳亂的開發。隨着時間的推移,message.properties文件與使用它的jsps不同步。現在我不知道哪些屬性被使用,哪些不是。有沒有一種工具(也許是eclipse插件)能夠消除死信息?在消息資源文件中查找未使用的值

+0

如果密鑰不是動態生成的(例如將前綴與後綴連接以獲得最終密鑰),則可以循環遍歷密鑰並grep所有JSP中的每個密鑰。我不是劇本專家,但這不應該太難。 –

+0

從一個空包開始(或者在你通過grep等標識出明顯的包後從基礎開始),並且根據需要不斷更新它。你可以在QA或DEV env中通過運行一些功能測試來做到這一點......我沒有看到其他更好的方法... –

+3

我只是將原始的'ResourceBundle'綁定到另一個自定義的'ResourceBundle'實現中(通過'ResourceBundle #setParent()'),'handleGetObject()'方法對每個請求做一些日誌記錄(或收集統計信息),但總是返回null。通過查看這些統計數據,您將瞭解使用哪些密鑰。 –

回答

1

問題是可以通過JSP或Java訪問消息,並且可以構造資源名稱而不是文字字符串。

簡單grep ping可能能夠識別「明顯的」資源訪問。另一種解決方案是跟蹤所用內容的資源查找機制,它只是半可靠的,因爲代碼路徑可能決定使用哪些資源,除非每條路徑都經過了,否則可能會漏掉一些。

兩者的結合將捕捉大部分內容(隨着時間的推移)。

+1

唉,我完全忘了驗證吐出了對消息的引用(NotNull.object.field)。我偶然發現了這個問題 –

1

或者,您可以將ResourceBundle的功能隱藏在另一個外牆ResourceBundle的後面,該功能通常應將所有呼叫都管理爲原始呼叫,但在頂部添加日誌記錄和/或統計信息收集。

的例子可以如下:

import java.util.Collection; 
import java.util.Enumeration; 
import java.util.HashSet; 
import java.util.NoSuchElementException; 
import java.util.ResourceBundle; 

public class WrapResourceBundle { 

    static class LoggingResourceBundle extends ResourceBundle { 
     private Collection<String> usedKeys = new HashSet<String>(); 

     public LoggingResourceBundle(ResourceBundle parentResourceBundle) { 
      setParent(parentResourceBundle); 
     } 

     @Override 
     protected Object handleGetObject(String key) { 
      Object value = parent.getObject(key); 

      if (value != null) { 
       usedKeys.add(key); 
       return value; 
      } 

      return null; 
     } 

     @Override 
     public Enumeration<String> getKeys() { 
      return EMPTY_ENUMERATOR; 
     } 

     public Collection<String> getUsedKeys() { 
      return usedKeys; 
     } 

     private static EmptyEnumerator EMPTY_ENUMERATOR = new EmptyEnumerator(); 

     private static class EmptyEnumerator implements Enumeration<String> { 

      EmptyEnumerator() { 
      } 

      public boolean hasMoreElements() { 
       return false; 
      } 

      public String nextElement() { 
       throw new NoSuchElementException("Empty Enumerator"); 
      } 
     } 
    } 

    public static void main(String[] args) { 
     LoggingResourceBundle bundle = new LoggingResourceBundle(ResourceBundle.getBundle("test")); 

     bundle.getString("key1"); 

     System.out.println("Used keys: " + bundle.getUsedKeys()); 
    } 
} 
0

我知道至少有兩個主要的Java IDE可以提供這種功能。

  • IntelliJ IDEA的有(禁用,默認情況下)檢查,你可以使用 做到這一點:

    進入設置 - >檢查 - >屬性文件 - > ...並啓用 的'未使用的財產'

    ..唯一的問題是,它沒有從我編寫的自定義標記庫中找到一些屬性的用法,這是我在幾個JSP中使用的。日食也有這樣的事情(http://help.eclipse.org/helios/index.jsp?topic=%2Forg.eclipse.jdt.doc.user%2Ftasks%2Ftasks-202.htm),但我還沒有真正用盡它的工作效果。

0

考慮到一些你的鑰匙是運行時產生的,我不認爲你永遠能夠找到一種工具來驗證哪些鍵在使用,哪些不是。

鑑於您提出的問題,我可能會編寫一個包裝MessageSource.getMessage()實現的AOP方面,並記錄從資源包中檢索到的所有請求代碼。鑑於MessageSource是一個接口,您需要知道您正在使用的實現,但我懷疑您必須知道這一點。

鑑於您將自己編寫方面,您可以創建一個與您的資源包容易關聯的格式,並且一旦您確信它包含了所需的所有關鍵點,則將這兩個文件進行比較將變得非常簡單並消除任何多餘的線。

如果您真的想徹底瞭解這一點,如果您已經爲註釋掃描配置了Spring,甚至可以將您的方面打包爲自己的jar(或.class),並將其放入生產的WEB-INF/lib(WEB-INF/classes)文件夾中,重新啓動webapp並讓它運行一段時間。關於註釋的好處在於它可以全部自成一體。一旦你確定你已經積累了足夠的數據,你只需刪除jar(.class),你就可以開始。