KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > examples > NumberCruncherServer


1 /*
2  * Copyright 1999-2005 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package examples;
18
19 import java.rmi.Remote JavaDoc;
20 import java.rmi.server.UnicastRemoteObject JavaDoc;
21 import java.rmi.RemoteException JavaDoc;
22 import java.rmi.Naming JavaDoc;
23 import java.util.Vector JavaDoc;
24
25
26 import org.apache.log4j.Logger;
27 import org.apache.log4j.NDC;
28 import org.apache.log4j.PropertyConfigurator;
29
30 /**
31    A simple {@link NumberCruncher} implementation that logs its
32    progress when factoring numbers. The purpose of the whole exercise
33    is to show the use of nested diagnostic contexts in order to
34    distinguish the log output from different client requests.
35
36    <pre>
37    <b>Usage:</b> java org.apache.log4j.examples.NumberCruncherServer <em>configFile</em>
38     &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;where <em>configFile</em> is a log4j configuration file.
39    </pre>
40
41    We supply a simple config file <a HREF=doc-files/factor.lcf>factor.lcf</a>
42    for directing log output to the file <code>factor.log</code>.
43
44    <p>Try it yourself by starting a <code>NumberCruncherServer</code>
45    and make queries from multiple {@link NumberCruncherClient
46    NumberCruncherClients} to factor numbers.
47
48    
49    <p><b><a HREF="doc-files/factor.html">Sample output</a></b> shows the log
50    output when two clients connect to the server near simultaneously.
51       
52    <p>See <a HREF=doc-files/NumberCruncherServer.java>source</a> code
53    of <code>NumberCruncherServer</code> for more details.
54
55    <p>Note that class files for the example code is not included in
56    any of the distributed log4j jar files. You will have to add the
57    directory <code>/dir-where-you-unpacked-log4j/classes</code> to
58    your classpath before trying out the examples.
59
60    
61  */

62 public class NumberCruncherServer extends UnicastRemoteObject JavaDoc
63                                   implements NumberCruncher {
64
65
66   static Logger logger = Logger.getLogger(NumberCruncherServer.class);
67
68   public
69   NumberCruncherServer() throws RemoteException JavaDoc {
70   }
71   
72   public
73   int[] factor(int number) throws RemoteException JavaDoc {
74
75     // The client's host is an important source of information.
76
try {
77       NDC.push(this.getClientHost());
78     }
79     catch(java.rmi.server.ServerNotActiveException JavaDoc e) {
80       // we are being called from same VM
81
NDC.push("localhost");
82     }
83
84     // The information contained within the request is another source of
85
// distinctive information. It might reveal the users name, date of request,
86
// request ID etc. In servlet type environments, much information is
87
// contained in cookies.
88
NDC.push(String.valueOf(number));
89
90     logger.info("Beginning to factor.");
91     if(number <= 0) {
92       throw new IllegalArgumentException JavaDoc(number+" is not a positive integer.");
93     }
94     else if(number == 1)
95        return new int[] {1};
96     
97     Vector JavaDoc factors = new Vector JavaDoc();
98     int n = number;
99
100     for(int i = 2; (i <= n) && (i*i <= number); i++) {
101       // It is bad practice to place log requests within tight loops.
102
// It is done here to show interleaved log output from
103
// different requests.
104
logger.debug("Trying to see if " + i + " is a factor.");
105
106       if((n % i) == 0) {
107     logger.info("Found factor "+i);
108     factors.addElement(new Integer JavaDoc(i));
109     do {
110       n /= i;
111     } while((n % i) == 0);
112       }
113       // Placing artificial delays in tight-loops will also lead to sub-optimal
114
// resuts. :-)
115
delay(100);
116     }
117
118     if(n != 1) {
119       logger.info("Found factor "+n);
120       factors.addElement(new Integer JavaDoc(n));
121     }
122     
123     int len = factors.size();
124     
125     int[] result = new int[len];
126     for(int i = 0; i < len; i++) {
127       result[i] = ((Integer JavaDoc) factors.elementAt(i)).intValue();
128     }
129
130     // Before leaving a thread we call NDC.remove. This deletes the reference
131
// to the thread in the internal hash table. Version 0.8.5 introduces a
132
// a lazy removal mechanism in case you forget to call remove when
133
// exiting a thread. See the java documentation in NDC.remove for further
134
// details.
135
NDC.remove();
136     
137     return result;
138   }
139
140   static
141   void usage(String JavaDoc msg) {
142     System.err.println(msg);
143     System.err.println(
144      "Usage: java org.apache.log4j.examples.NumberCruncherServer configFile\n" +
145      " where configFile is a log4j configuration file.");
146     System.exit(1);
147   }
148
149   public static
150   void delay(int millis) {
151     try{Thread.currentThread().sleep(millis);}
152     catch(InterruptedException JavaDoc e) {}
153   }
154   
155   public static void main(String JavaDoc[] args) {
156     if(args.length != 1)
157       usage("Wrong number of arguments.");
158     
159     NumberCruncherServer ncs;
160     PropertyConfigurator.configure(args[0]);
161     try {
162       ncs = new NumberCruncherServer();
163       Naming.rebind("Factor", ncs);
164       logger.info("NumberCruncherServer bound and ready to serve.");
165     }
166     catch(Exception JavaDoc e) {
167       logger.error("Could not bind NumberCruncherServer.", e);
168       return;
169     }
170     NumberCruncherClient.loop(ncs);
171   }
172 }
173
Popular Tags