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)
192 throws IOException, ClassNotFoundException{
193 this(
194 Valid.notNull(arg.get("policy", null, String.class), "Policy cannot be null"),
195 Valid.notNull(arg.get("classpath", null, String.class), "Classpath cannot be null"),
196 Valid.notNull(arg.get("log",null, String.class), "log cannot be null"),
197 arg.get("serverCommand", null, String.class),
198 arg.get("serverOptions", null, String[].class),
199 arg.get("serverProperties", null, String[].class),
200 arg.get("host", null, String.class),
201 arg.get("port", 0)
202 );
203 }
204
205
206
207
208
209
210 final public String getPolicy() { return policy; }
211
212
213
214
215
216
217 final public String getClasspath() { return classpath; }
218
219
220
221
222
223
224 final public String getLog() { return log; }
225
226
227
228
229
230
231
232 final public String getServerCommand() { return serverCommand; }
233
234
235
236
237
238
239 final public String[] getServerOptions() {
240 return (String[])serverOptions.clone();
241 }
242
243
244
245
246
247
248 final public Properties getServerProperties() {
249 return (Properties)serverProperties.clone();
250 }
251
252
253
254
255
256
257 final public String getActivationSystemHost() { return host; }
258
259
260
261
262
263
264 final public int getActivationSystemPort() { return port; }
265
266 private static String[] customizeSharedGroupOptions(
267 String classpath, String[] userOptions)
268 {
269 String[] customOpts = new String[] {"-cp", classpath};
270
271 if (userOptions != null) {
272 String[] tmp = new String[customOpts.length + userOptions.length];
273 System.arraycopy(customOpts, 0, tmp, 0, customOpts.length);
274 System.arraycopy(userOptions, 0, tmp, customOpts.length,
275 userOptions.length);
276 customOpts = tmp;
277 }
278 return customOpts;
279 }
280
281 private static Properties convertToProperties(String[] propertyValues)
282 {
283 Properties properties = new Properties();
284
285 if (propertyValues == null || propertyValues.length == 0)
286 return properties;
287
288 if (propertyValues.length % 2 != 0) {
289 throw new IllegalArgumentException(
290 "The service properties entry has an odd number of elements");
291 }
292 for (int i = 0; i < propertyValues.length; i += 2) {
293 properties.setProperty(propertyValues[i], propertyValues[i + 1]);
294 }
295 return properties;
296 }
297
298
299 private static Properties customizeSharedGroupProperties(
300 String policy, Properties userProperties)
301 {
302
303 if (userProperties == null) {
304 userProperties = new Properties();
305 }
306 userProperties.put("java.security.policy", policy);
307
308 return userProperties;
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
346 public Object create(Configuration config) throws Exception {
347 ServiceStarter.ensureSecurityManager();
348 logger.entering(SharedActivationGroupDescriptor.class.getName(),
349 "create", new Object[] {config});
350
351 if (config == null) {
352 throw new NullPointerException(
353 "Configuration argument cannot be null");
354 }
355
356
357
358
359
360 ActivationSystem sys =
361 ServiceStarter.getActivationSystem(
362 getActivationSystemHost(),
363 getActivationSystemPort(),
364 config);
365
366 CommandEnvironment cmdToExecute
367 = new CommandEnvironment(getServerCommand(),
368 getServerOptions());
369 ActivationGroupID gid = null;
370 try {
371 gid = sys.registerGroup(
372 new ActivationGroupDesc(getServerProperties(),
373 cmdToExecute));
374 storeGroupID(getLog(), gid);
375 } catch (Exception e) {
376 try {
377 if (gid != null) sys.unregisterGroup(gid);
378 } catch (Exception ee) {
379
380 }
381 if (e instanceof IOException)
382 throw (IOException)e;
383 else if (e instanceof ActivationException)
384 throw (ActivationException)e;
385 else if (e instanceof ClassNotFoundException)
386 throw (ClassNotFoundException)e;
387 else
388 throw new RuntimeException("Unexpected Exception", e);
389 }
390
391 logger.exiting(SharedActivationGroupDescriptor.class.getName(),
392 "create", gid);
393 return gid;
394 }
395
396
397
398
399
400 private static void storeGroupID(final String dir,
401 final ActivationGroupID obj)
402 throws IOException
403 {
404
405 File log = new File(dir);
406 String absDir = log.getAbsolutePath();
407 if (log.exists()) {
408 throw new IOException("Log " + absDir + " exists."
409 + " Please delete or select another path");
410 }
411 if (!log.mkdir()) {
412 throw new IOException("Could not create directory: " + absDir);
413
414 }
415
416 File cookieFile = new File(log, GROUP_COOKIE_FILE);
417 ObjectOutputStream oos = null;
418 try {
419 oos = new ObjectOutputStream(
420 new BufferedOutputStream(
421 new FileOutputStream(cookieFile)));
422 oos.writeObject(new MarshalledInstance(obj).convertToMarshalledObject());
423 oos.flush();
424
425 } catch (IOException e) {
426 cookieFile.delete();
427 throw (IOException)e.fillInStackTrace();
428 } finally {
429 if (oos != null) oos.close();
430 }
431 }
432
433
434
435
436
437 static ActivationGroupID restoreGroupID(final String dir)
438 throws IOException, ClassNotFoundException
439 {
440 File log = new File(dir);
441 String absDir = log.getAbsolutePath();
442 if (!log.exists() || !log.isDirectory()) {
443 throw new IOException("Log directory ["
444 + absDir + "] does not exist.");
445 }
446
447 File cookieFile = new File(log, GROUP_COOKIE_FILE);
448 ObjectInputStream ois = null;
449 ActivationGroupID obj = null;
450 try {
451
452 ois = new ObjectInputStream(
453 new BufferedInputStream(
454 new FileInputStream(cookieFile)));
455 MarshalledObject mo = (MarshalledObject)ois.readObject();
456 obj = (ActivationGroupID) new MarshalledInstance(mo).get(false);
457 } finally {
458 if (ois != null) ois.close();
459 }
460 return obj;
461 }
462
463 public String toString() {
464 ArrayList fields = new ArrayList(8);
465 fields.add(policy);
466 fields.add(classpath);
467 fields.add(log);
468 fields.add(serverCommand);
469 fields.add(Arrays.asList(serverOptions));
470 fields.add(serverProperties);
471 fields.add(host);
472 fields.add(Integer.valueOf(port));
473 return fields.toString();
474 }
475
476
477
478
479
480 private void readObject(ObjectInputStream in)
481 throws IOException, ClassNotFoundException
482 {
483 in.defaultReadObject();
484
485 if (policy == null) {
486 throw new InvalidObjectException("null policy");
487 }
488 if (classpath == null) {
489 throw new InvalidObjectException("null class path");
490 }
491 if (log == null) {
492 throw new InvalidObjectException("null log");
493 }
494 if (serverOptions == null) {
495 throw new InvalidObjectException("null server options");
496 }
497 if (serverProperties == null) {
498 throw new InvalidObjectException("null server properties");
499 }
500 if (host == null) {
501 throw new InvalidObjectException("null activation host name");
502 }
503 if (port <= 0) {
504 throw new InvalidObjectException("invalid activation port: " + port);
505 }
506 }
507
508
509
510
511 private void readObjectNoData() throws ObjectStreamException {
512 throw new InvalidObjectException("no data");
513 }
514
515 }
516
517