1 package com.maxiq.tools.jboss;
2
3 import java.util.Hashtable;
4
5 import java.lang.reflect.Constructor;
6 import java.lang.reflect.Method;
7 import java.lang.reflect.InvocationTargetException;
8
9 import javax.naming.Context;
10 import javax.naming.InitialContext;
11 import javax.naming.NamingException;
12
13 /***
14 * Worker class for JMX requests. Uses reflection to avoid
15 * compile-time dependencies on JBoss-specific classes (i.e. RMIAdaptor).
16 * Creation of this class must be made only in the context of a properly
17 * set-up JBossLibClassLoader.
18 *
19 * @author <a href="mailto:fvancea@maxiq.com">Florin Vancea</a>
20 */
21
22 public class JMXRMIAdaptor {
23
24 /*** The RMIAdaptor returned from JNDI */
25 private Object jbossRMIAdaptor = null;
26
27 /***
28 * Constructor from a server name. The name is used to build the JNDI name
29 * that holds the JBoss RMIAdaptor object wrapped in this JMXRMIAdaptor.
30 * That JNDI name will be "jmx:<code>serverName</code>:rmi". Note that JBoss
31 * 3.2 has changed this naming convention, but still supports it.
32 *
33 * @param serverName The name of the server machine.
34 * @throws JBossNotAvailable when there is a naming exception, usually
35 * indicating that the JBoss instance is not running.
36 */
37 public JMXRMIAdaptor(String serverName) throws JBossNotAvailable {
38 this("jnp://localhost:1099", "jmx:" + serverName + ":rmi");
39 }
40
41 /***
42 * Constructor from JNDI URL of target server and JNDI name of RMI adapter.
43 * @param jndiURL Seed URL of target server JNDI system
44 * @param rmiJndiName JNDI name of RMI adaptor.
45 * @throws JBossNotAvailable when there is a naming exception, usually
46 * indicating that the JBoss instance is not running.
47 */
48 public JMXRMIAdaptor(String jndiURL, String rmiJndiName) throws JBossNotAvailable {
49 try {
50 Hashtable env = new Hashtable();
51 System.out.println("Searching JMX-RMI adaptor at ("
52 + jndiURL + "," + rmiJndiName + ")");
53 env.put(Context.INITIAL_CONTEXT_FACTORY,
54 "org.jnp.interfaces.NamingContextFactory");
55 env.put(Context.PROVIDER_URL, jndiURL);
56 InitialContext ic = null;
57 ic = new InitialContext(env);
58 jbossRMIAdaptor = ic.lookup(rmiJndiName);
59 if (jbossRMIAdaptor == null) {
60 throw new RuntimeException(
61 "Null RMIAdaptor under " + rmiJndiName);
62 }
63 if (jbossRMIAdaptor.getClass().getName().indexOf("RMIAdaptor") < 0) {
64 throw new RuntimeException(
65 "Object under " + rmiJndiName + " is not RMIAdaptor");
66 }
67 } catch (NamingException namex) {
68 //namex.printStackTrace(System.out);
69 throw new JBossNotAvailable(
70 "Cannot access naming space. Error is NamingException:"
71 + namex.getMessage());
72 }
73 }
74
75 /* Maybe in the next release...
76 public MBeanInfo getMBeanInfo(ObjectName objectName) {
77 return null;
78 }
79 */
80
81 /***
82 * Obtains the value of an attribute on a remote MBean.
83 * It's similar to getAttribute(...) method of the RMIAdaptor
84 * from the JBoss kit.
85 * @return The attribute value
86 * @param objectName Name of the MBean.
87 * (Note: in RMIAdaptor this is a ObjectName)
88 * @param attrName The name of the attribute.
89 */
90 public Object getAttribute(String objectName, String attrName) {
91 ClassLoader cl = Thread.currentThread().getContextClassLoader();
92 Class objClass = null;
93 Object retval = null;
94 Object theObjectName = makeObjectName(objectName);
95 try {
96 objClass = Class.forName(
97 "org.jboss.jmx.adaptor.rmi.RMIAdaptor", true, cl);
98 Method objMeth = objClass.getMethod("getAttribute", new Class[] {
99 theObjectName.getClass(),
100 String.class}
101 );
102 retval = objMeth.invoke(jbossRMIAdaptor,
103 new Object[] {theObjectName, attrName});
104 } catch (Exception ex) {
105 throw new RuntimeException(
106 "Cannot invoke dynamically \"getAttribute\" on RMIAdaptor. "
107 + makeErrorMessage(ex));
108 }
109 return retval;
110 }
111
112 /***
113 * Invokes a method on a remote MBean. It's similar to the invoke(...)
114 * method of the RMIAdaptor from the JBoss kit.
115 * @return The result of the call, if any.
116 * @param objectName Name of the MBean.
117 * (Note: in RMIAdaptor this is a ObjectName)
118 * @param methodName Method name.
119 * @param args Array of arguments passed as plain Object(s)
120 * @param typeName Array of type names passed as String(s).
121 */
122 public Object invoke(
123 String objectName, String methodName,
124 Object[] args, String[] typeName) {
125 ClassLoader cl = Thread.currentThread().getContextClassLoader();
126 Class objClass = null;
127 Object retval = null;
128 Object theObjectName = makeObjectName(objectName);
129 try {
130 objClass = Class.forName(
131 "org.jboss.jmx.adaptor.rmi.RMIAdaptor", true, cl);
132 Method objMeth = objClass.getMethod("invoke", new Class[] {
133 theObjectName.getClass(),
134 String.class,
135 Object[].class,
136 String[].class}
137 );
138 retval = objMeth.invoke(jbossRMIAdaptor,
139 new Object[] {theObjectName, methodName, args, typeName});
140 } catch (Exception ex) {
141 throw new RuntimeException(
142 "Cannot invoke dynamically \"invoke\" on RMIAdaptor.\n"
143 + makeErrorMessage(ex));
144 }
145 return retval;
146 }
147
148 /***
149 * Creates an javax.management.ObjectName from objectName
150 * @return An Object which is in fact a javax.management.ObjectName
151 * @param objectName A String base for the required ObjectName
152 */
153 static Object makeObjectName(String objectName) {
154 ClassLoader cl = Thread.currentThread().getContextClassLoader();
155 Class objClass = null;
156 Object retval = null;
157 try {
158 objClass = Class.forName("javax.management.ObjectName", true, cl);
159 Constructor objCons =
160 objClass.getConstructor(new Class[] {String.class});
161 retval = objCons.newInstance(new Object[] {objectName});
162 } catch (Exception ex) {
163 throw new RuntimeException(
164 "Cannot load/create dynamically javax.management.ObjectName.\n"
165 + makeErrorMessage(ex));
166 }
167 return retval;
168 }
169
170 /***
171 * Format an error message.
172 * @return A formatted error message.
173 * @param theEx The original exception.
174 */
175 private static String makeErrorMessage(Exception theEx) {
176 String extra = "";
177 if (theEx instanceof InvocationTargetException) {
178 Throwable tex =
179 ((InvocationTargetException) theEx).getTargetException();
180 extra = "\nEmbedded error is " + tex.getClass().getName()
181 + ":" + tex.getMessage();
182 }
183 return "Error is "
184 + theEx.getClass().getName() + ":" + theEx.getMessage()
185 + extra;
186 }
187 }
This page was automatically generated by Maven