1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.river.start;
20
21 import java.io.BufferedInputStream;
22 import java.io.BufferedOutputStream;
23 import java.io.File;
24 import java.io.FileInputStream;
25 import java.io.FileOutputStream;
26 import java.io.IOException;
27 import java.io.InvalidObjectException;
28 import java.io.ObjectInputStream;
29 import java.io.ObjectOutputStream;
30 import java.io.ObjectStreamException;
31 import java.io.Serializable;
32 import java.rmi.MarshalledObject;
33 import java.rmi.activation.ActivationException;
34 import java.rmi.activation.ActivationGroupDesc;
35 import java.rmi.activation.ActivationGroupDesc.CommandEnvironment;
36 import java.rmi.activation.ActivationGroupID;
37 import java.rmi.activation.ActivationSystem;
38 import java.util.ArrayList;
39 import java.util.Arrays;
40 import java.util.Properties;
41 import java.util.logging.Logger;
42 import net.jini.config.Configuration;
43 import net.jini.io.MarshalledInstance;
44 import org.apache.river.api.io.AtomicSerial;
45 import org.apache.river.api.io.AtomicSerial.GetArg;
46 import org.apache.river.api.io.Valid;
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63 @AtomicSerial
64 public class SharedActivationGroupDescriptor
65 implements ServiceDescriptor, Serializable
66 {
67 private static final long serialVersionUID = 1L;
68
69
70
71
72
73 private final String policy;
74
75
76
77
78
79 private final String classpath;
80
81
82
83
84
85 private final String log;
86
87
88
89
90
91 private final String serverCommand;
92
93
94
95
96
97 private final String[] serverOptions;
98
99
100
101
102
103 private final Properties serverProperties;
104
105
106
107
108
109 private final String host;
110
111
112
113
114
115 private final int port;
116
117 private static final String GROUP_COOKIE_FILE = "cookie";
118
119 private static final Logger logger = ServiceStarter.logger;
120
121
122
123
124
125
126
127
128 public SharedActivationGroupDescriptor(
129
130 String policy, String classpath, String log,
131
132 String serverCommand, String[] serverOptions,
133 String[] serverProperties)
134 {
135 this(policy, classpath, log, serverCommand, serverOptions,
136 serverProperties, null,
137 ServiceStarter.getActivationSystemPort());
138 }
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162 public SharedActivationGroupDescriptor(
163
164 String policy, String classpath, String log,
165
166 String serverCommand, String[] serverOptions,
167 String[] serverProperties, String host, int port)
168 {
169 if (policy == null || classpath == null || log == null) {
170 throw new NullPointerException(
171 "Policy, classpath, or log cannot be null");
172 }
173 this.policy = policy;
174 this.classpath = classpath;
175 this.log = log;
176 this.serverCommand = serverCommand;
177 this.serverOptions =
178 customizeSharedGroupOptions(classpath, serverOptions);
179 Properties props =
180 convertToProperties(serverProperties);
181 this.serverProperties =
182 customizeSharedGroupProperties(policy, props);
183 this.host = (host == null) ? "" : host;
184 if (port <= 0) {
185 this.port = ServiceStarter.getActivationSystemPort();
186 } else {
187 this.port = port;
188 }
189 }
190
191 SharedActivationGroupDescriptor(GetArg arg) throws IOException{
192 this(
193 Valid.notNull(arg.get("policy", null, String.class), "Policy cannot be null"),
194 Valid.notNull(arg.get("classpath", null, String.class), "Classpath cannot be null"),
195 Valid.notNull(arg.get("log",null, String.class), "log cannot be null"),
196 arg.get("serverCommand", null, String.class),
197 arg.get("serverOptions", null, String[].class),
198 arg.get("serverProperties", null, String[].class),
199 arg.get("host", null, String.class),
200 arg.get("port", 0)
201 );
202 }
203
204
205
206
207
208
209 final public String getPolicy() { return policy; }
210
211
212
213
214
215
216 final public String getClasspath() { return classpath; }
217
218
219
220
221
222
223 final public String getLog() { return log; }
224
225
226
227
228
229
230
231 final public String getServerCommand() { return serverCommand; }
232
233
234
235
236
237
238 final public String[] getServerOptions() {
239 return (String[])serverOptions.clone();
240 }
241
242
243
244
245
246
247 final public Properties getServerProperties() {
248 return (Properties)serverProperties.clone();
249 }
250
251
252
253
254
255
256 final public String getActivationSystemHost() { return host; }
257
258
259
260
261
262
263 final public int getActivationSystemPort() { return port; }
264
265 private static String[] customizeSharedGroupOptions(
266 String classpath, String[] userOptions)
267 {
268 String[] customOpts = new String[] {"-cp", classpath};
269
270 if (userOptions != null) {
271 String[] tmp = new String[customOpts.length + userOptions.length];
272 System.arraycopy(customOpts, 0, tmp, 0, customOpts.length);
273 System.arraycopy(userOptions, 0, tmp, customOpts.length,
274 userOptions.length);
275 customOpts = tmp;
276 }
277 return customOpts;
278 }
279
280 private static Properties convertToProperties(String[] propertyValues)
281 {
282 Properties properties = new Properties();
283
284 if (propertyValues == null || propertyValues.length == 0)
285 return properties;
286
287 if (propertyValues.length % 2 != 0) {
288 throw new IllegalArgumentException(
289 "The service properties entry has an odd number of elements");
290 }
291 for (int i = 0; i < propertyValues.length; i += 2) {
292 properties.setProperty(propertyValues[i], propertyValues[i + 1]);
293 }
294 return properties;
295 }
296
297
298 private static Properties customizeSharedGroupProperties(
299 String policy, Properties userProperties)
300 {
301
302 if (userProperties == null) {
303 userProperties = new Properties();
304 }
305 userProperties.put("java.security.policy", policy);
306
307 return userProperties;
308 }
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345 public Object create(Configuration config) throws Exception {
346 ServiceStarter.ensureSecurityManager();
347 logger.entering(SharedActivationGroupDescriptor.class.getName(),
348 "create", new Object[] {config});
349
350 if (config == null) {
351 throw new NullPointerException(
352 "Configuration argument cannot be null");
353 }
354
355
356
357
358
359 ActivationSystem sys =
360 ServiceStarter.getActivationSystem(
361 getActivationSystemHost(),
362 getActivationSystemPort(),
363 config);
364
365 CommandEnvironment cmdToExecute
366 = new CommandEnvironment(getServerCommand(),
367 getServerOptions());
368 ActivationGroupID gid = null;
369 try {
370 gid = sys.registerGroup(
371 new ActivationGroupDesc(getServerProperties(),
372 cmdToExecute));
373 storeGroupID(getLog(), gid);
374 } catch (Exception e) {
375 try {
376 if (gid != null) sys.unregisterGroup(gid);
377 } catch (Exception ee) {
378
379 }
380 if (e instanceof IOException)
381 throw (IOException)e;
382 else if (e instanceof ActivationException)
383 throw (ActivationException)e;
384 else if (e instanceof ClassNotFoundException)
385 throw (ClassNotFoundException)e;
386 else
387 throw new RuntimeException("Unexpected Exception", e);
388 }
389
390 logger.exiting(SharedActivationGroupDescriptor.class.getName(),
391 "create", gid);
392 return gid;
393 }
394
395
396
397
398
399 private static void storeGroupID(final String dir,
400 final ActivationGroupID obj)
401 throws IOException
402 {
403
404 File log = new File(dir);
405 String absDir = log.getAbsolutePath();
406 if (log.exists()) {
407 throw new IOException("Log " + absDir + " exists."
408 + " Please delete or select another path");
409 }
410 if (!log.mkdir()) {
411 throw new IOException("Could not create directory: " + absDir);
412
413 }
414
415 File cookieFile = new File(log, GROUP_COOKIE_FILE);
416 ObjectOutputStream oos = null;
417 try {
418 oos = new ObjectOutputStream(
419 new BufferedOutputStream(
420 new FileOutputStream(cookieFile)));
421 oos.writeObject(new MarshalledInstance(obj).convertToMarshalledObject());
422 oos.flush();
423
424 } catch (IOException e) {
425 cookieFile.delete();
426 throw (IOException)e.fillInStackTrace();
427 } finally {
428 if (oos != null) oos.close();
429 }
430 }
431
432
433
434
435
436 static ActivationGroupID restoreGroupID(final String dir)
437 throws IOException, ClassNotFoundException
438 {
439 File log = new File(dir);
440 String absDir = log.getAbsolutePath();
441 if (!log.exists() || !log.isDirectory()) {
442 throw new IOException("Log directory ["
443 + absDir + "] does not exist.");
444 }
445
446 File cookieFile = new File(log, GROUP_COOKIE_FILE);
447 ObjectInputStream ois = null;
448 ActivationGroupID obj = null;
449 try {
450
451 ois = new ObjectInputStream(
452 new BufferedInputStream(
453 new FileInputStream(cookieFile)));
454 MarshalledObject mo = (MarshalledObject)ois.readObject();
455 obj = (ActivationGroupID) new MarshalledInstance(mo).get(false);
456 } finally {
457 if (ois != null) ois.close();
458 }
459 return obj;
460 }
461
462 public String toString() {
463 ArrayList fields = new ArrayList(8);
464 fields.add(policy);
465 fields.add(classpath);
466 fields.add(log);
467 fields.add(serverCommand);
468 fields.add(Arrays.asList(serverOptions));
469 fields.add(serverProperties);
470 fields.add(host);
471 fields.add(Integer.valueOf(port));
472 return fields.toString();
473 }
474
475
476
477
478
479 private void readObject(ObjectInputStream in)
480 throws IOException, ClassNotFoundException
481 {
482 in.defaultReadObject();
483
484 if (policy == null) {
485 throw new InvalidObjectException("null policy");
486 }
487 if (classpath == null) {
488 throw new InvalidObjectException("null class path");
489 }
490 if (log == null) {
491 throw new InvalidObjectException("null log");
492 }
493 if (serverOptions == null) {
494 throw new InvalidObjectException("null server options");
495 }
496 if (serverProperties == null) {
497 throw new InvalidObjectException("null server properties");
498 }
499 if (host == null) {
500 throw new InvalidObjectException("null activation host name");
501 }
502 if (port <= 0) {
503 throw new InvalidObjectException("invalid activation port: " + port);
504 }
505 }
506
507
508
509
510 private void readObjectNoData() throws ObjectStreamException {
511 throw new InvalidObjectException("no data");
512 }
513
514 }
515
516