Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Java Tip 135: Layer and compare property files

A utility for comparing and combining property files eases multilayer property file organization

  • Print
  • Feedback

Page 2 of 3

  • Global settings used by all application servers in a cluster
  • Settings specific to a host server
  • Application server instance-specific settings


The organizing principle here is reminiscent of how inheritance is used to specialize classes in object-oriented programming. Any particular WebLogic instance has its own process that listens for connections on one port and, on startup, loads one property file for each of these layers. Each layer can override any previous one for any particular setting because deeper layers provide less specific information, just like specialization in a subclass overrides the superclass. An ordered-by-precedence scheme like this is needed to separate settings into three groups: cluster, host, and instance.

While using WebLogic for development and deployment, I encountered situations where it became necessary to determine the differences among WebLogic instances to correct a misbehaving server or to bring a server up to date without wiping out particular settings it needed. The first time this situation arose, I tried to compare by hand, but eyeballing the needle in the haystack proved painfully difficult because the difference turned out to be a typo in a property name; a G in a property name should have been a C, and the particular fixed-width terminal font I was using minimized the difference between these two characters to one or two pixels.

The next time I needed to compare property files, I decided to automate the process. First I tried using the Unix diff tool on property files, but this did not successfully work because, while the order of settings within a property file is irrelevant, they show up as differences. Second, I tried concatenating and sorting the files first and then doing the diff. However, that revealed another difficulty: the layering of property files is completely lost in the results, making it hard to trace the differences to the original files. (Alternatively, comparing files layer by layer does not reveal the combined settings.) Finally, it became obvious that a small Java utility would solve this problem once and for all.

Organize properties by layer for development

We can generalize from the idea of using property file layers in a cluster to organizing properties over time and among people during development, testing, and deployment. For example, in one multiperson project I found the following layers to be useful:

  1. System defaults that are infrequently changed and valid for most configurations
  2. Purpose-delineated settings (coding, testing, deployment)
  3. Personal developer settings for each developer, like installation location, debug/log level, and experimental development


In projects organized like this, there typically would be one property file for Layer 1, three in Layer 2, and one or two for each developer in Layer 3. At runtime, the application loads one property file from each layer. The particular property files from Layers 2 and 3 are specified on the command line as an argument or -Dproperty.

The benefits of layering

Classifying properties in this way is analogous to a stylized inheritance hierarchy. The benefits are:

  • Multiple developers can maximize sharing of property files
  • Layering reduces the need to comment individual property settings because classification by layer and by particular file within a layer effectively makes implied comments about the expected variability
  • Compared to one big property file, layering reduces the number of source code control commits needed for any particular property file and also reduces the likelihood of merging


PropDiff utility

One problem with using multiple layers of property files is that understanding which properties are set or where they were overridden can become less than obvious. I wrote the PropDiff utility to easily solve these issues.

PropDiff is a command-line utility that can quickly find the union, intersection, and difference between property files. For instance, given two property files p1 and p2, from layer n and (n+1), and no other arguments, PropDiff creates six property files containing:

  1. Property settings common to both p1 and p2, where p2 takes precedence (-c)
  2. Union of p1 and p2, where p2 has higher precedence (-u)
  3. Property settings only in p1 (-1)
  4. Property settings only in p2 (-2)
  5. Intersection of properties in p1 and p2 that have different values (-d)
  6. Intersection of properties in p1 and p2 that have equal values (-e)


Using the specific command-line flags indicated in parentheses, the outputs can be selectively emitted. Each of these created property files is appropriately named and has a header comment indicating its contents along with the real filenames corresponding to p1 and p2. Alternatively, results can dump to the console (System.out) by typing -f - on the command line without creating any new files.

PropDiff eases the examination of two property layers with a precedence relationship. Just run the utility with the filenames and no extra command-line arguments, then view the files produced. Use -f - to see the output without creating new files.

In the WebLogic example, two application server instances on one host differ only among the instance-specific properties. You can compare these properties with any of the flags except -u or -c, which only make sense when a precedence relationship exists.

When comparing two or more layers between server instances, first use the -u flag to make, for each instance, a union of two property files that respects the precedence relationship. Then compare the union property files with any or all of the following flags: -1, -2, -d, -e.

Naming tips

This a good place to discuss best practices for selecting property names. The first example is from WebLogic: always put the units in the name of a property. For instance:

  • myapp.timeoutMsecs is better than myapp.timeout
  • myapp.heapsizeKBytes is better than myapp.heapsize
Self-documenting names like these makes configuration changes faster, easier, and less error prone.

Similarly, I recommend myapp.foo_path_BASEDIR_rel over myapp.foo_path to indicate that the path to foo could be relative to the path from property myapp.BASEDIR. You should define a property setting for a project's base directory as early as possible to avoid multiple, partially redundant paths right from the start.

  • Print
  • Feedback

Resources