001: /*
002: * Copyright 1999-2004 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.apache.jk.common;
018:
019: import org.apache.jk.core.JkHandler;
020:
021: import javax.management.MBeanServer;
022: import javax.management.ObjectName;
023: import javax.management.Attribute;
024: import javax.management.MBeanServerFactory;
025: import java.io.IOException;
026:
027: /**
028: * Load the HTTP or RMI adapters for MX4J and JMXRI.
029: *
030: * Add "mx.enabled=true" in jk2.properties to enable it.
031: * You could also select http and/or jrmp protocol,
032: * with mx.httpPort, mx.httpHost, mxjrmpPort and mx.jrmpPort
033: *
034: */
035: public class JkMX extends JkHandler {
036: MBeanServer mserver;
037: private boolean enabled = false;
038: private int httpport = -1;
039: private String httphost = "localhost";
040: private int jrmpport = -1;
041: private String jrmphost = "localhost";
042: private boolean useXSLTProcessor = true;
043:
044: public JkMX() {
045: }
046:
047: /* -------------------- Public methods -------------------- */
048:
049: /** Enable the MX4J adapters (new way)
050: */
051: public void setEnabled(boolean b) {
052: enabled = b;
053: }
054:
055: public boolean getEnabled() {
056: return enabled;
057: }
058:
059: /** Enable the MX4J adapters (old way, compatible)
060: */
061: public void setPort(int i) {
062: enabled = (i != -1);
063: }
064:
065: public int getPort() {
066: return ((httpport != -1) ? httpport : jrmpport);
067: }
068:
069: /** Enable the MX4J HTTP internal adapter
070: */
071: public void setHttpPort(int i) {
072: httpport = i;
073: }
074:
075: public int getHttpPort() {
076: return httpport;
077: }
078:
079: public void setHttpHost(String host) {
080: this .httphost = host;
081: }
082:
083: public String getHttpHost() {
084: return httphost;
085: }
086:
087: /** Enable the MX4J JRMP internal adapter
088: */
089: public void setJrmpPort(int i) {
090: jrmpport = i;
091: }
092:
093: public int getJrmpPort() {
094: return jrmpport;
095: }
096:
097: public void setJrmpHost(String host) {
098: this .jrmphost = host;
099: }
100:
101: public String getJrmpHost() {
102: return jrmphost;
103: }
104:
105: public boolean getUseXSLTProcessor() {
106: return useXSLTProcessor;
107: }
108:
109: public void setUseXSLTProcessor(boolean uxsltp) {
110: useXSLTProcessor = uxsltp;
111: }
112:
113: /* ==================== Start/stop ==================== */
114: ObjectName httpServerName = null;
115: ObjectName jrmpServerName = null;
116:
117: /** Initialize the worker. After this call the worker will be
118: * ready to accept new requests.
119: */
120: public void loadAdapter() throws IOException {
121: boolean httpAdapterLoaded = false;
122: boolean jrmpAdapterLoaded = false;
123:
124: if ((httpport != -1)
125: && classExists("mx4j.adaptor.http.HttpAdaptor")) {
126: try {
127: httpServerName = registerObject(
128: "mx4j.adaptor.http.HttpAdaptor",
129: "Http:name=HttpAdaptor");
130:
131: if (httphost != null)
132: mserver.setAttribute(httpServerName, new Attribute(
133: "Host", httphost));
134: mserver.setAttribute(httpServerName, new Attribute(
135: "Port", new Integer(httpport)));
136:
137: if (useXSLTProcessor) {
138: ObjectName processorName = registerObject(
139: "mx4j.adaptor.http.XSLTProcessor",
140: "Http:name=XSLTProcessor");
141: mserver.setAttribute(httpServerName, new Attribute(
142: "ProcessorName", processorName));
143: }
144:
145: // starts the server
146: mserver.invoke(httpServerName, "start", null, null);
147:
148: log.info("Started MX4J console on host " + httphost
149: + " at port " + httpport);
150:
151: httpAdapterLoaded = true;
152:
153: } catch (Throwable t) {
154: httpServerName = null;
155: log.error("Can't load the MX4J http adapter ", t);
156: }
157: }
158:
159: if ((httpport != -1) && (!httpAdapterLoaded)
160: && classExists("mx4j.tools.adaptor.http.HttpAdaptor")) {
161: try {
162: httpServerName = registerObject(
163: "mx4j.tools.adaptor.http.HttpAdaptor",
164: "Http:name=HttpAdaptor");
165:
166: if (httphost != null)
167: mserver.setAttribute(httpServerName, new Attribute(
168: "Host", httphost));
169: mserver.setAttribute(httpServerName, new Attribute(
170: "Port", new Integer(httpport)));
171:
172: if (useXSLTProcessor) {
173: ObjectName processorName = registerObject(
174: "mx4j.tools.adaptor.http.XSLTProcessor",
175: "Http:name=XSLTProcessor");
176: mserver.setAttribute(httpServerName, new Attribute(
177: "ProcessorName", processorName));
178: }
179: // starts the server
180: mserver.invoke(httpServerName, "start", null, null);
181:
182: log.info("Started MX4J console on host " + httphost
183: + " at port " + httpport);
184:
185: httpAdapterLoaded = true;
186:
187: } catch (Throwable t) {
188: httpServerName = null;
189: log.error("Can't load the MX4J http adapter ", t);
190: }
191: }
192:
193: if ((jrmpport != -1)
194: && classExists("mx4j.tools.naming.NamingService")) {
195: try {
196: jrmpServerName = registerObject(
197: "mx4j.tools.naming.NamingService",
198: "Naming:name=rmiregistry");
199: mserver.setAttribute(jrmpServerName, new Attribute(
200: "Port", new Integer(jrmpport)));
201: mserver.invoke(jrmpServerName, "start", null, null);
202: log.info("Creating " + jrmpServerName);
203:
204: // Create the JRMP adaptor
205: ObjectName adaptor = registerObject(
206: "mx4j.adaptor.rmi.jrmp.JRMPAdaptor",
207: "Adaptor:protocol=jrmp");
208:
209: mserver.setAttribute(adaptor, new Attribute("JNDIName",
210: "jrmp"));
211:
212: mserver
213: .invoke(
214: adaptor,
215: "putNamingProperty",
216: new Object[] {
217: javax.naming.Context.INITIAL_CONTEXT_FACTORY,
218: "com.sun.jndi.rmi.registry.RegistryContextFactory" },
219: new String[] { "java.lang.Object",
220: "java.lang.Object" });
221:
222: String jrpmurl = "rmi://" + jrmphost + ":"
223: + Integer.toString(jrmpport);
224:
225: mserver.invoke(adaptor, "putNamingProperty",
226: new Object[] {
227: javax.naming.Context.PROVIDER_URL,
228: jrpmurl },
229: new String[] { "java.lang.Object",
230: "java.lang.Object" });
231:
232: // Registers the JRMP adaptor in JNDI and starts it
233: mserver.invoke(adaptor, "start", null, null);
234: log.info("Creating " + adaptor + " on host " + jrmphost
235: + " at port " + jrmpport);
236:
237: jrmpAdapterLoaded = true;
238:
239: } catch (Exception ex) {
240: jrmpServerName = null;
241: log.error("MX4j RMI adapter not loaded: "
242: + ex.toString());
243: }
244: }
245:
246: if ((httpport != -1) && (!httpAdapterLoaded)
247: && classExists("com.sun.jdmk.comm.HtmlAdaptorServer")) {
248: try {
249: httpServerName = registerObject(
250: "com.sun.jdmk.comm.HtmlAdaptorServer",
251: "Adaptor:name=html,port=" + httpport);
252: log.info("Registering the JMX_RI html adapter "
253: + httpServerName + " at port " + httpport);
254:
255: mserver.setAttribute(httpServerName, new Attribute(
256: "Port", new Integer(httpport)));
257:
258: mserver.invoke(httpServerName, "start", null, null);
259:
260: httpAdapterLoaded = true;
261: } catch (Throwable t) {
262: httpServerName = null;
263: log.error("Can't load the JMX_RI http adapter "
264: + t.toString());
265: }
266: }
267:
268: if ((!httpAdapterLoaded) && (!jrmpAdapterLoaded))
269: log
270: .warn("No adaptors were loaded but mx.enabled was defined.");
271:
272: }
273:
274: public void destroy() {
275: try {
276: log.info("Stoping JMX ");
277:
278: if (httpServerName != null) {
279: mserver.invoke(httpServerName, "stop", null, null);
280: }
281: if (jrmpServerName != null) {
282: mserver.invoke(jrmpServerName, "stop", null, null);
283: }
284: } catch (Throwable t) {
285: log.error("Destroy error" + t);
286: }
287: }
288:
289: public void init() throws IOException {
290: try {
291: mserver = getMBeanServer();
292:
293: if (enabled) {
294: loadAdapter();
295: }
296:
297: try {
298: registerObject(
299: "org.apache.log4j.jmx.HierarchyDynamicMBean",
300: "log4j:hierarchy=default");
301: log.info("Registering the JMX hierarchy for Log4J ");
302: } catch (Throwable t) {
303: log.info("Can't enable log4j mx: " + t.toString());
304: }
305:
306: } catch (Throwable t) {
307: log.error("Init error", t);
308: }
309: }
310:
311: public void addHandlerCallback(JkHandler w) {
312: }
313:
314: MBeanServer getMBeanServer() {
315: MBeanServer server;
316: if (MBeanServerFactory.findMBeanServer(null).size() > 0) {
317: server = (MBeanServer) MBeanServerFactory.findMBeanServer(
318: null).get(0);
319: } else {
320: server = MBeanServerFactory.createMBeanServer();
321: }
322: return (server);
323: }
324:
325: private static boolean classExists(String className) {
326: try {
327: Thread.currentThread().getContextClassLoader().loadClass(
328: className);
329: return true;
330: } catch (Throwable e) {
331: if (log.isInfoEnabled())
332: log
333: .info("className [" + className
334: + "] does not exist");
335: return false;
336: }
337: }
338:
339: private ObjectName registerObject(String className, String oName)
340: throws Exception {
341: Class c = Class.forName(className);
342: Object o = c.newInstance();
343: ObjectName objN = new ObjectName(oName);
344: mserver.registerMBean(o, objN);
345: return objN;
346: }
347:
348: private static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory
349: .getLog(JkMX.class);
350:
351: }
|