Thursday, May 31, 2007

Log4j code template in Eclipse

I just tried adding my own code template to Eclipse, and wanted to recommend it to Java programmers, if you can identify a pattern you use all over the place. For me, it was the way I use log4j. Just about every class ends up declaring a Logger field, which all look like this:

private Logger m_logger = Logger.getLogger(getClass());
Even with Eclipse's tab completion accelerating this, it started to get tedious. Now, I just type logger, press Ctrl-Space and enter to confirm the selected template is what I meant. I do then have to use Ctrl-1 to Quick Fix the error that I need to import the log4j package. That's the only potential improvement I've identified.

Actually, it gets better. Instead of using the method call getClass(), I've seen some people use the static class member class, as in MyCollection.class. There's presumably some infinitesimal speed difference, I don't know as I've never looked into it. Frankly, before I thought of these templates I used the getClass() approach because it was faster for me to type in Eclipse. Once I've typed Logger.getLogger(g, I hit Ctrl-Space for the auto completion list and hit return since getClass() is the top choice. Now with the custom templates, I can get the Classname.class form for free by using a template variable:
private Logger m_logger = getLogger(${enclosing_type}.class);
If everything stays in Eclipse, even the hard-coded class name is no problem because it gets renamed when the class or file gets renamed.

To get started writing your own template, open Window > Preferences... and select Java, Editor, Templates.

Some thoughts on code templates

Java is an OOS, Object Of Scorn, for many functional and dynamic scripting programmers, partly for its verbosity. Just as VC++ helped me deal with C++, Eclipse is helping me deal with Java by providing some decent accelerators like these templates. The fact that I can write my own is nice. It's my opinion that even in the most elegant languages I know of, it's not always possible to factor out every pattern in a large code base to an tiny pearl of beauty. I think you inevitably end up with a few code patterns of significant size that could benefit from editor templating.

4 comments:

Jim said...
This comment has been removed by the author.
Jimothy said...

I'll do you one better:

${:import(org.apache.log4j.Logger)}private static final Logger logger = Logger.getLogger(${enclosing_type}.class);

With this template, Eclipse will also insert the import statement, in the correct place. If the import already exists, it will not put in a duplicate.

This also differs in that it uses "static final" for the logger, but you can easily edit it to use an instance, instead of class, variable.

Ryan said...

I tried using the "${:import(org.apache.log4j.Logger}" and Eclipse told me that the "Template has invalid variable identifiers". Any help as to how to get this to work? I'd love to be able to also add dynamic importing of the package as well to my template.
Thanks for sharing this template. Even without the "dynamic import" it has already helped me a ton!!

sam said...

This works for me:
${imp:import(org.apache.log4j.Logger)}
private static final Logger logger = Logger.getLogger(${enclosing_type}.class);