1 package com.maxiq.tools.jboss;
2
3 import java.io.File;
4
5 import java.net.InetAddress;
6 import java.net.UnknownHostException;
7
8 /***
9 * Wraps the JMXRMIAdaptor in proper classloading to remove completely
10 * any dependency on JBoss (and management) classes.
11 * For best performance, create one instance then repeatedly call "invoke"
12 * with proper arguments.
13 * <br>Note that the system property <code>com.maxiq.tools.jboss.home"</code>
14 * should be properly set to the home of a running JBoss installation.
15 *
16 * @author <a href="mailto:fvancea@maxiq.com">Florin Vancea</a>
17 */
18 public class JMXProxy {
19
20 /*** The classloader used, cached for speed */
21 private static JBossLibClassLoader jbClassLoader = null;
22 /*** The adaptor to wrap */
23 private JMXRMIAdaptor jra = null;
24 /*** Store here original classloader while switching classloaders */
25 private ClassLoader originalCL = null;
26
27 /***
28 * Plain constructor. The server name is auto-determined.
29 * @throws JBossNotAvailable when we suspect there's no JBoss in the backend
30 */
31 public JMXProxy() throws JBossNotAvailable {
32 this(getLocalServerName());
33 }
34
35 /***
36 * Constructor from server name.
37 * @param serverName The name of the server machine.
38 * @throws JBossNotAvailable when we suspect there's no JBoss in the backend
39 */
40 public JMXProxy(String serverName) throws JBossNotAvailable {
41 originalCL = Thread.currentThread().getContextClassLoader();
42 try {
43 Thread.currentThread().setContextClassLoader(getClassLoader());
44 jra = new JMXRMIAdaptor(serverName);
45 } finally {
46 Thread.currentThread().setContextClassLoader(originalCL);
47 }
48 }
49
50 /***
51 * Constructor from JNDI URL of target server and JNDI name of RMI adapter.
52 * @param jndiURL Seed URL of target server JNDI system
53 * @param rmiJndiName JNDI name of RMI adaptor.
54 * @throws JBossNotAvailable when we suspect there's no JBoss in the backend
55 */
56 public JMXProxy(String jndiURL, String rmiJndiName) throws JBossNotAvailable {
57 originalCL = Thread.currentThread().getContextClassLoader();
58 try {
59 Thread.currentThread().setContextClassLoader(getClassLoader());
60 jra = new JMXRMIAdaptor(jndiURL, rmiJndiName);
61 } finally {
62 Thread.currentThread().setContextClassLoader(originalCL);
63 }
64 }
65
66 /***
67 * Invokes a method on a remote MBean. It's similar to the invoke(...)
68 * method of the RMIAdaptor from the JBoss kit.
69 * No need to worry about classloading issues; they are handled internally.
70 *
71 * @return The result (if any)
72 * @param objectName Name of the MBean.
73 * (Note: in RMIAdaptor this is a ObjectName)
74 * @param methodName Method name.
75 * @param args Array of arguments passed as plain Object(s)
76 * @param typeName Array of type names passed as String(s).
77 */
78 public Object invoke(
79 String objectName, String methodName,
80 Object[] args, String[] typeName) {
81 originalCL = Thread.currentThread().getContextClassLoader();
82 try {
83 Thread.currentThread().setContextClassLoader(getClassLoader());
84 return jra.invoke(objectName, methodName, args, typeName);
85 } finally {
86 Thread.currentThread().setContextClassLoader(originalCL);
87 }
88 }
89
90 /***
91 * Invokes a method on a remote MBean. Similar with
92 * invoke(String, String, Object[], String[]) but auto-determines the type
93 * names. If one of the args is null, assumes String type.
94 * @return The result (if any)
95 * @param objectName Name of the MBean.
96 * (Note: in RMIAdaptor this is a ObjectName)
97 * @param methodName Method name.
98 * @param args An array of Objects to be used as params.
99 */
100 public Object invoke(String objectName, String methodName, Object[] args) {
101 String[] atypes = new String[args.length];
102 for (int i = 0; i < args.length; i++) {
103 if (args[i] == null) {
104 atypes[i] = "java.lang.String";
105 } else {
106 atypes[i] = args[i].getClass().getName();
107 }
108 }
109 return invoke(objectName, methodName, args, atypes);
110 }
111
112 /***
113 * Obtains the value of an attribute on a remote MBean.
114 * It's similar to getAttribute(...) method of the RMIAdaptor
115 * from the JBoss kit.
116 * No need to worry about classloading issues; they are handled internally.
117 * @return The attribute value
118 * @param objectName Name of the MBean.
119 * (Note: in RMIAdaptor this is a ObjectName)
120 * @param attrName The name of the attribute.
121 */
122 public Object getAttribute(String objectName, String attrName) {
123 originalCL = Thread.currentThread().getContextClassLoader();
124 try {
125 Thread.currentThread().setContextClassLoader(getClassLoader());
126 return jra.getAttribute(objectName, attrName);
127 } finally {
128 Thread.currentThread().setContextClassLoader(originalCL);
129 }
130 }
131
132 /***
133 * Obtains the name of the server from the Inet subsys
134 * @return the name as determined
135 */
136 private static String getLocalServerName() {
137 String serverName = null;
138 try {
139 serverName = InetAddress.getLocalHost().getHostName();
140 } catch (UnknownHostException uhex) {
141 throw new RuntimeException("Cannot get local machine name.");
142 }
143 return serverName;
144 }
145
146 /***
147 * Getter for the classloader. On each call will return the same
148 * classloader, speeding up things and cutting on memory consumption.
149 * @return A classloader able to load JBoss-specific classes
150 */
151 static JBossLibClassLoader getClassLoader() {
152 if (jbClassLoader == null) {
153 String jblibPath = System.getProperty("com.maxiq.tools.jboss.home");
154 if (jblibPath == null) {
155 throw new RuntimeException("Set the property"
156 + " com.maxiq.tools.jboss.home to the JBoss home path");
157 }
158 jbClassLoader = new JBossLibClassLoader(new File(jblibPath, "client"));
159 }
160 return jbClassLoader;
161 }
162 }
This page was automatically generated by Maven