View Javadoc
1 /*** 2 * Redistribution and use of this software and associated documentation 3 * ("Software"), with or without modification, are permitted provided 4 * that the following conditions are met: 5 * 6 * 1. Redistributions of source code must retain copyright 7 * statements and notices. Redistributions must also contain a 8 * copy of this document. 9 * 10 * 2. Redistributions in binary form must reproduce the 11 * above copyright notice, this list of conditions and the 12 * following disclaimer in the documentation and/or other 13 * materials provided with the distribution. 14 * 15 * 3. The name "Exolab" must not be used to endorse or promote 16 * products derived from this Software without prior written 17 * permission of Exoffice Technologies. For written permission, 18 * please contact info@exolab.org. 19 * 20 * 4. Products derived from this Software may not be called "Exolab" 21 * nor may "Exolab" appear in their names without prior written 22 * permission of Exoffice Technologies. Exolab is a registered 23 * trademark of Exoffice Technologies. 24 * 25 * 5. Due credit should be given to the Exolab Project 26 * (http://www.exolab.org/). 27 * 28 * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS 29 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT 30 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 31 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 32 * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 33 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 34 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 35 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 39 * OF THE POSSIBILITY OF SUCH DAMAGE. 40 * 41 * Copyright 2000-2004 (C) Exoffice Technologies Inc. All Rights Reserved. 42 * 43 * $Id: JmsServer.java,v 1.48 2004/01/03 04:00:56 tanderson Exp $ 44 * 45 * Date Author Changes 46 * 2/28/2000 jima Created 47 */ 48 package org.exolab.jms.server; 49 50 import java.io.PrintStream; 51 import java.lang.reflect.Constructor; 52 import java.util.ArrayList; 53 54 import javax.naming.Context; 55 import javax.naming.NamingException; 56 57 import org.apache.commons.logging.Log; 58 import org.apache.commons.logging.LogFactory; 59 import org.apache.log4j.xml.DOMConfigurator; 60 61 import org.exolab.core.service.ServiceException; 62 import org.exolab.core.service.ServiceManager; 63 import org.exolab.core.util.RmiRegistryService; 64 import org.exolab.jms.authentication.AuthenticationMgr; 65 import org.exolab.jms.config.Configuration; 66 import org.exolab.jms.config.ConfigurationManager; 67 import org.exolab.jms.config.Connector; 68 import org.exolab.jms.config.ConnectorHelper; 69 import org.exolab.jms.config.ConnectorResource; 70 import org.exolab.jms.config.LoggerConfiguration; 71 import org.exolab.jms.config.types.SchemeType; 72 import org.exolab.jms.events.BasicEventManager; 73 import org.exolab.jms.gc.GarbageCollectionService; 74 import org.exolab.jms.jndi.JndiServerIfc; 75 import org.exolab.jms.lease.LeaseManager; 76 import org.exolab.jms.messagemgr.DestinationManager; 77 import org.exolab.jms.messagemgr.MessageMgr; 78 import org.exolab.jms.persistence.DatabaseService; 79 import org.exolab.jms.scheduler.Scheduler; 80 import org.exolab.jms.threads.ThreadPoolManager; 81 import org.exolab.jms.util.CommandLine; 82 import org.exolab.jms.util.Version; 83 84 85 /*** 86 * This class contains the main line for instantiating the JMS Server. It 87 * dynamically detemrines, from the configuration information which of the 88 * servers to implement and then calls the init method on them. 89 * 90 * @version $Revision: 1.48 $ $Date: 2004/01/03 04:00:56 $ 91 * @author <a href="mailto:jima@exoffice.com">Jim Alateras</a> 92 * @author <a href="mailto:tima@intalio.com">Tim Anderson</a> 93 * @see ConfigurationManager 94 */ 95 public class JmsServer { 96 97 /*** 98 * The service manager 99 */ 100 protected ServiceManager _services = null; 101 102 /*** 103 * The interfaces to this server. One interface is constructed for 104 * each configured connector. 105 */ 106 private JmsServerIfc[] _interfaces = null; 107 108 /*** 109 * The JNDI providers, when using embedded JNDI. One server is 110 * constructed for each configured connector. 111 */ 112 private JndiServerIfc[] _jndiInterfaces = null; 113 114 /*** 115 * The configuration of this server 116 */ 117 private Configuration _config; 118 119 /*** 120 * The logger 121 */ 122 private static final Log _log = LogFactory.getLog(JmsServer.class); 123 124 /*** 125 * Construct a new <code>JmsServer</code> 126 * 127 * @param config the server configuration 128 * @throws ServerException if the server cannot be created 129 */ 130 public JmsServer(Configuration config) throws ServerException { 131 version(); 132 ConfigurationManager.setConfig(config); 133 } 134 135 136 /*** 137 * Construct a new <code>JmsServer</code>, configured from the specified 138 * configuration file. 139 * 140 * @param file configuration file name 141 * @throws ServerException if the server cannot be created 142 */ 143 public JmsServer(String file) throws ServerException { 144 version(); 145 146 try { 147 // initialise the configuration manager 148 ConfigurationManager.setConfig(file); 149 _config = ConfigurationManager.getConfig(); 150 } catch (Exception exception) { 151 throw new FailedToCreateServerException( 152 "Failed to read configuration: " + file, exception); 153 } 154 } 155 156 /*** 157 * Initialise the server 158 * 159 * @throws NamingException if administered objects cannot be bound in JNDI 160 * @throws ServerException if the server cannot be initialised 161 */ 162 public void init() throws NamingException, ServerException { 163 // initialise the logger 164 LoggerConfiguration log = _config.getLoggerConfiguration(); 165 166 // @todo - need to do this in main(), to allow pluggable log factories 167 // when embedding OpenJMS 168 DOMConfigurator.configure(log.getFile()); 169 170 // initialise the service manager 171 _services = ServiceManager.instance(); 172 173 // initialise the embedded JNDI server if required 174 if (_config.getServerConfiguration().getEmbeddedJNDI()) { 175 EmbeddedNameService.getInstance(); 176 } 177 178 // create the embedded RMI registry, if it is configured 179 if (hasConnector(SchemeType.RMI) && 180 _config.getRmiConfiguration().getEmbeddedRegistry()) { 181 createRegistry(); 182 } 183 184 // initialise the services, and start them 185 186 try { 187 registerServices(); 188 _services.startAll(); 189 } catch (ServiceException exception) { 190 throw new ServerException("Failed to start services", exception); 191 } 192 193 // create and bind administered destinations 194 DestinationManager.instance().registerConfiguredAdministeredDestinations(); 195 196 Context context = NamingHelper.getInitialContext(_config); 197 198 // create the server interfaces 199 initConnectors(context); 200 201 // create the JNDI provider interfaces if required 202 if (_config.getServerConfiguration().getEmbeddedJNDI()) { 203 initJNDIConnectors(context); 204 } 205 } 206 207 /*** 208 * This is the main line for the JMS Server. It processes the command line 209 * argument, instantiates an instance of the server class and calls the 210 * init routine on it. 211 */ 212 public static void main(String[] args) { 213 try { 214 CommandLine cmdline = new CommandLine(args); 215 216 boolean helpSet = cmdline.exists("help"); 217 boolean versionSet = cmdline.exists("version"); 218 boolean configSet = cmdline.exists("config"); 219 220 if (helpSet) { 221 usage(); 222 } else if (versionSet) { 223 version(); 224 } else if (!configSet && args.length != 0) { 225 // invalid argument specified 226 usage(); 227 } else { 228 String config = cmdline.value( 229 "config", getOpenJMSHome() + "/config/openjms.xml"); 230 JmsServer server = new JmsServer(config); 231 server.init(); 232 } 233 } catch (Exception exception) { 234 exception.printStackTrace(); 235 // force termination of any threads 236 System.exit(-1); 237 } 238 } 239 240 public static void version() { 241 System.err.println(Version.TITLE + " " + Version.VERSION); 242 System.err.println(Version.COPYRIGHT); 243 System.err.println(Version.VENDOR_URL); 244 } 245 246 /*** 247 * Print out information on running this sevice 248 */ 249 protected static void usage() { 250 PrintStream out = System.out; 251 252 out.println("\n\n"); 253 out.println("====================================================="); 254 out.println("Usage information for org.exolab.jms.server.JmsServer"); 255 out.println("====================================================="); 256 out.println("\norg.exolab.jms.server.JmsServer"); 257 out.println(" [-config <xml config file> | -version | -help]\n"); 258 out.println("\t-config file name of xml-based config file\n"); 259 out.println("\t-version displays OpenJMS version information\n"); 260 out.println("\t-help displays this screen\n"); 261 } 262 263 /*** 264 * Initialise the services 265 */ 266 protected void registerServices() throws ServiceException { 267 // add the thread pool manager 268 _services.add(ThreadPoolManager.instance().getName(), 269 ThreadPoolManager.instance()); 270 271 // add the event manager 272 _services.add(BasicEventManager.instance().getName(), 273 BasicEventManager.instance()); 274 275 // add the database service 276 _services.add(DatabaseService.instance().getName(), 277 DatabaseService.instance()); 278 279 // add the scheduler 280 _services.add(Scheduler.createInstance().getName(), 281 Scheduler.instance()); 282 283 // add the lease manager 284 _services.add(LeaseManager.instance().getName(), 285 LeaseManager.instance()); 286 287 // add the transaction manager 288 //_services.add (TransactionService.instance().getName(), 289 // TransactionService.instance()); 290 291 // add the garbage collection service 292 _services.add(GarbageCollectionService.instance().getName(), 293 GarbageCollectionService.instance()); 294 295 // add the authentication manager 296 _services.add(AuthenticationMgr.createInstance().getName(), 297 AuthenticationMgr.instance()); 298 299 // add the resource manager service 300 //_services.add(ResourceManager.instance().getName(), 301 // ResourceManager.instance()); 302 303 // add the message manager 304 _services.add(MessageMgr.createInstance().getName(), 305 MessageMgr.instance()); 306 } 307 308 /*** 309 * Creates an interface to the server for each configured connector 310 * 311 * @param context the initial context 312 * @throws NamingException if administered objects cannot be bound in JNDI 313 * @throws ServerException if an interface can't be created 314 */ 315 protected void initConnectors(Context context) 316 throws NamingException, ServerException { 317 318 Connector[] connectors = _config.getConnectors().getConnector(); 319 _interfaces = new JmsServerIfc[connectors.length]; 320 321 for (int i = 0; i < connectors.length; ++i) { 322 Connector connector = connectors[i]; 323 _interfaces[i] = initConnector(connector, context); 324 } 325 } 326 327 /*** 328 * Create an interface to the server for the specified connector 329 * 330 * @param connector the connector 331 * @param context the initial context 332 * @return the interface corresponding to <code>connector</code> 333 * @throws NamingException if administered objects cannot be bound in JNDI 334 * @throws ServerException if the interface can't be created 335 */ 336 protected JmsServerIfc initConnector(Connector connector, Context context) 337 throws NamingException, ServerException { 338 339 _log.info("Creating server interface for the " + connector.getScheme() 340 + " connector"); 341 342 JmsServerIfc server; 343 ConnectorResource resource = ConnectorHelper.getConnectorResource( 344 connector.getScheme()); 345 346 String className = resource.getServer().getImplementationClass(); 347 Class clazz; 348 try { 349 clazz = Class.forName(className); 350 } catch (ClassNotFoundException exception) { 351 throw new FailedToCreateServerException( 352 "Failed to load class " + className); 353 } 354 355 if (!JmsServerIfc.class.isAssignableFrom(clazz)) { 356 throw new FailedToCreateServerException( 357 "Class " + className + " does not implement JmsServerIfc"); 358 } 359 try { 360 server = (JmsServerIfc) clazz.newInstance(); 361 _log.debug("Created an instance of " + className 362 + " as a server interface"); 363 } catch (Exception exception) { 364 throw new FailedToCreateServerException( 365 exception.getMessage(), exception); 366 } 367 368 // initialise the interface 369 server.init(); 370 371 // bind any configured connection factories 372 server.bindConnectionFactories(context); 373 374 return server; 375 } 376 377 protected void createRegistry() throws ServerException { 378 379 int port = _config.getRmiConfiguration().getRegistryPort(); 380 try { 381 RmiRegistryService service = new RmiRegistryService(port); 382 _services.add(service.getName(), service); 383 } catch (Exception exception) { 384 throw new FailedToCreateServerException( 385 "Failed to start the RMI registry", exception); 386 } 387 _log.info("Embedded RMI registry running on port " + port); 388 } 389 390 /*** 391 * Creates a JNDI provider interface for each connector that supports it 392 * 393 * @param context the initial context 394 * @throws NamingException if a provider can't be initialised 395 * @throws ServerException if a provider can't be created 396 */ 397 protected void initJNDIConnectors(Context context) 398 throws NamingException, ServerException { 399 400 Connector[] connectors = _config.getConnectors().getConnector(); 401 ArrayList interfaces = new ArrayList(); 402 403 for (int i = 0; i < connectors.length; ++i) { 404 Connector connector = connectors[i]; 405 ConnectorResource resource = ConnectorHelper.getConnectorResource( 406 connector.getScheme()); 407 if (resource.getJndi().getImplementationClass() != null) { 408 JndiServerIfc provider = initJNDIConnector(resource, context); 409 interfaces.add(provider); 410 } 411 } 412 _jndiInterfaces = (JndiServerIfc[]) interfaces.toArray( 413 new JndiServerIfc[0]); 414 } 415 416 /*** 417 * Creates a JNDI provider interface for the specified connector 418 * 419 * @param connector the connector 420 * @param context the initial context 421 * @return the JNDI provider interface 422 * @throws NamingException if the provider can't be initialised 423 * @throws ServerException if the provider can't be created 424 */ 425 protected JndiServerIfc initJNDIConnector( 426 ConnectorResource connector, Context context) 427 throws NamingException, ServerException { 428 429 _log.info("Creating JNDI interface for the " + connector.getScheme() 430 + " connector"); 431 432 JndiServerIfc result; 433 String className = connector.getJndi().getImplementationClass(); 434 Class clazz; 435 try { 436 clazz = Class.forName(className); 437 } catch (ClassNotFoundException exception) { 438 throw new FailedToCreateServerException( 439 "Failed to load class " + className); 440 } 441 if (!JndiServerIfc.class.isAssignableFrom(clazz)) { 442 throw new FailedToCreateServerException( 443 "Class " + className + " does not implement JndiServerIfc"); 444 } 445 try { 446 Constructor constructor = clazz.getDeclaredConstructor( 447 new Class[]{Context.class}); 448 result = (JndiServerIfc) constructor.newInstance( 449 new Object[]{context}); 450 result.init(); 451 _log.debug("Created an instance of " + className 452 + " as a JNDI provider interface"); 453 } catch (Exception exception) { 454 throw new FailedToCreateServerException( 455 exception.getMessage(), exception); 456 } 457 return result; 458 } 459 460 /*** 461 * Determines if the configuration has the specified connector 462 * 463 * @param scheme the connector scheme 464 * @return <code>true<code> if the configuration has a connector 465 * corresponding to <code>scheme</code> 466 */ 467 private boolean hasConnector(SchemeType scheme) { 468 boolean result = false; 469 Connector[] connectors = _config.getConnectors().getConnector(); 470 for (int i = 0; i < connectors.length; ++i) { 471 if (connectors[i].getScheme().equals(scheme)) { 472 result = true; 473 break; 474 } 475 } 476 return result; 477 } 478 479 /*** 480 * Returns the value of the openjms.home environment variable 481 */ 482 private static String getOpenJMSHome() { 483 return System.getProperty("openjms.home", 484 System.getProperty("user.dir")); 485 } 486 487 } //-- JmsServer

This page was automatically generated by Maven