001: /*
002: * The contents of this file are subject to the Sapient Public License
003: * Version 1.0 (the "License"); you may not use this file except in compliance
004: * with the License. You may obtain a copy of the License at
005: * http://carbon.sf.net/License.html.
006: *
007: * Software distributed under the License is distributed on an "AS IS" basis,
008: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
009: * the specific language governing rights and limitations under the License.
010: *
011: * The Original Code is The Carbon Component Framework.
012: *
013: * The Initial Developer of the Original Code is Sapient Corporation
014: *
015: * Copyright (C) 2003 Sapient Corporation. All Rights Reserved.
016: */
017:
018: package org.sape.carbon.services.jmx.server.mx4j;
019:
020: import java.rmi.server.ExportException;
021:
022: import javax.management.Attribute;
023: import javax.management.InstanceAlreadyExistsException;
024: import javax.management.MBeanException;
025: import javax.management.MBeanServer;
026: import javax.management.ObjectInstance;
027: import javax.management.ObjectName;
028: import javax.naming.InitialContext;
029:
030: import org.sape.carbon.core.component.ComponentConfiguration;
031: import org.sape.carbon.core.component.lifecycle.Configurable;
032: import org.sape.carbon.core.component.lifecycle.Startable;
033: import org.sape.carbon.services.jmx.server.MBeanServerRetreiveException;
034: import org.sape.carbon.services.jmx.server.MBeanServerService;
035:
036: import mx4j.adaptor.rmi.jrmp.JRMPAdaptorMBean;
037: import mx4j.util.StandardMBeanProxy;
038: import org.apache.commons.logging.Log;
039: import org.apache.commons.logging.LogFactory;
040:
041: /**
042: * <p>This is the default and very simple implementation of a JRMP admin
043: * server built via the functionality in the MX4J JMX implementation. It
044: * opens a basic RMI over JRMP administration listener to the MX4J client
045: * adaptor.</p>
046: *
047: *
048: * Copyright 2002 Sapient
049: * @since carbon 1.0
050: * @author Greg Hinkle, May 2002
051: * @version $Revision: 1.7 $($Author: dvoet $ / $Date: 2003/05/05 21:21:31 $)
052: */
053: public class DefaultJrmpRemotingImpl implements MBeanServerService,
054: Configurable, Startable {
055:
056: /**
057: * Provides a handle to Apache-commons logger
058: */
059: private Log log = LogFactory.getLog(this .getClass());
060:
061: /** Object name for the registry. */
062: private ObjectName registryObjectName;
063:
064: /** Object instance for the registry. */
065: private ObjectInstance registryObjectInstance;
066:
067: /** The Jmx type string. */
068: private static final String REGISTRY_OBJECT_NAME_STRING = "Naming:type=rmiregistry";
069:
070: /** Class to use for the naming service. */
071: private static final String NAMING_SERVICE_CLASS_NAME = "mx4j.tools.naming.NamingService";
072:
073: /** The Jmx object name for the adapter. */
074: private ObjectName adaptorObjectName;
075:
076: /** The Adapter MBean. */
077: private JRMPAdaptorMBean adaptorMBean;
078:
079: /** JMX Adapter object name string. */
080: private static final String ADAPTOR_OBJECT_NAME_STRING = "Adaptor:protocol=JRMP";
081:
082: /** Name of adapter class. */
083: private static final String ADAPTOR_CLASS_NAME = "mx4j.adaptor.rmi.jrmp.JRMPAdaptor";
084:
085: /** Protocol prefix to the URL. */
086: private static final String URL_ID = "rmi://";
087:
088: /** Class for the initial context factory. */
089: private Class initialContextFactoryClass;
090:
091: /** Hostname. */
092: private String hostname;
093:
094: /** Port to expose on. */
095: private int port;
096:
097: /** MBeanServerService being exposed remotely. */
098: private MBeanServerService mbeanServerService;
099:
100: /**
101: * Configures the component.
102: *
103: * @param componentConfiguration <code>JrmpRemotingConfiguration</code>
104: * to configure the component
105: * @throws Exception indicates an error configuring the component
106: */
107: public void configure(ComponentConfiguration componentConfiguration)
108: throws Exception {
109:
110: JrmpRemotingConfiguration config = (JrmpRemotingConfiguration) componentConfiguration;
111:
112: this .initialContextFactoryClass = config
113: .getInitialContextFactoryClass();
114:
115: this .hostname = config.getHostname();
116: this .port = config.getPort();
117: this .mbeanServerService = config.getMBeanServerService();
118:
119: MBeanServer server = getMBeanServer();
120:
121: // Create the naming service
122: this .registryObjectName = new ObjectName(
123: REGISTRY_OBJECT_NAME_STRING);
124:
125: try {
126: this .registryObjectInstance = server.createMBean(
127: NAMING_SERVICE_CLASS_NAME, this .registryObjectName,
128: null);
129: } catch (InstanceAlreadyExistsException iaee) {
130: // Completely expected second+ time through
131: }
132:
133: boolean started = false;
134: while (!started) {
135: started = true;
136: try {
137: // Start the registry server
138: server.invoke(this .registryObjectName, "start", null,
139: null);
140: } catch (MBeanException mbe) {
141: if (this .port > (config.getPort() + 5)) {
142: throw mbe;
143: }
144:
145: started = false;
146: if (mbe.getTargetException() instanceof ExportException) {
147: server.setAttribute(this .registryObjectName,
148: new Attribute("Port", new Integer(
149: ++this .port)));
150: }
151: }
152:
153: }
154: if (log.isDebugEnabled()) {
155: log.debug("Able to start naming server on port ["
156: + this .port + "]");
157: }
158:
159: // Create the JRMP adaptor
160: this .adaptorObjectName = new ObjectName(
161: ADAPTOR_OBJECT_NAME_STRING);
162:
163: try {
164: server.createMBean(ADAPTOR_CLASS_NAME,
165: this .adaptorObjectName, null);
166:
167: } catch (InstanceAlreadyExistsException iaee) {
168: // Completely expected second+ time through
169: }
170:
171: this .adaptorMBean = (JRMPAdaptorMBean) StandardMBeanProxy
172: .create(JRMPAdaptorMBean.class, server,
173: adaptorObjectName);
174:
175: // Set the JNDI name with which will be registered
176: String jndiName = "jrmp";
177: this .adaptorMBean.putNamingProperty(
178: InitialContext.INITIAL_CONTEXT_FACTORY,
179: this .initialContextFactoryClass.getName());
180: this .adaptorMBean.putNamingProperty(
181: InitialContext.PROVIDER_URL, this .URL_ID
182: + this .hostname + ":" + this .port);
183:
184: this .adaptorMBean.setJNDIName(jndiName);
185:
186: }
187:
188: /**
189: * Starts the service.
190: *
191: * @throws Exception indicates an error starting the service
192: */
193: public void start() throws Exception {
194: // Get a MBeanServer
195: MBeanServer server = getMBeanServer();
196:
197: // Register the JRMP adaptor in JNDI and start it
198: this .adaptorMBean.start();
199: }
200:
201: /**
202: * Stops the service.
203: *
204: * @throws Exception indicates an error stopping the service
205: */
206: public void stop() throws Exception {
207: // Get a MBeanServer
208: MBeanServer server = getMBeanServer();
209:
210: this .adaptorMBean.stop();
211:
212: // Stop the registry server
213: server.invoke(this .registryObjectName, "stop", null, null);
214: }
215:
216: /**
217: * Gets the MBeanServer.
218: *
219: * @return the MBean Server
220: * @throws MBeanServerRetreiveException indicates and error
221: * retreiving the MBean server
222: */
223: public MBeanServer getMBeanServer()
224: throws MBeanServerRetreiveException {
225: return this.mbeanServerService.getMBeanServer();
226: }
227:
228: }
|