001: /*
002: * BEGIN_HEADER - DO NOT EDIT
003: *
004: * The contents of this file are subject to the terms
005: * of the Common Development and Distribution License
006: * (the "License"). You may not use this file except
007: * in compliance with the License.
008: *
009: * You can obtain a copy of the license at
010: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
011: * See the License for the specific language governing
012: * permissions and limitations under the License.
013: *
014: * When distributing Covered Code, include this CDDL
015: * HEADER in each file and include the License file at
016: * https://open-esb.dev.java.net/public/CDDLv1.0.html.
017: * If applicable add the following below this CDDL HEADER,
018: * with the fields enclosed by brackets "[]" replaced with
019: * your own identifying information: Portions Copyright
020: * [year] [name of copyright owner]
021: */
022:
023: /*
024: * @(#)JSEJBIFramework.java
025: * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved.
026: *
027: * END_HEADER - DO NOT EDIT
028: */
029: package com.sun.jbi.framework.jse;
030:
031: import com.sun.jndi.rmi.registry.RegistryContextFactory;
032: import java.rmi.registry.Registry;
033: import java.rmi.registry.LocateRegistry;
034: import java.rmi.server.UnicastRemoteObject;
035: import java.util.HashMap;
036: import java.util.Properties;
037: import java.util.logging.Logger;
038:
039: import javax.management.MBeanServer;
040: import javax.management.ObjectName;
041: import javax.management.remote.JMXConnectorServer;
042: import javax.management.remote.JMXConnectorServerFactory;
043: import javax.management.remote.JMXServiceURL;
044: import javax.transaction.TransactionManager;
045:
046: /**
047: * JBI framework wrapper for Java SE platform.
048: * <br><br>
049: * A JSEJBIFramework instance cannot be loaded multiple times in the same
050: * VM. If multiple instances of the framework are required in a VM,
051: * instantiate multiple instances of JSEJBIFramework and load each one
052: * independently. There is no limit on the number of uniquely named
053: * JSEJBIFramework instances in the same VM. A specific JSEJBIFramework instance
054: * can be loaded and unloaded multiple times in a VM.
055: *
056: * @author Sun Microsystems, Inc.
057: */
058: public class JSEJBIFramework extends com.sun.jbi.framework.JBIFramework
059: implements JSEJBIFrameworkMBean {
060: public static final String INSTALL_ROOT = "install.root";
061: public static final String INSTANCE_NAME = "instance.name";
062: public static final String CONNECTOR_PORT = "connector.port";
063:
064: /** Configuration defaults. */
065: private static final String DEFAULT_INSTALL_ROOT = System
066: .getProperty("user.dir");
067: private static final String DEFAULT_INSTANCE_NAME = "server";
068:
069: private JSEPlatformContext mPlatformContext;
070: private boolean mLoaded;
071: private Properties mEnvironment;
072: private JMXConnectorServer mJMXServer;
073: private Registry mRegistry;
074: private Logger mLog = Logger.getLogger(this .getClass().getPackage()
075: .getName());
076:
077: /** Creates a new instance of the JBI framework.
078: */
079: public JSEJBIFramework(Properties environment) {
080: super ();
081:
082: mEnvironment = environment;
083: mPlatformContext = new JSEPlatformContext(mEnvironment
084: .getProperty(INSTANCE_NAME, DEFAULT_INSTANCE_NAME),
085: mEnvironment.getProperty(INSTALL_ROOT,
086: DEFAULT_INSTALL_ROOT));
087: }
088:
089: /** Load the JBI framework with the specified environment. When this method
090: * retuns, all public interfaces and system services have completely
091: * initialized. If a connector port is specified in the environment
092: * properties, a remote JMX connector server is created.
093: * @throws Exception failed to load JBI framework
094: */
095: public synchronized void load() throws Exception {
096: if (mLoaded) {
097: throw new IllegalStateException(
098: "JBI framework already loaded!");
099: }
100:
101: // Register a management MBean for this framework instance
102: ObjectName fwMBeanName = new ObjectName("com.sun.jbi.jse",
103: "instance", mPlatformContext.getInstanceName());
104: MBeanServer mbs = mPlatformContext.getMBeanServer();
105: if (mbs.isRegistered(fwMBeanName)) {
106: if (mbs.getAttribute(fwMBeanName, "Loaded").equals(
107: Boolean.TRUE)) {
108: // Framework already loaded from a separate thread/process
109: throw new IllegalStateException(
110: "JBI framework instance "
111: + mPlatformContext.getInstanceName()
112: + " has already been loaded");
113: } else {
114: // MBean should not be registered - try to clean up
115: mbs.unregisterMBean(fwMBeanName);
116: }
117: }
118: mbs.registerMBean(this , fwMBeanName);
119:
120: // Setup the remote JMX connector server
121: String portStr = mEnvironment.getProperty(CONNECTOR_PORT);
122: if (portStr != null) {
123: try {
124: int port = Integer.parseInt(portStr);
125: createJMXConnectorServer(port);
126: } catch (NumberFormatException nfEx) {
127: mLog
128: .warning("Invalid connector server port: "
129: + portStr
130: + ". Remote JMX connector will not be created.");
131: }
132: }
133:
134: // For stand-alone JBI, JBI_HOME = platform install root
135: mEnvironment.setProperty("com.sun.jbi.home", mPlatformContext
136: .getInstallRoot());
137:
138: init(mPlatformContext, mEnvironment);
139: startup(mPlatformContext.getNamingContext(), "");
140: prepare();
141: ready(true);
142:
143: // JBI framework has been loaded
144: mLoaded = true;
145: }
146:
147: /** Queries the state of the JBI Framework.
148: * @return true if the JBI framework is loaded, false otherwise.
149: */
150: public boolean isLoaded() {
151: return mLoaded;
152: }
153:
154: /** Unloads the JBI framework. When this method retuns, all
155: * public interfaces, system services, and JMX connector (if configured)
156: * have been destroyed.
157: * @throws javax.jbi.JBIException failed to unload JBI framework
158: */
159: public synchronized void unload() throws Exception {
160: if (!mLoaded) {
161: return;
162: }
163:
164: shutdown();
165: terminate();
166:
167: try {
168: mJMXServer.stop();
169: UnicastRemoteObject.unexportObject(mRegistry, true);
170: } catch (Exception ex) {
171: mLog.severe("Error during framework shutdown: "
172: + ex.toString());
173: }
174:
175: mLoaded = false;
176: }
177:
178: public JMXServiceURL getServiceURL(int port)
179: throws java.net.MalformedURLException {
180: return new JMXServiceURL(
181: "service:jmx:rmi:///jndi/rmi://localhost:" + port
182: + "/jmxrmi");
183: }
184:
185: /** Creates a JMX connector server at the specified port.
186: * @param port port for the JMX connector server.
187: */
188: private void createJMXConnectorServer(int port) {
189: HashMap<String, String> map = new HashMap<String, String>();
190: map.put("java.naming.factory.initial",
191: RegistryContextFactory.class.getName());
192:
193: try {
194: // Create the service URL
195: JMXServiceURL serviceURL = getServiceURL(port);
196:
197: // Create an RMI registry instance to hold the JMX connector server
198: mRegistry = LocateRegistry.createRegistry(port);
199:
200: // Create and start the connector server
201: mJMXServer = JMXConnectorServerFactory
202: .newJMXConnectorServer(serviceURL, map,
203: mPlatformContext.getMBeanServer());
204: mJMXServer.start();
205:
206: mLog.info("remote JMX connector available at "
207: + mJMXServer.getAddress());
208: } catch (Exception ex) {
209: mLog.severe("Failed to create remote JMX connector: "
210: + ex.toString());
211: }
212: }
213:
214: }
|