1 7 8 package javax.management.remote.rmi; 9 10 import javax.management.Attribute ; 12 import javax.management.AttributeList ; 13 import javax.management.AttributeNotFoundException ; 14 import javax.management.InstanceAlreadyExistsException ; 15 import javax.management.InstanceNotFoundException ; 16 import javax.management.IntrospectionException ; 17 import javax.management.InvalidAttributeValueException ; 18 import javax.management.ListenerNotFoundException ; 19 import javax.management.MalformedObjectNameException ; 20 import javax.management.MBeanException ; 21 import javax.management.MBeanInfo ; 22 import javax.management.MBeanRegistrationException ; 23 import javax.management.MBeanServerConnection ; 24 import javax.management.MBeanServerNotification ; 25 import javax.management.NotCompliantMBeanException ; 26 import javax.management.Notification ; 27 import javax.management.NotificationBroadcasterSupport ; 28 import javax.management.NotificationEmitter ; 29 import javax.management.NotificationFilter ; 30 import javax.management.NotificationFilterSupport ; 31 import javax.management.NotificationListener ; 32 import javax.management.ObjectInstance ; 33 import javax.management.ObjectName ; 34 import javax.management.QueryExp ; 35 import javax.management.ReflectionException ; 36 37 import javax.management.remote.JMXAuthenticator ; 38 import javax.management.remote.JMXConnectionNotification ; 39 import javax.management.remote.JMXConnector ; 40 import javax.management.remote.JMXConnectorFactory ; 41 import javax.management.remote.JMXServiceURL ; 42 import javax.management.remote.NotificationResult ; 43 import javax.management.remote.TargetedNotification ; 44 import javax.management.remote.JMXServerErrorException ; 45 46 import java.lang.ref.WeakReference ; 47 48 import java.lang.reflect.Constructor ; 49 import java.lang.reflect.InvocationTargetException ; 50 51 import java.util.Arrays ; 53 import java.util.ArrayList ; 54 import java.util.Collections ; 55 import java.util.HashMap ; 56 import java.util.Map ; 57 import java.util.Properties ; 58 import java.util.Set ; 59 import java.util.WeakHashMap ; 60 61 import java.io.ByteArrayInputStream ; 63 import java.io.IOException ; 64 import java.io.InputStream ; 65 import java.io.InvalidObjectException ; 66 import java.io.ObjectInputStream ; 67 import java.io.ObjectStreamClass ; 68 import java.io.Serializable ; 69 import java.io.WriteAbortedException ; 70 import java.io.NotSerializableException ; 71 72 import java.net.MalformedURLException ; 74 75 import java.rmi.MarshalledObject ; 77 import java.rmi.NoSuchObjectException ; 78 import java.rmi.MarshalException ; 79 import java.rmi.UnmarshalException ; 80 import java.rmi.ServerException ; 81 import java.rmi.server.RemoteObject ; 82 import java.rmi.server.RemoteRef ; 83 84 import javax.rmi.PortableRemoteObject ; 86 import javax.rmi.CORBA.Stub ; 87 import org.omg.CORBA.portable.Delegate ; 88 89 import javax.naming.InitialContext ; 91 import javax.naming.NamingException ; 92 93 import com.sun.jmx.remote.internal.ClientNotifForwarder; 94 import com.sun.jmx.remote.internal.ClientCommunicatorAdmin; 95 import com.sun.jmx.remote.internal.ClientListenerInfo; 96 import com.sun.jmx.remote.internal.ProxyInputStream; 97 import com.sun.jmx.remote.internal.ProxyRef; 98 import com.sun.jmx.remote.util.ClassLogger; 99 import com.sun.jmx.remote.util.EnvHelp; 100 101 import java.security.AccessController ; 103 import java.security.PrivilegedAction ; 104 import java.security.PrivilegedExceptionAction ; 105 import java.security.ProtectionDomain ; 106 import javax.security.auth.Subject ; 107 108 119 public class RMIConnector implements JMXConnector , Serializable { 120 121 private static final ClassLogger logger = 122 new ClassLogger("javax.management.remote.rmi", "RMIConnector"); 123 124 private static final long serialVersionUID = 817323035842634473L; 125 126 private RMIConnector(RMIServer rmiServer, JMXServiceURL address, 127 Map environment) { 128 if (rmiServer == null && address == null) throw new 129 IllegalArgumentException ("rmiServer and jmxServiceURL both null"); 130 131 initTransients(); 132 133 this.rmiServer = rmiServer; 134 this.jmxServiceURL = address; 135 if (environment == null) { 136 this.env = Collections.EMPTY_MAP; 137 } else { 138 EnvHelp.checkAttributes(environment); 139 this.env = Collections.unmodifiableMap(environment); 140 } 141 } 142 143 184 public RMIConnector(JMXServiceURL url, Map <String ,?> environment) { 185 this(null, url, environment); 186 } 187 188 199 public RMIConnector(RMIServer rmiServer, Map <String ,?> environment) { 200 this(rmiServer, null, environment); 201 } 202 203 212 public String toString() { 213 final StringBuffer b = new StringBuffer (this.getClass().getName()); 214 b.append(":"); 215 if (rmiServer != null) { 216 b.append(" rmiServer=").append(rmiServer.toString()); 217 } 218 if (jmxServiceURL != null) { 219 if (rmiServer!=null) b.append(","); 220 b.append(" jmxServiceURL=").append(jmxServiceURL.toString()); 221 } 222 return b.toString(); 223 } 224 225 public void connect() throws IOException { 229 connect(null); 230 } 231 232 public synchronized void connect(Map <String ,?> environment) 233 throws IOException { 234 final boolean tracing = logger.traceOn(); 235 String idstr = (tracing?"["+this.toString()+"]":null); 236 237 if (terminated) { 238 logger.trace("connect",idstr + " already closed."); 239 throw new IOException ("Connector closed"); 240 } 241 if (connected) { 242 logger.trace("connect",idstr + " already connected."); 243 return; 244 } 245 246 try { 247 if (tracing) logger.trace("connect",idstr + " connecting..."); 248 249 final Map usemap = 250 new HashMap ((this.env==null)?Collections.EMPTY_MAP:this.env); 251 252 if (environment != null) { 253 EnvHelp.checkAttributes(environment); 254 usemap.putAll(environment); 255 } 256 257 if (tracing) logger.trace("connect",idstr + " finding stub..."); 259 RMIServer stub = (rmiServer!=null)?rmiServer: 260 findRMIServer(jmxServiceURL, usemap); 261 262 if (tracing) logger.trace("connect",idstr + " connecting stub..."); 264 stub = connectStub(stub,usemap); 265 idstr = (tracing?"["+this.toString()+"]":null); 266 267 if (tracing) 269 logger.trace("connect",idstr + " getting connection..."); 270 Object credentials = usemap.get(CREDENTIALS); 271 connection = getConnection(stub, credentials); 272 273 if (tracing) 277 logger.trace("connect",idstr + " getting class loader..."); 278 defaultClassLoader = EnvHelp.resolveClientClassLoader(usemap); 279 280 usemap.put(JMXConnectorFactory.DEFAULT_CLASS_LOADER, 281 defaultClassLoader); 282 283 rmiNotifClient = new RMINotifClient(defaultClassLoader, usemap); 284 285 env = usemap; 286 final long checkPeriod = EnvHelp.getConnectionCheckPeriod(usemap); 287 communicatorAdmin = new RMIClientCommunicatorAdmin(checkPeriod); 288 289 connected = true; 290 291 connectionId = getConnectionId(); 295 296 Notification connectedNotif = 297 new JMXConnectionNotification (JMXConnectionNotification.OPENED, 298 this, 299 connectionId, 300 clientNotifID++, 301 "Successful connection", 302 null); 303 sendNotification(connectedNotif); 304 305 if (tracing) logger.trace("connect",idstr + " done..."); 306 } catch (IOException e) { 307 if (tracing) 308 logger.trace("connect",idstr + " failed to connect: " + e); 309 throw e; 310 } catch (RuntimeException e) { 311 if (tracing) 312 logger.trace("connect",idstr + " failed to connect: " + e); 313 throw e; 314 } catch (NamingException e) { 315 final String msg = "Failed to retrieve RMIServer stub: " + e; 316 if (tracing) logger.trace("connect",idstr + " " + msg); 317 throw (IOException ) EnvHelp.initCause(new IOException (msg),e); 318 } 319 } 320 321 public synchronized String getConnectionId() throws IOException { 322 if (terminated || !connected) { 323 if (logger.traceOn()) 324 logger.trace("getConnectionId","["+this.toString()+ 325 "] not connected."); 326 327 throw new IOException ("Not connected"); 328 } 329 330 return connection.getConnectionId(); 333 } 334 335 public synchronized MBeanServerConnection getMBeanServerConnection() 336 throws IOException { 337 return getMBeanServerConnection(null); 338 } 339 340 public synchronized MBeanServerConnection 341 getMBeanServerConnection(Subject delegationSubject) 342 throws IOException { 343 344 if (terminated) { 345 if (logger.traceOn()) 346 logger.trace("getMBeanServerConnection","[" + this.toString() + 347 "] already closed."); 348 throw new IOException ("Connection closed"); 349 } else if (!connected) { 350 if (logger.traceOn()) 351 logger.trace("getMBeanServerConnection","[" + this.toString() + 352 "] is not connected."); 353 throw new IOException ("Not connected"); 354 } 355 356 MBeanServerConnection mbsc = 357 (MBeanServerConnection ) rmbscMap.get(delegationSubject); 358 if (mbsc != null) 359 return mbsc; 360 361 mbsc = new RemoteMBeanServerConnection(delegationSubject); 362 rmbscMap.put(delegationSubject, mbsc); 363 return mbsc; 364 } 365 366 public void 367 addConnectionNotificationListener(NotificationListener listener, 368 NotificationFilter filter, 369 Object handback) { 370 if (listener == null) 371 throw new NullPointerException ("listener"); 372 connectionBroadcaster.addNotificationListener(listener, filter, 373 handback); 374 } 375 376 public void 377 removeConnectionNotificationListener(NotificationListener listener) 378 throws ListenerNotFoundException { 379 if (listener == null) 380 throw new NullPointerException ("listener"); 381 connectionBroadcaster.removeNotificationListener(listener); 382 } 383 384 public void 385 removeConnectionNotificationListener(NotificationListener listener, 386 NotificationFilter filter, 387 Object handback) 388 throws ListenerNotFoundException { 389 if (listener == null) 390 throw new NullPointerException ("listener"); 391 connectionBroadcaster.removeNotificationListener(listener, filter, 392 handback); 393 } 394 395 private void sendNotification(Notification n) { 396 connectionBroadcaster.sendNotification(n); 397 } 398 399 public synchronized void close() throws IOException { 400 close(false); 401 } 402 403 private synchronized void close(boolean intern) throws IOException { 406 final boolean tracing = logger.traceOn(); 407 final boolean debug = logger.debugOn(); 408 final String idstr = (tracing?"["+this.toString()+"]":null); 409 410 if (!intern) { 411 if (terminated) { 414 if (closeException == null) { 415 if (tracing) logger.trace("close",idstr + " already closed."); 416 return; 417 } 418 } else { 419 terminated = true; 420 } 421 } 422 423 if (closeException != null && tracing) { 424 if (tracing) { 427 logger.trace("close",idstr + " had failed: " + closeException); 428 logger.trace("close",idstr + " attempting to close again."); 429 } 430 } 431 432 String savedConnectionId = null; 433 if (connected) { 434 savedConnectionId = connectionId; 435 } 436 437 closeException = null; 438 439 if (tracing) logger.trace("close",idstr + " closing."); 440 441 if (communicatorAdmin != null) { 442 communicatorAdmin.terminate(); 443 } 444 445 if (rmiNotifClient != null) { 446 try { 447 rmiNotifClient.terminate(); 448 if (tracing) logger.trace("close",idstr + 449 " RMI Notification client terminated."); 450 } catch (RuntimeException x) { 451 closeException = x; 452 if (tracing) logger.trace("close",idstr + 453 " Failed to terminate RMI Notification client: " + x); 454 if (debug) logger.debug("close",x); 455 } 456 } 457 458 if (connection != null) { 459 try { 460 connection.close(); 461 if (tracing) logger.trace("close",idstr + " closed."); 462 } catch (NoSuchObjectException nse) { 463 } catch (IOException e) { 465 closeException = e; 466 if (tracing) logger.trace("close",idstr + 467 " Failed to close RMIServer: " + e); 468 if (debug) logger.debug("close",e); 469 } 470 } 471 472 rmbscMap.clear(); 475 476 479 480 if (savedConnectionId != null) { 481 Notification closedNotif = 482 new JMXConnectionNotification (JMXConnectionNotification.CLOSED, 483 this, 484 savedConnectionId, 485 clientNotifID++, 486 "Client has been closed", 487 null); 488 sendNotification(closedNotif); 489 } 490 491 if (closeException != null) { 494 if (tracing) logger.trace("close",idstr + " failed to close: " + 495 closeException); 496 if (closeException instanceof IOException ) 497 throw (IOException ) closeException; 498 if (closeException instanceof RuntimeException ) 499 throw (RuntimeException ) closeException; 500 final IOException x = 501 new IOException ("Failed to close: " + closeException); 502 throw (IOException ) EnvHelp.initCause(x,closeException); 503 } 504 } 505 506 private Integer addListenerWithSubject(ObjectName name, 508 MarshalledObject filter, 509 Subject delegationSubject, 510 boolean reconnect) 511 throws InstanceNotFoundException , IOException { 512 513 final boolean debug = logger.debugOn(); 514 if (debug) 515 logger.debug("addListenerWithSubject", 516 "(ObjectName,MarshalledObject,Subject)"); 517 518 final ObjectName [] names = new ObjectName [] {name}; 519 final MarshalledObject [] filters = new MarshalledObject [] {filter}; 520 final Subject [] delegationSubjects = new Subject [] { 521 delegationSubject 522 }; 523 524 final Integer [] listenerIDs = 525 addListenersWithSubjects(names,filters,delegationSubjects, 526 reconnect); 527 528 if (debug) logger.debug("addListenerWithSubject","listenerID=" 529 + listenerIDs[0]); 530 return listenerIDs[0]; 531 } 532 533 private Integer [] addListenersWithSubjects(ObjectName [] names, 535 MarshalledObject [] filters, 536 Subject [] delegationSubjects, 537 boolean reconnect) 538 throws InstanceNotFoundException , IOException { 539 540 final boolean debug = logger.debugOn(); 541 if (debug) 542 logger.debug("addListenersWithSubjects", 543 "(ObjectName[],MarshalledObject[],Subject[])"); 544 545 final ClassLoader old = pushDefaultClassLoader(); 546 Integer [] listenerIDs = null; 547 548 try { 549 listenerIDs = connection.addNotificationListeners(names, 550 filters, 551 delegationSubjects); 552 } catch (NoSuchObjectException noe) { 553 if (reconnect) { 555 communicatorAdmin.gotIOException(noe); 556 557 listenerIDs = connection.addNotificationListeners(names, 558 filters, 559 delegationSubjects); 560 } else { 561 throw noe; 562 } 563 } catch (IOException ioe) { 564 communicatorAdmin.gotIOException(ioe); 566 } finally { 567 popDefaultClassLoader(old); 568 } 569 570 if (debug) logger.debug("addListenersWithSubjects","registered " 571 + listenerIDs.length + " listener(s)"); 572 return listenerIDs; 573 } 574 575 private class RemoteMBeanServerConnection 579 implements MBeanServerConnection { 580 581 private Subject delegationSubject; 582 583 public RemoteMBeanServerConnection() { 584 this(null); 585 } 586 587 public RemoteMBeanServerConnection(Subject delegationSubject) { 588 this.delegationSubject = delegationSubject; 589 } 590 591 public ObjectInstance createMBean(String className, 592 ObjectName name) 593 throws ReflectionException , 594 InstanceAlreadyExistsException , 595 MBeanRegistrationException , 596 MBeanException , 597 NotCompliantMBeanException , 598 IOException { 599 if (logger.debugOn()) 600 logger.debug("createMBean(String,ObjectName)", 601 "className=" + className + ", name=" + 602 name); 603 604 final ClassLoader old = pushDefaultClassLoader(); 605 try { 606 return connection.createMBean(className, 607 name, 608 delegationSubject); 609 } catch (IOException ioe) { 610 communicatorAdmin.gotIOException(ioe); 611 612 return connection.createMBean(className, 613 name, 614 delegationSubject); 615 } finally { 616 popDefaultClassLoader(old); 617 } 618 } 619 620 public ObjectInstance createMBean(String className, 621 ObjectName name, 622 ObjectName loaderName) 623 throws ReflectionException , 624 InstanceAlreadyExistsException , 625 MBeanRegistrationException , 626 MBeanException , 627 NotCompliantMBeanException , 628 InstanceNotFoundException , 629 IOException { 630 631 if (logger.debugOn()) 632 logger.debug("createMBean(String,ObjectName,ObjectName)", 633 "className=" + className + ", name=" 634 + name + ", loaderName=" 635 + loaderName + ")"); 636 637 final ClassLoader old = pushDefaultClassLoader(); 638 try { 639 return connection.createMBean(className, 640 name, 641 loaderName, 642 delegationSubject); 643 644 } catch (IOException ioe) { 645 communicatorAdmin.gotIOException(ioe); 646 647 return connection.createMBean(className, 648 name, 649 loaderName, 650 delegationSubject); 651 652 } finally { 653 popDefaultClassLoader(old); 654 } 655 } 656 657 public ObjectInstance createMBean(String className, 658 ObjectName name, 659 Object params[], 660 String signature[]) 661 throws ReflectionException , 662 InstanceAlreadyExistsException , 663 MBeanRegistrationException , 664 MBeanException , 665 NotCompliantMBeanException , 666 IOException { 667 if (logger.debugOn()) 668 logger.debug("createMBean(String,ObjectName,Object[],String[])", 669 "className=" + className + ", name=" 670 + name + ", params=" 671 + objects(params) + ", signature=" 672 + strings(signature)); 673 674 final MarshalledObject sParams = new MarshalledObject (params); 675 final ClassLoader old = pushDefaultClassLoader(); 676 try { 677 return connection.createMBean(className, 678 name, 679 sParams, 680 signature, 681 delegationSubject); 682 } catch (IOException ioe) { 683 communicatorAdmin.gotIOException(ioe); 684 685 return connection.createMBean(className, 686 name, 687 sParams, 688 signature, 689 delegationSubject); 690 } finally { 691 popDefaultClassLoader(old); 692 } 693 } 694 695 public ObjectInstance createMBean(String className, 696 ObjectName name, 697 ObjectName loaderName, 698 Object params[], 699 String signature[]) 700 throws ReflectionException , 701 InstanceAlreadyExistsException , 702 MBeanRegistrationException , 703 MBeanException , 704 NotCompliantMBeanException , 705 InstanceNotFoundException , 706 IOException { 707 if (logger.debugOn()) logger.debug( 708 "createMBean(String,ObjectName,ObjectName,Object[],String[])", 709 "className=" + className + ", name=" + name + ", loaderName=" 710 + loaderName + ", params=" + objects(params) 711 + ", signature=" + strings(signature)); 712 713 final MarshalledObject sParams = new MarshalledObject (params); 714 final ClassLoader old = pushDefaultClassLoader(); 715 try { 716 return connection.createMBean(className, 717 name, 718 loaderName, 719 sParams, 720 signature, 721 delegationSubject); 722 } catch (IOException ioe) { 723 communicatorAdmin.gotIOException(ioe); 724 725 return connection.createMBean(className, 726 name, 727 loaderName, 728 sParams, 729 signature, 730 delegationSubject); 731 } finally { 732 popDefaultClassLoader(old); 733 } 734 } 735 736 public void unregisterMBean(ObjectName name) 737 throws InstanceNotFoundException , 738 MBeanRegistrationException , 739 IOException { 740 if (logger.debugOn()) 741 logger.debug("unregisterMBean", "name=" + name); 742 743 final ClassLoader old = pushDefaultClassLoader(); 744 try { 745 connection.unregisterMBean(name, delegationSubject); 746 } catch (IOException ioe) { 747 communicatorAdmin.gotIOException(ioe); 748 749 connection.unregisterMBean(name, delegationSubject); 750 } finally { 751 popDefaultClassLoader(old); 752 } 753 } 754 755 public ObjectInstance getObjectInstance(ObjectName name) 756 throws InstanceNotFoundException , 757 IOException { 758 if (logger.debugOn()) 759 logger.debug("getObjectInstance", "name=" + name); 760 761 final ClassLoader old = pushDefaultClassLoader(); 762 try { 763 return connection.getObjectInstance(name, delegationSubject); 764 } catch (IOException ioe) { 765 communicatorAdmin.gotIOException(ioe); 766 767 return connection.getObjectInstance(name, delegationSubject); 768 } finally { 769 popDefaultClassLoader(old); 770 } 771 } 772 773 public Set queryMBeans(ObjectName name, 774 QueryExp query) 775 throws IOException { 776 if (logger.debugOn()) logger.debug("queryMBeans", 777 "name=" + name + ", query=" + query); 778 779 final MarshalledObject sQuery = new MarshalledObject (query); 780 final ClassLoader old = pushDefaultClassLoader(); 781 try { 782 return connection.queryMBeans(name, sQuery, delegationSubject); 783 } catch (IOException ioe) { 784 communicatorAdmin.gotIOException(ioe); 785 786 return connection.queryMBeans(name, sQuery, delegationSubject); 787 } finally { 788 popDefaultClassLoader(old); 789 } 790 } 791 792 public Set queryNames(ObjectName name, 793 QueryExp query) 794 throws IOException { 795 if (logger.debugOn()) logger.debug("queryNames", 796 "name=" + name + ", query=" + query); 797 798 final MarshalledObject sQuery = new MarshalledObject (query); 799 final ClassLoader old = pushDefaultClassLoader(); 800 try { 801 return connection.queryNames(name, sQuery, delegationSubject); 802 } catch (IOException ioe) { 803 communicatorAdmin.gotIOException(ioe); 804 805 return connection.queryNames(name, sQuery, delegationSubject); 806 } finally { 807 popDefaultClassLoader(old); 808 } 809 } 810 811 public boolean isRegistered(ObjectName name) 812 throws IOException { 813 if (logger.debugOn()) 814 logger.debug("isRegistered", "name=" + name); 815 816 final ClassLoader old = pushDefaultClassLoader(); 817 try { 818 return connection.isRegistered(name, delegationSubject); 819 } catch (IOException ioe) { 820 communicatorAdmin.gotIOException(ioe); 821 822 return connection.isRegistered(name, delegationSubject); 823 } finally { 824 popDefaultClassLoader(old); 825 } 826 } 827 828 public Integer getMBeanCount() 829 throws IOException { 830 if (logger.debugOn()) logger.debug("getMBeanCount", ""); 831 832 final ClassLoader old = pushDefaultClassLoader(); 833 try { 834 return connection.getMBeanCount(delegationSubject); 835 } catch (IOException ioe) { 836 communicatorAdmin.gotIOException(ioe); 837 838 return connection.getMBeanCount(delegationSubject); 839 } finally { 840 popDefaultClassLoader(old); 841 } 842 } 843 844 public Object getAttribute(ObjectName name, 845 String attribute) 846 throws MBeanException , 847 AttributeNotFoundException , 848 InstanceNotFoundException , 849 ReflectionException , 850 IOException { 851 if (logger.debugOn()) logger.debug("getAttribute", 852 "name=" + name + ", attribute=" 853 + attribute); 854 855 final ClassLoader old = pushDefaultClassLoader(); 856 try { 857 return connection.getAttribute(name, 858 attribute, 859 delegationSubject); 860 } catch (IOException ioe) { 861 communicatorAdmin.gotIOException(ioe); 862 863 return connection.getAttribute(name, 864 attribute, 865 delegationSubject); 866 } finally { 867 popDefaultClassLoader(old); 868 } 869 } 870 871 public AttributeList getAttributes(ObjectName name, 872 String [] attributes) 873 throws InstanceNotFoundException , 874 ReflectionException , 875 IOException { 876 if (logger.debugOn()) logger.debug("getAttributes", 877 "name=" + name + ", attributes=" 878 + strings(attributes)); 879 880 final ClassLoader old = pushDefaultClassLoader(); 881 try { 882 return connection.getAttributes(name, 883 attributes, 884 delegationSubject); 885 886 } catch (IOException ioe) { 887 communicatorAdmin.gotIOException(ioe); 888 889 return connection.getAttributes(name, 890 attributes, 891 delegationSubject); 892 } finally { 893 popDefaultClassLoader(old); 894 } 895 } 896 897 898 public void setAttribute(ObjectName name, 899 Attribute attribute) 900 throws InstanceNotFoundException , 901 AttributeNotFoundException , 902 InvalidAttributeValueException , 903 MBeanException , 904 ReflectionException , 905 IOException { 906 907 if (logger.debugOn()) logger.debug("setAttribute", 908 "name=" + name + ", attribute=" 909 + attribute); 910 911 final MarshalledObject sAttribute = 912 new MarshalledObject (attribute); 913 final ClassLoader old = pushDefaultClassLoader(); 914 try { 915 connection.setAttribute(name, sAttribute, delegationSubject); 916 } catch (IOException ioe) { 917 communicatorAdmin.gotIOException(ioe); 918 919 connection.setAttribute(name, sAttribute, delegationSubject); 920 } finally { 921 popDefaultClassLoader(old); 922 } 923 } 924 925 public AttributeList setAttributes(ObjectName name, 926 AttributeList attributes) 927 throws InstanceNotFoundException , 928 ReflectionException , 929 IOException { 930 931 if (logger.debugOn()) logger.debug("setAttributes", 932 "name=" + name + ", attributes=" 933 + attributes); 934 935 final MarshalledObject sAttributes = 936 new MarshalledObject (attributes); 937 final ClassLoader old = pushDefaultClassLoader(); 938 try { 939 return connection.setAttributes(name, 940 sAttributes, 941 delegationSubject); 942 } catch (IOException ioe) { 943 communicatorAdmin.gotIOException(ioe); 944 945 return connection.setAttributes(name, 946 sAttributes, 947 delegationSubject); 948 } finally { 949 popDefaultClassLoader(old); 950 } 951 } 952 953 954 public Object invoke(ObjectName name, 955 String operationName, 956 Object params[], 957 String signature[]) 958 throws InstanceNotFoundException , 959 MBeanException , 960 ReflectionException , 961 IOException { 962 963 if (logger.debugOn()) logger.debug("invoke", 964 "name=" + name 965 + ", operationName=" + operationName 966 + ", params=" + objects(params) 967 + ", signature=" + strings(signature)); 968 969 final MarshalledObject sParams = new MarshalledObject (params); 970 final ClassLoader old = pushDefaultClassLoader(); 971 try { 972 return connection.invoke(name, 973 operationName, 974 sParams, 975 signature, 976 delegationSubject); 977 } catch (IOException ioe) { 978 communicatorAdmin.gotIOException(ioe); 979 980 return connection.invoke(name, 981 operationName, 982 sParams, 983 signature, 984 delegationSubject); 985 } finally { 986 popDefaultClassLoader(old); 987 } 988 } 989 990 991 public String getDefaultDomain() 992 throws IOException { 993 if (logger.debugOn()) logger.debug("getDefaultDomain", ""); 994 995 final ClassLoader old = pushDefaultClassLoader(); 996 try { 997 return connection.getDefaultDomain(delegationSubject); 998 } catch (IOException ioe) { 999 communicatorAdmin.gotIOException(ioe); 1000 1001 return connection.getDefaultDomain(delegationSubject); 1002 } finally { 1003 popDefaultClassLoader(old); 1004 } 1005 } 1006 1007 public String [] getDomains() throws IOException { 1008 if (logger.debugOn()) logger.debug("getDomains", ""); 1009 1010 final ClassLoader old = pushDefaultClassLoader(); 1011 try { 1012 return connection.getDomains(delegationSubject); 1013 } catch (IOException ioe) { 1014 communicatorAdmin.gotIOException(ioe); 1015 1016 return connection.getDomains(delegationSubject); 1017 } finally { 1018 popDefaultClassLoader(old); 1019 } 1020 } 1021 1022 public MBeanInfo getMBeanInfo(ObjectName name) 1023 throws InstanceNotFoundException , 1024 IntrospectionException , 1025 ReflectionException , 1026 IOException { 1027 1028 if (logger.debugOn()) logger.debug("getMBeanInfo", "name=" + name); 1029 final ClassLoader old = pushDefaultClassLoader(); 1030 try { 1031 return connection.getMBeanInfo(name, delegationSubject); 1032 } catch (IOException ioe) { 1033 communicatorAdmin.gotIOException(ioe); 1034 1035 return connection.getMBeanInfo(name, delegationSubject); 1036 } finally { 1037 popDefaultClassLoader(old); 1038 } 1039 } 1040 1041 1042 public boolean isInstanceOf(ObjectName name, 1043 String className) 1044 throws InstanceNotFoundException , 1045 IOException { 1046 if (logger.debugOn()) 1047 logger.debug("isInstanceOf", "name=" + name + 1048 ", className=" + className); 1049 1050 final ClassLoader old = pushDefaultClassLoader(); 1051 try { 1052 return connection.isInstanceOf(name, 1053 className, 1054 delegationSubject); 1055 } catch (IOException ioe) { 1056 communicatorAdmin.gotIOException(ioe); 1057 1058 return connection.isInstanceOf(name, 1059 className, 1060 delegationSubject); 1061 } finally { 1062 popDefaultClassLoader(old); 1063 } 1064 } 1065 1066 public void addNotificationListener(ObjectName name, 1067 ObjectName listener, 1068 NotificationFilter filter, 1069 Object handback) 1070 throws InstanceNotFoundException , 1071 IOException { 1072 1073 if (logger.debugOn()) 1074 logger.debug("addNotificationListener" + 1075 "(ObjectName,ObjectName,NotificationFilter,Object)", 1076 "name=" + name + ", listener=" + listener 1077 + ", filter=" + filter + ", handback=" + handback); 1078 1079 final MarshalledObject sFilter = new MarshalledObject (filter); 1080 final MarshalledObject sHandback = new MarshalledObject (handback); 1081 final ClassLoader old = pushDefaultClassLoader(); 1082 try { 1083 connection.addNotificationListener(name, 1084 listener, 1085 sFilter, 1086 sHandback, 1087 delegationSubject); 1088 } catch (IOException ioe) { 1089 communicatorAdmin.gotIOException(ioe); 1090 1091 connection.addNotificationListener(name, 1092 listener, 1093 sFilter, 1094 sHandback, 1095 delegationSubject); 1096 } finally { 1097 popDefaultClassLoader(old); 1098 } 1099 } 1100 1101 public void removeNotificationListener(ObjectName name, 1102 ObjectName listener) 1103 throws InstanceNotFoundException , 1104 ListenerNotFoundException , 1105 IOException { 1106 1107 if (logger.debugOn()) logger.debug("removeNotificationListener" + 1108 "(ObjectName,ObjectName)", 1109 "name=" + name 1110 + ", listener=" + listener); 1111 1112 final ClassLoader old = pushDefaultClassLoader(); 1113 try { 1114 connection.removeNotificationListener(name, 1115 listener, 1116 delegationSubject); 1117 } catch (IOException ioe) { 1118 communicatorAdmin.gotIOException(ioe); 1119 1120 connection.removeNotificationListener(name, 1121 listener, 1122 delegationSubject); 1123 } finally { 1124 popDefaultClassLoader(old); 1125 } 1126 } 1127 1128 public void removeNotificationListener(ObjectName name, 1129 ObjectName listener, 1130 NotificationFilter filter, 1131 Object handback) 1132 throws InstanceNotFoundException , 1133 ListenerNotFoundException , 1134 IOException { 1135 if (logger.debugOn()) 1136 logger.debug("removeNotificationListener" + 1137 "(ObjectName,ObjectName,NotificationFilter,Object)", 1138 "name=" + name 1139 + ", listener=" + listener 1140 + ", filter=" + filter 1141 + ", handback=" + handback); 1142 1143 final MarshalledObject sFilter = new MarshalledObject (filter); 1144 final MarshalledObject sHandback = new MarshalledObject (handback); 1145 final ClassLoader old = pushDefaultClassLoader(); 1146 try { 1147 connection.removeNotificationListener(name, 1148 listener, 1149 sFilter, 1150 sHandback, 1151 delegationSubject); 1152 } catch (IOException ioe) { 1153 communicatorAdmin.gotIOException(ioe); 1154 1155 connection.removeNotificationListener(name, 1156 listener, 1157 sFilter, 1158 sHandback, 1159 delegationSubject); 1160 } finally { 1161 popDefaultClassLoader(old); 1162 } 1163 } 1164 1165 1167 public void addNotificationListener(ObjectName name, 1168 NotificationListener listener, 1169 NotificationFilter filter, 1170 Object handback) 1171 throws InstanceNotFoundException , 1172 IOException { 1173 1174 final boolean debug = logger.debugOn(); 1175 if (debug) 1176 logger.debug("addNotificationListener" + 1177 "(ObjectName,NotificationListener,"+ 1178 "NotificationFilter,Object)", 1179 "name=" + name 1180 + ", listener=" + listener 1181 + ", filter=" + filter 1182 + ", handback=" + handback); 1183 1184 final Integer listenerID = 1185 addListenerWithSubject(name, new MarshalledObject (filter), 1186 delegationSubject,true); 1187 rmiNotifClient.addNotificationListener(listenerID, name, listener, 1188 filter, handback, 1189 delegationSubject); 1190 } 1191 1192 public void removeNotificationListener(ObjectName name, 1193 NotificationListener listener) 1194 throws InstanceNotFoundException , 1195 ListenerNotFoundException , 1196 IOException { 1197 final boolean debug = logger.debugOn(); 1198 1199 if (debug) logger.debug("removeNotificationListener"+ 1200 "(ObjectName,NotificationListener)", 1201 "name=" + name 1202 + ", listener=" + listener); 1203 1204 final Integer [] ret = 1205 rmiNotifClient.removeNotificationListener(name, listener); 1206 1207 if (debug) logger.debug("removeNotificationListener", 1208 "listenerIDs=" + objects(ret)); 1209 1210 final ClassLoader old = pushDefaultClassLoader(); 1211 1212 try { 1213 connection.removeNotificationListeners(name, 1214 ret, 1215 delegationSubject); 1216 } catch (IOException ioe) { 1217 communicatorAdmin.gotIOException(ioe); 1218 1219 connection.removeNotificationListeners(name, 1220 ret, 1221 delegationSubject); 1222 } finally { 1223 popDefaultClassLoader(old); 1224 } 1225 1226 } 1227 1228 public void removeNotificationListener(ObjectName name, 1229 NotificationListener listener, 1230 NotificationFilter filter, 1231 Object handback) 1232 throws InstanceNotFoundException , 1233 ListenerNotFoundException , 1234 IOException { 1235 final boolean debug = logger.debugOn(); 1236 1237 if (debug) 1238 logger.debug("removeNotificationListener"+ 1239 "(ObjectName,NotificationListener,"+ 1240 "NotificationFilter,Object)", 1241 "name=" + name 1242 + ", listener=" + listener 1243 + ", filter=" + filter 1244 + ", handback=" + handback); 1245 1246 final Integer ret = 1247 rmiNotifClient.removeNotificationListener(name, listener, 1248 filter, handback); 1249 1250 if (debug) logger.debug("removeNotificationListener", 1251 "listenerID=" + ret); 1252 1253 final ClassLoader old = pushDefaultClassLoader(); 1254 try { 1255 connection.removeNotificationListeners(name, 1256 new Integer [] {ret}, 1257 delegationSubject); 1258 } catch (IOException ioe) { 1259 communicatorAdmin.gotIOException(ioe); 1260 1261 connection.removeNotificationListeners(name, 1262 new Integer [] {ret}, 1263 delegationSubject); 1264 } finally { 1265 popDefaultClassLoader(old); 1266 } 1267 1268 } 1269 } 1270 1271 private class RMINotifClient extends ClientNotifForwarder { 1273 public RMINotifClient(ClassLoader cl, Map env) { 1274 super(cl, env); 1275 } 1276 1277 protected NotificationResult fetchNotifs(long clientSequenceNumber, 1278 int maxNotifications, 1279 long timeout) 1280 throws IOException , ClassNotFoundException { 1281 IOException org; 1282 1283 while (true) { try { 1285 return connection.fetchNotifications(clientSequenceNumber, 1286 maxNotifications, 1287 timeout); 1288 } catch (IOException ioe) { 1289 org = ioe; 1290 1291 try { 1293 communicatorAdmin.gotIOException(ioe); 1294 1295 continue; 1297 } catch (IOException ee) { 1298 break; 1300 } } } 1303 1304 if (org instanceof UnmarshalException ) { 1306 UnmarshalException ume = (UnmarshalException )org; 1307 1308 if (ume.detail instanceof ClassNotFoundException ) 1309 throw (ClassNotFoundException ) ume.detail; 1310 1311 1324 if (ume.detail instanceof WriteAbortedException ) { 1325 WriteAbortedException wae = 1326 (WriteAbortedException ) ume.detail; 1327 if (wae.detail instanceof IOException ) 1328 throw (IOException ) wae.detail; 1329 } 1330 } else if (org instanceof MarshalException ) { 1331 MarshalException me = (MarshalException )org; 1334 if (me.detail instanceof NotSerializableException ) { 1335 throw (NotSerializableException )me.detail; 1336 } 1337 } 1338 1339 throw org; 1341 } 1342 1343 protected Integer addListenerForMBeanRemovedNotif() 1344 throws IOException , InstanceNotFoundException { 1345 MarshalledObject sFilter = null; 1346 NotificationFilterSupport clientFilter = 1347 new NotificationFilterSupport (); 1348 clientFilter.enableType( 1349 MBeanServerNotification.UNREGISTRATION_NOTIFICATION); 1350 sFilter = new MarshalledObject (clientFilter); 1351 1352 Integer [] listenerIDs; 1353 final ObjectName [] names = new ObjectName [] {delegateName}; 1354 final MarshalledObject [] filters = 1355 new MarshalledObject [] {sFilter}; 1356 final Subject [] subjects = new Subject [] {null}; 1357 try { 1358 listenerIDs = 1359 connection.addNotificationListeners(names, 1360 filters, 1361 subjects); 1362 1363 } catch (IOException ioe) { 1364 communicatorAdmin.gotIOException(ioe); 1365 1366 listenerIDs = 1367 connection.addNotificationListeners(names, 1368 filters, 1369 subjects); 1370 } 1371 return listenerIDs[0]; 1372 } 1373 1374 protected void removeListenerForMBeanRemovedNotif(Integer id) 1375 throws IOException , InstanceNotFoundException , 1376 ListenerNotFoundException { 1377 try { 1378 connection.removeNotificationListeners(delegateName, 1379 new Integer [] {id}, 1380 null); 1381 } catch (IOException ioe) { 1382 communicatorAdmin.gotIOException(ioe); 1383 1384 connection.removeNotificationListeners(delegateName, 1385 new Integer [] {id}, 1386 null); 1387 } 1388 1389 } 1390 1391 protected void lostNotifs(String message, long number) { 1392 final String notifType = JMXConnectionNotification.NOTIFS_LOST; 1393 1394 final JMXConnectionNotification n = 1395 new JMXConnectionNotification (notifType, 1396 RMIConnector.this, 1397 connectionId, 1398 clientNotifCounter++, 1399 message, 1400 new Long (number)); 1401 sendNotification(n); 1402 } 1403 } 1404 1405 private class RMIClientCommunicatorAdmin extends ClientCommunicatorAdmin { 1406 public RMIClientCommunicatorAdmin(long period) { 1407 super(period); 1408 } 1409 1410 public void gotIOException (IOException ioe) throws IOException { 1411 if (ioe instanceof NoSuchObjectException ) { 1412 super.gotIOException(ioe); 1414 1415 return; 1416 } 1417 1418 try { 1420 connection.getDefaultDomain(null); 1421 } catch (IOException ioexc) { 1422 boolean toClose = false; 1423 1424 synchronized(this) { 1425 if (!terminated) { 1426 terminated = true; 1427 1428 toClose = true; 1429 } 1430 } 1431 1432 if (toClose) { 1433 final Notification failedNotif = 1436 new JMXConnectionNotification ( 1437 JMXConnectionNotification.FAILED, 1438 this, 1439 connectionId, 1440 clientNotifID++, 1441 "Failed to communicate with the server: "+ioe.toString(), 1442 ioe); 1443 1444 sendNotification(failedNotif); 1445 1446 try { 1447 close(true); 1448 } catch (Exception e) { 1449 } 1452 } 1453 } 1454 1455 if (ioe instanceof ServerException ) { 1457 1466 Throwable tt = ((ServerException )ioe).detail; 1467 1468 if (tt instanceof IOException ) { 1469 throw (IOException )tt; 1470 } else if (tt instanceof RuntimeException ) { 1471 throw (RuntimeException )tt; 1472 } 1473 } 1474 1475 throw ioe; 1476 } 1477 1478 public void reconnectNotificationListeners(ClientListenerInfo[] old) throws IOException { 1479 final int len = old.length; 1480 int i; 1481 1482 ClientListenerInfo[] clis = new ClientListenerInfo[len]; 1483 1484 final Subject [] subjects = new Subject [len]; 1485 final ObjectName [] names = new ObjectName [len]; 1486 final NotificationListener [] listeners = new NotificationListener [len]; 1487 final NotificationFilter [] filters = new NotificationFilter [len]; 1488 final MarshalledObject [] mFilters = new MarshalledObject [len]; 1489 final Object [] handbacks = new Object [len]; 1490 1491 for (i=0;i<len;i++) { 1492 subjects[i] = old[i].getDelegationSubject(); 1493 names[i] = old[i].getObjectName(); 1494 listeners[i] = old[i].getListener(); 1495 filters[i] = old[i].getNotificationFilter(); 1496 mFilters[i] = new MarshalledObject (filters[i]); 1497 handbacks[i] = old[i].getHandback(); 1498 } 1499 1500 try { 1501 Integer [] ids = addListenersWithSubjects(names,mFilters,subjects,false); 1502 1503 for (i=0;i<len;i++) { 1504 clis[i] = new ClientListenerInfo(ids[i], 1505 names[i], 1506 listeners[i], 1507 filters[i], 1508 handbacks[i], 1509 subjects[i]); 1510 } 1511 1512 rmiNotifClient.postReconnection(clis); 1513 1514 return; 1515 } catch (InstanceNotFoundException infe) { 1516 } 1518 1519 int j = 0; 1520 for (i=0;i<len;i++) { 1521 try { 1522 Integer id = addListenerWithSubject(names[i], 1523 new MarshalledObject (filters[i]), 1524 subjects[i], 1525 false); 1526 1527 clis[j++] = new ClientListenerInfo(id, 1528 names[i], 1529 listeners[i], 1530 filters[i], 1531 handbacks[i], 1532 subjects[i]); 1533 } catch (InstanceNotFoundException infe) { 1534 logger.warning("reconnectNotificationListeners", 1535 "Can't reconnect listener for " + 1536 names[i]); 1537 } 1538 } 1539 1540 if (j != len) { 1541 ClientListenerInfo[] tmp = clis; 1542 clis = new ClientListenerInfo[j]; 1543 System.arraycopy(tmp, 0, clis, 0, j); 1544 } 1545 1546 rmiNotifClient.postReconnection(clis); 1547 } 1548 1549 protected void checkConnection() throws IOException { 1550 if (logger.debugOn()) 1551 logger.debug("RMIClientCommunicatorAdmin-checkConnection", 1552 "Calling the method getDefaultDomain."); 1553 1554 connection.getDefaultDomain(null); 1555 } 1556 1557 protected void doStart() throws IOException { 1558 RMIServer stub = null; 1560 try { 1561 stub = (rmiServer!=null)?rmiServer: 1562 findRMIServer(jmxServiceURL, env); 1563 } catch (NamingException ne) { 1564 throw new IOException ("Failed to get a RMI stub: "+ne); 1565 } 1566 1567 stub = connectStub(stub,env); 1569 1570 Object credentials = env.get(CREDENTIALS); 1572 connection = stub.newClient(credentials); 1573 1574 final ClientListenerInfo[] old = rmiNotifClient.preReconnection(); 1576 1577 reconnectNotificationListeners(old); 1578 1579 connectionId = getConnectionId(); 1580 1581 Notification reconnectedNotif = 1582 new JMXConnectionNotification (JMXConnectionNotification.OPENED, 1583 this, 1584 connectionId, 1585 clientNotifID++, 1586 "Reconnected to server", 1587 null); 1588 sendNotification(reconnectedNotif); 1589 1590 } 1591 1592 protected void doStop() { 1593 try { 1594 close(); 1595 } catch (IOException ioe) { 1596 logger.warning("RMIClientCommunicatorAdmin-doStop", 1597 "Failed to call the method close():" + ioe); 1598 logger.debug("RMIClientCommunicatorAdmin-doStop",ioe); 1599 } 1600 } 1601 } 1602 1603 1649 static RMIServer connectStub(RMIServer rmiServer, 1650 Map environment) 1651 throws IOException { 1652 if (rmiServer instanceof javax.rmi.CORBA.Stub ) { 1653 javax.rmi.CORBA.Stub stub = (javax.rmi.CORBA.Stub ) rmiServer; 1654 try { 1655 stub._orb(); 1656 } catch (org.omg.CORBA.BAD_OPERATION x) { 1657 stub.connect(resolveOrb(environment)); 1658 } 1659 } 1660 return rmiServer; 1661 } 1662 1663 1684 static org.omg.CORBA.ORB resolveOrb(Map environment) 1685 throws IOException { 1686 if (environment != null) { 1687 final Object orb = environment.get(EnvHelp.DEFAULT_ORB); 1688 if (orb != null && !(orb instanceof org.omg.CORBA.ORB )) 1689 throw new IllegalArgumentException (EnvHelp.DEFAULT_ORB + 1690 " must be an instance of org.omg.CORBA.ORB."); 1691 if (orb != null) return (org.omg.CORBA.ORB )orb; 1692 } 1693 final Object orb = 1694 (RMIConnector.orb==null)?null:RMIConnector.orb.get(); 1695 if (orb != null) return (org.omg.CORBA.ORB )orb; 1696 1697 final org.omg.CORBA.ORB newOrb = 1698 org.omg.CORBA.ORB.init((String [])null, (Properties )null); 1699 RMIConnector.orb = new WeakReference (newOrb); 1700 return newOrb; 1701 } 1702 1703 1714 private void readObject(java.io.ObjectInputStream s) 1715 throws IOException , ClassNotFoundException { 1716 s.defaultReadObject(); 1717 1718 if (rmiServer == null && jmxServiceURL == null) throw new 1719 InvalidObjectException ("rmiServer and jmxServiceURL both null"); 1720 1721 initTransients(); 1722 } 1723 1724 1755 private void writeObject(java.io.ObjectOutputStream s) 1756 throws IOException { 1757 if (rmiServer == null && jmxServiceURL == null) throw new 1758 InvalidObjectException ("rmiServer and jmxServiceURL both null."); 1759 connectStub(this.rmiServer,env); 1760 s.defaultWriteObject(); 1761 } 1762 1763 private void initTransients() { 1765 rmbscMap = new WeakHashMap (); 1766 connected = false; 1767 terminated = false; 1768 1769 connectionBroadcaster = new NotificationBroadcasterSupport (); 1770 } 1771 1772 1776 private RMIServer findRMIServer(JMXServiceURL directoryURL, 1777 Map environment) 1778 throws NamingException , IOException { 1779 final boolean isIiop = RMIConnectorServer.isIiopURL(directoryURL,true); 1780 if (isIiop) { 1781 environment.put(EnvHelp.DEFAULT_ORB,resolveOrb(environment)); 1783 } 1784 1785 String path = directoryURL.getURLPath(); 1786 if (path.startsWith("/jndi/")) 1787 return findRMIServerJNDI(path.substring(6), environment, isIiop); 1788 else if (path.startsWith("/stub/")) 1789 return findRMIServerJRMP(path.substring(6), environment, isIiop); 1790 else if (path.startsWith("/ior/")) 1791 return findRMIServerIIOP(path.substring(5), environment, isIiop); 1792 else { 1793 final String msg = "URL path must begin with /jndi/ or /stub/ " + 1794 "or /ior/: " + path; 1795 throw new MalformedURLException (msg); 1796 } 1797 } 1798 1799 1812 private RMIServer findRMIServerJNDI(String jndiURL, Map env, boolean isIiop) 1813 throws NamingException { 1814 1815 InitialContext ctx = new InitialContext (EnvHelp.mapToHashtable(env)); 1816 1817 Object objref = ctx.lookup(jndiURL); 1818 ctx.close(); 1819 1820 if (isIiop) 1821 return narrowIIOPServer(objref); 1822 else 1823 return narrowJRMPServer(objref); 1824 } 1825 1826 private static RMIServer narrowJRMPServer(Object objref) { 1827 1828 return (RMIServer ) objref; 1829 } 1830 1831 private static RMIServer narrowIIOPServer(Object objref) { 1832 try { 1833 return (RMIServer ) 1834 PortableRemoteObject.narrow(objref, RMIServer .class); 1835 } catch (ClassCastException e) { 1836 if (logger.traceOn()) 1837 logger.trace("narrowIIOPServer","Failed to narrow objref=" + 1838 objref + ": " + e); 1839 if (logger.debugOn()) logger.debug("narrowIIOPServer",e); 1840 return null; 1841 } 1842 } 1843 1844 private RMIServer findRMIServerIIOP(String ior, Map env, boolean isIiop) { 1845 final org.omg.CORBA.ORB orb = (org.omg.CORBA.ORB ) 1847 env.get(EnvHelp.DEFAULT_ORB); 1848 final Object stub = orb.string_to_object(ior); 1849 return (RMIServer ) PortableRemoteObject.narrow(stub, RMIServer .class); 1850 } 1851 1852 private RMIServer findRMIServerJRMP(String base64, Map env, boolean isIiop) 1853 throws IOException { 1854 final byte[] serialized; 1856 try { 1857 serialized = base64ToByteArray(base64); 1858 } catch (IllegalArgumentException e) { 1859 throw new MalformedURLException ("Bad BASE64 encoding: " + 1860 e.getMessage()); 1861 } 1862 final ByteArrayInputStream bin = new ByteArrayInputStream (serialized); 1863 1864 final ClassLoader loader = EnvHelp.resolveClientClassLoader(env); 1865 final ObjectInputStream oin = 1866 (loader == null) ? 1867 new ObjectInputStream (bin) : 1868 new ObjectInputStreamWithLoader(bin, loader); 1869 final Object stub; 1870 try { 1871 stub = oin.readObject(); 1872 } catch (ClassNotFoundException e) { 1873 throw new MalformedURLException ("Class not found: " + e); 1874 } 1875 return (RMIServer ) PortableRemoteObject.narrow(stub, RMIServer .class); 1876 } 1877 1878 private static final class ObjectInputStreamWithLoader 1879 extends ObjectInputStream { 1880 ObjectInputStreamWithLoader(InputStream in, ClassLoader cl) 1881 throws IOException { 1882 super(in); 1883 this.loader = cl; 1884 } 1885 1886 protected Class resolveClass(ObjectStreamClass classDesc) 1887 throws IOException , ClassNotFoundException { 1888 return Class.forName(classDesc.getName(), false, loader); 1889 } 1890 1891 private final ClassLoader loader; 1892 } 1893 1894 1958 1959 private static final String rmiConnectionImplStubClassName = 1960 RMIConnection .class.getName() + "Impl_Stub"; 1961 private static final Class rmiConnectionImplStubClass; 1962 private static final String pRefClassName = 1963 "com.sun.jmx.remote.internal.PRef"; 1964 private static final Constructor proxyRefConstructor; 1965 static { 1966 final String pRefByteCodeString = 1967 "\312\376\272\276\0\0\0.\0\27\12\0\5\0\15\11\0\4\0\16\13\0\17\0"+ 1968 "\20\7\0\21\7\0\22\1\0\6<init>\1\0\36(Ljava/rmi/server/RemoteRef;"+ 1969 ")V\1\0\4Code\1\0\6invoke\1\0S(Ljava/rmi/Remote;Ljava/lang/reflec"+ 1970 "t/Method;[Ljava/lang/Object;J)Ljava/lang/Object;\1\0\12Exception"+ 1971 "s\7\0\23\14\0\6\0\7\14\0\24\0\25\7\0\26\14\0\11\0\12\1\0\40com/"+ 1972 "sun/jmx/remote/internal/PRef\1\0$com/sun/jmx/remote/internal/Pr"+ 1973 "oxyRef\1\0\23java/lang/Exception\1\0\3ref\1\0\33Ljava/rmi/serve"+ 1974 "r/RemoteRef;\1\0\31java/rmi/server/RemoteRef\0!\0\4\0\5\0\0\0\0"+ 1975 "\0\2\0\1\0\6\0\7\0\1\0\10\0\0\0\22\0\2\0\2\0\0\0\6*+\267\0\1\261"+ 1976 "\0\0\0\0\0\1\0\11\0\12\0\2\0\10\0\0\0\33\0\6\0\6\0\0\0\17*\264\0"+ 1977 "\2+,-\26\4\271\0\3\6\0\260\0\0\0\0\0\13\0\0\0\4\0\1\0\14\0\0"; 1978 final byte[] pRefByteCode = 1979 NoCallStackClassLoader.stringToBytes(pRefByteCodeString); 1980 PrivilegedExceptionAction action = new PrivilegedExceptionAction () { 1981 public Object run() throws Exception { 1982 Class thisClass = RMIConnector .class; 1983 ClassLoader thisLoader = thisClass.getClassLoader(); 1984 ProtectionDomain thisProtectionDomain = 1985 thisClass.getProtectionDomain(); 1986 String [] otherClassNames = {ProxyRef.class.getName()}; 1987 ClassLoader cl = 1988 new NoCallStackClassLoader (pRefClassName, 1989 pRefByteCode, 1990 otherClassNames, 1991 thisLoader, 1992 thisProtectionDomain); 1993 Class c = cl.loadClass(pRefClassName); 1994 return c.getConstructor(new Class [] {RemoteRef .class}); 1995 } 1996 }; 1997 1998 Class stubClass; 1999 Constructor constr; 2000 try { 2001 stubClass = Class.forName(rmiConnectionImplStubClassName); 2002 constr = (Constructor ) AccessController.doPrivileged(action); 2003 } catch (Exception e) { 2004 logger.error("<clinit>", 2005 "Failed to initialize proxy reference consructor "+ 2006 "for " + rmiConnectionImplStubClassName + ": " + e); 2007 logger.debug("<clinit>",e); 2008 stubClass = null; 2009 constr = null; 2010 } 2011 rmiConnectionImplStubClass = stubClass; 2012 proxyRefConstructor = constr; 2013 } 2014 2015 private static RMIConnection shadowJrmpStub(RemoteObject stub) 2016 throws InstantiationException , IllegalAccessException , 2017 InvocationTargetException , ClassNotFoundException , 2018 NoSuchMethodException { 2019 RemoteRef ref = stub.getRef(); 2020 RemoteRef proxyRef = (RemoteRef ) 2021 proxyRefConstructor.newInstance(new Object [] {ref}); 2022 final Class [] constrTypes = {RemoteRef .class}; 2023 final Constructor rmiConnectionImplStubConstructor = 2024 rmiConnectionImplStubClass.getConstructor(constrTypes); 2025 Object [] args = {proxyRef}; 2026 RMIConnection proxyStub = (RMIConnection ) 2027 rmiConnectionImplStubConstructor.newInstance(args); 2028 return proxyStub; 2029 } 2030 2031 2146 private static final String iiopConnectionStubClassName = 2147 "org.omg.stub.javax.management.remote.rmi._RMIConnection_Stub"; 2148 private static final String proxyStubClassName = 2149 "com.sun.jmx.remote.internal.ProxyStub"; 2150 private static final String pInputStreamClassName = 2151 "com.sun.jmx.remote.internal.PInputStream"; 2152 private static final Class proxyStubClass; 2153 static { 2154 final String proxyStubByteCodeString = 2155 "\312\376\272\276\0\0\0.\0)\12\0\14\0\26\7\0\27\12\0\14\0\30\12"+ 2156 "\0\2\0\31\7\0\32\12\0\5\0\33\12\0\5\0\34\12\0\5\0\35\12\0\2\0"+ 2157 "\36\12\0\14\0\37\7\0\40\7\0!\1\0\6<init>\1\0\3()V\1\0\4Code\1"+ 2158 "\0\7_invoke\1\0K(Lorg/omg/CORBA/portable/OutputStream;)Lorg/o"+ 2159 "mg/CORBA/portable/InputStream;\1\0\12Exceptions\7\0\"\1\0\15_"+ 2160 "releaseReply\1\0'(Lorg/omg/CORBA/portable/InputStream;)V\14\0"+ 2161 "\15\0\16\1\0(com/sun/jmx/remote/internal/PInputStream\14\0\20"+ 2162 "\0\21\14\0\15\0\25\1\0+org/omg/CORBA/portable/ApplicationExce"+ 2163 "ption\14\0#\0$\14\0%\0&\14\0\15\0'\14\0(\0$\14\0\24\0\25\1\0%"+ 2164 "com/sun/jmx/remote/internal/ProxyStub\1\0<org/omg/stub/javax/"+ 2165 "management/remote/rmi/_RMIConnection_Stub\1\0)org/omg/CORBA/p"+ 2166 "ortable/RemarshalException\1\0\16getInputStream\1\0&()Lorg/om"+ 2167 "g/CORBA/portable/InputStream;\1\0\5getId\1\0\24()Ljava/lang/S"+ 2168 "tring;\1\09(Ljava/lang/String;Lorg/omg/CORBA/portable/InputSt"+ 2169 "ream;)V\1\0\25getProxiedInputStream\0!\0\13\0\14\0\0\0\0\0\3\0"+ 2170 "\1\0\15\0\16\0\1\0\17\0\0\0\21\0\1\0\1\0\0\0\5*\267\0\1\261\0"+ 2171 "\0\0\0\0\1\0\20\0\21\0\2\0\17\0\0\0;\0\4\0\4\0\0\0'\273\0\2Y*"+ 2172 "+\267\0\3\267\0\4\260M\273\0\2Y,\266\0\6\267\0\4N\273\0\5Y,\266"+ 2173 "\0\7-\267\0\10\277\0\1\0\0\0\14\0\15\0\5\0\0\0\22\0\0\0\6\0\2"+ 2174 "\0\5\0\23\0\1\0\24\0\25\0\1\0\17\0\0\0\36\0\2\0\2\0\0\0\22+\306"+ 2175 "\0\13+\300\0\2\266\0\11L*+\267\0\12\261\0\0\0\0\0\0"; 2176 final String pInputStreamByteCodeString = 2177 "\312\376\272\276\0\0\0.\0\36\12\0\7\0\17\11\0\6\0\20\12\0\21\0"+ 2178 "\22\12\0\6\0\23\12\0\24\0\25\7\0\26\7\0\27\1\0\6<init>\1\0'(L"+ 2179 "org/omg/CORBA/portable/InputStream;)V\1\0\4Code\1\0\10read_an"+ 2180 "y\1\0\25()Lorg/omg/CORBA/Any;\1\0\12read_value\1\0)(Ljava/lan"+ 2181 "g/Class;)Ljava/io/Serializable;\14\0\10\0\11\14\0\30\0\31\7\0"+ 2182 "\32\14\0\13\0\14\14\0\33\0\34\7\0\35\14\0\15\0\16\1\0(com/sun"+ 2183 "/jmx/remote/internal/PInputStream\1\0,com/sun/jmx/remote/inte"+ 2184 "rnal/ProxyInputStream\1\0\2in\1\0$Lorg/omg/CORBA/portable/Inp"+ 2185 "utStream;\1\0\"org/omg/CORBA/portable/InputStream\1\0\6narrow"+ 2186 "\1\0*()Lorg/omg/CORBA_2_3/portable/InputStream;\1\0&org/omg/C"+ 2187 "ORBA_2_3/portable/InputStream\0!\0\6\0\7\0\0\0\0\0\3\0\1\0\10"+ 2188 "\0\11\0\1\0\12\0\0\0\22\0\2\0\2\0\0\0\6*+\267\0\1\261\0\0\0\0"+ 2189 "\0\1\0\13\0\14\0\1\0\12\0\0\0\24\0\1\0\1\0\0\0\10*\264\0\2\266"+ 2190 "\0\3\260\0\0\0\0\0\1\0\15\0\16\0\1\0\12\0\0\0\25\0\2\0\2\0\0\0"+ 2191 "\11*\266\0\4+\266\0\5\260\0\0\0\0\0\0"; 2192 final byte[] proxyStubByteCode = 2193 NoCallStackClassLoader.stringToBytes(proxyStubByteCodeString); 2194 final byte[] pInputStreamByteCode = 2195 NoCallStackClassLoader.stringToBytes(pInputStreamByteCodeString); 2196 final String [] classNames={proxyStubClassName, pInputStreamClassName}; 2197 final byte[][] byteCodes = {proxyStubByteCode, pInputStreamByteCode}; 2198 final String [] otherClassNames = { 2199 iiopConnectionStubClassName, 2200 ProxyInputStream.class.getName(), 2201 }; 2202 PrivilegedExceptionAction action = new PrivilegedExceptionAction () { 2203 public Object run() throws Exception { 2204 Class thisClass = RMIConnector .class; 2205 ClassLoader thisLoader = thisClass.getClassLoader(); 2206 ProtectionDomain thisProtectionDomain = 2207 thisClass.getProtectionDomain(); 2208 ClassLoader cl = 2209 new NoCallStackClassLoader (classNames, 2210 byteCodes, 2211 otherClassNames, 2212 thisLoader, 2213 thisProtectionDomain); 2214 return cl.loadClass(proxyStubClassName); 2215 } 2216 }; 2217 Class stubClass; 2218 try { 2219 stubClass = (Class ) AccessController.doPrivileged(action); 2220 } catch (Exception e) { 2221 logger.error("<clinit>", 2222 "Unexpected exception making shadow IIOP stub class: "+e); 2223 logger.debug("<clinit>",e); 2224 stubClass = null; 2225 } 2226 proxyStubClass = stubClass; 2227 } 2228 2229 private static RMIConnection shadowIiopStub(Stub stub) 2230 throws InstantiationException , IllegalAccessException { 2231 Stub proxyStub = (Stub ) proxyStubClass.newInstance(); 2232 proxyStub._set_delegate(stub._get_delegate()); 2233 return (RMIConnection ) proxyStub; 2234 } 2235 2236 private static RMIConnection getConnection(RMIServer server, 2237 Object credentials) 2238 throws IOException { 2239 RMIConnection c = server.newClient(credentials); 2240 try { 2241 if (c.getClass() == rmiConnectionImplStubClass) 2242 return shadowJrmpStub((RemoteObject ) c); 2243 if (c.getClass().getName().equals(iiopConnectionStubClassName)) 2244 return shadowIiopStub((Stub ) c); 2245 logger.trace("getConnection", 2246 "Did not wrap " + c.getClass() + " to foil " + 2247 "stack search for classes: class loading semantics " + 2248 "may be incorrect"); 2249 } catch (Exception e) { 2250 logger.error("getConnection", 2251 "Could not wrap " + c.getClass() + " to foil " + 2252 "stack search for classes: class loading semantics " + 2253 "may be incorrect: " + e); 2254 logger.debug("getConnection",e); 2255 } 2258 return c; 2259 } 2260 2261 private static byte[] base64ToByteArray(String s) { 2262 int sLen = s.length(); 2263 int numGroups = sLen/4; 2264 if (4*numGroups != sLen) 2265 throw new IllegalArgumentException ( 2266 "String length must be a multiple of four."); 2267 int missingBytesInLastGroup = 0; 2268 int numFullGroups = numGroups; 2269 if (sLen != 0) { 2270 if (s.charAt(sLen-1) == '=') { 2271 missingBytesInLastGroup++; 2272 numFullGroups--; 2273 } 2274 if (s.charAt(sLen-2) == '=') 2275 missingBytesInLastGroup++; 2276 } 2277 byte[] result = new byte[3*numGroups - missingBytesInLastGroup]; 2278 2279 int inCursor = 0, outCursor = 0; 2281 for (int i=0; i<numFullGroups; i++) { 2282 int ch0 = base64toInt(s.charAt(inCursor++)); 2283 int ch1 = base64toInt(s.charAt(inCursor++)); 2284 int ch2 = base64toInt(s.charAt(inCursor++)); 2285 int ch3 = base64toInt(s.charAt(inCursor++)); 2286 result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4)); 2287 result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2)); 2288 result[outCursor++] = (byte) ((ch2 << 6) | ch3); 2289 } 2290 2291 if (missingBytesInLastGroup != 0) { 2293 int ch0 = base64toInt(s.charAt(inCursor++)); 2294 int ch1 = base64toInt(s.charAt(inCursor++)); 2295 result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4)); 2296 2297 if (missingBytesInLastGroup == 1) { 2298 int ch2 = base64toInt(s.charAt(inCursor++)); 2299 result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2)); 2300 } 2301 } 2302 return result; 2305 } 2306 2307 2314 private static int base64toInt(char c) { 2315 int result; 2316 2317 if (c >= base64ToInt.length) 2318 result = -1; 2319 else 2320 result = base64ToInt[c]; 2321 2322 if (result < 0) 2323 throw new IllegalArgumentException ("Illegal character " + c); 2324 return result; 2325 } 2326 2327 2334 private static final byte base64ToInt[] = { 2335 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2336 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2337 -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 2338 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 2339 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 2340 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 2341 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 2342 }; 2343 2344 private ClassLoader pushDefaultClassLoader() { 2348 final Thread t = Thread.currentThread(); 2349 final ClassLoader old = t.getContextClassLoader(); 2350 if (defaultClassLoader != null) 2351 AccessController.doPrivileged(new PrivilegedAction () { 2352 public Object run() { 2353 t.setContextClassLoader(defaultClassLoader); 2354 return null; 2355 } 2356 }); 2357 return old; 2358 } 2359 2360 private void popDefaultClassLoader(final ClassLoader old) { 2361 AccessController.doPrivileged(new PrivilegedAction () { 2362 public Object run() { 2363 Thread.currentThread().setContextClassLoader(old); 2364 return null; 2365 } 2366 }); 2367 } 2368 2369 2383 private final RMIServer rmiServer; 2384 2385 2394 private final JMXServiceURL jmxServiceURL; 2395 2396 private transient Map env; 2402 private transient ClassLoader defaultClassLoader; 2403 private transient RMIConnection connection; 2404 private transient String connectionId; 2405 2406 private long clientNotifID = 0; 2407 2408 private transient WeakHashMap rmbscMap; 2409 2410 private transient RMINotifClient rmiNotifClient; 2411 2413 private transient long clientNotifCounter = 0; 2414 2415 private transient boolean connected; 2416 private transient boolean terminated; 2418 2420 private transient Exception closeException; 2421 2422 private transient NotificationBroadcasterSupport connectionBroadcaster; 2423 2424 private transient ClientCommunicatorAdmin communicatorAdmin; 2425 2426 2430 private static WeakReference orb = null; 2431 2432 private static final ObjectName delegateName; 2433 static { 2434 try { 2435 delegateName = 2436 new ObjectName ("JMImplementation:type=MBeanServerDelegate"); 2437 } catch (MalformedObjectNameException e) { 2438 Error error = new Error ("Can't initialize delegateName"); 2439 EnvHelp.initCause(error, e); 2440 throw error; 2441 } 2442 } 2443 2444 private static String objects(final Object [] objs) { 2447 if (objs == null) 2448 return "null"; 2449 else 2450 return Arrays.asList(objs).toString(); 2451 } 2452 2453 private static String strings(final String [] strs) { 2454 return objects(strs); 2455 } 2456} 2457 | Popular Tags |