1
2
3
4
5
6
7
8
9
10
11
12
13
14 package chapter7;
15
16 import java.rmi.RemoteException;
17 import java.rmi.registry.LocateRegistry;
18 import java.rmi.registry.Registry;
19 import java.rmi.server.UnicastRemoteObject;
20 import java.util.Vector;
21
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24 import org.slf4j.MDC;
25
26 import ch.qos.logback.classic.LoggerContext;
27 import ch.qos.logback.classic.joran.JoranConfigurator;
28 import ch.qos.logback.core.joran.spi.JoranException;
29
30
31
32
33
34
35
36
37 public class NumberCruncherServer extends UnicastRemoteObject
38 implements NumberCruncher {
39
40 private static final long serialVersionUID = 1L;
41
42 static Logger logger = LoggerFactory.getLogger(NumberCruncherServer.class);
43
44 public NumberCruncherServer() throws RemoteException {
45 }
46
47 public int[] factor(int number) throws RemoteException {
48
49 try {
50 MDC.put("client", NumberCruncherServer.getClientHost());
51 } catch (java.rmi.server.ServerNotActiveException e) {
52 logger.warn("Caught unexpected ServerNotActiveException.", e);
53 }
54
55
56
57
58
59
60 MDC.put("number", String.valueOf(number));
61
62 logger.info("Beginning to factor.");
63
64 if (number <= 0) {
65 throw new IllegalArgumentException(number +
66 " is not a positive integer.");
67 } else if (number == 1) {
68 return new int[] { 1 };
69 }
70
71 Vector<Integer> factors = new Vector<Integer>();
72 int n = number;
73
74 for (int i = 2; (i <= n) && ((i * i) <= number); i++) {
75
76
77
78 logger.debug("Trying " + i + " as a factor.");
79
80 if ((n % i) == 0) {
81 logger.info("Found factor " + i);
82 factors.addElement(new Integer(i));
83
84 do {
85 n /= i;
86 } while ((n % i) == 0);
87 }
88
89
90
91 delay(100);
92 }
93
94 if (n != 1) {
95 logger.info("Found factor " + n);
96 factors.addElement(new Integer(n));
97 }
98
99 int len = factors.size();
100
101 int[] result = new int[len];
102
103 for (int i = 0; i < len; i++) {
104 result[i] = ((Integer) factors.elementAt(i)).intValue();
105 }
106
107
108 MDC.remove("client");
109 MDC.remove("number");
110
111 return result;
112 }
113
114 static void usage(String msg) {
115 System.err.println(msg);
116 System.err.println("Usage: java chapter7.NumberCruncherServer configFile\n" +
117 " where configFile is a logback configuration file.");
118 System.exit(1);
119 }
120
121 public static void delay(int millis) {
122 try {
123 Thread.sleep(millis);
124 } catch (InterruptedException e) {
125 }
126 }
127
128 public static void main(String[] args) {
129 if (args.length != 1) {
130 usage("Wrong number of arguments.");
131 }
132
133 String configFile = args[0];
134
135 if (configFile.endsWith(".xml")) {
136 try {
137 LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
138 JoranConfigurator configurator = new JoranConfigurator();
139 configurator.setContext(lc);
140 lc.reset();
141 configurator.doConfigure(args[0]);
142 } catch (JoranException je) {
143 je.printStackTrace();
144 }
145 }
146
147 NumberCruncherServer ncs;
148
149 try {
150 ncs = new NumberCruncherServer();
151 logger.info("Creating registry.");
152
153 Registry registry = LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
154 registry.rebind("Factor", ncs);
155 logger.info("NumberCruncherServer bound and ready.");
156 } catch (Exception e) {
157 logger.error("Could not bind NumberCruncherServer.", e);
158
159 return;
160 }
161 }
162 }