View Javadoc

1   /*
2    * $Id: ClassloaderSwitchingMBeanWrapper.java 20320 2010-11-24 15:03:31Z dfeist $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.module.management.agent;
12  
13  import javax.management.MBeanException;
14  import javax.management.MBeanRegistration;
15  import javax.management.MBeanServer;
16  import javax.management.NotCompliantMBeanException;
17  import javax.management.ObjectName;
18  import javax.management.ReflectionException;
19  import javax.management.StandardMBean;
20  
21  import org.apache.commons.logging.Log;
22  import org.apache.commons.logging.LogFactory;
23  
24  /**
25   * Ensures any external jmx invocation (like e.g. remote) is executed with a correct application
26   * classloader (otherwise a bootstrap classloader is used by default for platform mbean server). Note
27   * the irony - extends StandardMBean, but StandardMBean is not your 'standard mbean', but rather a
28   * special kind of the DynamicMBean which generates attributes/operations based on the passed in
29   * interface (via reflection).
30   */
31  public class ClassloaderSwitchingMBeanWrapper extends StandardMBean implements MBeanRegistration
32  {
33      protected Log logger = LogFactory.getLog(getClass());
34  
35      private ClassLoader executionClassLoader;
36  
37      public <T> ClassloaderSwitchingMBeanWrapper(T implementation, Class<T> mbeanInterface, ClassLoader executionClassLoader)
38              throws NotCompliantMBeanException
39      {
40          super(implementation, mbeanInterface);
41          this.executionClassLoader = executionClassLoader;
42      }
43  
44      @Override
45      public Object invoke(String actionName, Object[] params, String[] signature) throws MBeanException, ReflectionException
46      {
47          ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
48          try
49          {
50              Thread.currentThread().setContextClassLoader(executionClassLoader);
51              return super.invoke(actionName, params, signature);
52          }
53          catch (MBeanException mbex)
54          {
55              throw mbex;
56          }
57          catch (ReflectionException rex)
58          {
59              throw rex;
60          }
61          catch (Exception ex)
62          {
63              logger.error(String.format("MBean operation '%s' failed", actionName), ex);
64              if (ex instanceof RuntimeException)
65              {
66                  throw (RuntimeException) ex;
67              }
68  
69              throw new RuntimeException(ex);
70          }
71          finally
72          {
73              Thread.currentThread().setContextClassLoader(oldCl);
74          }
75      }
76  
77      public ClassLoader getExecutionClassLoader()
78      {
79          return executionClassLoader;
80      }
81  
82      public void setExecutionClassLoader(ClassLoader executionClassLoader)
83      {
84          this.executionClassLoader = executionClassLoader;
85      }
86  
87      public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception
88      {
89          if (getImplementation() instanceof MBeanRegistration)
90          {
91              return ((MBeanRegistration) getImplementation()).preRegister(server, name);
92          }
93  
94          return name;
95      }
96  
97      public void postRegister(Boolean registrationDone)
98      {
99          if (getImplementation() instanceof MBeanRegistration)
100         {
101             ((MBeanRegistration) getImplementation()).postRegister(registrationDone);
102         }
103     }
104 
105     public void preDeregister() throws Exception
106     {
107         if (getImplementation() instanceof MBeanRegistration)
108         {
109             ((MBeanRegistration) getImplementation()).preDeregister();
110         }
111     }
112 
113     public void postDeregister()
114     {
115         if (getImplementation() instanceof MBeanRegistration)
116         {
117             ((MBeanRegistration) getImplementation()).postDeregister();
118         }
119     }
120 }