1 23 package com.sun.ejb.containers; 24 25 import java.lang.reflect.Constructor ; 26 import java.lang.reflect.Method ; 27 28 import java.util.*; 29 import java.lang.reflect.InvocationTargetException ; 30 31 import javax.ejb.*; 32 33 import javax.ejb.MessageDriven ; 34 35 import javax.naming.InitialContext ; 36 import javax.naming.Context ; 37 38 import javax.transaction.*; 39 import javax.transaction.xa.*; 40 41 import com.sun.ejb.*; 42 43 import com.sun.ejb.containers.util.pool.Pool; 44 import com.sun.ejb.containers.util.pool.AbstractPool; 45 import com.sun.ejb.containers.util.pool.NonBlockingPool; 46 import com.sun.ejb.containers.util.pool.ObjectFactory; 47 import com.sun.enterprise.util.LocalStringManagerImpl; 48 import com.sun.enterprise.*; 49 import com.sun.enterprise.deployment.EjbDescriptor; 50 import com.sun.enterprise.deployment.MethodDescriptor; 51 import com.sun.enterprise.deployment.EjbMessageBeanDescriptor; 52 import static com.sun.enterprise.deployment.LifecycleCallbackDescriptor.CallbackType; 53 import com.sun.enterprise.deployment.runtime.BeanPoolDescriptor; 54 import com.sun.enterprise.server.ServerContext; 55 import com.sun.enterprise.server.ApplicationServer; 56 import com.sun.enterprise.config.serverbeans.ServerBeansFactory; 57 import com.sun.enterprise.config.serverbeans.MdbContainer; 58 import com.sun.enterprise.config.ConfigException; 59 import com.sun.enterprise.resource.ResourceHandle; 60 import com.sun.enterprise.log.Log; 61 import com.sun.enterprise.ServerConfiguration; 62 import com.sun.enterprise.admin.monitor.callflow.ComponentType; 63 64 import com.sun.enterprise.appverification.factory.AppVerification; 65 import com.sun.enterprise.admin.monitor.*; 66 import com.sun.ejb.containers.util.pool.AbstractPool; 67 68 import java.util.logging.*; 69 70 import com.sun.logging.*; 71 72 import com.sun.ejb.spi.stats.MessageDrivenBeanStatsProvider; 73 74 92 public final class MessageBeanContainer extends BaseContainer 93 implements MessageBeanProtocolManager, MessageDrivenBeanStatsProvider 94 { 95 private static Logger _logger; 96 static { 97 _logger=LogDomains.getLogger(LogDomains.MDB_LOGGER); 98 } 99 100 private String appEJBName_; 101 102 private static LocalStringManagerImpl localStrings = 103 new LocalStringManagerImpl(MessageBeanContainer.class); 104 105 private static final int POOLED=1, INVOKING=2, DESTROYED=3; 107 108 private MessageBeanClient messageBeanClient_ = null; 109 110 private AbstractPool messageBeanPool_ = null; 111 112 private BeanPoolDescriptor beanPoolDesc_ = null; 113 private int maxMessageBeanListeners_; 114 private int numMessageBeanListeners_; 115 116 private static final String MESSAGE_BEAN_CLIENT_FACTORY_PROP = 119 "com.sun.enterprise.MessageBeanClientFactory"; 120 121 private static final String DEFAULT_MESSAGE_BEAN_CLIENT_FACTORY = 122 "com.sun.enterprise.connectors.inflow.ConnectorMessageBeanClientFactory"; 123 124 private static final int DEFAULT_RESIZE_QUANTITY = 1; 125 private static final int DEFAULT_STEADY_SIZE = 10; 126 private static final int DEFAULT_MAX_POOL_SIZE = 60; 127 private static final int DEFAULT_IDLE_TIMEOUT = 600; 128 private static final int MIN_IDLE_TIMEOUT = 1; 129 130 private int statMessageCount = 0; 131 132 MessageBeanContainer(EjbDescriptor desc, ClassLoader loader) 133 throws Exception 134 { 135 super(desc, loader); 136 137 appEJBName_ = 138 desc.getApplication().getRegistrationName() + ":" +desc.getName(); 139 140 EjbMessageBeanDescriptor msgBeanDesc = 141 (EjbMessageBeanDescriptor) desc; 142 143 try { 144 145 Method [] msgListenerMethods = 151 msgBeanDesc.getMessageListenerInterfaceMethods(loader); 152 153 for(int i = 0; i < msgListenerMethods.length; i++) { 154 Method next = msgListenerMethods[i]; 155 super.registerTxAttrForMethod(next, MethodDescriptor.EJB_BEAN); 156 } 157 161 162 String factoryClassName = System.getProperty 169 (MESSAGE_BEAN_CLIENT_FACTORY_PROP, 170 DEFAULT_MESSAGE_BEAN_CLIENT_FACTORY); 171 172 Class clientFactoryClass = Class.forName(factoryClassName); 173 MessageBeanClientFactory clientFactory = (MessageBeanClientFactory) 174 clientFactoryClass.newInstance(); 175 176 _logger.log(Level.FINE, "Using " + factoryClassName + 177 " for message bean client factory in " + appEJBName_); 178 179 createMessageBeanPool(msgBeanDesc); 183 184 maxMessageBeanListeners_ = beanPoolDesc_.getMaxPoolSize(); 189 numMessageBeanListeners_ = 0; 190 191 messageBeanClient_ = 192 clientFactory.createMessageBeanClient(msgBeanDesc); 193 194 messageBeanClient_.setup(this); 195 196 registerMonitorableComponents(msgListenerMethods); 197 198 createCallFlowAgent(ComponentType.MDB); 199 } 200 catch (Exception ex) { 201 202 if (messageBeanClient_ != null) { 203 messageBeanClient_.close(); 204 } 205 206 _logger.log(Level.SEVERE, 207 "containers.mdb.create_container_exception", 208 new Object []{desc.getName(), ex.toString()}); 209 _logger.log(Level.SEVERE, ex.getClass().getName(), ex); 210 throw ex; 211 } 212 } 213 214 protected void registerMonitorableComponents(Method [] msgListenerMethods) { 215 registryMediator.registerProvider(this); 216 super.registerMonitorableComponents(); 217 super.populateMethodMonitorMap(msgListenerMethods); 218 _logger.log(Level.FINE, "[Entity Container] registered monitorable"); 219 } 220 221 private void createMessageBeanPool(EjbMessageBeanDescriptor descriptor) 222 throws ConfigException { 223 224 beanPoolDesc_ = descriptor.getIASEjbExtraDescriptors().getBeanPool(); 225 226 if (beanPoolDesc_ == null) { 227 beanPoolDesc_ = new BeanPoolDescriptor(); 228 } 229 230 ServerContext sc = ApplicationServer.getServerContext(); 231 MdbContainer mdbc = ServerBeansFactory. 232 getConfigBean(sc.getConfigContext()).getMdbContainer(); 233 234 int maxPoolSize = beanPoolDesc_.getMaxPoolSize(); 235 if (maxPoolSize < 0) { 236 maxPoolSize = 237 stringToInt(mdbc.getMaxPoolSize(), appEJBName_, _logger); 238 } 239 maxPoolSize = validateValue(maxPoolSize, 1, -1, DEFAULT_MAX_POOL_SIZE, 240 "max-pool-size", appEJBName_, _logger); 241 beanPoolDesc_.setMaxPoolSize(maxPoolSize); 242 243 int value = beanPoolDesc_.getSteadyPoolSize(); 244 if (value < 0) { 245 value = stringToInt 246 (mdbc.getSteadyPoolSize(), appEJBName_, _logger); 247 } 248 value = validateValue(value, 0, maxPoolSize, DEFAULT_STEADY_SIZE, 249 "steady-pool-size", appEJBName_, _logger); 250 beanPoolDesc_.setSteadyPoolSize(value); 251 252 value = beanPoolDesc_.getPoolResizeQuantity(); 253 if (value < 0 ) { 254 value = stringToInt 255 (mdbc.getPoolResizeQuantity(), appEJBName_, _logger); 256 } 257 value = validateValue(value, 1, maxPoolSize, DEFAULT_RESIZE_QUANTITY, 258 "pool-resize-quantity", appEJBName_, _logger); 259 beanPoolDesc_.setPoolResizeQuantity(value); 260 261 value = beanPoolDesc_.getPoolIdleTimeoutInSeconds(); 262 if (value <= 0) { 263 value = stringToInt(mdbc.getIdleTimeoutInSeconds(), 264 appEJBName_, _logger); 265 } 266 value = validateValue(value, MIN_IDLE_TIMEOUT, -1, 267 DEFAULT_IDLE_TIMEOUT, "idle-timeout-in-seconds", 268 appEJBName_, _logger); 269 beanPoolDesc_.setPoolIdleTimeoutInSeconds(value); 270 271 if (_logger.isLoggable(Level.FINE)) { 272 _logger.log(Level.FINE, appEJBName_ + 273 ": Setting message-driven bean pool max-pool-size=" + 274 beanPoolDesc_.getMaxPoolSize() + 275 ", steady-pool-size=" + beanPoolDesc_.getSteadyPoolSize() + 276 ", pool-resize-quantity=" + 277 beanPoolDesc_.getPoolResizeQuantity() + 278 ", idle-timeout-in-seconds=" + 279 beanPoolDesc_.getPoolIdleTimeoutInSeconds()); 280 } 281 282 ObjectFactory objFactory = new MessageBeanContextFactory(); 286 messageBeanPool_ = new NonBlockingPool 287 (appEJBName_, 288 objFactory, 289 beanPoolDesc_.getSteadyPoolSize(), 290 beanPoolDesc_.getPoolResizeQuantity(), 291 beanPoolDesc_.getMaxPoolSize(), 292 beanPoolDesc_.getPoolIdleTimeoutInSeconds(), 293 loader); 294 295 registryMediator.registerProvider(messageBeanPool_); 296 } 298 299 protected static int stringToInt(String val, String appName, 300 Logger logger) { 301 int value = -1; 302 try { 303 value = Integer.parseInt(val); 304 } catch (Exception e) { 305 _logger.log(Level.WARNING,"containers.mdb.invalid_value" , 306 new Object []{appName, new Integer (val) , e.toString(), 307 new Integer (0)} ); 308 _logger.log(Level.WARNING, "", e); 309 } 310 return value; 311 } 312 313 protected int validateValue(int value, int lowLimit, int highLimit, 315 int deft, String emsg, String appName, Logger logger) { 316 317 if (value < lowLimit ) { 318 _logger.log(Level.WARNING,"containers.mdb.invalid_value" , 319 new Object []{appName, new Integer (value) , emsg , 320 new Integer (lowLimit)} ); 321 value = deft; 322 } 323 324 if ((highLimit >= 0) && (value > highLimit)) { 325 _logger.log(Level.WARNING,"containers.mdb.invalid_value" , 326 new Object []{appName, new Integer (value) , emsg , 327 new Integer (highLimit)} ); 328 value = highLimit; 329 } 330 331 return value; 332 } 333 334 private boolean containerStartsTx(Method method) { 335 int txMode = getTxAttr(method, MethodDescriptor.EJB_BEAN); 336 337 return method.equals(ejbTimeoutMethod) ? 338 ( (txMode == TX_REQUIRES_NEW) || (txMode == TX_REQUIRED) ) 339 : (txMode == TX_REQUIRED); 340 } 341 342 public String getMonitorAttributeValues() { 343 StringBuffer sbuf = new StringBuffer (); 344 sbuf.append("MESSAGEDRIVEN "); 345 sbuf.append(appEJBName_); 346 347 sbuf.append(messageBeanPool_.getAllAttrValues()); 348 sbuf.append("]"); 349 return sbuf.toString(); 350 } 351 352 public boolean userTransactionMethodsAllowed(ComponentInvocation inv) 353 { 354 boolean utMethodsAllowed = false; 355 if( isBeanManagedTran ) { 356 if( inv instanceof Invocation ) { 357 Invocation i = (Invocation) inv; 358 EJBContextImpl mdc = (EJBContextImpl) i.context; 359 utMethodsAllowed = (mdc.isUnitialized() || mdc.isInEjbRemove()) 360 ? false : true; 361 } 362 } 363 return utMethodsAllowed; 364 } 365 366 public void setEJBHome(EJBHome ejbHome) 367 throws Exception 368 { 369 throw new Exception ("Can't set EJB Home on Message-driven bean"); 370 } 371 372 public EJBObjectImpl getEJBObjectImpl(byte[] instanceKey) 373 { 374 throw new EJBException("No EJBObject for message-driven beans"); 375 } 376 377 public EJBObjectImpl createEJBObjectImpl() 378 throws CreateException 379 { 380 throw new EJBException("No EJBObject for message-driven beans"); 381 } 382 383 void removeBean(EJBLocalRemoteObject ejbo, Method removeMethod, 384 boolean local) 385 throws RemoveException, EJBException 386 { 387 throw new EJBException("not used in message-driven beans"); 388 } 389 390 391 395 boolean callEJBTimeout(RuntimeTimerState timerState, 396 EJBTimerService timerService) throws Exception { 397 398 boolean redeliver = false; 399 400 ResourceHandle nullResourceHandle = null; 402 403 try { 404 405 beforeMessageDelivery(ejbTimeoutMethod, false, nullResourceHandle); 408 409 Object [] args = { new TimerWrapper(timerState.getTimerId(), 411 timerService) }; 412 413 deliverMessage(args); 414 415 } catch(Throwable t) { 416 redeliver = true; 421 422 _logger.log(Level.FINE, "ejbTimeout threw Runtime exception", t); 423 424 } finally { 425 if( !isBeanManagedTran && (transactionManager.getStatus() == 426 Status.STATUS_MARKED_ROLLBACK) ) { 427 redeliver = true; 428 _logger.log(Level.FINE, "ejbTimeout called setRollbackOnly"); 429 } 430 431 if( !redeliver ) { 433 boolean successfulPostEjbTimeout = 434 timerService.postEjbTimeout(timerState.getTimerId()); 435 redeliver = !successfulPostEjbTimeout; 436 } 437 438 boolean successfulAfterMessageDelivery = 442 afterMessageDeliveryInternal(nullResourceHandle); 443 if( !redeliver && !successfulAfterMessageDelivery) { 444 redeliver = true; 445 } 446 } 447 448 return redeliver; 449 } 450 451 452 457 void forceDestroyBean(EJBContextImpl sc) 458 { 459 if ( sc.getState() == DESTROYED ) 460 return; 461 462 sc.setState(DESTROYED); 464 465 messageBeanPool_.destroyObject(sc); 466 } 467 468 public void preInvoke(Invocation inv) { 470 throw new EJBException("preInvoke(Invocation) not supported"); 471 } 472 473 private class MessageBeanContextFactory implements ObjectFactory { 474 475 public Object create(Object param) { 476 try { 477 return createMessageDrivenEJB(); 478 } catch (CreateException ex) { 479 throw new EJBException(ex); 480 } 481 } 482 483 public void destroy(Object obj) { 484 485 MessageBeanContextImpl beanContext = 486 (MessageBeanContextImpl) obj; 487 488 Object ejb = beanContext.getEJB(); 489 490 if( beanContext.getState() != DESTROYED ) { 491 492 Invocation inv = null; 496 497 try { 498 500 inv = new Invocation(ejb, MessageBeanContainer.this); 501 inv.context = beanContext; 502 503 inv.isMessageDriven = true; 504 invocationManager.preInvoke(inv); 505 506 beanContext.setInEjbRemove(true); 507 interceptorManager.intercept( 508 CallbackType.PRE_DESTROY, beanContext); 509 statRemoveCount++; 510 } catch ( Throwable t ) { 511 _logger.log(Level.SEVERE, 512 "containers.mdb_preinvoke_exception_indestroy", 513 new Object []{appEJBName_, t.toString()}); 514 _logger.log(Level.SEVERE, t.getClass().getName(), t); 515 } finally { 516 beanContext.setInEjbRemove(false); 517 if ( inv != null ) { 518 invocationManager.postInvoke(inv); 519 } 520 } 521 522 beanContext.setState(DESTROYED); 523 524 } 525 526 transactionManager.ejbDestroyed(beanContext); 528 529 beanContext.setTransaction(null); 532 } 533 534 } 535 536 protected ComponentContext _getContext(Invocation inv) 537 { 538 MessageBeanContextImpl context = null; 539 try { 540 context = (MessageBeanContextImpl) messageBeanPool_.getObject(null); 541 context.setState(INVOKING); 542 } catch(Exception e) { 543 throw new EJBException(e); 544 } 545 return context; 546 } 547 548 551 public void releaseContext(Invocation inv) 552 { 553 MessageBeanContextImpl beanContext = (MessageBeanContextImpl) 554 inv.context; 555 556 if( beanContext.getState() == DESTROYED ) { 557 return; 558 } 559 560 beanContext.setState(POOLED); 561 562 beanContext.setTransaction(null); 564 565 beanContext.touch(); 567 568 messageBeanPool_.returnObject(beanContext); 569 } 570 571 public void appendStats(StringBuffer sbuf) { 572 sbuf.append("\nMessageBeanContainer: ") 573 .append("CreateCount=").append(statCreateCount).append("; ") 574 .append("RemoveCount=").append(statRemoveCount).append("; ") 575 .append("MsgCount=").append(statMessageCount).append("; "); 576 sbuf.append("]"); 577 } 578 579 public void postInvoke(Invocation inv) { 581 throw new EJBException("postInvoke(Invocation) not supported " + 582 "in message-driven bean container"); 583 } 584 585 589 590 public MessageBeanListener createMessageBeanListener 591 (ResourceHandle resource) throws ResourcesExceededException { 592 593 boolean resourcesExceeded = false; 594 595 synchronized (this) { 596 if( numMessageBeanListeners_ < maxMessageBeanListeners_ ) { 597 numMessageBeanListeners_++; 598 } else { 599 resourcesExceeded = true; 600 } 601 } 602 603 if( resourcesExceeded ) { 604 ResourcesExceededException ree = 605 new ResourcesExceededException("Message Bean Resources " + 606 "exceeded for message bean " + appEJBName_); 607 _logger.log(Level.FINE, "exceeded max of " + 608 maxMessageBeanListeners_, ree); 609 throw ree; 610 } 611 612 return new MessageBeanListenerImpl(this, resource); 632 } 633 634 public void destroyMessageBeanListener(MessageBeanListener listener) { 635 synchronized (this) { 636 numMessageBeanListeners_--; 637 } 638 } 639 640 647 public boolean isDeliveryTransacted (Method method) { 648 return containerStartsTx(method); 649 } 650 651 public BeanPoolDescriptor getPoolDescriptor() { 652 return beanPoolDesc_; 653 } 654 655 658 private MessageBeanContextImpl createMessageDrivenEJB() 659 throws CreateException { 660 661 Invocation inv = null; 662 MessageBeanContextImpl context = null; 663 ClassLoader originalClassLoader = null; 664 boolean methodCalled = false; 665 boolean methodCallFailed = false; 666 667 try { 668 originalClassLoader = setContextClassLoader(getClassLoader()); 670 671 Object ejb = ejbClass.newInstance(); 673 674 context = new MessageBeanContextImpl(ejb, this); 676 context.setInterceptorInstances( 677 interceptorManager.createInterceptorInstances()); 678 679 inv = new Invocation(ejb, this); 681 inv.context = context; 682 683 inv.isMessageDriven = true; 684 invocationManager.preInvoke(inv); 685 686 if( ejb instanceof MessageDrivenBean ) { 687 ((MessageDrivenBean)ejb).setMessageDrivenContext(context); 690 } 691 692 injectionManager.injectInstance(ejb, ejbDescriptor, false); 697 for (Object interceptorInstance : context.getInterceptorInstances()) { 698 injectionManager.injectInstance(interceptorInstance, 699 ejbDescriptor, false); 700 } 701 702 context.setContextCalled(); 709 710 interceptorManager.intercept( 712 CallbackType.POST_CONSTRUCT, context); 713 714 statCreateCount++; 715 716 context.setState(POOLED); 719 } 720 catch ( Throwable t ) { 721 _logger.log(Level.SEVERE, 722 "containers.mdb.ejb_creation_exception", 723 new Object []{appEJBName_, t.toString()}); 724 if (t instanceof InvocationTargetException ) { 725 _logger.log(Level.SEVERE, t.getClass().getName(), 726 t.getCause()); 727 } 728 _logger.log(Level.SEVERE, t.getClass().getName(), t); 729 730 CreateException ce = 731 new CreateException("Could not create Message-Driven EJB"); 732 ce.initCause(t); 733 throw ce; 734 735 } finally { 736 if( originalClassLoader != null ) { 737 setContextClassLoader(originalClassLoader); 738 } 739 if ( inv != null ) { 740 invocationManager.postInvoke(inv); 741 } 742 } 743 744 return context; 745 } 746 747 751 private void registerMessageBeanResource(ResourceHandle resourceHandle) 752 throws Exception { 753 if( resourceHandle != null ) { 754 Switch theSwitch = Switch.getSwitch(); 755 PoolManager poolMgr = theSwitch.getPoolManager(); 756 poolMgr.registerResource(resourceHandle); 757 } 758 } 759 760 private void unregisterMessageBeanResource(ResourceHandle resourceHandle) { 761 762 if (resourceHandle != null) { 765 Switch theSwitch = Switch.getSwitch(); 766 PoolManager poolMgr = theSwitch.getPoolManager(); 767 poolMgr.unregisterResource(resourceHandle, XAResource.TMSUCCESS); 768 } 769 } 770 771 void afterBegin(EJBContextImpl context) 772 { 773 } 775 776 void beforeCompletion(EJBContextImpl context) 777 { 778 } 780 781 void afterCompletion(EJBContextImpl ctx, int status) 782 { 783 } 785 786 public boolean passivateEJB(ComponentContext context) 788 { 789 return false; 790 } 791 792 public void activateEJB(Object ctx, Object instanceKey) 794 { 795 } 796 797 801 public void doAfterApplicationDeploy() { 802 super.doAfterApplicationDeploy(); 803 804 try { 806 messageBeanClient_.start(); 807 808 } 809 catch(Exception e) { 810 _logger.log(Level.SEVERE, 811 "containers.mdb.start_message_delivery_exception", 812 new Object []{appEJBName_, e.toString()}); 813 _logger.log(Level.SEVERE, e.getClass().getName(), e); 814 } 815 } 816 817 private void cleanupResources() { 818 819 try { 821 messageBeanClient_.close(); 822 } 823 catch(Exception e) { 824 _logger.log(Level.SEVERE, "containers.mdb.cleanup_exception", 825 new Object []{appEJBName_, e.toString()}); 826 _logger.log(Level.SEVERE, e.getClass().getName(), e); 827 } 828 829 messageBeanPool_.close(); 830 } 831 832 833 public void undeploy() 834 { 835 super.setUndeployedState(); 837 838 _logger.log(Level.FINE, "containers.mdb.undeploy", appEJBName_); 839 840 cleanupResources(); 841 842 super.undeploy(); 843 } 844 845 848 public void onShutdown() { 849 _logger.log(Level.FINE, 850 "containers.mdb.shutdown_cleanup_start", appEJBName_); 851 setStoppedState(); 852 monitorOn = false; 853 cleanupResources(); 854 _logger.log(Level.FINE, 855 "containers.mdb.shutdown_cleanup_end", appEJBName_); 856 } 857 858 876 877 public void beforeMessageDelivery(Method method, boolean txImported, 878 ResourceHandle resourceHandle) { 879 880 881 if (containerState != CONTAINER_STARTED) { String errorMsg = localStrings.getLocalString 883 ("containers.mdb.invocation_closed", appEJBName_ + 884 ": Message-driven bean invocation closed by container", 885 new Object [] { appEJBName_ }); 886 887 throw new EJBException(errorMsg); 888 } 889 890 Invocation invocation = new Invocation(); 891 892 try { 893 894 MessageBeanContextImpl context = 895 (MessageBeanContextImpl) getContext(invocation); 896 897 902 invocation.originalContextClassLoader = 903 setContextClassLoader(getClassLoader()); 904 invocation.isMessageDriven = true; 905 invocation.method = method; 906 907 context.setState(INVOKING); 908 909 invocation.context = context; 910 invocation.instance = context.getEJB(); 911 invocation.ejb = context.getEJB(); 912 invocation.container = this; 913 914 boolean startTx = false; 919 if( !txImported ) { 920 startTx = containerStartsTx(method); 921 } 922 923 invocation.containerStartsTx = startTx; 925 926 this.invocationManager.preInvoke(invocation); 927 928 if( startTx ) { 929 registerMessageBeanResource(resourceHandle); 933 } 934 935 preInvokeTx(invocation); 936 937 } catch(Throwable c) { 938 if (containerState != CONTAINER_STARTED ) { 939 _logger.log(Level.SEVERE,"containers.mdb.preinvoke_exception", 940 new Object []{appEJBName_, c.toString()}); 941 _logger.log(Level.SEVERE, c.getClass().getName(), c); 942 } 943 invocation.exception = c; 944 } 945 } 946 947 public Object deliverMessage(Object [] params) throws Throwable { 948 949 Invocation invocation = null; 950 boolean methodCalled = false; Object result = null; 952 953 invocation = (Invocation) invocationManager.getCurrentInvocation(); 954 955 if (invocation == null && _logger.isLoggable(Level.FINEST)) { 956 if (containerState != CONTAINER_STARTED) { 957 _logger.log(Level.FINEST, "No invocation in onMessage " + 958 " (container closing)"); 959 } 960 else { 961 _logger.log(Level.FINEST, "No invocation in onMessage : "); 962 } 963 } 964 965 if( ( invocation != null ) && ( invocation.exception == null ) ) { 966 967 try { 968 969 972 methodCalled = true; 973 if (ejbMethodStatsManager.isMethodMonitorOn()){ 974 ejbMethodStatsManager.preInvoke(invocation.method); 975 } 976 977 invocation.methodParams = params; 978 979 if( isTimedObject() && 980 invocation.method.equals(ejbTimeoutMethod) ) { 981 invocation.beanMethod = invocation.method; 982 invokeTargetBeanMethod(ejbTimeoutMethod, invocation, 983 invocation.ejb, 984 invocation.methodParams, null); 985 } else { 986 993 invocation.beanMethod = invocation.ejb.getClass().getMethod 994 (invocation.method.getName(), 995 invocation.method.getParameterTypes()); 996 997 result = super.intercept(invocation); 998 } 999 1000 } catch(InvocationTargetException ite) { 1001 1002 1026 Throwable cause = ite.getCause(); 1027 invocation.exception = cause; 1030 1031 if( isSystemUncheckedException(cause) ) { 1032 EJBException ejbEx = new EJBException 1033 ("message-driven bean method " + invocation.method + 1034 " system exception"); 1035 ejbEx.initCause(cause); 1036 cause = ejbEx; 1037 } 1038 throw cause; 1039 } catch(Throwable t) { 1040 EJBException ejbEx = 1041 new EJBException("message-bean container dispatch error"); 1042 ejbEx.initCause(t); 1043 invocation.exception = ejbEx; 1044 throw ejbEx; 1045 } finally { 1046 if (methodCalled && (ejbMethodStatsManager.isMethodMonitorOn())) { 1047 ejbMethodStatsManager.postInvoke( 1048 invocation.method, invocation.exception); 1049 } 1050 1051 if ( AppVerification.doInstrument() ) { 1052 AppVerification.getInstrumentLogger().doInstrumentForEjb 1053 (getEjbDescriptor(), invocation.method, 1054 invocation.exception); 1055 } 1056 } 1057 1058 } else { 1060 if (invocation == null) { 1061 String errorMsg = localStrings.getLocalString 1062 ("containers.mdb.invocation_closed", 1063 appEJBName_ + ": Message-driven bean invocation " + 1064 "closed by container", new Object [] { appEJBName_}); 1065 throw new EJBException(errorMsg); 1066 } 1067 else { 1068 _logger.log(Level.SEVERE, 1069 "containers.mdb.invocation_exception", 1070 new Object []{appEJBName_, invocation.exception.toString()}); 1071 _logger.log(Level.SEVERE, invocation.exception.getClass(). 1072 getName(), invocation.exception); 1073 EJBException ejbEx = new EJBException(); 1074 ejbEx.initCause(invocation.exception); 1075 throw ejbEx; 1076 } 1077 } 1078 1079 return result; 1080 } 1081 1082 public void afterMessageDelivery(ResourceHandle resourceHandle) { 1083 afterMessageDeliveryInternal(resourceHandle); 1084 } 1085 1086 private boolean afterMessageDeliveryInternal(ResourceHandle resourceHandle) 1087 { 1088 boolean success = false; 1090 1091 Invocation invocation = null; 1092 1093 invocation = (Invocation) invocationManager.getCurrentInvocation(); 1094 if (invocation == null) { 1095 _logger.log(Level.SEVERE, "containers.mdb.no_invocation", 1096 new Object []{appEJBName_, ""}); 1097 } else { 1098 MessageBeanContextImpl beanContext = 1099 (MessageBeanContextImpl) invocation.context; 1100 1101 try { 1102 if( invocation.containerStartsTx ) { 1103 unregisterMessageBeanResource(resourceHandle); 1106 } 1107 1108 invocationManager.postInvoke(invocation); 1110 1111 postInvokeTx(invocation); 1113 1114 success = true; 1117 1118 statMessageCount++; 1120 1121 } catch(Throwable ce) { 1122 _logger.log(Level.SEVERE, 1123 "containers.mdb.postinvoke_exception", 1124 new Object []{appEJBName_, ce.toString()}); 1125 _logger.log(Level.SEVERE,ce.getClass().getName(), ce); 1126 } finally { 1127 releaseContext(invocation); 1128 } 1129 1130 setContextClassLoader(invocation.originalContextClassLoader); 1132 1133 if( invocation.exception != null ) { 1134 1135 if( isSystemUncheckedException(invocation.exception) ) { 1136 success = false; 1137 } 1138 1139 Level exLogLevel = 1142 isSystemUncheckedException(invocation.exception) ? 1143 Level.INFO : Level.FINE; 1144 1145 _logger.log(exLogLevel, 1147 "containers.mdb.invocation_exception", 1148 new Object []{appEJBName_, 1149 invocation.exception.toString()}); 1150 _logger.log(exLogLevel, invocation.exception.getClass(). 1151 getName(), invocation.exception); 1152 } 1153 } 1154 1155 return success; 1156 } 1157 1158 1162 private ClassLoader setContextClassLoader(ClassLoader newClassLoader) { 1163 1164 final ClassLoader classLoaderToSet = newClassLoader; 1166 1167 final Thread currentThread = Thread.currentThread(); 1168 ClassLoader originalClassLoader = 1169 currentThread.getContextClassLoader(); 1170 1171 java.security.AccessController.doPrivileged 1172 (new java.security.PrivilegedAction () { 1173 public java.lang.Object run() { 1174 currentThread.setContextClassLoader(classLoaderToSet); 1175 return null; 1176 } 1177 }); 1178 return originalClassLoader; 1179 } 1180 1181 public long getCreateCount() { 1182 return statCreateCount; 1183 } 1184 1185 public long getRemoveCount() { 1186 return statRemoveCount; 1187 } 1188 1189 public long getMessageCount() { 1190 return statMessageCount; 1191 } 1192 1193} 1194 | Popular Tags |