2
* JBoss, Home of Professional Open Source
3
* Copyright 2005, JBoss Inc., and individual contributors as indicated
4
* by the @authors tag. See the copyright.txt in the distribution for a
5
* full listing of individual contributors.
7
* This is free software; you can redistribute it and/or modify it
8
* under the terms of the GNU Lesser General Public License as
9
* published by the Free Software Foundation; either version 2.1 of
10
* the License, or (at your option) any later version.
12
* This software is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this software; if not, write to the Free
19
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
23
package org.jboss.remoting.transporter;
25
import org.jboss.remoting.InvokerLocator;
26
import org.jboss.remoting.ServerInvocationHandler;
27
import org.jboss.remoting.detection.multicast.MulticastDetector;
28
import org.jboss.remoting.transport.Connector;
29
import org.jboss.remoting.util.SecurityUtility;
30
import org.w3c.dom.Element;
32
import javax.management.MBeanServer;
33
import javax.management.MBeanServerFactory;
35
import java.security.AccessController;
36
import java.security.PrivilegedActionException;
37
import java.security.PrivilegedExceptionAction;
38
import java.util.ArrayList;
39
import java.util.List;
43
* The remoting server to expose the target POJO. This should be called on as a factory via
46
* @author <a href="mailto:tom.elrod@jboss.com">Tom Elrod</a>
48
public class TransporterServer
50
private Connector connector = null;
53
* Creates a remoting server using the provided locator and subsytem and creating a TransporterHandler which
54
* takes the specified target object.
61
public TransporterServer(InvokerLocator locator, Object target, String subsystem) throws Exception
63
connector = getConnector(locator, null, null);
64
ServerInvocationHandler handler = new TransporterHandler(target);
65
if (subsystem != null)
67
connector.addInvocationHandler(subsystem.toUpperCase(), handler);
71
addInterfaceSubsystems(connector, handler, target);
76
* Creates a remoting server using the provided locator and subsytem and creating a TransporterHandler which
77
* takes the specified target object.
84
public TransporterServer(Element xmlConfig, Object target, String subsystem) throws Exception
86
connector = getConnector(null, null, xmlConfig);
87
ServerInvocationHandler handler = new TransporterHandler(target);
88
if (subsystem != null)
90
connector.addInvocationHandler(subsystem.toUpperCase(), handler);
94
addInterfaceSubsystems(connector, handler, target);
99
* Creates a remoting server using the provided locator and subsytem and creating a TransporterHandler which
100
* takes the specified target object.
105
* @param config - configuration data for Connector
108
public TransporterServer(InvokerLocator locator, Object target, String subsystem, Map config) throws Exception
110
connector = getConnector(locator, config, null);
111
ServerInvocationHandler handler = new TransporterHandler(target);
112
if (subsystem != null)
114
connector.addInvocationHandler(subsystem.toUpperCase(), handler);
118
addInterfaceSubsystems(connector, handler, target);
122
private void addInterfaceSubsystems(Connector connector, ServerInvocationHandler handler, Object target) throws Exception
124
Class targetClass = target.getClass();
126
//first have to build list of interface names
127
List interfaceNames = new ArrayList();
128
populateInterfaceNames(interfaceNames, targetClass);
130
for (int i = 0; i < interfaceNames.size(); i++)
132
String interfaceClassName = (String) interfaceNames.get(i);
133
connector.addInvocationHandler(interfaceClassName.toUpperCase(), handler);
137
private void populateInterfaceNames(List interfaceNames, Class targetClass)
139
Class[] interfaces = targetClass.getInterfaces();
140
if (interfaces != null)
142
for (int x = 0; x < interfaces.length; x++)
144
interfaceNames.add(interfaces[x].getName());
145
populateInterfaceNames(interfaceNames, interfaces[x]);
151
* Returns the connector that this transporter server will use. Subclasses are free to override this method in order
152
* to create a more customized connector.
155
* @param config configuration data for connector
156
* @param xmlConfig configuration data for connector (in xml form)
157
* @return the connector to be used by this transporter server
160
protected Connector getConnector(InvokerLocator locator, Map config, Element xmlConfig)
163
Connector c = new Connector(locator, config);
164
if (xmlConfig != null)
166
c.setConfiguration(xmlConfig);
174
* Adds a transporter handler to receive remote invocations on the target object passed.
176
* @param target the target implementation to call on
177
* @param proxyclassname the fully qualified classname of the interface that clients will use to call on
179
public void addHandler(Object target, String proxyclassname) throws Exception
181
if (connector != null)
183
connector.addInvocationHandler(proxyclassname, new TransporterHandler(target));
187
throw new Exception("Can not add handler to transporter server as has not be initialized yet.");
192
* Starts the remoting server. This is called automatically upon any of the static createTransporterServer() methods.
196
public void start() throws Exception
202
* Stops the remoting server. This must be called when no longer want to expose the target POJO for remote
211
* Creates a MBeanServer and MulticastDetector to start publishing detection messages so
212
* other detectors will be aware this server is available.
216
private static void setupDetector() throws Exception
218
InternalTransporterServices services = InternalTransporterServices.getInstance();
220
// if no one has setup our internal services yet, let's do it now
221
if (!services.isSetup())
223
// we need an MBeanServer to store our network registry and multicast detector services
224
MBeanServer server = createMBeanServer();
226
// multicast detector will detect new network registries that come online
227
MulticastDetector detector = new MulticastDetector();
228
services.setup(server, detector, null, null, null, true, false);
231
else if (services.getDetector() == null)
233
// the internal services singleton is already setup, make sure it has a detector because we need it
234
MulticastDetector detector = new MulticastDetector();
235
services.assignDetector(detector, null, true);
243
* Creates a remoting server based on given locator. Will convert any remote invocation requests into
244
* method calls on the given target object.Note: the TransporterServer instance returned will be a live (started)
247
* Once the TransporterServer has been returned, it will have already been started automatically, so is a live server
248
* ready to receive requests.
250
* @param locator - specifies what transport, host and port binding, etc. to use by the remoting server.
251
* @param target - the target POJO to receive the method call upon getting remote invocation requests.
252
* @param subsystem - the name under which to register the handler within the remoting server. <b>This must be
253
* the fully qualified name of the interface for clients to use a the remote proxy to the target POJO. Otherwise,
254
* clustering will not work, as this is the value used to identifiy remote POJOs on the client side.</b> If not clustered,
255
* this is not as critical, and simply use the fully qualified class name of the POJO if desired.
256
* @param isClustered - true indicates that would like this server to be considered available for
257
* failover from clients calling on the same interface as exposed by the subsystem value. False will only allow
258
* those client that explicitly targeting this server to make calls on it.
259
* @return TransporterServer. Note, it will already be started upon return.
262
public static TransporterServer createTransporterServer(InvokerLocator locator, Object target,
263
String subsystem, boolean isClustered) throws Exception
265
return createTransporterServer(locator, target, subsystem, null, isClustered);
269
* Creates a remoting server based on given locator. Will convert any remote invocation requests into
270
* method calls on the given target object.Note: the TransporterServer instance returned will be a live (started)
273
* Once the TransporterServer has been returned, it will have already been started automatically, so is a live server
274
* ready to receive requests.
276
* @param locator - specifies what transport, host and port binding, etc. to use by the remoting server.
277
* @param target - the target POJO to receive the method call upon getting remote invocation requests.
278
* @param subsystem - the name under which to register the handler within the remoting server. <b>This must be
279
* the fully qualified name of the interface for clients to use a the remote proxy to the target POJO. Otherwise,
280
* clustering will not work, as this is the value used to identifiy remote POJOs on the client side.</b> If not clustered,
281
* this is not as critical, and simply use the fully qualified class name of the POJO if desired.
282
* @param config - the configuration to be used in setting up the Connector.
283
* @param isClustered - true indicates that would like this server to be considered available for
284
* failover from clients calling on the same interface as exposed by the subsystem value. False will only allow
285
* those client that explicitly targeting this server to make calls on it.
286
* @return TransporterServer. Note, it will already be started upon return.
289
public static TransporterServer createTransporterServer(InvokerLocator locator, Object target,
290
String subsystem, Map config, boolean isClustered) throws Exception
292
if (isClustered && (InternalTransporterServices.getInstance().getDetector() == null))
297
TransporterServer server = new TransporterServer(locator, target, subsystem, config);
303
* Creates a remoting server based on given locator. Will convert any remote invocation requests into
304
* method calls on the given target object.Note: the TransporterServer instance returned will be a live (started)
307
* Once the TransporterServer has been returned, it will have already been started automatically, so is a live server
308
* ready to receive requests.
310
* @param locatorURI - specifies what transport, host and port binding, etc. to use by the remoting server.
311
* @param target - the target POJO to receive the method call upon getting remote invocation requests.
312
* @param subsystem - the name under which to register the handler within the remoting server. <b>This must be
313
* the fully qualified name of the interface for clients to use a the remote proxy to the target POJO. Otherwise,
314
* clustering will not work, as this is the value used to identifiy remote POJOs on the client side.</b> If not clustered,
315
* this is not as critical, and simply use the fully qualified class name of the POJO if desired.
316
* @param isClustered - true indicates that would like this server to be considered available for
317
* failover from clients calling on the same interface as exposed by the subsystem value. False will only allow
318
* those client that explicitly targeting this server to make calls on it.
319
* @return TransporterServer. Note, it will already be started upon return.
322
public static TransporterServer createTransporterServer(String locatorURI, Object target,
323
String subsystem, boolean isClustered) throws Exception
325
return createTransporterServer(new InvokerLocator(locatorURI), target, subsystem, null, isClustered);
329
* Creates a remoting server based on given locator. Will convert any remote invocation requests into
330
* method calls on the given target object.Note: the TransporterServer instance returned will be a live (started)
333
* Once the TransporterServer has been returned, it will have already been started automatically, so is a live server
334
* ready to receive requests.
336
* @param locatorURI - specifies what transport, host and port binding, etc. to use by the remoting server.
337
* @param target - the target POJO to receive the method call upon getting remote invocation requests.
338
* @param subsystem - the name under which to register the handler within the remoting server. <b>This must be
339
* the fully qualified name of the interface for clients to use a the remote proxy to the target POJO. Otherwise,
340
* clustering will not work, as this is the value used to identifiy remote POJOs on the client side.</b> If not clustered,
341
* this is not as critical, and simply use the fully qualified class name of the POJO if desired.
342
* @param config - the configuration data for the Connector.
343
* @param isClustered - true indicates that would like this server to be considered available for
344
* failover from clients calling on the same interface as exposed by the subsystem value. False will only allow
345
* those client that explicitly targeting this server to make calls on it.
346
* @return TransporterServer. Note, it will already be started upon return.
349
public static TransporterServer createTransporterServer(String locatorURI, Object target,
350
String subsystem, Map config, boolean isClustered) throws Exception
352
return createTransporterServer(new InvokerLocator(locatorURI), target, subsystem, config, isClustered);
356
* Creates a remoting server based on given locator. Will convert any remote invocation requests into
357
* method calls on the given target object. Note: the TransporterServer instance returned will be a live (started)
360
* Once the TransporterServer has been returned, it will have already been started automatically, so is a live server
361
* ready to receive requests.
363
* @param xmlconfig - specifies config for Connector
364
* @param target - the target POJO to receive the method call upon getting remote invocation requests.
365
* @param subsystem - the name under which to register the handler within the remoting server. <b>This must be
366
* the fully qualified name of the interface for clients to use a the remote proxy to the target POJO. Otherwise,
367
* clustering will not work, as this is the value used to identifiy remote POJOs on the client side.</b> If not clustered,
368
* this is not as critical, and simply use the fully qualified class name of the POJO if desired.
369
* @param isClustered - true indicates that would like this server to be considered available for
370
* failover from clients calling on the same interface as exposed by the subsystem value. False will only allow
371
* those client that explicitly targeting this server to make calls on it.
372
* @return TransporterServer. Note, it will already be started upon return.
375
public static TransporterServer createTransporterServer(Element xmlconfig, Object target,
376
String subsystem, boolean isClustered) throws Exception
378
if (isClustered && (InternalTransporterServices.getInstance().getDetector() == null))
383
TransporterServer server = new TransporterServer(xmlconfig, target, subsystem);
389
* Creates a remoting server based on given locator. Will convert any remote invocation requests into
390
* method calls on the given target object.Note: the TransporterServer instance returned will be a live (started)
393
* Once the TransporterServer has been returned, it will have already been started automatically, so is a live server
394
* ready to receive requests.
396
* @param locator - specifies what transport, host and port binding, etc. to use by the remoting server.
397
* @param target - the target POJO to receive the method call upon getting remote invocation requests.
398
* @param subsystem - the name under which to register the handler within the remoting server. Can
399
* simply use the fully qualified class name of the POJO if desired.
400
* @return TransporterServer. Note, it will already be started upon return.
403
public static TransporterServer createTransporterServer(InvokerLocator locator, Object target, String subsystem) throws Exception
405
return createTransporterServer(locator, target, subsystem, false);
409
* Creates a remoting server based on given locator. Will convert any remote invocation requests into
410
* method calls on the given target object.Note: the TransporterServer instance returned will be a live (started)
413
* Once the TransporterServer has been returned, it will have already been started automatically, so is a live server
414
* ready to receive requests.
416
* @param locator - specifies what transport, host and port binding, etc. to use by the remoting server.
417
* @param target - the target POJO to receive the method call upon getting remote invocation requests.
418
* @return TransporterServer. Note, it will already be started upon return.
421
public static TransporterServer createTransporterServer(InvokerLocator locator, Object target) throws Exception
423
return createTransporterServer(locator, target, false);
427
* Creates a remoting server based on given locator. Will convert any remote invocation requests into
428
* method calls on the given target object.Note: the TransporterServer instance returned will be a live (started)
431
* Once the TransporterServer has been returned, it will have already been started automatically, so is a live server
432
* ready to receive requests.
434
* @param locator - specifies what transport, host and port binding, etc. to use by the remoting server.
435
* @param target - the target POJO to receive the method call upon getting remote invocation requests.
436
* @param isClustered - indicates if want automatic failover on calls to remote servers.
437
* @return TransporterServer. Note, it will already be started upon return.
440
public static TransporterServer createTransporterServer(InvokerLocator locator, Object target, boolean isClustered) throws Exception
442
if (isClustered && (InternalTransporterServices.getInstance().getDetector() == null))
447
TransporterServer server = new TransporterServer(locator, target, null, null);
454
* Creates a remoting server based on given locator. Will convert any remote invocation requests into
455
* method calls on the given target object.Note: the TransporterServer instance returned will be a live (started)
458
* Once the TransporterServer has been returned, it will have already been started automatically, so is a live server
459
* ready to receive requests.
461
* @param locator - specifies what transport, host and port binding, etc. to use by the remoting server.
462
* @param target - the target POJO to receive the method call upon getting remote invocation requests.
463
* @return TransporterServer. Note, it will already be started upon return.
466
public static TransporterServer createTransporterServer(String locator, Object target) throws Exception
468
return createTransporterServer(new InvokerLocator(locator), target, false);
472
* Creates a remoting server based on given locator. Will convert any remote invocation requests into
473
* method calls on the given target object.Note: the TransporterServer instance returned will be a live (started)
476
* Once the TransporterServer has been returned, it will have already been started automatically, so is a live server
477
* ready to receive requests.
479
* @param locator - specifies what transport, host and port binding, etc. to use by the remoting server.
480
* @param target - the target POJO to receive the method call upon getting remote invocation requests.
481
* @param isClustered - indicates if want automatic failover on calls to remote servers.
482
* @return TransporterServer. Note, it will already be started upon return.
485
public static TransporterServer createTransporterServer(String locator, Object target, boolean isClustered) throws Exception
487
return createTransporterServer(new InvokerLocator(locator), target, isClustered);
491
* Creates a remoting server based on given locator. Will convert any remote invocation requests into
492
* method calls on the given target object.Note: the TransporterServer instance returned will be a live (started)
495
* Once the TransporterServer has been returned, it will have already been started automatically, so is a live server
496
* ready to receive requests.
498
* @param locatorURI - specifies what transport, host and port binding, etc. to use by the remoting server.
499
* @param target - the target POJO to receive the method call upon getting remote invocation requests.
500
* @param subsystem - the name under which to register the handler within the remoting server. Can
501
* simply use the fully qualified class name of the POJO if desired.
502
* @return TransporterServer. Note, it will already be started upon return.
505
public static TransporterServer createTransporterServer(String locatorURI, Object target, String subsystem) throws Exception
507
return createTransporterServer(new InvokerLocator(locatorURI), target, subsystem, false);
510
static private MBeanServer createMBeanServer() throws Exception
512
if (SecurityUtility.skipAccessControl())
514
return MBeanServerFactory.createMBeanServer();
519
return (MBeanServer) AccessController.doPrivileged( new PrivilegedExceptionAction()
521
public Object run() throws Exception
523
return MBeanServerFactory.createMBeanServer();
527
catch (PrivilegedActionException e)
529
throw (Exception) e.getCause();
b'\\ No newline at end of file'