FileDocCategorySizeDatePackage
NumberCruncherServer.javaAPI DocApache log4j 1.2.155691Sat Aug 25 00:09:44 BST 2007examples

NumberCruncherServer

public class NumberCruncherServer extends UnicastRemoteObject implements NumberCruncher
A simple {@link NumberCruncher} implementation that logs its progress when factoring numbers. The purpose of the whole exercise is to show the use of nested diagnostic contexts in order to distinguish the log output from different client requests.
Usage: java org.apache.log4j.examples.NumberCruncherServer configFile
      where configFile is a log4j configuration file.
We supply a simple config file factor.lcf for directing log output to the file factor.log.

Try it yourself by starting a NumberCruncherServer and make queries from multiple {@link NumberCruncherClient NumberCruncherClients} to factor numbers.

Sample output shows the log output when two clients connect to the server near simultaneously.

See source code of NumberCruncherServer for more details.

Note that class files for the example code is not included in any of the distributed log4j jar files. You will have to add the directory /dir-where-you-unpacked-log4j/classes to your classpath before trying out the examples.

Fields Summary
private static final long
serialVersionUID
static Logger
logger
Constructors Summary
public NumberCruncherServer()


  
     
  
Methods Summary
public static voiddelay(int millis)

    try{Thread.sleep(millis);}
    catch(InterruptedException e) {}
  
public int[]factor(int number)


    // The client's host is an important source of information.
    try {
      NDC.push(getClientHost());
    }
    catch(java.rmi.server.ServerNotActiveException e) {
      // we are being called from same VM
      NDC.push("localhost");
    }

    // The information contained within the request is another source of
    // distinctive information. It might reveal the users name, date of request,
    // request ID etc. In servlet type environments, much information is
    // contained in cookies.
    NDC.push(String.valueOf(number));    

    logger.info("Beginning to factor.");
    if(number <= 0) {
      throw new IllegalArgumentException(number+" is not a positive integer.");
    }
    else if(number == 1)
       return new int[] {1};
    
    Vector factors = new Vector();
    int n = number;

    for(int i = 2; (i <= n) && (i*i <= number); i++) {
      // It is bad practice to place log requests within tight loops.
      // It is done here to show interleaved log output from
      // different requests. 
      logger.debug("Trying to see if " + i + " is a factor.");

      if((n % i) == 0) {
	logger.info("Found factor "+i);
	factors.addElement(new Integer(i));
	do {
	  n /= i;
	} while((n % i) == 0);
      }
      // Placing artificial delays in tight-loops will also lead to sub-optimal
      // resuts. :-)
      delay(100);
    }

    if(n != 1) {
      logger.info("Found factor "+n);
      factors.addElement(new Integer(n));
    }
    
    int len = factors.size();
    
    int[] result = new int[len];
    for(int i = 0; i < len; i++) {
      result[i] = ((Integer) factors.elementAt(i)).intValue();
    }

    // Before leaving a thread we call NDC.remove. This deletes the reference
    // to the thread in the internal hash table. Version 0.8.5 introduces a
    // a lazy removal mechanism in case you forget to call remove when
    // exiting a thread. See the java documentation in NDC.remove for further
    // details.
    NDC.remove();
    
    return result;
  
public static voidmain(java.lang.String[] args)

    if(args.length != 1) 
      usage("Wrong number of arguments.");
    
    NumberCruncherServer ncs;
    PropertyConfigurator.configure(args[0]);
    try {
      ncs = new NumberCruncherServer();
      Naming.rebind("Factor", ncs);
      logger.info("NumberCruncherServer bound and ready to serve.");
    }
    catch(Exception e) {
      logger.error("Could not bind NumberCruncherServer.", e);
      return;
    }
    NumberCruncherClient.loop(ncs);          
  
static voidusage(java.lang.String msg)

    System.err.println(msg);
    System.err.println(
     "Usage: java org.apache.log4j.examples.NumberCruncherServer configFile\n" +
     "   where configFile is a log4j configuration file.");
    System.exit(1);