1 8 9 package mx4j.remote; 10 11 import java.io.BufferedReader ; 12 import java.io.IOException ; 13 import java.io.InputStream ; 14 import java.io.InputStreamReader ; 15 import java.net.MalformedURLException ; 16 import java.net.URL ; 17 import java.security.AccessController ; 18 import java.security.PrivilegedActionException ; 19 import java.security.PrivilegedExceptionAction ; 20 import java.util.ArrayList ; 21 import java.util.Collections ; 22 import java.util.Enumeration ; 23 import java.util.List ; 24 import java.util.Map ; 25 import java.util.StringTokenizer ; 26 27 import javax.management.MBeanServer ; 28 import javax.management.remote.JMXConnector ; 29 import javax.management.remote.JMXConnectorFactory ; 30 import javax.management.remote.JMXConnectorProvider ; 31 import javax.management.remote.JMXConnectorServer ; 32 import javax.management.remote.JMXConnectorServerFactory ; 33 import javax.management.remote.JMXConnectorServerProvider ; 34 import javax.management.remote.JMXProviderException ; 35 import javax.management.remote.JMXServiceURL ; 36 37 import mx4j.log.Logger; 38 39 42 public class ProviderFactory extends ProviderHelper 43 { 44 public static JMXConnector newJMXConnector(JMXServiceURL url, Map env) throws IOException 45 { 46 String protocol = normalizeProtocol(url.getProtocol()); 48 String providerPackages = findProviderPackageList(env, JMXConnectorFactory.PROTOCOL_PROVIDER_PACKAGES); 49 ClassLoader classLoader = findProviderClassLoader(env, JMXConnectorFactory.PROTOCOL_PROVIDER_CLASS_LOADER); 50 List providers = loadProviders(JMXConnectorProvider .class, providerPackages, protocol, MX4JRemoteConstants.CLIENT_PROVIDER_CLASS, classLoader); 51 for (int i = 0; i < providers.size(); i++) 52 { 53 JMXConnectorProvider provider = (JMXConnectorProvider )providers.get(i); 54 try 55 { 56 return provider.newJMXConnector(url, Collections.unmodifiableMap(env)); 57 } 58 catch (JMXProviderException x) 59 { 60 throw x; 61 } 62 catch (IOException x) 63 { 64 continue; 65 } 66 } 67 throw new MalformedURLException ("Could not find provider for protocol " + protocol); 68 } 69 70 public static JMXConnectorServer newJMXConnectorServer(JMXServiceURL url, Map env, MBeanServer server) throws IOException 71 { 72 String protocol = normalizeProtocol(url.getProtocol()); 74 String providerPackages = findProviderPackageList(env, JMXConnectorServerFactory.PROTOCOL_PROVIDER_PACKAGES); 75 ClassLoader classLoader = findProviderClassLoader(env, JMXConnectorServerFactory.PROTOCOL_PROVIDER_CLASS_LOADER); 76 List providers = loadProviders(JMXConnectorServerProvider .class, providerPackages, protocol, MX4JRemoteConstants.SERVER_PROVIDER_CLASS, classLoader); 77 for (int i = 0; i < providers.size(); i++) 78 { 79 JMXConnectorServerProvider provider = (JMXConnectorServerProvider )providers.get(i); 80 try 81 { 82 return provider.newJMXConnectorServer(url, Collections.unmodifiableMap(env), server); 83 } 84 catch (JMXProviderException x) 85 { 86 throw x; 87 } 88 catch (IOException x) 89 { 90 continue; 91 } 92 } 93 throw new MalformedURLException ("Could not find provider for protocol " + protocol); 94 } 95 96 117 private static String findEnvironmentProviderPackageList(Map environment, String key) throws JMXProviderException 118 { 119 String providerPackages = null; 120 if (environment != null) 121 { 122 Logger logger = getLogger(); 123 Object pkgs = environment.get(key); 124 if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Provider packages in the environment: " + pkgs); 125 if (pkgs != null && !(pkgs instanceof String )) throw new JMXProviderException ("Provider package list must be a string"); 126 providerPackages = (String )pkgs; 127 } 128 return providerPackages; 129 } 130 131 private static String findProviderPackageList(Map environment, final String providerPkgsKey) throws JMXProviderException 132 { 133 137 String providerPackages = findEnvironmentProviderPackageList(environment, providerPkgsKey); 138 139 if (providerPackages == null) 140 { 141 providerPackages = findSystemPackageList(providerPkgsKey); 142 } 143 144 if (providerPackages != null && providerPackages.trim().length() == 0) throw new JMXProviderException ("Provider package list cannot be an empty string"); 145 146 if (providerPackages == null) 147 providerPackages = MX4JRemoteConstants.PROVIDER_PACKAGES; 148 else 149 providerPackages += MX4JRemoteConstants.PROVIDER_PACKAGES_SEPARATOR + MX4JRemoteConstants.PROVIDER_PACKAGES; 150 151 Logger logger = getLogger(); 152 if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Provider packages list is: " + providerPackages); 153 154 return providerPackages; 155 } 156 157 private static ClassLoader findProviderClassLoader(Map environment, String providerLoaderKey) 158 { 159 Logger logger = getLogger(); 160 161 ClassLoader classLoader = null; 162 if (environment != null) 163 { 164 Object loader = environment.get(providerLoaderKey); 165 if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Provider classloader in the environment: " + loader); 166 if (loader != null && !(loader instanceof ClassLoader )) throw new IllegalArgumentException ("Provider classloader is not a ClassLoader"); 167 classLoader = (ClassLoader )loader; 168 } 169 170 if (classLoader == null) 171 { 172 classLoader = Thread.currentThread().getContextClassLoader(); 173 if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Provider classloader in the environment: " + classLoader); 174 } 175 176 environment.put(JMXConnectorFactory.PROTOCOL_PROVIDER_CLASS_LOADER, classLoader); 178 if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Provider classloader added to the environment"); 179 180 return classLoader; 181 } 182 183 private static List loadProviders(Class providerType, String packages, String protocol, String className, ClassLoader loader) throws JMXProviderException 184 { 185 Logger logger = getLogger(); 186 List result = new ArrayList (); 187 188 StringTokenizer tokenizer = new StringTokenizer (packages, MX4JRemoteConstants.PROVIDER_PACKAGES_SEPARATOR); 189 while (tokenizer.hasMoreTokens()) 190 { 191 String pkg = tokenizer.nextToken().trim(); 192 if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Provider package: " + pkg); 193 194 if (pkg.length() == 0) throw new JMXProviderException ("Empty package list not allowed: " + packages); 196 197 String providerClassName = constructClassName(pkg, protocol, className); 198 199 Class providerClass = null; 200 try 201 { 202 providerClass = loadClass(providerClassName, loader); 203 } 204 catch (ClassNotFoundException x) 205 { 206 if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Provider class " + providerClassName + " not found, " + (tokenizer.hasMoreTokens() ? "continuing with next package" : "no more packages to try")); 207 continue; 208 } 209 catch (Exception x) 210 { 211 if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Cannot load provider class " + providerClassName, x); 212 throw new JMXProviderException ("Cannot load provider class " + providerClassName, x); 213 } 214 215 try 216 { 217 Object provider = providerClass.newInstance(); 218 result.add(provider); 219 } 220 catch (Exception x) 221 { 222 if (logger.isEnabledFor(Logger.TRACE)) logger.trace("Cannot instantiate provider class " + providerClassName, x); 223 throw new JMXProviderException ("Cannot instantiate provider class " + providerClassName, x); 224 } 225 } 226 227 try 228 { 229 List serviceProviders = fromServiceProviders(providerType, protocol, className, loader); 230 result.addAll(serviceProviders); 231 } 232 catch (IOException x) 233 { 234 if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Error retrieving service providers", x); 235 } 236 237 if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Providers found are: " + result); 238 return result; 239 } 240 241 private static List fromServiceProviders(Class providerType, String protocol, String className, ClassLoader loader) throws IOException 242 { 243 String services = "META-INF/services/"; 244 245 Logger logger = getLogger(); 246 if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Loading providers from " + services); 247 248 if (loader == null) loader = Thread.currentThread().getContextClassLoader(); 249 if (loader == null) loader = ClassLoader.getSystemClassLoader(); 250 Enumeration providerURLs = loader.getResources(services + providerType.getName()); 251 List providers = new ArrayList (); 252 while (providerURLs.hasMoreElements()) 253 { 254 final URL providerURL = (URL )providerURLs.nextElement(); 255 256 InputStream stream = null; 257 try 258 { 259 stream = (InputStream )AccessController.doPrivileged(new PrivilegedExceptionAction () 260 { 261 public Object run() throws Exception 262 { 263 return providerURL.openStream(); 264 } 265 }); 266 } 267 catch (PrivilegedActionException x) 268 { 269 Exception xx = x.getException(); 270 if (xx instanceof IOException ) throw (IOException )xx; 271 throw new IOException (xx.toString()); 272 } 273 274 BufferedReader reader = null; 275 try 276 { 277 if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Reading provider from " + providerURL); 278 reader = new BufferedReader (new InputStreamReader (stream, "UTF-8")); 279 String line = null; 280 while ((line = reader.readLine()) != null) 281 { 282 int comment = line.indexOf('#'); 283 if (comment >= 0) line = line.substring(0, comment); 284 line = line.trim(); 285 if (line.length() == 0) continue; 286 if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Found provider '" + line + "' in " + providerURL); 287 try 288 { 289 Class providerClass = loader.loadClass(line); 290 if (providerType.isAssignableFrom(providerClass)) 291 { 292 Object providerInstance = providerClass.newInstance(); 293 providers.add(providerInstance); 294 } 295 } 296 catch (Exception ignored) 297 { 298 } 300 } 301 } 302 finally 303 { 304 if (reader != null) reader.close(); 305 } 306 } 307 308 return providers; 309 } 310 } 311 | Popular Tags |