View Javadoc

1   /*
2    * Copyright (c) 2004 Peter Antman, Mogul  <peter.antman@mogul.com>
3    *
4    * $Id: MBeanProxyFactory.java,v 1.2 2004/05/19 12:20:14 pra Exp $
5    *
6    * This library is free software; you can redistribute it and/or
7    * modify it under the terms of the GNU Lesser General Public
8    * License as published by the Free Software Foundation; either
9    * version 2 of the License, or (at your option) any later version
10   * 
11   * This library is distributed in the hope that it will be useful,
12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   * Lesser General Public License for more details.
15   * 
16   * You should have received a copy of the GNU Lesser General Public
17   * License along with this library; if not, write to the Free Software
18   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19   */
20  package org.backsource.jmx;
21  import java.lang.reflect.Proxy;
22  import javax.naming.InitialContext;
23  import javax.naming.Context;
24  import javax.naming.NamingException;
25  import java.lang.reflect.Proxy;
26  
27  import org.apache.commons.logging.Log;
28  import org.apache.commons.logging.LogFactory; 
29  
30  import javax.management.*;
31  
32  import org.backsource.utils.naming.NamingHelper;
33  /***
34   * A factory for creating and binding MBean proxies.
35   *
36   * <p>This factory will create and bind MBean proxies. These have three capabilities:</p>
37   * <ul>
38   <li>It makes an MBean types through an interface. The proxy will use the normal JMX invokation style under the hood, but to the caller it is as if invoking a normal object.</li>
39   <li>It will bind the proxy in JNDI where it is possible to lookup both locally and remotely. When used locally the invokation will goto directly against the local mbean server, whith one exception - see below, when looked up from a remote JVM (or through a JNDI with remote semantics) the mbean server will be invoked over RMI.</li>
40   <li>When configured with jndiURL, the proxy is actually a proxy to another remote MBean server. In that case the invokation will go to the other remote MBean server. Normally one should probably bind these types of proxied in the java: naming domain, since they are reallt meant to be used only locally!</li>
41   <p>To be able to guarantee this semantics the rebinds and unbind methods int this class must be used to bind the proxied into JNDI.</p>
42   *
43   * @author <a href="mailto:pra@mogul.com">Peter Antman</a>
44   * @version $Revision: 1.2 $
45   */
46  
47  public class MBeanProxyFactory {
48     private static Log log = LogFactory.getLog(MBeanProxyFactory.class);
49     /***
50      * Create an MBean proxy.
51      * @param intf class of interface to cover for.
52      * @param name ObjectName of MBean to invoke.
53      */
54     public static Object create(Class intf, String name)
55        throws OperationsException,NamingException
56     {
57        return Proxy.newProxyInstance(intf.getClassLoader(),
58                                      new Class[] { intf },
59                                      new MBeanProxy(name));
60     }
61  
62     /***
63      * Create an MBean proxy.
64      * @param intf class of interface to cover for.
65      * @param name ObjectName of MBean to invoke.
66      * @param jndiURL a java.naming.provider.url pointing to another JNDI space, which holds an MBean server to invoke, if null the local server is used.
67      */
68     public static Object create(Class intf, String name, String jndiURL)
69        throws OperationsException,NamingException
70     {
71        return Proxy.newProxyInstance(intf.getClassLoader(),
72                                      new Class[] { intf },
73                                      new MBeanProxy(name,jndiURL));
74     }
75  
76     /***
77      * Create an MBean proxy.
78      * @param intf classname of interface to cover for.
79      * @param name ObjectName of MBean to invoke.
80      * @param jndiURL a java.naming.provider.url pointing to another JNDI space, which holds an MBean server to invoke, if null the local server is used.
81      */
82  
83     public static Object create(String intfName, String name, String jndiURL)
84        throws OperationsException,ClassNotFoundException,NamingException
85     {
86        ClassLoader cl = Thread.currentThread().getContextClassLoader();
87        Class intf = cl.loadClass(intfName);
88        return create(intf,name,jndiURL);
89     }
90     
91     /***
92      * Create an MBean proxy.
93      * @param intf classname of interface to cover for.
94      * @param name ObjectName of MBean to invoke.
95      */
96     public static Object create(String intfName, String name)
97        throws OperationsException,ClassNotFoundException,NamingException
98     {
99        ClassLoader cl = Thread.currentThread().getContextClassLoader();
100       Class intf = cl.loadClass(intfName);
101       return create(intf,name);
102    }
103 
104    /***
105     * Helper to bind object at the given jndiName, any missing parent name will
106     * be created.
107     *
108     * <p>by using the method, users will be failsafe if JBoss changes is JNDI semantics. JBoss currently does not serialize object when running in the
109 same vm,see org.jnp.interfaces.NamingContext.rebind and lookup and the
110 usage of MarshalledValuePair.
111  This may ofcource change</p>
112     */
113    public static void rebind(String jndiName, Object o) throws NamingException {
114       try {
115          unbind(jndiName);
116       } catch (NamingException e) {
117          // go a head
118       } // end of try-catch
119       
120 
121       NamingHelper.bind(new InitialContext(),
122                         jndiName,
123                         o
124                         );
125    }
126 
127    /***
128     * An object bound through the rebind method whould use this method when unbinding!
129     */
130    public static void unbind(String jndiName) throws NamingException {
131       new InitialContext().unbind(jndiName);
132    }
133    
134 }// MBeanProxyFactory