/* * Copyright (c) 1998-2011 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * Free SoftwareFoundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * * @author Sam */ package com.caucho.resources.rmi; import com.caucho.config.ConfigException; import com.caucho.jca.ra.AbstractResourceAdapter; import com.caucho.util.L10N; import javax.resource.spi.BootstrapContext; import javax.resource.spi.ResourceAdapterInternalException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import java.util.Iterator; import java.util.LinkedList; import java.util.logging.Level; import java.util.logging.Logger; /** * An RMI registry and its services. This resource is used to register * services with an RMI Registry. The Registry is either on localhost, in * which case it is created in the local JVM unless it already exists, or the * Registry is on a remote server, in which case it is assumed that the * Registry has already been started. */ public class RmiRegistry extends AbstractResourceAdapter { static private final Logger log = Logger.getLogger(RmiRegistry.class.getName()); static final L10N L = new L10N(RmiRegistry.class); private String _server = "localhost"; private int _port = 1099; private LinkedList<RmiService> _services = new LinkedList<RmiService>(); private String _namePrefix; /** * The server that runs the RMI registry. If this is `localhost' (the * default), then the Registry is created on the localhost if it does not * already exist. If the server is not localhost, then it is assumed that * the remote Registry already exists. */ public void setServer(String server) { _server = server; } public String getServer() { return _server; } /** * The port for the Registry, default is 1099. */ public void setPort(int port) { _port = port; } /** * The port for the Registry. */ public int getPort() { return _port; } /** * Add an RMI service to register with this Registry. */ public void addRmiService(RmiService service) throws ConfigException { _services.add(service); } @javax.annotation.PostConstruct public void init() throws ConfigException { if (System.getSecurityManager() == null) throw new ConfigException("RMI requires a SecurityManager - add a <security-manager/> element to <resin>"); _namePrefix =("//" + _server + ':' + _port + '/'); } public void start(BootstrapContext ctx) throws ResourceAdapterInternalException { if (_server.equals("localhost")) startRegistry(); else { log.config(L.l("using remote RMI Registry `{0}:{1}'",_server,String.valueOf(_port))); } // start (export and bind) all services for (Iterator<RmiService> i = _services.iterator(); i.hasNext(); ) { RmiService s = i.next(); s.start(); } } /** * Make a full name for a service with this registry and * the given serviceName. */ String makeFullName(String serviceName) { return _namePrefix + serviceName; } /** * Start the RMI registry in the local JVM, if it has not been started * already. */ private void startRegistry() throws ResourceAdapterInternalException { /** * Some tricks are required here, the RMI Registry needs to be * started from the system classloader. */ Thread thread = Thread.currentThread(); ClassLoader oldLoader = thread.getContextClassLoader(); try { thread.setContextClassLoader(ClassLoader.getSystemClassLoader()); try { Registry reg = LocateRegistry.getRegistry(_port); reg.list(); // Verify it's alive and well if (log.isLoggable(Level.CONFIG)) log.config(L.l("found RMI Registry on port `{0}'", _port)); } catch (Exception e) { // couldn't find a valid registry so create one if (log.isLoggable(Level.CONFIG)) log.config(L.l("creating RMI Registry on port `{0}'", _port)); LocateRegistry.createRegistry(_port); } } catch (Exception ex) { throw new ResourceAdapterInternalException(ex); } finally { thread.setContextClassLoader(oldLoader); } } /** * stop (unbind and unexport) all services */ public void stop() { // unbind and unexport all services for (Iterator<RmiService> i = _services.iterator(); i.hasNext(); ) { RmiService s = i.next(); s.stop(); } } }