Using the Eclipse Java Code Formatter from Command Line

There have been many discussions about how source code should be formatted. Isn't it incredible how much energy is wasted in 'spaces' versus 'tab' discussions? Fighting battles about things you don't see? Well, it affects the layout of your code, but both are not directly visible.

One solution is to use a format which is used in the department, company, wherever. But often only the client side is affected.

Many people are using Eclipse on a daily base editing Java code and formatting it using the Eclipse Java code formatter. This is often used to comply with company rules (or to punish yourself!?)

But then and know people do forget to proper format some source code before check in. This always causes trouble since diffs start to show changes which aren't real changes.

Better than complaining is to use a pre-checking hook which does the formatting.

NOTE THAT THIS DOES NOT WORK WITH SVN!!
svn does not allow to modify data. Try CVS, mercurial or git instead! Then search for checkin filters:
But how can you be sure that the formatting tool yields the same result as your IDE?
If you are using Eclipse you can utilize the Eclipse formatter from command line. You just need
  1. a bunch of eclipse jars
  2. an equinox config.ini file to start the Eclipse formatter
  3. a formatter fmt.ini file to define the format options.

UPDATED to ECLIPSE 4.6

Get the recent version /download/eclipse_java_formatter_win_4_6.zip

Eclipse jars

You need these files from Eclipse Helios:
com.ibm.icu_4.2.1.v20100412.jar
configuration
org.eclipse.core.commands_3.6.0.I20100512-1500.jar
org.eclipse.core.contenttype_3.4.100.v20100505-1235.jar
org.eclipse.core.expressions_3.4.200.v20100505.jar
org.eclipse.core.filesystem.win32.x86_1.1.201.R36x_v20100727-0745.jar
org.eclipse.core.filesystem_1.3.1.R36x_v20100727-0745.jar
org.eclipse.core.jobs_3.5.1.R36x_v20100824.jar
org.eclipse.core.resources.win32.x86_3.5.100.v20100505-1345.jar
org.eclipse.core.resources_3.6.0.R36x_v20100825-0600.jar
org.eclipse.core.runtime_3.6.0.v20100505.jar
org.eclipse.equinox.app_1.3.1.R36x_v20100803.jar
org.eclipse.equinox.common_3.6.0.v20100503.jar
org.eclipse.equinox.preferences_3.3.0.v20100503.jar
org.eclipse.equinox.registry_3.5.0.v20100503.jar
org.eclipse.jdt.core_3.6.1.v_A68_R36x.jar
org.eclipse.osgi_3.6.1.R36x_v20100806.jar
org.eclipse.text_3.5.0.v20100601-1300.jar
and place them into a plugins folder.

config.ini

Then create a plugins/configuration folder and create a config.ini file inside:
osgi.instance.area.default=./workspace
osgi.bundles.defaultStartLevel=4
eclipse.application=org.eclipse.jdt.core.JavaCodeFormatter
osgi.bundles= \
  org.eclipse.core.runtime_3.6.0.v20100505.jar@2:start ,\
  org.eclipse.core.jobs_3.5.1.R36x_v20100824.jar ,\
  org.eclipse.core.contenttype_3.4.100.v20100505-1235.jar ,\
  org.eclipse.equinox.registry_3.5.0.v20100503.jar ,\
  org.eclipse.equinox.preferences_3.3.0.v20100503.jar ,\
  org.eclipse.equinox.common_3.6.0.v20100503.jar ,\
  org.eclipse.equinox.app_1.3.1.R36x_v20100803.jar ,\
  org.eclipse.jdt.core_3.6.1.v_A68_R36x.jar@start ,\
  org.eclipse.core.resources_3.6.0.R36x_v20100825-0600.jar ,\
  org.eclipse.core.filesystem_1.3.1.R36x_v20100727-0745.jar ,\
  org.eclipse.core.commands_3.6.0.I20100512-1500.jar ,\
  org.eclipse.core.expressions_3.4.200.v20100505.jar ,\
  org.eclipse.text_3.5.0.v20100601-1300.jar ,\
  com.ibm.icu_4.2.1.v20100412.jar ,\
  org.eclipse.core.resources.win32.x86_3.5.100.v20100505-1345.jar ,\
  org.eclipse.core.filesystem.win32.x86_1.1.201.R36x_v20100727-0745.jar ,\
If you use a different operation system than Windows then use the files matching your OS and modify the configuration.ini accordingly.

fmt.ini

The fmt.ini can be obtained by exporting the Eclipse format settings into a XML file and convert it into a property file.
  1. copy the XML file into a ini file
  2. remove all lines not starting with <setting
  3. convert the content using a regular expression
    <setting id="([^"]*)" value="([^"]*)"/>
    $1=$2
    

happy formatting

You can also start using the ready packed zip file. It also contains a convenience batch file.

adding the checkin hook to CVS

If you use CVS then add this line to CVSROOT/cvswrappers (or replace an existing *.java line) :
*.java -t '/usr/local/fmt/fmt.sh "%s" "%s"'
This will invoke a script for each checkin. My script looks like (assume you have installed the formatter in '/usr/local/fmt'):
#! /bin/sh
cp "$1" "$2.java"
pushd /usr/local/fmt
java -jar plugins/org.eclipse.osgi_3.6.1.R36x_v20100806.jar -config fmt.ini $2.java >/dev/null
mv $2.java $2
popd


Unfortunately the checkin/checkout hooks are disabled in recent CVS versions. So you have to download, patch and compile CVS yourself.
  1. download and unpack cvs
  2. run './configure'
  3. remove the error messages for the -t, -f options in src/wrapper.c:
    Index: src/wrapper.c
    ===================================================================
    RCS file: /sources/cvs/ccvs/src/wrapper.c,v
    retrieving revision 1.50
    diff -u -r1.50 wrapper.c
    --- src/wrapper.c             12 Sep 2007 17:27:25 -0000         1.50
    +++ src/wrapper.c          12 Dec 2010 21:03:58 -0000
    @@ -424,8 +424,8 @@
                       /* Before this is reenabled, need to address the problem in
                          commit.c (see
                          <http://ximbiot.com/cvs/cvshome/docs/infowrapper.html>).  */
    -                  error (1, 0,
    -                                 "-t/-f wrappers not supported by this version of CVS");
    +//             error (1, 0,
    +//                            "-t/-f wrappers not supported by this version of CVS");
    
                        if(e.tocvsFilter)
                                  free(e.tocvsFilter);
    
  4. fix a bug in checkin.c:
    Index: src/checkin.c
    ===================================================================
    RCS file: /sources/cvs/ccvs/src/checkin.c,v
    retrieving revision 1.62
    diff -u -r1.62 checkin.c
    --- checkin.c       16 Sep 2008 21:00:20 -0000         1.62
    +++ checkin.c    12 Dec 2010 21:06:14 -0000
    @@ -52,6 +52,7 @@
                                  if (! existence_error (errno))
                                      error (1, errno, "cannot remove %s", finfo->fullname);
                       rename_file (tocvsPath, finfo->file);
    +                 tocvsPath = NULL;
                   }
         }
    
  5. run
     make install 

There is still a bug left which causes each checkin to be formatted twice, but it works.

Enjoy!
rev: 1.16