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