1 22 package org.jboss.invocation.jrmp.server; 23 24 import java.lang.reflect.Method ; 25 import java.net.InetAddress ; 26 import java.net.UnknownHostException ; 27 import java.io.Serializable ; 28 import java.rmi.server.RemoteServer ; 29 import java.rmi.server.UnicastRemoteObject ; 30 import java.rmi.server.RMIServerSocketFactory ; 31 import java.rmi.server.RMIClientSocketFactory ; 32 import java.rmi.server.RemoteStub ; 33 import java.rmi.MarshalledObject ; 34 import java.security.PrivilegedAction ; 35 import java.security.AccessController ; 36 import java.security.PrivilegedExceptionAction ; 37 import java.security.PrivilegedActionException ; 38 39 import javax.management.ObjectName ; 40 import javax.management.MBeanRegistration ; 41 import javax.management.MBeanServer ; 42 import javax.naming.Name ; 43 import javax.naming.InitialContext ; 44 import javax.naming.Context ; 45 import javax.naming.NamingException ; 46 import javax.naming.NameNotFoundException ; 47 import javax.transaction.Transaction ; 48 49 import org.jboss.invocation.jrmp.interfaces.JRMPInvokerProxy; 50 import org.jboss.invocation.Invocation; 51 import org.jboss.invocation.Invoker; 52 import org.jboss.invocation.MarshalledInvocation; 53 import org.jboss.invocation.MarshalledValueInputStream; 54 import org.jboss.logging.Logger; 55 import org.jboss.mx.util.JMXExceptionDecoder; 56 import org.jboss.net.sockets.DefaultSocketFactory; 57 import org.jboss.security.SecurityDomain; 58 import org.jboss.system.Registry; 59 import org.jboss.system.ServiceMBeanSupport; 60 import org.jboss.tm.TransactionPropagationContextImporter; 61 import org.jboss.tm.TransactionPropagationContextUtil; 62 63 72 public class JRMPInvoker 73 extends RemoteServer 74 implements Invoker, JRMPInvokerMBean, MBeanRegistration 75 { 76 79 public static final int ANONYMOUS_PORT = 0; 80 81 84 protected Logger log; 85 86 89 protected ServiceMBeanSupport support; 90 91 94 protected int rmiPort = ANONYMOUS_PORT; 95 96 99 protected RMIClientSocketFactory clientSocketFactory; 100 101 104 protected RMIServerSocketFactory serverSocketFactory; 105 106 109 protected String clientSocketFactoryName; 110 111 114 protected String serverSocketFactoryName; 115 116 119 protected String serverAddress; 120 123 protected String sslDomain; 124 125 protected RemoteStub invokerStub; 126 129 protected int backlog = 200; 130 133 protected boolean enableClassCaching = false; 134 137 private MBeanServerAction serverAction = new MBeanServerAction(); 138 139 private static TransactionPropagationContextImporter tpcImporter; 140 141 public JRMPInvoker() 142 { 143 final JRMPInvoker delegate = this; 144 145 support = new ServiceMBeanSupport(getClass()) 147 { 148 protected void startService() throws Exception 149 { 150 delegate.startService(); 151 } 152 protected void stopService() throws Exception 153 { 154 delegate.stopService(); 155 } 156 protected void destroyService() throws Exception 157 { 158 delegate.destroyService(); 159 } 160 }; 161 162 log = support.getLog(); 164 } 165 166 169 public int getBacklog() 170 { 171 return backlog; 172 } 173 174 177 public void setBacklog(int back) 178 { 179 backlog = back; 180 } 181 182 185 public boolean getEnableClassCaching() 186 { 187 return enableClassCaching; 188 } 189 190 193 public void setEnableClassCaching(boolean flag) 194 { 195 enableClassCaching = flag; 196 MarshalledValueInputStream.useClassCache(enableClassCaching); 197 } 198 199 202 public String getServerHostName() 203 { 204 try 205 { 206 return InetAddress.getLocalHost().getHostName(); 207 } 208 catch (Exception ignored) 209 { 210 return null; 211 } 212 } 213 214 217 public void setRMIObjectPort(final int rmiPort) 218 { 219 this.rmiPort = rmiPort; 220 } 221 222 225 public int getRMIObjectPort() 226 { 227 return rmiPort; 228 } 229 230 233 public void setRMIClientSocketFactory(final String name) 234 { 235 clientSocketFactoryName = name; 236 } 237 238 241 public String getRMIClientSocketFactory() 242 { 243 return clientSocketFactoryName; 244 } 245 246 249 public void setRMIClientSocketFactoryBean(final RMIClientSocketFactory bean) 250 { 251 clientSocketFactory = bean; 252 } 253 254 257 public RMIClientSocketFactory getRMIClientSocketFactoryBean() 258 { 259 return clientSocketFactory; 260 } 261 262 265 public void setRMIServerSocketFactory(final String name) 266 { 267 serverSocketFactoryName = name; 268 } 269 270 273 public String getRMIServerSocketFactory() 274 { 275 return serverSocketFactoryName; 276 } 277 278 281 public void setRMIServerSocketFactoryBean(final RMIServerSocketFactory bean) 282 { 283 serverSocketFactory = bean; 284 } 285 286 289 public RMIServerSocketFactory getRMIServerSocketFactoryBean() 290 { 291 return serverSocketFactory; 292 } 293 294 297 public void setServerAddress(final String address) 298 { 299 serverAddress = address; 300 } 301 302 305 public String getServerAddress() 306 { 307 return serverAddress; 308 } 309 310 313 public void setSecurityDomain(String domainName) 314 { 315 this.sslDomain = domainName; 316 } 317 318 321 public String getSecurityDomain() 322 { 323 return sslDomain; 324 } 325 326 public Serializable getStub() 327 { 328 return this.invokerStub; 329 } 330 331 protected void startService() throws Exception 332 { 333 loadCustomSocketFactories(); 334 335 log.debug("RMI Port='" + 336 (rmiPort == ANONYMOUS_PORT ? "Anonymous" : 337 Integer.toString(rmiPort)) + "'"); 338 339 log.debug("Client SocketFactory='" + 340 (clientSocketFactory == null ? "Default" : 341 clientSocketFactory.toString()) + "'"); 342 343 log.debug("Server SocketFactory='" + 344 (serverSocketFactory == null ? "Default" : 345 serverSocketFactory.toString()) + "'"); 346 347 log.debug("Server SocketAddr='" + 348 (serverAddress == null ? "Default" : 349 serverAddress) + "'"); 350 log.debug("SecurityDomain='" + 351 (sslDomain == null ? "Default" : 352 sslDomain) + "'"); 353 354 InitialContext ctx = new InitialContext (); 355 356 tpcImporter = TransactionPropagationContextUtil.getTPCImporter(); 359 360 361 364 Invoker delegateInvoker = createDelegateInvoker(); 365 366 Registry.bind(support.getServiceName(), delegateInvoker); 368 369 exportCI(); 371 372 log.debug("Bound JRMP invoker for JMX node"); 373 374 ctx.close(); 375 } 376 377 protected void stopService() throws Exception 378 { 379 InitialContext ctx = new InitialContext (); 380 381 try 382 { 383 unexportCI(); 384 } 385 finally 386 { 387 ctx.close(); 388 } 389 this.clientSocketFactory = null; 390 this.serverSocketFactory = null; 391 this.invokerStub = null; 392 } 393 394 protected void destroyService() throws Exception 395 { 396 Registry.unbind(support.getServiceName()); 398 } 399 400 403 public Object invoke(Invocation invocation) 404 throws Exception 405 { 406 ClassLoader oldCl = TCLAction.UTIL.getContextClassLoader(); 407 ObjectName mbean = null; 408 try 409 { 410 MarshalledInvocation mi = (MarshalledInvocation) invocation; 412 invocation.setTransaction(importTPC(mi.getTransactionPropagationContext())); 413 414 mbean = (ObjectName ) Registry.lookup(invocation.getObjectName()); 415 416 Object obj = serverAction.invoke(mbean, 418 "invoke", 419 new Object []{invocation}, 420 Invocation.INVOKE_SIGNATURE); 421 return new MarshalledObject (obj); 422 } 423 catch (Exception e) 424 { 425 Throwable th = JMXExceptionDecoder.decode(e); 426 if (log.isTraceEnabled()) 427 log.trace("Failed to invoke on mbean: " + mbean, th); 428 429 if (th instanceof Exception ) 430 e = (Exception ) th; 431 432 throw e; 433 } 434 finally 435 { 436 TCLAction.UTIL.setContextClassLoader(oldCl); 437 Thread.interrupted(); } 439 } 440 441 protected Invoker createDelegateInvoker() 442 { 443 return new JRMPInvokerProxy(this); 444 } 445 446 protected void exportCI() throws Exception 447 { 448 this.invokerStub = (RemoteStub ) UnicastRemoteObject.exportObject 449 (this, rmiPort, clientSocketFactory, serverSocketFactory); 450 } 451 452 protected void unexportCI() throws Exception 453 { 454 UnicastRemoteObject.unexportObject(this, true); 455 } 456 457 protected void rebind(Context ctx, String name, Object val) 458 throws NamingException 459 { 460 463 Name n = ctx.getNameParser("").parse(name); 464 while (n.size() > 1) 465 { 466 String ctxName = n.get(0); 467 try 468 { 469 ctx = (Context ) ctx.lookup(ctxName); 470 } 471 catch (NameNotFoundException e) 472 { 473 ctx = ctx.createSubcontext(ctxName); 474 } 475 n = n.getSuffix(1); 476 } 477 478 ctx.rebind(n.get(0), val); 479 } 480 481 486 protected void loadCustomSocketFactories() 487 { 488 ClassLoader loader = TCLAction.UTIL.getContextClassLoader(); 489 490 if( clientSocketFactory == null ) 491 { 492 try 493 { 494 if (clientSocketFactoryName != null) 495 { 496 Class csfClass = loader.loadClass(clientSocketFactoryName); 497 clientSocketFactory = (RMIClientSocketFactory ) csfClass.newInstance(); 498 } 499 } 500 catch (Exception e) 501 { 502 log.error("Failed to load client socket factory", e); 503 clientSocketFactory = null; 504 } 505 } 506 507 if( serverSocketFactory == null ) 508 { 509 try 510 { 511 if (serverSocketFactoryName != null) 512 { 513 Class ssfClass = loader.loadClass(serverSocketFactoryName); 514 serverSocketFactory = (RMIServerSocketFactory ) ssfClass.newInstance(); 515 if (serverAddress != null) 516 { 517 try 519 { 520 Class [] parameterTypes = {String .class}; 521 Method m = ssfClass.getMethod("setBindAddress", parameterTypes); 522 Object [] args = {serverAddress}; 523 m.invoke(serverSocketFactory, args); 524 } 525 catch (NoSuchMethodException e) 526 { 527 log.warn("Socket factory does not support setBindAddress(String)"); 528 } 530 catch (Exception e) 531 { 532 log.warn("Failed to setBindAddress=" + serverAddress + " on socket factory", e); 533 } 535 } 536 539 if (sslDomain != null) 540 { 541 try 542 { 543 InitialContext ctx = new InitialContext (); 544 SecurityDomain domain = (SecurityDomain) ctx.lookup(sslDomain); 545 Class [] parameterTypes = {SecurityDomain.class}; 546 Method m = ssfClass.getMethod("setSecurityDomain", parameterTypes); 547 Object [] args = {domain}; 548 m.invoke(serverSocketFactory, args); 549 } 550 catch (NoSuchMethodException e) 551 { 552 log.error("Socket factory does not support setSecurityDomain(SecurityDomain)"); 553 } 554 catch (Exception e) 555 { 556 log.error("Failed to setSecurityDomain=" + sslDomain + " on socket factory", e); 557 } 558 } 559 } 560 else if (serverAddress != null) 562 { 563 DefaultSocketFactory defaultFactory = new DefaultSocketFactory(backlog); 564 serverSocketFactory = defaultFactory; 565 try 566 { 567 defaultFactory.setBindAddress(serverAddress); 568 } 569 catch (UnknownHostException e) 570 { 571 log.error("Failed to setBindAddress=" + serverAddress + " on socket factory", e); 572 } 573 } 574 } 575 catch (Exception e) 576 { 577 log.error("operation failed", e); 578 serverSocketFactory = null; 579 } 580 } 581 } 582 583 589 protected Transaction importTPC(Object tpc) 590 { 591 if (tpc != null) 592 return tpcImporter.importTransactionPropagationContext(tpc); 593 return null; 594 } 595 596 600 public String getName() 601 { 602 return support.getName(); 603 } 604 605 public MBeanServer getServer() 606 { 607 return support.getServer(); 608 } 609 610 public int getState() 611 { 612 return support.getState(); 613 } 614 615 public String getStateString() 616 { 617 return support.getStateString(); 618 } 619 620 public void create() throws Exception 621 { 622 support.create(); 623 } 624 625 public void start() throws Exception 626 { 627 support.start(); 628 } 629 630 public void stop() 631 { 632 support.stop(); 633 } 634 635 public void destroy() 636 { 637 support.destroy(); 638 } 639 640 public void jbossInternalLifecycle(String method) throws Exception 641 { 642 support.jbossInternalLifecycle(method); 643 } 644 645 public ObjectName preRegister(MBeanServer server, ObjectName name) 646 throws Exception 647 { 648 return support.preRegister(server, name); 649 } 650 651 public void postRegister(Boolean registrationDone) 652 { 653 support.postRegister(registrationDone); 654 } 655 656 public void preDeregister() throws Exception 657 { 658 support.preDeregister(); 659 } 660 661 public void postDeregister() 662 { 663 support.postDeregister(); 664 } 665 666 interface TCLAction 667 { 668 class UTIL 669 { 670 static TCLAction getTCLAction() 671 { 672 return System.getSecurityManager() == null ? NON_PRIVILEGED : PRIVILEGED; 673 } 674 675 static ClassLoader getContextClassLoader() 676 { 677 return getTCLAction().getContextClassLoader(); 678 } 679 680 static ClassLoader getContextClassLoader(Thread thread) 681 { 682 return getTCLAction().getContextClassLoader(thread); 683 } 684 685 static void setContextClassLoader(ClassLoader cl) 686 { 687 getTCLAction().setContextClassLoader(cl); 688 } 689 690 static void setContextClassLoader(Thread thread, ClassLoader cl) 691 { 692 getTCLAction().setContextClassLoader(thread, cl); 693 } 694 } 695 696 TCLAction NON_PRIVILEGED = new TCLAction() 697 { 698 public ClassLoader getContextClassLoader() 699 { 700 return Thread.currentThread().getContextClassLoader(); 701 } 702 703 public ClassLoader getContextClassLoader(Thread thread) 704 { 705 return thread.getContextClassLoader(); 706 } 707 708 public void setContextClassLoader(ClassLoader cl) 709 { 710 Thread.currentThread().setContextClassLoader(cl); 711 } 712 713 public void setContextClassLoader(Thread thread, ClassLoader cl) 714 { 715 thread.setContextClassLoader(cl); 716 } 717 }; 718 719 TCLAction PRIVILEGED = new TCLAction() 720 { 721 private final PrivilegedAction getTCLPrivilegedAction = new PrivilegedAction () 722 { 723 public Object run() 724 { 725 return Thread.currentThread().getContextClassLoader(); 726 } 727 }; 728 729 public ClassLoader getContextClassLoader() 730 { 731 return (ClassLoader ) AccessController.doPrivileged(getTCLPrivilegedAction); 732 } 733 734 public ClassLoader getContextClassLoader(final Thread thread) 735 { 736 return (ClassLoader ) AccessController.doPrivileged(new PrivilegedAction () 737 { 738 public Object run() 739 { 740 return thread.getContextClassLoader(); 741 } 742 }); 743 } 744 745 public void setContextClassLoader(final ClassLoader cl) 746 { 747 AccessController.doPrivileged(new PrivilegedAction () 748 { 749 public Object run() 750 { 751 Thread.currentThread().setContextClassLoader(cl); 752 return null; 753 } 754 }); 755 } 756 757 public void setContextClassLoader(final Thread thread, final ClassLoader cl) 758 { 759 AccessController.doPrivileged(new PrivilegedAction () 760 { 761 public Object run() 762 { 763 thread.setContextClassLoader(cl); 764 return null; 765 } 766 }); 767 } 768 }; 769 770 ClassLoader getContextClassLoader(); 771 772 ClassLoader getContextClassLoader(Thread thread); 773 774 void setContextClassLoader(ClassLoader cl); 775 776 void setContextClassLoader(Thread thread, ClassLoader cl); 777 } 778 779 783 class MBeanServerAction implements PrivilegedExceptionAction 784 { 785 private ObjectName target; 786 String method; 787 Object [] args; 788 String [] sig; 789 790 MBeanServerAction() 791 { 792 } 793 794 MBeanServerAction(ObjectName target, String method, Object [] args, String [] sig) 795 { 796 this.target = target; 797 this.method = method; 798 this.args = args; 799 this.sig = sig; 800 } 801 802 public Object run() throws Exception 803 { 804 Object rtnValue = support.getServer().invoke(target, method, args, sig); 805 return rtnValue; 806 } 807 808 Object invoke(ObjectName target, String method, Object [] args, String [] sig) 809 throws Exception 810 { 811 SecurityManager sm = System.getSecurityManager(); 812 Object rtnValue = null; 813 if (sm == null) 814 { 815 rtnValue = support.getServer().invoke(target, method, args, sig); 817 } 818 else 819 { 820 try 821 { 822 MBeanServerAction action = new MBeanServerAction(target, method, args, sig); 824 rtnValue = AccessController.doPrivileged(action); 825 } 826 catch (PrivilegedActionException e) 827 { 828 Exception ex = e.getException(); 829 throw ex; 830 } 831 } 832 return rtnValue; 833 } 834 } 835 } 836 | Popular Tags |