Friday, June 28, 2013

Solution to Store Credit

This is a probable solution to CODE JAM's Store Credit.


import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;


public class StoreCredit {
   
    public static void main(String[] args) {
        try {
            Scanner scanner = new Scanner(ReverseWords.class.getClassLoader().getResourceAsStream("A-large-practice.in"));
            int problemCount = Integer.parseInt(scanner.nextLine());
            int caseCounter = 1;
            for(int iProblemCounter = 0; iProblemCounter < problemCount; iProblemCounter++) {
                Set completedIndexes = new HashSet();
               
                int creditAmount = Integer.parseInt(scanner.nextLine());
                int numberOfItems = Integer.parseInt(scanner.nextLine());
                String itemsLine = scanner.nextLine();
                String[] intArray = itemsLine.split(" ");
                String output = "";
                itemLoop:{
                    for (int iArrayCounter = 0; iArrayCounter < numberOfItems; iArrayCounter++) {
                        completedIndexes.add(iArrayCounter);
                        for (int iArrayInnerCounter = 0; iArrayInnerCounter < numberOfItems; iArrayInnerCounter++) {
                            if(completedIndexes.contains(iArrayInnerCounter)) {
                                continue;
                            }
                            int sum = (Integer.parseInt(intArray[iArrayCounter]) + Integer.parseInt(intArray[iArrayInnerCounter]));
                            output = (iArrayCounter + 1) + " " + (iArrayInnerCounter + 1);
                            if(sum == creditAmount) {
                                break itemLoop;
                            }
                        }
                    }
                }
                System.out.println("Case #" + (caseCounter++) + ": " + output);
            }
        } catch (Throwable a_th) {
            a_th.printStackTrace();
        }
    }
}
See you later friends.

Thursday, March 14, 2013

Windows Service Monitor and starting

Hi friends,

It's been long since my last post. Again I am here with some solution. Specifically for windows. The problem statement was, few windows service was getting stopped all of a sudden due to some error. What we needed is one small utility which monitors the specific service and start that if that is stopped.

There was many suggestion and solution, many monitoring softwares. But I liked the solution mentioned below. Took quite some time to collect all the information and build it.

First copy paste the below code in a file named as "serviceMonitor.vbs" or you can choose any other name as well.


Set sh = CreateObject("Shell.Application")
set shellLogger = CreateObject("WScript.Shell")

If sh.IsServiceRunning("SERVICE_TO_MONITOR") Then
    shellLogger.LogEvent 4, "
SERVICE_TO_MONITOR is running"
Else
    shellLogger.LogEvent 4, "
SERVICE_TO_MONITOR is not running"
    if sh.ServiceStart("
SERVICE_TO_MONITOR", true) Then
        shellLogger.LogEvent 4, "
SERVICE_TO_MONITOR automatically started"
    Else
        shellLogger.LogEvent 4, "
SERVICE_TO_MONITOR could not be started"
    End If
End If   

Replace the word SERVICE_TO_MONITOR with name of your service.
Then open scheduler and create a task. Choose the trigger you want, I kept it at every 1 min.

wolla...  your windows service will never be down. If it is down, It will be up within next one min. :)

Saturday, June 23, 2012

DiamondPattern

Hi friends,

This is a simple program which generates a diamond kind of pattern with the passed character which is 'e' in this case.




public class DiamondPattern {
    public static void main(String[] args) {
        printPattern('e');
    }
   
    private static final int BASE_CHAR = (int)'a';
   
    private static void printPattern(char a_endChar) {
        int charCounter = BASE_CHAR;
        boolean isIncreasing = true;
        do {
            System.out.print(getPadding(a_endChar - charCounter + 1));
           
            for(int iHCounter = BASE_CHAR; iHCounter < charCounter; iHCounter++) {
                System.out.print((char)iHCounter);
            }
           
            for(int iHCounter = charCounter - 2; iHCounter >= BASE_CHAR; iHCounter--) {
                System.out.print((char)iHCounter);
            }
           
            if(isIncreasing) {
                charCounter++;
            }else {
                charCounter--;
            }
           
            if(charCounter > a_endChar) {
                isIncreasing = false;
            }
            System.out.println();
        }while(charCounter >= BASE_CHAR);
    }
   
    public static String getPadding(int a_padCount) {
        StringBuffer strPadding = new StringBuffer();
        for (int iCounter = 0; iCounter < a_padCount; iCounter++) {
            strPadding.append(' ');
        }
        return strPadding.toString();
    }
}

Thursday, March 8, 2012

Number Formatter in JAVASCRIPT

Hi friends,

When we want to format, type cast and convert numbers in JAVASCRIPT with multilingual support, there are none. So came out with this.

This supports European & English both kind of number formatting. While using this, just set the basic 3 variables.

Save the code with any name, say NumberFormatter.js then call like this with jQuery

jQuery.getScript(
{
  url: 'NumberFormatter.js',
  dataType: "script",
  success: function(){
NumberFormatter._tSep = '<get the data from user profile with server side code&gt>';
               NumberFormatter._dSep = '<get the data from user profile with server side code>';
               NumberFormatter.DEFAULT_PRECISION = <get the data from user profile with server side code>; 
}
}
);



 The code for Javascript file starts from here....

String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ""); };

function NumberFormatter(){}

NumberFormatter._tSep = ',';
NumberFormatter._dSep = '.';
NumberFormatter.DEFAULT_PRECISION = 2;
NumberFormatter.IS_STRICT_THOUSAND_SEPARATOR_VALIDATION = false;

NumberFormatter.setThousandSeparator = function(tSep){
    NumberFormatter._tSep = tSep;
}

NumberFormatter.setDecimalSeparator = function(dSep){
    NumberFormatter._dSep = dSep;
}

NumberFormatter.getInteger = function(num2Get){
    return NumberFormatter.parseNumber(num2Get, true);
}

NumberFormatter.getDecimal = function(num2Get, decimalPrecision){
    return NumberFormatter.parseNumber(num2Get, false, decimalPrecision);
}

/**
 * this function is to be used before sending
 * to server side.
 */
NumberFormatter.parseNumber = function(num2Get, isNumberOnly, a_decimalPrecision){
    if(num2Get == ""){
        return "";
    }
    var tSep = NumberFormatter._tSep;
    var dSep = NumberFormatter._dSep;
    var parts = (num2Get + "").split(dSep);
    var firstPart = parts[0];
    var decPrec = (typeof(a_decimalPrecision) != "undefined"  && !isNaN(a_decimalPrecision) && a_decimalPrecision >= 0) ? a_decimalPrecision : NumberFormatter.DEFAULT_PRECISION;
    var secondPart = parts.length > 1 ? parts[1] : "00";  
    if(secondPart.trim() == ""){
        secondPart = "00";
    }
  
    var tSepIndex = firstPart.indexOf(tSep);
    while(tSepIndex >= 0){
        firstPart = firstPart.replace(tSep, "");
        tSepIndex = firstPart.indexOf(tSep, tSepIndex);
    }
    if(isNumberOnly){
        return parseInt(firstPart);
    }else{
        if(isNaN(firstPart) || isNaN(secondPart))
        {
            return NaN;
        }  
        //alert(Math.round(parseFloat(firstPart + "." + secondPart)*Math.pow(10,decPrec))/Math.pow(10,decPrec));
        return Math.round(parseFloat(firstPart + "." + secondPart)*Math.pow(10, decPrec)) / Math.pow(10, decPrec);
    }
}

function roundVal(val, decPrec){
    var result = Math.round(val * Math.pow(10, decPrec)) / Math.pow(10, decPrec);
    return result;
}

/**
 * please do not use this, use the formatDecimal instead
 *
 * @deprecated
 */
NumberFormatter.formatNumber = function(num2Format){
    return NumberFormatter.formatDecimal(num2Format, true);
}

NumberFormatter.formatDecimal = function(num2Format, isNumberOnly, a_decimalPrecision){
    if(isNaN(num2Format)){
        return num2Format;
    }
  
    if(!isFinite(num2Format)){
        return num2Format;
    }
  
    if(typeof(num2Format) == 'number'){
        num2Format = num2Format.toString();
    }
  
    if(num2Format == ""){
        return "";
    }
  
    var tSep = NumberFormatter._tSep;
    var dSep = NumberFormatter._dSep;
    var decPrec = (typeof(a_decimalPrecision) != "undefined" && !isNaN(a_decimalPrecision) && a_decimalPrecision >= 0) ? a_decimalPrecision : NumberFormatter.DEFAULT_PRECISION;
    var formattedNum = parseFloat(num2Format).toFixed(decPrec);
    var isMinus = formattedNum < 0;
    var parts = String(Math.abs(formattedNum)).split('.');
    var firstPart = parts[0];
    var secondPart = parts.length > 1 ? parts[1] + NumberFormatter.getLeading0s(decPrec - parts[1].length) : NumberFormatter.getLeading0s(decPrec);
    if(firstPart.length <= 3){      
        if(isMinus){
            firstPart = "-" + firstPart;
        }
      
        if(decPrec > 0 && !isNumberOnly) {
            return (firstPart + dSep + secondPart);
        }
      
        return firstPart;                  
    }
  
    var newStr = "";
    for(var i = firstPart.length - 1; i >= 0; i--){
        newStr = firstPart.charAt(i) + newStr ;
        if(i == firstPart.length - 1){
            continue;
        }
        if(i == 0){
            continue;
        }
        var d = (firstPart.length - i) / 3;
        if(Math.ceil(d) == Math.floor(d)){
            newStr = tSep + newStr;
        }
    }
    if(isMinus){
        newStr = "-" + newStr;
    }
    if(isNumberOnly){
        return newStr;
    }
    return newStr + (decPrec > 0 ? (dSep + secondPart) : "");
}

NumberFormatter.validateInput = function(inputText, isNumberOnly, isToAllowNegetive, isMandatory, a_decimalPrecision){
    if(typeof(inputText) == 'number'){
        inputText = inputText.toString();
    }
  
    var returnObject = new Object();
    var decPrec = (typeof(a_decimalPrecision) != "undefined"  && !isNaN(a_decimalPrecision) && a_decimalPrecision >= 0) ? a_decimalPrecision : NumberFormatter.DEFAULT_PRECISION;
  
    //lets test blank input
    if(isMandatory && String(inputText).trim().length <= 0){
        returnObject.message = "BLANK_INPUT";
        returnObject.isValid = false;
        return returnObject;
    }
  
    //no white space is allowed
    if(inputText.indexOf(" ") >= 0){
        returnObject.message = "WHITE_SPACE_IN_INPUT";
        returnObject.isValid = false;
        return returnObject;
    }
  
    //check valid chars
    var ln = inputText.length;
    for(var iCounter = 0; iCounter < ln; iCounter++){
        var currentChar = inputText.charAt(iCounter);
        //if the first char is minus then let it go
        if(isToAllowNegetive && iCounter == 0 && currentChar == '-'){
            continue;
        }
        if(isValidChar(currentChar) == false){
            returnObject.message = "INVALID_CHARACTER_IN_INPUT";
            returnObject.isValid = false;
            return returnObject;
        }
    }
  
    if(isNumberOnly && inputText.indexOf(NumberFormatter._dSep) >= 0){
        returnObject.message = "DECIMAL_NOT_ALLOWED";
        returnObject.isValid = false;
        return returnObject;
    }
  
    var firstChar = inputText.charAt(0);
    var lnToTest = inputText.split(NumberFormatter._tSep).join("").length;
    if(firstChar == '-'){
        lnToTest = lnToTest - 1;
    }
    if(lnToTest > 15){
        returnObject.message = "TOO_LONG_INPUT";
        returnObject.isValid = false;
        return returnObject;
    }
  
    //check single decimal separator
    var parts = inputText.split(NumberFormatter._dSep);              
    if(parts.length > 2){
        returnObject.message = "MULTIPLE_DECIMAL_SEPARATOR";
        returnObject.isValid = false;
        return returnObject;
    }
  
    var firstPart = parts[0];
    var secondPart = parts[1];
  
    //in the decimal part there can not be thousand separator
    if(secondPart!= null && secondPart.length > 0 && secondPart.indexOf(NumberFormatter._tSep) >= 0){
        returnObject.message = "THOUSAND_SEPARATOR_IN_DECIMAL_PART";
        returnObject.isValid = false;
        return returnObject;
    }
  
    if(NumberFormatter.IS_STRICT_THOUSAND_SEPARATOR_VALIDATION){
        var thousandParts = firstPart.split(NumberFormatter._tSep);
        for(var iCounter = thousandParts.length - 1; iCounter > 0; iCounter--){
            if(thousandParts[iCounter].length != 3){
                returnObject.message = "INVALID_POSITIONING_OF_THOUSAND_SEPARATOR";
                returnObject.isValid = false;
                return returnObject;
            }
        }
    }
  
    /*if(secondPart.length > decPrec){
        returnObject.message = "TOO_LONG_DECIMAL_PART";
        returnObject.isValid = false;
        return returnObject;
    }*/
  
    returnObject.message = "VALID_NUMBER";
    returnObject.isValid = true;
    return returnObject;
}

NumberFormatter.formatCurrency = function(num2Format){
    return NumberFormatter.formatDecimal(num2Format);
}

NumberFormatter.getLeading0s = function(decPrec) {
    var s0s=[];
    for(var i = 0; i < decPrec; i++) {
        s0s.push('0');
    }
    return s0s.join('');
}

function isValidChar(charToTest){
    switch(charToTest){
        case '0':
            return true;
        case '1':
            return true;
        case '2':
            return true;
        case '3':
            return true;
        case '4':
            return true;
        case '5':
            return true;
        case '6':
            return true;
        case '7':
            return true;
        case '8':
            return true;
        case '9':
            return true;
        case '.':
            return true;
        case ',':
            return true;
        default:
            return false;
    }  
}



Hope this will help you all. So long till next time...



Saturday, November 12, 2011

Java Hibernate Multiple Map into One Table

Hi Friends,

Recently I was trying to do something different. I could not find exact solution what I was looking for. Thus sharing here. Some one else might be benefited by this.

Now I will get straight to the point. First the problem statement:

I have a Java class like this


import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;

/**
 * @author: Aniruddha Dutta Chowdhury

 *
 */
public class HibernateDemo implements Serializable {
    private static Logger        logger            = Logger.getLogger(HibernateDemo.class);

    private Map    requestData        = new HashMap();
    private Map    contextData        = new HashMap();
    private Map    responsetData    = new HashMap();
    private Date                timeOfAction    = null;
    private Long                id                = null;
   
    public Map getResponsetData() {
        return responsetData;
    }
   
    public void setResponsetData(Map responsetData) {
        this.responsetData = responsetData;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Date getTimeOfAction() {
        return timeOfAction;
    }

    public void setTimeOfAction(Date timeOfAction) {
        this.timeOfAction = timeOfAction;
    }

    public Map getRequestData() {
        return requestData;
    }

    public void setRequestData(Map requestData) {
        this.requestData = requestData;
    }

    public Map getContextData() {
        return contextData;
    }

    public void setContextData(Map contextData) {
        this.contextData = contextData;
    }

    public Map getResponseData() {
        return responseData;
    }

    public void setResponseData(Map responseData) {
        this.responseData = responseData;
    }

    private Map    responseData    = new HashMap();
}


And I wanted only two tables for this whole class. One for the main class and another one for all the map members.

Desired tables are as follows:


MAIN_TABLE
ID PK
ACTION_TIME


AND the child table would be


CHILD_TABLE
PARENT_ID FK
KEY
VALUE
DISCRIMINATOR

Now this is not a big deal for hibernate. Using the where clause. But the question comes that how to fill the value for discriminator. Then after going through hibernate api I came up with this. The SQL-INSERT is really very handy in this case.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping
    PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
    <class name="HibernateDemo" table="MAIN_TABLE">
        <id name="id">
            <generator class="native" />
        </id>
        <property name="timeOfAction" />
        <map name="requestData" table="CHILD_TABLE" where="DISCRIMENATOR='REQUEST'">       
            <key column="PARENT_ID" />
            <index column="KEY" type="string" />
            <element column="VALUE" type="string" />
            <sql-insert>insert into CHILD_TABLE (PARENT_ID, KEY, VALUE, DISCRIMENATOR) values (?, ?, ?, 'REQUEST')</sql-insert>
        </map>
       
        <map name="contextData" table="CHILD_TABLE" where="DISCRIMENATOR='CONTEXT'">       
            <key column="PARENT_ID" />
            <index column="KEY" type="string" />
            <element column="VALUE" type="string" />
            <sql-insert>insert into CHILD_TABLE (PARENT_ID, KEY, VALUE, DISCRIMENATOR) values (?, ?, ?, 'CONTEXT')</sql-insert>
        </map>
       
        <map name="responsetData" table="CHILD_TABLE" where="DISCRIMENATOR='RESPONSE'">       
            <key column="PARENT_ID" />
            <index column="KEY" type="string" />
            <element column="VALUE" type="string" />
            <sql-insert>insert into CHILD_TABLE (PARENT_ID, KEY, VALUE, DISCRIMENATOR) values (?, ?, ?, 'RESPONSE')</sql-insert>
        </map>
    </class>
</hibernate-mapping>



Hope this will help you. Till next time, BYE.

Sunday, September 25, 2011

Start command prompt from context menu in windows

Hi folks,

Again another techie blog.

 This is to solve a simple problem we all face quite often in our daily life. Mainly QA person and developers face this. For getting Command prompt from any opened folder we have to open command prompt then copy the path then paste and ...... long process... Huh..

So here is a simple solution, copy the following text in a .reg file and save that. Now run it once, In some secured system it may ask for admin rights, as it will update the registry. But no worry, just allow it. After that on any right click of any folder will give u an option to open command prompt from there.

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Directory\shell\startCmd]
@="Start Command Prompt From Here"
"@author"="Aniruddha Dutta Chowdhury"

[HKEY_CLASSES_ROOT\Directory\shell\startCmd\command]
@="cmd /k pushd \"%1\""

Saturday, August 27, 2011

Apache log4j queue appender

Hi friends,

Starting another techie post. This is regarding apache log4j appenders. I was using log4j for quite some time. It is excellent one. It has got almost everything required for normal to advanced logging, except if we use it extensively then the application tends to slow down a bit, like if we use the mail and DB appender then the application slows down. Thats not a fault of the system. It will slow down. To solve this we have JMS appender. put every thing in the JMS queue and then read from there and again resend to respective appender. In this we have a small catch. That is, the utility have the JMS appender but it does not have a reader. and to avail this we need to be on J2EE container.

So to solve this I just made one small class which can take care of this situation. This is having a internal JDK5 queue and reader as well. So application does not slows down and all kind of logging we can do.


The Java class:

import java.util.Enumeration;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

import org.apache.log4j.Appender;
import org.apache.log4j.AppenderSkeleton;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.spi.LoggingEvent;

/**
 * @author: Aniruddha Dutta Chowdhury
 * @since: 11-Aug-2011 : 4:35:01 PM
 */

public class QuedAppender extends AppenderSkeleton {

    private Appender[]            targetAppender        = null;
    private String                adapter                = null;
    private Queue    loggingEventQueue    = null;
    private boolean                isActive            = false;
    private Executor            executor            = null;

    public QuedAppender() {
        loggingEventQueue = new ConcurrentLinkedQueue();
        System.out.println("QuedAppender.QuedAppender()");
        startQueueCheck();
    }

    private void startQueueCheck() {
        Thread l_th = new Thread(new Runnable() {
            @Override
            public void run() {
                callTargetAppender();
            }
        });
        // l_th.setDaemon(true);
        l_th.setName("QuedAppenderChecker");
        l_th.start();
    }

    public void setQueueSize(String a_queueSize) {
        try {
            executor = Executors.newFixedThreadPool(Integer.parseInt(a_queueSize), new ThreadFactory() {

                @Override
                public Thread newThread(Runnable r) {
                    Thread l_th = new Thread(r);
                    l_th.setDaemon(true);
                    return l_th;
                }
            });
        } catch (NumberFormatException a_numberFormatExceptionIgnore) {
        }
    }

    public String getTargetAppender() {
        return adapter;
    }

    public void setTargetAppender(String a_adapter) {
        // System.out.println("QuedAppender.setTargetAppender(" + a_adapter +")");
        if (targetAppender != null) {
            return;
        }

        adapter = a_adapter;
        String[] l_appenders = adapter.split(",");
        targetAppender = new Appender[l_appenders.length];
        int iCounter = 0;
        for (String l_ap : l_appenders) {
            targetAppender[iCounter] = getAppenderById(l_ap.trim());

            if (targetAppender[iCounter] == null) {
                targetAppender = null;
                return;
            }
            iCounter++;
        }
        // targetAppender = getAppenderById(a_adapter);
    }

    public static Appender getAppenderById(String a_strAppenderName) {
        Logger logger = LogManager.getLogger("app.logger.DummyLogger");
        Appender l_targetAppender = logger.getAppender(a_strAppenderName);
        return l_targetAppender;
    }

    private static void printAllAppenders() {
        Enumeration allLoggers = LogManager.getCurrentLoggers();
        while (allLoggers.hasMoreElements()) {
            Logger l = (Logger) allLoggers.nextElement();
            Enumeration appernders = l.getAllAppenders();
            while (appernders.hasMoreElements()) {
                Appender l_ap = (Appender) appernders.nextElement();
                System.out.println("QuedAppender.getAppenderById()" + l_ap.getName());
            }
        }
    }

    @Override
    protected void append(LoggingEvent loggingEvent) {
        if (executor == null) {
            setQueueSize("5");
        }

        if (targetAppender == null) {
            setTargetAppender(adapter);
        }

        if (targetAppender == null || targetAppender.length <= 0) {
            throw new RuntimeException("Target appender is properly not initialised. Please do that first before you start this");
        }

        System.out.println("QuedAppender.append(" + loggingEvent.getLoggerName() + ")");
        loggingEventQueue.offer(loggingEvent);

        try {
            Thread.sleep(100);
        } catch (Throwable a_th) {
        }

        startQueueCheck();
    }

    /**
     * nothing much to do, so just keep it like this
     */
    @Override
    public void close() {
    }

    @Override
    public boolean requiresLayout() {
        return false;
    }

    private void callTargetAppender() {
        LoggingEvent loggingEvent = null;

        /**
         * check is already running then just ignore it
         */
        if (isActive) {
            return;
        }

        /**
         * now mark as this method in action
         */
        isActive = true;

        while ((loggingEvent = loggingEventQueue.poll()) != null) {
            executor.execute(new TargetLogger(loggingEvent, targetAppender));
            try {
                Thread.sleep(100);
            } catch (Throwable a_th) {
            }
        }

        /**
         * lets set it false for others to access
         */
        isActive = false;
    }

    private class TargetLogger implements Runnable {
        private LoggingEvent    loggingEvent    = null;
        private Appender[]        targetAppenders    = null;

        public TargetLogger(LoggingEvent loggingEvent, Appender[] a_targetAppenders) {
            this.loggingEvent = loggingEvent;
            targetAppenders = a_targetAppenders;
        }

        @Override
        public void run() {
            for (Appender targetAppender : targetAppenders) {
                if (((AppenderSkeleton) targetAppender).getThreshold() == null || ((AppenderSkeleton) targetAppender).getThreshold().toInt() <= loggingEvent.getLevel().toInt()) {
                    targetAppender.doAppend(loggingEvent);
                }
            }
        }
    }
}

The Sample Log4j.properties:

log4j.rootLogger=DEBUG,quedAppender

#a dummy logger to initialized, so that all appenders can be loaded
log4j.logger.app.logger.DummyLogger=DEBUG,sendMail,CA,FA

log4j.appender.sendMail=org.apache.log4j.net.SMTPAppender
log4j.appender.sendMail.Threshold=ERROR
log4j.appender.sendMail.To=to@target.com
log4j.appender.sendMail.From=from@source.com
log4j.appender.sendMail.SMTPHost=smtp.source.com
log4j.appender.sendMail.Subject=iSource @ on []
log4j.appender.sendMail.layout=org.apache.log4j.PatternLayout
log4j.appender.sendMail.layout.ConversionPattern=[%d{ISO8601}]%n%n%-5p%n%n%c%n%n%m%n%n
log4j.appender.sendMail.BufferSize=1
#log4j.appender.sendMail.SMTPDebug=true

log4j.appender.quedAppender=QuedAppender
log4j.appender.quedAppender.Threshold=DEBUG
log4j.appender.quedAppender.targetAppender=sendMail, CA, FA

log4j.appender.RquedAppender=QuedAppender
log4j.appender.RquedAppender.Threshold=DEBUG
log4j.appender.RquedAppender.targetAppender=FA

#Console Appender
log4j.appender.CA=org.apache.log4j.ConsoleAppender
log4j.appender.CA.layout=org.apache.log4j.PatternLayout
log4j.appender.CA.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
log4j.appender.CA.Threshold=DEBUG

#File Appender
log4j.appender.FA=org.apache.log4j.FileAppender
log4j.appender.FA.File=sample.log
log4j.appender.FA.layout=org.apache.log4j.PatternLayout
log4j.appender.FA.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
log4j.appender.FA.Threshold=INFO

In this sample log4j.properties the dummy logger is required for finding all required appender. I could not come up with any other mechanism.

If any one has any suggestion or modification proposal, please put forward. I would be glad to know that.