Tech Tip: Remove Duplicate and Unused Entries From Your Property Files

This Tech Tip shows you how to clean up property files. It demonstrates the use of the UNIX command line as well as the Bundlizer tool to identify duplicate or unused entries.

Removing “stale” entries is important: Not only do they create unnecessary work for localizers who translate these files, but unused keys also incur more runtime overhead. It is easy to accidentally end up with unused key entries while your code develops, so you ought to check your property files even if you don't suspect any “stale” entries.

Using the Unix Command Line to Scan Bundle Files

In Unix, you can use the command line to scan your files for unused entries. This is an example Unix shell command by Tor Norbye using nawk.

find . -name -exec cat {} \; | /bin/grep "=" | sed
'/^#/d' | sed '/^OpenIDE-Module-/d' | nawk 'BEGIN { FS="=" } {print $1}'
| sort | uniq | nawk '{system("/bin/fgrep " $0 " `find . -name
\"*.class\" -o -name \"*.xml\"` \| nawk \"BEGIN \{i=0\} \{ i++ \} END \{
if \(i==0\) print key \}\" key=" $0)}' | /bin/xargs -n 1 -I @ grep @
`find . -name` 

Using Bundlizer to Scan Bundle Files

If you prefer a graphical tool to scan your Bundle files, take a look at Bundlizer. Bundlizer is a stand-alone tool and is not integrated into the NetBeans IDE.

You can download the source code from contrib/bundlizer or via the NetBeans CVS. To start the tool, load it as a project in NetBeans IDE and run it.

Here is a screenshot of the utility in action (click for full size):

A screenshot of the Bundlizer tool GUI.

Bundlizer helps you clean a file in several ways:

  • It looks for unused keys: These are removed from the file.
  • It looks for duplicates: When the same key is used more than once, you are alerted to this since you will need to decide which value to keep.
  • It cleans up formatting in the file: For instance, it removes empty lines.
  • When you are done, it saves the resulting file.

Be aware that you should definitely check the results before accepting any proposed changes. Determining if a key is unused or not is not a task which can be done fully automatically. If for instance your code is computing keys rather than looking them up directly, Bundlizer will not be able to identify them and will erroneously report these keys unused.

Patching Bundlizer

If you have downloaded the Bundlizer's source code, you can adapt this utility to your own needs. For example, the executable jar file mentioned above includes two improvements by Tor Norbye. The first patch makes Bundlizer also look in XML files for key references; the second makes the tool more robust against the encounter of non-commented lines that do not contain any “=” signs.

XML Suffix Patch

Index: contrib/bundlizer/src/org/netbeans/modules/bundlizer/
RCS file: /cvs/contrib/bundlizer/src/org/netbeans/modules/bundlizer/,v
retrieving revision 1.3
diff -u -r1.3
--- contrib/bundlizer/src/org/netbeans/modules/bundlizer/   7 May 2004 23:48:40 -0000        1.3
+++ contrib/bundlizer/src/org/netbeans/modules/bundlizer/   2 Aug 2005 05:45:46 -0000
@@ -449,7 +449,7 @@
     private class JavaFilenameFilter implements {
         public boolean accept( file, String str) {
-            return str.endsWith ("java");
+            return str.endsWith ("java") || str.endsWith("xml");

Ignore Missing Equal-Sign Patch

Index: contrib/bundlizer/src/org/netbeans/modules/bundlizer/
RCS file: /cvs/contrib/bundlizer/src/org/netbeans/modules/bundlizer/,v
retrieving revision 1.2
diff -u -r1.2
--- contrib/bundlizer/src/org/netbeans/modules/bundlizer/       1 May 2004 13:52:24 -0000        1.2
+++ contrib/bundlizer/src/org/netbeans/modules/bundlizer/       2 Aug 2005 05:45:46 -0000
@@ -115,6 +115,10 @@
                 String keyValuePair = line;
                 int equals = keyValuePair.indexOf ("=");
+                if (equals == -1) {
+                    continue;
+                }
                 assert equals != -1;
                 String key = keyValuePair.substring (0, equals).trim();
@@ -203,6 +207,9 @@
     private boolean isKeyValuePair (String line) {
         int equals = line.indexOf("=");
+        if (equals == -1) {
+            return false;
+        }
         int cmt = line.indexOf ("#");
         return (cmt > 0 && equals < cmt) || (cmt < 0 && equals >= 0);

See also

get support for the NetBeans