1 7 8 package javax.management.remote; 9 10 import java.io.IOException ; 11 import java.net.MalformedURLException ; 12 import java.util.Collections ; 13 import java.util.HashMap ; 14 import java.util.Map ; 15 import java.util.Iterator ; 16 import java.util.StringTokenizer ; 17 import java.security.AccessController ; 18 import java.security.PrivilegedAction ; 19 20 import com.sun.jmx.remote.util.ClassLogger; 21 import com.sun.jmx.remote.util.EnvHelp; 22 import com.sun.jmx.remote.util.Service; 23 24 144 public class JMXConnectorFactory { 145 146 153 public static final String DEFAULT_CLASS_LOADER = 154 "jmx.remote.default.class.loader"; 155 156 162 public static final String PROTOCOL_PROVIDER_PACKAGES = 163 "jmx.remote.protocol.provider.pkgs"; 164 165 171 public static final String PROTOCOL_PROVIDER_CLASS_LOADER = 172 "jmx.remote.protocol.provider.class.loader"; 173 174 private static final String PROTOCOL_PROVIDER_DEFAULT_PACKAGE = 175 "com.sun.jmx.remote.protocol"; 176 177 private static final ClassLogger logger = 178 new ClassLogger("javax.management.remote.misc", "JMXConnectorFactory"); 179 180 181 private JMXConnectorFactory() { 182 } 183 184 205 public static JMXConnector connect(JMXServiceURL serviceURL) 206 throws IOException { 207 return connect(serviceURL, null); 208 } 209 210 242 public static JMXConnector connect(JMXServiceURL serviceURL, 243 Map <String ,?> environment) 244 throws IOException { 245 if (serviceURL == null) 246 throw new NullPointerException ("Null JMXServiceURL"); 247 JMXConnector conn = newJMXConnector(serviceURL, environment); 248 conn.connect(environment); 249 return conn; 250 } 251 252 281 public static JMXConnector newJMXConnector(JMXServiceURL serviceURL, 282 Map <String ,?> environment) 283 throws IOException { 284 if (environment == null) 285 environment = new HashMap (); 286 else { 287 EnvHelp.checkAttributes(environment); 288 environment = new HashMap (environment); 289 } 290 291 final ClassLoader loader = resolveClassLoader(environment); 292 final Class targetInterface = JMXConnectorProvider .class; 293 final String protocol = serviceURL.getProtocol(); 294 final String providerClassName = "ClientProvider"; 295 296 JMXConnectorProvider provider = 297 (JMXConnectorProvider ) getProvider(serviceURL, environment, 298 providerClassName, 299 targetInterface, 300 loader); 301 if(provider == null) { 302 if(loader != null) { 307 JMXConnector connection = getConnectorAsService(loader, 308 serviceURL, 309 environment); 310 if(connection != null) 311 return connection; 312 } 313 314 provider = (JMXConnectorProvider ) 315 getProvider(protocol, PROTOCOL_PROVIDER_DEFAULT_PACKAGE, 316 JMXConnectorFactory .class.getClassLoader(), 317 providerClassName, targetInterface); 318 } 319 320 if(provider == null) 321 throw new MalformedURLException ("Unsupported protocol: " + 322 protocol); 323 324 environment = Collections.unmodifiableMap(environment); 325 326 return provider.newJMXConnector(serviceURL, environment); 327 } 328 329 private static String resolvePkgs(Map env) throws JMXProviderException { 330 331 Object pkgsObject = null; 332 333 if (env != null) 334 pkgsObject = env.get(PROTOCOL_PROVIDER_PACKAGES); 335 336 if (pkgsObject == null) 337 pkgsObject = 338 AccessController.doPrivileged(new PrivilegedAction () { 339 public Object run() { 340 return System.getProperty(PROTOCOL_PROVIDER_PACKAGES); 341 } 342 }); 343 344 if (pkgsObject == null) 345 return null; 346 347 if (!(pkgsObject instanceof String )) { 348 final String msg = "Value of " + PROTOCOL_PROVIDER_PACKAGES + 349 " parameter is not a String: " + 350 pkgsObject.getClass().getName(); 351 throw new JMXProviderException (msg); 352 } 353 354 final String pkgs = (String ) pkgsObject; 355 if (pkgs.trim().equals("")) 356 return null; 357 358 if (pkgs.startsWith("|") || pkgs.endsWith("|") || 360 pkgs.indexOf("||") >= 0) { 361 final String msg = "Value of " + PROTOCOL_PROVIDER_PACKAGES + 362 " contains an empty element: " + pkgs; 363 throw new JMXProviderException (msg); 364 } 365 366 return pkgs; 367 } 368 369 static Object getProvider(JMXServiceURL serviceURL, 370 Map environment, String providerClassName, 371 Class targetInterface, 372 ClassLoader loader) 373 throws IOException { 374 375 final String protocol = serviceURL.getProtocol(); 376 377 final String pkgs = resolvePkgs(environment); 378 379 Object instance = null; 380 381 if (pkgs != null) { 382 environment.put(PROTOCOL_PROVIDER_CLASS_LOADER, loader); 383 384 instance = 385 getProvider(protocol, pkgs, loader, providerClassName, 386 targetInterface); 387 } 388 389 return instance; 390 } 391 392 static Iterator getProviderIterator(final Class providerClass, 393 final ClassLoader loader) { 394 PrivilegedAction action = new PrivilegedAction () { 395 public Object run() { 396 return Service.providers(providerClass, loader); 397 } 398 }; 399 return (Iterator ) AccessController.doPrivileged(action); 400 } 401 402 private static JMXConnector getConnectorAsService(ClassLoader loader, 403 JMXServiceURL url, 404 Map map) 405 throws IllegalArgumentException , JMXProviderException { 406 407 Iterator providers = getProviderIterator(JMXConnectorProvider .class, 408 loader); 409 JMXConnectorProvider provider = null; 410 JMXConnector connection = null; 411 while(providers.hasNext()) { 412 provider = 413 (JMXConnectorProvider ) providers.next(); 414 try { 415 connection = provider.newJMXConnector(url, map); 416 return connection; 417 } catch (JMXProviderException e) { 418 throw e; 419 } 420 catch (Exception e) { 421 if (logger.traceOn()) 422 logger.trace("getConnectorAsService", 423 "URL[" + url + 424 "] Service provider exception: " + e); 425 continue; 426 } 427 } 428 return null; 429 } 430 431 static Object getProvider(String protocol, 432 String pkgs, 433 ClassLoader loader, 434 String providerClassName, 435 Class targetInterface) 436 throws IOException { 437 438 StringTokenizer tokenizer = new StringTokenizer (pkgs, "|"); 439 440 while (tokenizer.hasMoreTokens()) { 441 String pkg = tokenizer.nextToken(); 442 String className = (pkg + "." + protocol2package(protocol) + 443 "." + providerClassName); 444 Class providerClass; 445 try { 446 providerClass = Class.forName(className, true, loader); 447 } catch (ClassNotFoundException e) { 448 continue; 450 } 451 452 if (!targetInterface.isAssignableFrom(providerClass)) { 453 final String msg = 454 "Provider class does not implement " + 455 targetInterface.getName() + ": " + 456 providerClass.getName(); 457 throw new JMXProviderException (msg); 458 } 459 460 try { 461 return providerClass.newInstance(); 462 } catch (Exception e) { 463 final String msg = 464 "Exception when instantiating provider [" + className + 465 "]"; 466 throw new JMXProviderException (msg, e); 467 } 468 } 469 470 return null; 471 } 472 473 static ClassLoader resolveClassLoader(Map environment) { 474 ClassLoader loader = null; 475 476 if (environment != null) { 477 try { 478 loader = (ClassLoader ) 479 environment.get(PROTOCOL_PROVIDER_CLASS_LOADER); 480 } catch (ClassCastException e) { 481 final String msg = 482 "The ClassLoader supplied in the environment map using " + 483 "the " + PROTOCOL_PROVIDER_CLASS_LOADER + 484 " attribute is not an instance of java.lang.ClassLoader"; 485 throw new IllegalArgumentException (msg); 486 } 487 } 488 489 if (loader == null) 490 loader = (ClassLoader ) 491 AccessController.doPrivileged(new PrivilegedAction () { 492 public Object run() { 493 return 494 Thread.currentThread().getContextClassLoader(); 495 } 496 }); 497 498 return loader; 499 } 500 501 private static String protocol2package(String protocol) { 502 return protocol.replace('+', '.').replace('-', '_'); 503 } 504 } 505 | Popular Tags |