1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.river.start.group.impl;
20
21 import org.apache.river.api.util.Startable;
22 import org.apache.river.start.group.SharedGroup;
23 import java.io.IOException;
24 import java.rmi.MarshalledObject;
25 import java.rmi.Remote;
26 import java.rmi.RemoteException;
27 import java.rmi.activation.ActivationException;
28 import java.rmi.activation.ActivationGroup;
29 import java.rmi.activation.ActivationID;
30 import java.rmi.activation.ActivationSystem;
31 import java.rmi.server.ExportException;
32 import java.security.AccessControlContext;
33 import java.security.AccessController;
34 import java.security.PrivilegedActionException;
35 import java.security.PrivilegedExceptionAction;
36 import java.util.logging.Level;
37 import java.util.logging.Logger;
38 import javax.security.auth.Subject;
39 import javax.security.auth.login.LoginContext;
40 import net.jini.config.Configuration;
41 import net.jini.config.ConfigurationException;
42 import net.jini.config.ConfigurationProvider;
43 import net.jini.core.constraint.RemoteMethodControl;
44 import net.jini.export.Exporter;
45 import net.jini.export.ProxyAccessor;
46 import net.jini.io.MarshalledInstance;
47 import net.jini.security.TrustVerifier;
48 import net.jini.security.proxytrust.ServerProxyTrust;
49 import org.apache.river.proxy.BasicProxyTrustVerifier;
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189 public class SharedGroupImpl implements Remote,
190 SharedGroup,
191 ServerProxyTrust,
192 ProxyAccessor, Startable {
193
194
195 static final String START_PACKAGE = "org.apache.river.start.group";
196
197
198 static final Logger logger =
199 Logger.getLogger(START_PACKAGE + ".SharedGroup");
200
201
202 private final ActivationID activationID;
203
204
205 private volatile ActivationSystem activationSystem;
206
207
208 private Remote ourStub;
209
210
211 private final LoginContext loginContext;
212
213
214 protected final Exporter exporter;
215
216 private final AccessControlContext context;
217
218
219
220
221 SharedGroupImpl(ActivationID activationID, MarshalledObject data)
222 throws Exception
223 {
224 this(getInit(activationID, data));
225 }
226
227 private static SharedGroupImplInit getInit(ActivationID activationID,
228 MarshalledObject data)
229 throws IOException, ClassNotFoundException, ConfigurationException, Exception
230 {
231 LoginContext loginContext = null;
232 try {
233 logger.entering(SharedGroupImpl.class.getName(), "SharedGroupImpl",
234 new Object[] { activationID, data});
235 String[] configArgs = (String[]) new MarshalledInstance(data).get(false);
236 Configuration config = ConfigurationProvider.getInstance(configArgs);
237 loginContext = (LoginContext) config.getEntry(
238 START_PACKAGE, "loginContext", LoginContext.class, null);
239 SharedGroupImplInit init = null;
240 if (loginContext != null) {
241 init = doInitWithLogin(config, activationID, loginContext);
242 } else {
243 init = doInit(config, activationID, null);
244 }
245 return init;
246 } catch (Exception e) {
247
248
249
250 if (loginContext != null) {
251 try {
252 loginContext.logout();
253 logger.finest("SharedGroupImpl logged-out.");
254 } catch (Exception ex) {
255 logger.log(Level.FINEST,
256 "Problem logging out for SharedGroupImpl.", ex);
257 }
258 }
259 throw e;
260 } finally {
261 logger.exiting(SharedGroupImpl.class.getName(), "SharedGroupImpl");
262 }
263 }
264
265 private SharedGroupImpl(SharedGroupImplInit init){
266 activationSystem = init.activationSystem;
267 this.activationID = init.activationID;
268 exporter = init.exporter;
269 context = init.context;
270 loginContext = init.loginContext;
271 }
272
273 private static SharedGroupImplInit doInitWithLogin(final Configuration config,
274 final ActivationID id,
275 final LoginContext loginContext)
276 throws Exception
277 {
278 loginContext.login();
279 try {
280 return Subject.doAsPrivileged(
281 loginContext.getSubject(),
282 new PrivilegedExceptionAction<SharedGroupImplInit>() {
283 public SharedGroupImplInit run() throws Exception {
284 return doInit(config, id, loginContext);
285 }
286 },
287 null);
288 } catch (PrivilegedActionException e) {
289 throw e.getException();
290 }
291 }
292
293 private static SharedGroupImplInit doInit(Configuration config,
294 ActivationID id,
295 LoginContext loginContext)
296 throws Exception
297 {
298 return new SharedGroupImplInit(config, id, loginContext);
299 }
300
301 public final synchronized void start() throws ExportException {
302 try {
303
304
305 ourStub = AccessController.doPrivileged(new PrivilegedExceptionAction<Remote>(){
306
307 @Override
308 public Remote run() throws ExportException {
309 return exporter.export(SharedGroupImpl.this);
310 }
311
312 }, context);
313 } catch (PrivilegedActionException ex) {
314 ExportException e = (ExportException) ex.getException();
315 cleanup();
316 throw e;
317 }
318
319 logger.log(Level.FINEST, "Exported service proxy: {0}",
320 ourStub);
321 }
322
323
324 @Override
325 public void destroyVM() throws RemoteException, ActivationException {
326 logger.entering(SharedGroupImpl.class.getName(), "destroyVM");
327
328
329
330
331 if (activationSystem != null) {
332 activationSystem.unregisterGroup(
333 ActivationGroup.currentGroupID());
334 logger.finest("ActivationGroup unregistered.");
335
336
337
338 activationSystem = null;
339 }
340 (new SharedGroupImpl.DestroyThread()).start();
341 logger.exiting(SharedGroupImpl.class.getName(), "destroyVM");
342 }
343
344
345
346
347
348 private void cleanup() {
349 logger.entering(SharedGroupImpl.class.getName(), "cleanup");
350
351
352
353 if (exporter != null) {
354 try {
355
356 exporter.unexport(true);
357 logger.finest("SharedGroupImpl unexported.");
358 } catch (Exception e) {
359 logger.log(Level.FINEST,
360 "Problem unexporting SharedGroupImpl.", e);
361 }
362 }
363
364 if (loginContext != null) {
365 try {
366 loginContext.logout();
367 logger.finest("SharedGroupImpl logged-out.");
368 } catch (Exception e) {
369 logger.log(Level.FINEST,
370 "Problem logging out for SharedGroupImpl.", e);
371 }
372 }
373 logger.exiting(SharedGroupImpl.class.getName(), "cleanup");
374 }
375
376
377
378
379
380
381
382 private class DestroyThread extends Thread {
383
384
385 public DestroyThread() {
386 super("DestroyThread");
387
388 setDaemon(false);
389 }
390
391 public void run() {
392 logger.entering(SharedGroupImpl.DestroyThread.class.getName(),
393 "run");
394
395 logger.finest("Calling System.exit() ...");
396
397
398
399
400
401 System.exit(0);
402 }
403 }
404
405 public synchronized Object getProxy() {
406 logger.entering(SharedGroupImpl.class.getName(),
407 "getProxy");
408 logger.exiting(SharedGroupImpl.class.getName(),
409 "getProxy", ourStub);
410 return ourStub;
411 }
412
413
414
415
416
417 public synchronized TrustVerifier getProxyVerifier( ) {
418
419 if (!(ourStub instanceof RemoteMethodControl)) {
420 throw new UnsupportedOperationException();
421 } else {
422 return new BasicProxyTrustVerifier(ourStub);
423 }
424 }
425 }