PageRenderTime 209ms CodeModel.GetById 20ms RepoModel.GetById 21ms app.codeStats 0ms

/apache-log4j-1.2.17/examples/NumberCruncherServer.java

#
Java | 172 lines | 85 code | 23 blank | 64 comment | 14 complexity | d5f2c7fbc9e5166e9e11aa4c1b7bb879 MD5 | raw file
Possible License(s): Apache-2.0
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. package examples;
  18. import java.rmi.server.UnicastRemoteObject;
  19. import java.rmi.RemoteException;
  20. import java.rmi.Naming;
  21. import java.util.Vector;
  22. import org.apache.log4j.Logger;
  23. import org.apache.log4j.NDC;
  24. import org.apache.log4j.PropertyConfigurator;
  25. /**
  26. A simple {@link NumberCruncher} implementation that logs its
  27. progress when factoring numbers. The purpose of the whole exercise
  28. is to show the use of nested diagnostic contexts in order to
  29. distinguish the log output from different client requests.
  30. <pre>
  31. <b>Usage:</b> java org.apache.log4j.examples.NumberCruncherServer <em>configFile</em>
  32. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;where <em>configFile</em> is a log4j configuration file.
  33. </pre>
  34. We supply a simple config file <a href=doc-files/factor.lcf>factor.lcf</a>
  35. for directing log output to the file <code>factor.log</code>.
  36. <p>Try it yourself by starting a <code>NumberCruncherServer</code>
  37. and make queries from multiple {@link NumberCruncherClient
  38. NumberCruncherClients} to factor numbers.
  39. <p><b><a href="doc-files/factor.html">Sample output</a></b> shows the log
  40. output when two clients connect to the server near simultaneously.
  41. <p>See <a href=doc-files/NumberCruncherServer.java>source</a> code
  42. of <code>NumberCruncherServer</code> for more details.
  43. <p>Note that class files for the example code is not included in
  44. any of the distributed log4j jar files. You will have to add the
  45. directory <code>/dir-where-you-unpacked-log4j/classes</code> to
  46. your classpath before trying out the examples.
  47. */
  48. public class NumberCruncherServer extends UnicastRemoteObject
  49. implements NumberCruncher {
  50. private static final long serialVersionUID = 2626753561969426769L;
  51. static Logger logger = Logger.getLogger(NumberCruncherServer.class);
  52. public
  53. NumberCruncherServer() throws RemoteException {
  54. }
  55. public
  56. int[] factor(int number) throws RemoteException {
  57. // The client's host is an important source of information.
  58. try {
  59. NDC.push(getClientHost());
  60. }
  61. catch(java.rmi.server.ServerNotActiveException e) {
  62. // we are being called from same VM
  63. NDC.push("localhost");
  64. }
  65. // The information contained within the request is another source of
  66. // distinctive information. It might reveal the users name, date of request,
  67. // request ID etc. In servlet type environments, much information is
  68. // contained in cookies.
  69. NDC.push(String.valueOf(number));
  70. logger.info("Beginning to factor.");
  71. if(number <= 0) {
  72. throw new IllegalArgumentException(number+" is not a positive integer.");
  73. }
  74. else if(number == 1)
  75. return new int[] {1};
  76. Vector factors = new Vector();
  77. int n = number;
  78. for(int i = 2; (i <= n) && (i*i <= number); i++) {
  79. // It is bad practice to place log requests within tight loops.
  80. // It is done here to show interleaved log output from
  81. // different requests.
  82. logger.debug("Trying to see if " + i + " is a factor.");
  83. if((n % i) == 0) {
  84. logger.info("Found factor "+i);
  85. factors.addElement(new Integer(i));
  86. do {
  87. n /= i;
  88. } while((n % i) == 0);
  89. }
  90. // Placing artificial delays in tight-loops will also lead to sub-optimal
  91. // resuts. :-)
  92. delay(100);
  93. }
  94. if(n != 1) {
  95. logger.info("Found factor "+n);
  96. factors.addElement(new Integer(n));
  97. }
  98. int len = factors.size();
  99. int[] result = new int[len];
  100. for(int i = 0; i < len; i++) {
  101. result[i] = ((Integer) factors.elementAt(i)).intValue();
  102. }
  103. // Before leaving a thread we call NDC.remove. This deletes the reference
  104. // to the thread in the internal hash table. Version 0.8.5 introduces a
  105. // a lazy removal mechanism in case you forget to call remove when
  106. // exiting a thread. See the java documentation in NDC.remove for further
  107. // details.
  108. NDC.remove();
  109. return result;
  110. }
  111. static
  112. void usage(String msg) {
  113. System.err.println(msg);
  114. System.err.println(
  115. "Usage: java org.apache.log4j.examples.NumberCruncherServer configFile\n" +
  116. " where configFile is a log4j configuration file.");
  117. System.exit(1);
  118. }
  119. public static
  120. void delay(int millis) {
  121. try{Thread.sleep(millis);}
  122. catch(InterruptedException e) {}
  123. }
  124. public static void main(String[] args) {
  125. if(args.length != 1)
  126. usage("Wrong number of arguments.");
  127. NumberCruncherServer ncs;
  128. PropertyConfigurator.configure(args[0]);
  129. try {
  130. ncs = new NumberCruncherServer();
  131. Naming.rebind("Factor", ncs);
  132. logger.info("NumberCruncherServer bound and ready to serve.");
  133. }
  134. catch(Exception e) {
  135. logger.error("Could not bind NumberCruncherServer.", e);
  136. return;
  137. }
  138. NumberCruncherClient.loop(ncs);
  139. }
  140. }