Add log4j to RCP application

log4j is always one of the best logging frameworks available. But, adding a log4j framework in RCP application can be quite a hectic sometime, because we need to add the references in many files and many places. Also, while working on my own, it tooks me a few hours to figure what they are! So, I decided to sum them up in this tutorial.

So, let us start adding log4j framework in RCP application.

Step 1: Obviously the first step is downloading latest version of log4j.jar. I downloaded  log4j-1.2.17.jar. Save the jar inside a folder (namely lib) in side the workspace.

Step 2: Next step is to create a log4j.properties. I am  not going in to the detail of how to create one. Rather I will use a simple template for that.


# Root logger option
log4j.rootLogger=DEBUG, stdout, file

# Redirect log messages to console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

# Redirect log messages to a log file, support file rolling.
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=C:\\Users\\srijani.ghosh\\Desktop\\log\\Application.log
log4j.appender.file.MaxFileSize=5MB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n


log4j.category.fileLogger=DEBUG, file
log4j.additivity.fileLogger=false

In the above example, I have used a simple logger called file.  Also, I have mentioned the path where the log files should be generated with parameter log4j.appender.file.File. Also, I have mentioned some pattern for the logs to be generated.

Step 3: Place the above log4j.properties file in the eclipse installation folder. For example, for me the path for Eclipse installation is : C:\Srijani\Softwares\eclipse-rcp-luna-SR2-win32\eclipse.

Probably many of you already know that, we can also place log4j.properties file in the root folder of the project. But, while working with RCP, I learned that, when we export the RCP product, it is not possible for the exported product to read the log4j.properties from the exported jar file of the RCP application.

So what is the solution?
Well, we can make the exported .exe to read from the log4j.properties from any another place. So, what I did was, I created a feature project which will export the log4j.properties in the root folder of the RCP application. Now you can read it.

Now the question is why I am saving the log4j.properties now in Eclipse installation folder.?
Well, that is because, if we are running the RCP project now from Eclipse only, it will throw some error if it doesn't find any log4j.properties. So, this is basically for testing purpose. Once you are completed, you can remove that log4j.properties from Eclipse installation folder.

Step 4: Open MANIFEST.MF and add log4j-1.2.17.jar as Bundle-classpath and in Require-Bundle. Finally the MANIFEST.MF will look like this:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: HelloWorldRCP
Bundle-SymbolicName: HelloWorldRCP;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-Activator: helloworldrcp.Activator
Require-Bundle: org.apache.log4j;bundle-version="1.2.15",
 org.eclipse.ui,
 org.eclipse.core.runtime
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ActivationPolicy: lazy
Bundle-ClassPath: .,
 lib/log4j-1.2.17.jar

Step 5: Open build.properies, and add log4j-1.2.17.jar in bin.includes. Finally, it will look like this:

source.. = src/
output.. = bin/
bin.includes = plugin.xml,\
               META-INF/,\
               .,\
                lib/log4j-1.2.17.jar
Step 6: Now it is time to add the logger at the entry point of the RCP application.


 
public Object start(IApplicationContext context) throws Exception {
    BasicConfigurator.configure();
    String log4jConfPathBase = Platform
            .getInstallLocation()
            .getURL()
            .getPath()
            .substring(
                    1,
                    Platform.getInstallLocation().getURL().getPath()
                            .length() - 1);
    String log4jConfPath = log4jConfPathBase + "/log4j.properties";
    PropertyConfigurator.configure(log4jConfPath);
    LOGGER.debug("STARTING APPLICATION ..");
    Display display = PlatformUI.createDisplay();
    try {
        int returnCode = PlatformUI.createAndRunWorkbench(display, new ApplicationWorkbenchAdvisor());
        if (returnCode == PlatformUI.RETURN_RESTART)
            return IApplication.EXIT_RESTART;
        else
            return IApplication.EXIT_OK;
    } finally {
        display.dispose();
    }

}

BasicConfigurator.configure(); configures log4j framework.

String log4jConfPathBase = Platform
            .getInstallLocation()
            .getURL()
            .getPath()
            .substring(
                    1,
                    Platform.getInstallLocation().getURL().getPath()
                            .length() - 1);
    String log4jConfPath = log4jConfPathBase + "/log4j.properties";
The above lines define where to read the log4j.properties.

 PropertyConfigurator.configure(log4jConfPath); This line reads log4j.properties from the given path.

LOGGER.debug("STARTING APPLICATION ..");  Finally this is how we are using the logger.

Step 6: Create a Feature Based Project with log4j.properties and use that feature in the RCP application. If you do not know how to, check at this link - Create Feature Based RCP Project .

Step 7: You are ready to go. Export the product for the RCP application.