KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > system > server > jmx > JMXKernel


1 /*
2  * JBoss, Home of Professional Open Source
3  * Copyright 2005, JBoss Inc., and individual contributors as indicated
4  * by the @authors tag. See the copyright.txt in the distribution for a
5  * full listing of individual contributors.
6  *
7  * This is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as
9  * published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * This software is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this software; if not, write to the Free
19  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21  */

22 package org.jboss.system.server.jmx;
23
24 import java.io.File JavaDoc;
25 import java.lang.reflect.Method JavaDoc;
26 import java.net.URL JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.util.Date JavaDoc;
29 import java.util.Iterator JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.Properties JavaDoc;
32 import java.util.logging.LogManager JavaDoc;
33
34 import javax.management.ListenerNotFoundException JavaDoc;
35 import javax.management.MBeanNotificationInfo JavaDoc;
36 import javax.management.MBeanServer JavaDoc;
37 import javax.management.MBeanServerFactory JavaDoc;
38 import javax.management.NotificationEmitter JavaDoc;
39 import javax.management.NotificationFilter JavaDoc;
40 import javax.management.NotificationListener JavaDoc;
41 import javax.management.ObjectInstance JavaDoc;
42 import javax.management.ObjectName JavaDoc;
43
44 import org.jboss.kernel.Kernel;
45 import org.jboss.logging.JBossJDKLogManager;
46 import org.jboss.mx.loading.RepositoryClassLoader;
47 import org.jboss.mx.server.ServerConstants;
48 import org.jboss.mx.util.JMXExceptionDecoder;
49 import org.jboss.mx.util.MBeanServerLocator;
50 import org.jboss.mx.util.ObjectNameFactory;
51 import org.jboss.system.ServiceController;
52 import org.jboss.system.ServiceControllerMBean;
53 import org.jboss.system.server.Server;
54 import org.jboss.system.server.ServerConfig;
55 import org.jboss.system.server.ServerConfigImpl;
56 import org.jboss.system.server.ServerConfigImplMBean;
57 import org.jboss.system.server.ServerImplMBean;
58 import org.jboss.util.JBossObject;
59 import org.jboss.util.file.FileSuffixFilter;
60
61 /**
62  * A pojo that creates a legacy jmx kernel ala the jboss-4.x server bootstrap.
63  * This is used to support the SARDeployer and mbean integration.
64  *
65  * @author Scott.Stark@jboss.org
66  * @version $Revision:$
67  */

68 public class JMXKernel extends JBossObject
69    implements JMXKernelMBean, NotificationEmitter JavaDoc
70 {
71    private final static ObjectName JavaDoc DEFAULT_LOADER_NAME =
72       ObjectNameFactory.create(ServerConstants.DEFAULT_LOADER_NAME);
73
74    /** The JMX MBeanServer which will serve as our communication bus. */
75    private MBeanServer JavaDoc mbeanServer;
76    private Server JavaDoc serverImpl;
77    private ServiceController controller;
78    private ServerConfig serverConfig;
79    private ServerConfigImplMBean serverConfigMBean;
80    /** The kernel */
81    private Kernel kernel;
82    /** The serverImpl cast as an emitter */
83    private NotificationEmitter JavaDoc notificationEmitter;
84    
85    /** The bootstrap UCL class loader ObjectName */
86    private ObjectName JavaDoc bootstrapUCLName;
87    private boolean started;
88    /** A flag indicating if shutdown has been called */
89    private boolean isInShutdown;
90
91    public Server JavaDoc getServerImpl()
92    {
93       return serverImpl;
94    }
95    public void setServerImpl(Server JavaDoc serverImpl)
96    {
97       this.serverImpl = serverImpl;
98       this.notificationEmitter = (NotificationEmitter JavaDoc) serverImpl;
99    }
100
101    public ServiceControllerMBean getServiceController()
102    {
103       return this.controller;
104    }
105    public MBeanServer JavaDoc getMbeanServer()
106    {
107       return mbeanServer;
108    }
109
110    /**
111     * Set the kernel.
112     *
113     * @param kernel the kernel.
114     */

115    public void setKernel(Kernel kernel)
116    {
117       this.kernel = kernel;
118    }
119    
120    public void start() throws Exception JavaDoc
121    {
122       ClassLoader JavaDoc tcl = Thread.currentThread().getContextClassLoader();
123       // Create the MBeanServer
124
String JavaDoc builder = System.getProperty(ServerConstants.MBEAN_SERVER_BUILDER_CLASS_PROPERTY,
125                                           ServerConstants.DEFAULT_MBEAN_SERVER_BUILDER_CLASS);
126       System.setProperty(ServerConstants.MBEAN_SERVER_BUILDER_CLASS_PROPERTY, builder);
127
128       serverConfig = serverImpl.getConfig();
129       serverConfigMBean = new ServerConfigImpl(serverConfig);
130       // Check if we'll use the platform MBeanServer or instantiate our own
131
if (serverConfig.getPlatformMBeanServer() == true)
132       {
133          // jdk1.5+
134
ClassLoader JavaDoc cl = Thread.currentThread().getContextClassLoader();
135          Class JavaDoc clazz = cl.loadClass("java.lang.management.ManagementFactory");
136          Class JavaDoc[] sig = null;
137          Method JavaDoc method = clazz.getMethod("getPlatformMBeanServer", sig);
138          Object JavaDoc[] args = null;
139          mbeanServer = (MBeanServer JavaDoc) method.invoke(null, args);
140          // Tell the MBeanServerLocator to point to this mbeanServer
141
MBeanServerLocator.setJBoss(mbeanServer);
142          /* If the LazyMBeanServer was used, we need to reset to the jboss
143          MBeanServer to use our implementation for the jboss services.
144          */

145          mbeanServer = LazyMBeanServer.resetToJBossServer(mbeanServer);
146       }
147       else
148       {
149          // Create our own MBeanServer
150
mbeanServer = MBeanServerFactory.createMBeanServer("jboss");
151       }
152       log.debug("Created MBeanServer: " + mbeanServer);
153
154       // Register mbeanServer components
155
mbeanServer.registerMBean(this, ServerImplMBean.OBJECT_NAME);
156       mbeanServer.registerMBean(serverConfigMBean, ServerConfigImplMBean.OBJECT_NAME);
157
158       // Initialize spine boot libraries
159
RepositoryClassLoader ucl = initBootLibraries();
160       bootstrapUCLName = ucl.getObjectName();
161       mbeanServer.registerMBean(ucl, bootstrapUCLName);
162
163       // Set ServiceClassLoader as classloader for the construction of
164
// the basic system
165
try
166       {
167          Thread.currentThread().setContextClassLoader(ucl);
168    
169          // General Purpose Architecture information
170
createMBean("org.jboss.system.server.ServerInfo",
171             "jboss.system:type=ServerInfo");
172    
173          // Service Controller
174
controller = new ServiceController();
175          controller.setKernel(kernel);
176          controller.setMBeanServer(mbeanServer);
177          mbeanServer.registerMBean(controller, new ObjectName JavaDoc("jboss.system:service=ServiceController"));
178    
179          log.info("Legacy JMX core initialized");
180          started = true;
181       }
182       finally
183       {
184          Thread.currentThread().setContextClassLoader(tcl);
185       }
186    }
187
188    /**
189     * Stop the mbeans
190     *
191     * @throws IllegalStateException - if not started.
192     */

193    public void stop() throws IllegalStateException JavaDoc
194    {
195       if (log.isTraceEnabled())
196          log.trace("stop caller:", new Throwable JavaDoc("Here"));
197
198       if (!started)
199          throw new IllegalStateException JavaDoc("Server not started");
200
201       isInShutdown = true;
202       // start in new thread to give positive
203
// feedback to requesting client of success.
204
new Thread JavaDoc()
205       {
206          public void run()
207          {
208             // just run the hook, don't call System.exit, as we may
209
// be embeded in a vm that would not like that very much
210
shutdown();
211          }
212       }.start();
213    }
214
215    ///////////////////////////////////////////////////////////////////////////
216
// NotificationEmitter //
217
///////////////////////////////////////////////////////////////////////////
218

219    public void addNotificationListener(NotificationListener JavaDoc listener, NotificationFilter JavaDoc filter, Object JavaDoc handback)
220    {
221       notificationEmitter.addNotificationListener(listener, filter, handback);
222    }
223    
224    public void removeNotificationListener(NotificationListener JavaDoc listener) throws ListenerNotFoundException JavaDoc
225    {
226       notificationEmitter.removeNotificationListener(listener);
227    }
228    
229    public void removeNotificationListener(NotificationListener JavaDoc listener, NotificationFilter JavaDoc filter, Object JavaDoc handback)
230       throws ListenerNotFoundException JavaDoc
231    {
232       notificationEmitter.removeNotificationListener(listener, filter, handback);
233    }
234       
235    public MBeanNotificationInfo JavaDoc[] getNotificationInfo()
236    {
237       return notificationEmitter.getNotificationInfo();
238    }
239
240    // ServerImplMBean delegation
241
public void init(Properties JavaDoc props) throws Exception JavaDoc
242    {
243       serverImpl.init(props);
244    }
245
246    public void exit()
247    {
248       serverImpl.exit();
249    }
250
251    public void exit(int exitcode)
252    {
253       serverImpl.exit(exitcode);
254    }
255
256    public ServerConfig getConfig()
257    {
258       return serverConfig;
259    }
260    public String JavaDoc getBuildDate()
261    {
262       return serverImpl.getBuildDate();
263    }
264
265    public String JavaDoc getBuildID()
266    {
267       return serverImpl.getBuildID();
268    }
269
270    public String JavaDoc getBuildJVM()
271    {
272       return serverImpl.getBuildJVM();
273    }
274
275    public String JavaDoc getBuildNumber()
276    {
277       return serverImpl.getBuildNumber();
278    }
279
280    public String JavaDoc getBuildOS()
281    {
282       return serverImpl.getBuildOS();
283    }
284
285    public Date JavaDoc getStartDate()
286    {
287       return serverImpl.getStartDate();
288    }
289
290    public String JavaDoc getVersion()
291    {
292       return serverImpl.getVersion();
293    }
294
295    public String JavaDoc getVersionName()
296    {
297       return serverImpl.getVersionName();
298    }
299
300    public void halt()
301    {
302       serverImpl.halt();
303    }
304
305    public void halt(int exitcode)
306    {
307       serverImpl.halt(exitcode);
308    }
309
310    public boolean isInShutdown()
311    {
312       return serverImpl.isInShutdown();
313    }
314
315    public boolean isStarted()
316    {
317       return serverImpl.isStarted();
318    }
319
320    public void runFinalization()
321    {
322       
323    }
324
325    public void runGarbageCollector()
326    {
327       
328    }
329
330    public void traceInstructions(Boolean JavaDoc flag)
331    {
332       
333    }
334
335    public void traceMethodCalls(Boolean JavaDoc flag)
336    {
337       
338    }
339    
340    public void shutdown()
341    {
342       if (log.isTraceEnabled())
343          log.trace("Shutdown caller:", new Throwable JavaDoc("Here"));
344       
345       // Execute the jdk JBossJDKLogManager doReset
346
LogManager JavaDoc lm = LogManager.getLogManager();
347       if (lm instanceof JBossJDKLogManager)
348       {
349          JBossJDKLogManager jbosslm = (JBossJDKLogManager)lm;
350          jbosslm.doReset();
351       }
352
353       // avoid entering twice; may happen when called directly
354
// from ServerImpl.shutdown(), then called again when all
355
// non-daemon threads have exited and the ShutdownHook runs.
356
if (isInShutdown)
357          return;
358       else
359          isInShutdown = true;
360       
361       // ServiceController.shutdown()
362
log.debug("Shutting down all services");
363       shutdownServices();
364
365       // Make sure all mbeans are unregistered
366
removeMBeans();
367
368       // Done
369
log.info("Legacy kernel shutdown complete");
370       System.out.println("Legacy kernel shutdown complete");
371    }
372
373    /**
374     * The <code>shutdownServices</code> method calls the one and only
375     * ServiceController to shut down all the mbeans registered with it.
376     */

377    protected void shutdownServices()
378    {
379       try
380       {
381          // get the deployed objects from ServiceController
382
controller.shutdown();
383       }
384       catch (Exception JavaDoc e)
385       {
386          Throwable JavaDoc t = JMXExceptionDecoder.decode(e);
387          log.error("Failed to shutdown services", t);
388       }
389    }
390
391    /**
392     * The <code>removeMBeans</code> method uses the mbean mbeanServer to unregister
393     * all the mbeans registered here.
394     */

395    protected void removeMBeans()
396    {
397       try
398       {
399          mbeanServer.unregisterMBean(ServiceControllerMBean.OBJECT_NAME);
400          mbeanServer.unregisterMBean(ServerConfigImplMBean.OBJECT_NAME);
401          mbeanServer.unregisterMBean(ServerImplMBean.OBJECT_NAME);
402       }
403       catch (Exception JavaDoc e)
404       {
405          Throwable JavaDoc t = JMXExceptionDecoder.decode(e);
406          log.error("Failed to unregister mbeans", t);
407       }
408       try
409       {
410          MBeanServer JavaDoc registeredServer = mbeanServer;
411          if (serverConfig.getPlatformMBeanServer() == true)
412             registeredServer = LazyMBeanServer.getRegisteredMBeanServer(mbeanServer);
413          MBeanServerFactory.releaseMBeanServer(registeredServer);
414       }
415       catch (Exception JavaDoc e)
416       {
417          Throwable JavaDoc t = JMXExceptionDecoder.decode(e);
418          log.error("Failed to release mbean mbeanServer", t);
419       }
420    }
421
422
423    /**
424     * Initialize the boot libraries.
425     *
426     * @return the classloader
427     * @throws Exception for any error
428     */

429    private RepositoryClassLoader initBootLibraries() throws Exception JavaDoc
430    {
431       // Build the list of URL for the spine to boot
432
List JavaDoc<URL JavaDoc> list = new ArrayList JavaDoc<URL JavaDoc>();
433
434       // Add the patch URL. If the url protocol is file, then
435
// add the contents of the directory it points to
436
URL JavaDoc patchURL = serverConfig.getPatchURL();
437       if (patchURL != null)
438       {
439          if (patchURL.getProtocol().equals("file"))
440          {
441             File JavaDoc dir = new File JavaDoc(patchURL.getFile());
442             if (dir.exists())
443             {
444                // Add the local file patch directory
445
list.add(dir.toURL());
446
447                // Add the contents of the directory too
448
File JavaDoc[] jars = dir.listFiles(new FileSuffixFilter(new String JavaDoc[] { ".jar", ".zip" }, true));
449
450                for (int j = 0; jars != null && j < jars.length; j++)
451                {
452                   list.add(jars[j].getCanonicalFile().toURL());
453                }
454             }
455          }
456          else
457          {
458             list.add(patchURL);
459          }
460       }
461
462       // Add the mbeanServer configuration directory to be able to load serverConfig files as resources
463
list.add(serverConfig.getServerConfigURL());
464       log.debug("Boot url list: " + list);
465
466       // Create loaders for each URL
467
RepositoryClassLoader loader = null;
468       for (Iterator JavaDoc iter = list.iterator(); iter.hasNext();)
469       {
470          URL JavaDoc url = (URL JavaDoc)iter.next();
471          log.debug("Creating loader for URL: " + url);
472
473          // This is a boot URL, so key it on itself.
474
Object JavaDoc[] args = {url, Boolean.TRUE};
475          String JavaDoc[] sig = {"java.net.URL", "boolean"};
476          loader = (RepositoryClassLoader) mbeanServer.invoke(DEFAULT_LOADER_NAME, "newClassLoader", args, sig);
477       }
478       return loader;
479    }
480
481    /**
482     * Instantiate and register a service for the given classname into the MBean mbeanServer.
483     *
484     * @param classname the mbean class name
485     * @param name the obejct name
486     * @return the object name
487     * @throws Exception for any error
488     */

489    private ObjectName JavaDoc createMBean(final String JavaDoc classname, String JavaDoc name)
490       throws Exception JavaDoc
491    {
492       ObjectName JavaDoc mbeanName = null;
493       if( name != null )
494          mbeanName = new ObjectName JavaDoc(name);
495       try
496       {
497          // See if there is an xmbean descriptor for the bootstrap mbean
498
URL JavaDoc xmbeanDD = new URL JavaDoc("resource:xmdesc/"+classname+"-xmbean.xml");
499          Object JavaDoc resource = mbeanServer.instantiate(classname);
500          // Create the XMBean
501
Object JavaDoc[] args = {resource, xmbeanDD};
502          String JavaDoc[] sig = {Object JavaDoc.class.getName(), URL JavaDoc.class.getName()};
503          ObjectInstance JavaDoc instance = mbeanServer.createMBean("org.jboss.mx.modelmbean.XMBean",
504                                        mbeanName,
505                                        bootstrapUCLName,
506                                        args,
507                                        sig);
508          mbeanName = instance.getObjectName();
509          log.debug("Created system XMBean: "+mbeanName);
510       }
511       catch(Exception JavaDoc e)
512       {
513          log.debug("Failed to create xmbean for: "+classname);
514          mbeanName = mbeanServer.createMBean(classname, mbeanName).getObjectName();
515          log.debug("Created system MBean: " + mbeanName);
516       }
517
518       return mbeanName;
519    }
520 }
521
Popular Tags