How to Easily Replace Slf4J with java.util.logging Framework

SLF4J is becoming complex by the day (Marker feature for instance) while JUL (java.util.logging) is becoming more powerful and better. It is easy to replace SLF4J from any existing codebase without having to change anything but internally it will use JUL. Let’s see how.

Create org/slf4j (org\slfj for windows users) directory under your source tree and place the following files:
// Licensed under Apache License version 2.0
package org.slf4j; // Mimicked slf4j package structure to avoid changing existing codebase or usage

import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Handler;
 * Replacement for slf4j Logger. Uses java.util.logging framework.
public class Logger {
    private static java.util.logging.Logger logger;
    public Logger(java.util.logging.Logger l) { logger = l; }
     * Clean room implementation of slf4j delayed evaluation of Strings
    public void log(Level level, String message, Object ... args) {
        if(logger.isLoggable(level)) {
            int aL = args.length;
            int index = 0;
            StringBuilder b = new StringBuilder();
            StringTokenizer st = new StringTokenizer(message, "{}");
            while(st.hasMoreTokens()) {
                if(index < aL) b.append(args[index++]);
            logger.log(level, b.toString());
    // Add additional mapping methods below
    public void addHandler(Handler handler) { logger.addHandler(handler); }
    public boolean isInfoEnabled()  { return logger.isLoggable(Level.INFO); }
    public boolean isErrorEnabled() { return logger.isLoggable(Level.SEVERE); }
    public boolean isDebugEnabled() { return logger.isLoggable(Level.FINE);    }
    public boolean isTraceEnabled() { return logger.isLoggable(Level.FINEST); }
    public void  info(String message, Object ... args) { log(Level.INFO,    message, args);    }
    public void debug(String message, Object ... args) { log(Level.FINE,    message, args); }
    public void  warn(String message, Object ... args) { log(Level.WARNING, message, args); }
    public void error(String message, Object ... args) { log(Level.SEVERE,  message, args); }
    public void trace(String message, Object ... args) { log(Level.FINEST,  message, args); }
package org.slf4j;

import java.util.HashMap;
import java.util.Map;

/** Replacement for slf4j package */
public class LoggerFactory {
    private static final Map<String, Logger> loggers = new HashMap<String, Logger>();
    public static Logger getLogger(String name) {
        Logger l = loggers.get(name);
        if(l == null) {
            l = new Logger(java.util.logging.Logger.getLogger(name));
            loggers.put(name, l);
        return l;

The much vaunted capability of Slf4j – delayed evaluation of Strings substitutions has been implemented in the log() method. The String substitutions will be made only if required for output. It improves performance.

You can also pass Objects whose toString() method will be called only if required.

Logger implements most of the common methods used in Slf4j. If you need to add any method, follow the examples shown in It should be one line of code, calling log() or a method in logger. Marker feature has not been implemented. Does anyone use it!?

How to use dd (Linux copy tool) with progress indicator

/dev/sdcdd, the ubiquitous copy tool of Unix/Linux, now comes in with a decent built-in progress indicator.

You can run it by the command-line option: status=progress


dd status=progress if=/dev/sda of=/dev/sdb

Notice how I didn’t add the bs option and used the default. In my experiences the default works best.

Tested on: Ubuntu

Safest way to Update and Upgrade Raspbian Wheezy (Raspberry Pi OS)

There are plethora of instructions on the web to update and upgrade Raspbian and they work too, under normal conditions. However as Raspberry Pi is increasingly being used for Mission Critical tasks, it is important to adopt a procedure which won’t leave you with broken packages or worst, a un-bootable Operating System with your data on it. The following is a simple procedure, with explanations which will make sure that your Pi remains working.

First let’s update and upgrade the Pi with a single line command, run from terminal:

sudo apt-get update -y && sudo apt-get upgrade -y && echo success

This will update and upgrade your Pi and if successful will print success at the end.

Now reboot the Pi with:

sudo reboot

Normally Pi would reboot properly 99% of the time. If it refuses to boot then you can select the old kernel while booting to get back an usable version of Raspbian OS.

After this only two more steps remain. First is to dist-upgrade the Raspbian OS:

sudo apt-get dist-upgrade -y && sudo apt-get autoremove -y && echo success

You  may wonder why I didn’t do it the very first time. While dist-upgrade is better than plain upgrade as it can intelligently install packages based on dependency, upgrade retains the older kernel and gives you a way to back out safely, unlike dist-upgrade. The procedure outlined above protects your OS from cases where the upgrade is broken for any reason.

Now all that is left is to reboot again to make sure everything is OK.:

sudo reboot

You may notice that I didn’t ask you to rpi-update, an instruction you will find at many places online. This is because you do not need rpi-update, the necessary firmware updates are already installed when you upgraded Raspbian. In fact, and I speak from experience, rpi-update can break your running system. Let’s leave that bleeding edge to who really needs it. If you are reading this article, then it can safely be said you don’t.

I used sudo apt-get autoremove to remove any extra packages.

The && before echo success makes sure success is printed only when the previous command succeeds.

Disk space is premium in SD Card. So it may not be out of place to check for available disk space before running update, upgrade or dist-upgrade:

df -h

To save some space clean up the downloaded debian archives with:

sudo apt-get clean

Now you understand why automating Raspbian updates / upgrades is a bad idea, unless you want to use the Raspberry pi only for testing purposes.

Advanced Note on why rpi-update was not suggested:

It’s current Raspberry Pi practice not to use this [ rpi-update ] unless you REALLY need it as it can bring in a non-working kernel (i.e. the latest bleeding edge version, which is not guaranteed to work).

My thoughts are that it is not actually required once you have done the apt-get update/upgrade cycle.

James, Raspberry Pi Foundation (Trading)