1 22 package org.jboss.ejb3.service; 23 24 import java.lang.reflect.Method ; 25 import java.util.Hashtable ; 26 27 import javax.ejb.EJBException ; 28 import javax.ejb.Handle ; 29 import javax.ejb.Timer ; 30 import javax.ejb.TimerService ; 31 import javax.management.Attribute ; 32 import javax.management.AttributeList ; 33 import javax.management.AttributeNotFoundException ; 34 import javax.management.InstanceNotFoundException ; 35 import javax.management.InvalidAttributeValueException ; 36 import javax.management.MBeanException ; 37 import javax.management.MBeanInfo ; 38 import javax.management.MBeanRegistrationException ; 39 import javax.management.MBeanServer ; 40 import javax.management.ObjectName ; 41 import javax.management.ReflectionException ; 42 43 import org.jboss.annotation.ejb.Management; 44 import org.jboss.annotation.ejb.Service; 45 import org.jboss.aop.AspectManager; 46 import org.jboss.aop.MethodInfo; 47 import org.jboss.aop.advice.Interceptor; 48 import org.jboss.aop.joinpoint.Invocation; 49 import org.jboss.aop.joinpoint.InvocationResponse; 50 import org.jboss.aop.joinpoint.MethodInvocation; 51 import org.jboss.aop.util.MethodHashing; 52 import org.jboss.aop.util.PayloadKey; 53 import org.jboss.aspects.asynch.FutureHolder; 54 import org.jboss.ejb.AllowedOperationsAssociation; 55 import org.jboss.ejb.AllowedOperationsFlags; 56 import org.jboss.ejb3.BeanContext; 57 import org.jboss.ejb3.EJBContainerInvocation; 58 import org.jboss.ejb3.Ejb3Deployment; 59 import org.jboss.ejb3.ProxyFactory; 60 import org.jboss.ejb3.SessionContainer; 61 import org.jboss.ejb3.ThreadLocalENCFactory; 62 import org.jboss.ejb3.asynchronous.AsynchronousInterceptor; 63 import org.jboss.ejb3.interceptor.InterceptorInfoRepository; 64 import org.jboss.ejb3.timerservice.TimedObjectInvoker; 65 import org.jboss.ejb3.timerservice.TimerServiceFactory; 66 import org.jboss.logging.Logger; 67 import org.jboss.injection.Injector; 68 69 73 public class ServiceContainer extends SessionContainer implements TimedObjectInvoker 74 { 75 ServiceMBeanDelegate delegate; 76 Object singleton; 77 boolean injected; 78 BeanContext beanContext; 79 MBeanServer mbeanServer; 80 ObjectName delegateObjectName; 81 private TimerService timerService; 82 83 @SuppressWarnings ("unused") 84 private static final Logger log = Logger.getLogger(ServiceContainer.class); 85 86 public ServiceContainer(MBeanServer server, ClassLoader cl, String beanClassName, String ejbName, 87 AspectManager manager, Hashtable ctxProperties, InterceptorInfoRepository interceptorRepository, 88 Ejb3Deployment deployment) 89 { 90 super(cl, beanClassName, ejbName, manager, ctxProperties, interceptorRepository, deployment); 91 beanContextClass = ServiceBeanContext.class; 92 this.mbeanServer = server; 93 } 94 95 public void callTimeout(Timer timer) throws Exception 96 { 97 Method timeout = callbackHandler.getTimeoutCallback(); 98 if (timeout == null) throw new EJBException ("No method has been annotated with @Timeout"); 99 Object [] args = {timer}; 100 AllowedOperationsAssociation.pushInMethodFlag(AllowedOperationsFlags.IN_EJB_TIMEOUT); 101 try 102 { 103 localInvoke(timeout, args); 104 } 105 catch(Throwable throwable) 106 { 107 if (throwable instanceof Exception ) throw (Exception ) throwable; 108 if(throwable instanceof Error ) throw (Error ) throwable; 109 throw new RuntimeException (throwable); 110 } 111 finally 112 { 113 AllowedOperationsAssociation.popInMethodFlag(); 114 } 115 } 116 117 protected Object createSession(Class initTypes[], Object initArgs[]) 118 { 119 throw new RuntimeException ("NYI"); 122 } 123 124 public Object getSingleton() 125 { 126 return singleton; 127 } 128 129 public void create() throws Exception 130 { 131 super.create(); 132 133 singleton = super.construct(); 135 136 139 invokeOptionalMethod("create"); 140 } 141 142 143 public void start() throws Exception 144 { 145 super.start(); 146 147 try 148 { 149 initBeanContext(); 150 151 timerService = TimerServiceFactory.getInstance().createTimerService(this.getObjectName(), this); 153 154 injectDependencies(beanContext); 155 156 registerManagementInterface(); 158 159 TimerServiceFactory.getInstance().restoreTimerService(timerService); 160 161 invokeOptionalMethod("start"); 162 } 163 catch (Exception e) 164 { 165 e.printStackTrace(); 166 stop(); 167 } 168 } 169 170 public void stop() throws Exception 171 { 172 invokeOptionalMethod("stop"); 173 174 if (timerService != null) TimerServiceFactory.getInstance().removeTimerService(timerService); 175 176 unregisterManagementInterface(); 178 179 super.stop(); 180 181 injected = false; 182 } 183 184 public void destroy() throws Exception 185 { 186 invokeOptionalMethod("destroy"); 187 188 190 super.destroy(); 191 } 192 193 public void initializePool() throws Exception 194 { 195 resolveInjectors(); 196 } 197 198 public TimerService getTimerService() 199 { 200 return timerService; 201 } 202 203 public TimerService getTimerService(Object pKey) 204 { 205 assert timerService != null : "Timer Service not yet initialized"; 206 return timerService; 207 } 208 209 214 private void invokeOptionalMethod(String methodName) 215 { 216 247 } 248 249 public void invokePostConstruct(BeanContext beanContext) 250 { 251 } 253 254 public void invokePreDestroy(BeanContext beanContext) 255 { 256 } 258 259 public void invokeInit(Object bean) 260 { 261 } 263 264 267 public Object localInvoke(Method method, Object [] args) throws Throwable 268 { 269 return localInvoke(method, args, null); 270 } 271 272 277 public Object localInvoke(Method method, Object [] args, FutureHolder provider) throws Throwable 278 { 279 long start = System.currentTimeMillis(); 280 281 ClassLoader oldLoader = Thread.currentThread().getContextClassLoader(); 282 try 283 { 284 invokeStats.callIn(); 285 286 Thread.currentThread().setContextClassLoader(classloader); 287 long hash = MethodHashing.calculateHash(method); 288 MethodInfo info = (MethodInfo) methodInterceptors.get(hash); 289 if (info == null) 290 { 291 throw new RuntimeException ("Could not resolve beanClass method from proxy call: " + method.toString()); 292 } 293 Interceptor[] aspects = info.getInterceptors(); 294 EJBContainerInvocation nextInvocation = new EJBContainerInvocation(info, aspects); 295 nextInvocation.setAdvisor(this); 296 nextInvocation.setArguments(args); 297 298 nextInvocation = populateInvocation(nextInvocation); 299 300 if (provider != null) 301 { 302 nextInvocation.getMetaData().addMetaData(AsynchronousInterceptor.ASYNCH, AsynchronousInterceptor.INVOKE_ASYNCH, "YES", PayloadKey.AS_IS); 303 nextInvocation.getMetaData().addMetaData(AsynchronousInterceptor.ASYNCH, AsynchronousInterceptor.FUTURE_HOLDER, provider, PayloadKey.AS_IS); 304 } 305 return nextInvocation.invokeNext(); 306 } 307 finally 308 { 309 if (method != null) 310 { 311 long end = System.currentTimeMillis(); 312 long elapsed = end - start; 313 invokeStats.updateStats(method, elapsed); 314 } 315 316 invokeStats.callOut(); 317 318 Thread.currentThread().setContextClassLoader(oldLoader); 319 } 320 } 321 322 public InvocationResponse dynamicInvoke(Object target, Invocation invocation) throws Throwable 323 { 324 long start = System.currentTimeMillis(); 325 326 ClassLoader oldLoader = Thread.currentThread().getContextClassLoader(); 327 EJBContainerInvocation newSi = null; 328 329 MethodInvocation si = (MethodInvocation) invocation; 330 MethodInfo info = (MethodInfo) methodInterceptors.get(si.getMethodHash()); 331 Method method = info.getUnadvisedMethod(); 332 try 333 { 334 invokeStats.callIn(); 335 336 Thread.currentThread().setContextClassLoader(classloader); 337 338 if (info == null) 339 { 340 throw new RuntimeException ("Could not resolve beanClass method from proxy call"); 341 } 342 Interceptor[] aspects = info.getInterceptors(); 343 newSi = new EJBContainerInvocation(info, aspects); 344 newSi.setArguments(si.getArguments()); 345 newSi.setMetaData(si.getMetaData()); 346 newSi.setAdvisor(this); 347 348 newSi = populateInvocation(newSi); 349 350 Object rtn = null; 351 try 352 { 353 rtn = newSi.invokeNext(); 354 } 355 catch (Throwable throwable) 356 { 357 return marshallException(invocation, throwable, newSi.getResponseContextInfo()); 358 } 359 InvocationResponse response = SessionContainer.marshallResponse(invocation, rtn, newSi.getResponseContextInfo()); 360 361 return response; 362 } 363 finally 364 { 365 if (method != null) 366 { 367 long end = System.currentTimeMillis(); 368 long elapsed = end - start; 369 invokeStats.updateStats(method, elapsed); 370 } 371 372 invokeStats.callOut(); 373 374 Thread.currentThread().setContextClassLoader(oldLoader); 375 } 376 } 377 378 protected void initBeanContext() throws RuntimeException 379 { 380 if (beanContext == null) 381 { 382 synchronized(singleton) 383 { 384 if (beanContext == null) 385 { 386 try 387 { 388 beanContext = (BeanContext) beanContextClass.newInstance(); 389 beanContext.setContainer(this); 390 beanContext.initialiseInterceptorInstances(); 391 beanContext.setInstance(singleton); 392 } 393 catch (InstantiationException e) 394 { 395 throw new RuntimeException (e); } 397 catch (IllegalAccessException e) 398 { 399 throw new RuntimeException (e); } 401 } 402 } 403 } 404 } 405 406 @Override 407 protected EJBContainerInvocation populateInvocation(EJBContainerInvocation invocation) 408 { 409 invocation.setTargetObject(singleton); 410 invocation.setBeanContext(beanContext); 411 return invocation; 412 } 413 414 protected synchronized void injectDependencies(BeanContext ctx) 415 { 416 if (injectors != null) 417 { 418 try 419 { 420 ThreadLocalENCFactory.push(enc); 421 for (Injector injector : injectors) 422 { 423 injector.inject(ctx); 424 } 425 } 426 finally 427 { 428 ThreadLocalENCFactory.pop(); 429 } 430 } 431 injected = true; 432 } 433 434 436 public Object getAttribute(String attribute) throws AttributeNotFoundException , 437 MBeanException , ReflectionException 438 { 439 return delegate.getAttribute(attribute); 440 } 441 442 public void setAttribute(Attribute attribute) throws AttributeNotFoundException , 443 InvalidAttributeValueException , MBeanException , ReflectionException 444 { 445 delegate.setAttribute(attribute); 446 } 447 448 public AttributeList getAttributes(String [] attributes) 449 { 450 return delegate.getAttributes(attributes); 451 } 452 453 public AttributeList setAttributes(AttributeList attributes) 454 { 455 return delegate.setAttributes(attributes); 456 } 457 458 public Object invoke(String actionName, Object params[], String signature[]) 459 throws MBeanException , ReflectionException 460 { 461 return delegate.invoke(actionName, params, signature); 462 } 463 464 @Override 465 protected Object invokeEJBObjectMethod(ProxyFactory factory, Object id, MethodInfo info, Object [] args) throws Exception 466 { 467 throw new RuntimeException ("NYI"); 468 } 469 470 public MBeanInfo getMBeanInfo() 471 { 472 return delegate.getMBeanInfo(); 473 } 474 475 476 private void registerManagementInterface() 477 { 478 try 479 { 480 Management annotation = (Management)resolveAnnotation(Management.class); 481 482 Class intf = null; 483 if (annotation != null) 484 intf = annotation.value(); 485 486 if (intf ==null) 487 { 488 Class [] interfaces = this.getBeanClass().getInterfaces(); 489 int interfaceIndex = 0; 490 while (intf == null && interfaceIndex < interfaces.length) 491 { 492 if (interfaces[interfaceIndex].getAnnotation(Management.class) != null) 493 intf = interfaces[interfaceIndex]; 494 else 495 ++interfaceIndex; 496 } 497 } 498 499 if (intf != null) 500 { 501 if (mbeanServer == null) 502 mbeanServer = org.jboss.mx.util.MBeanServerLocator.locateJBoss(); 503 504 if (mbeanServer == null) 505 throw new RuntimeException ("There is a @Management interface on " + ejbName + " but the MBeanServer has not been initialized for it"); 506 507 Service service = (Service )resolveAnnotation(Service .class); 508 509 String objname = service.objectName(); 510 delegateObjectName = (objname == null || objname.equals("")) ? 511 new ObjectName (getObjectName().getCanonicalName() + ",type=ManagementInterface") : new ObjectName (service.objectName()); 512 513 delegate = new ServiceMBeanDelegate(mbeanServer, this, intf, delegateObjectName); 514 515 Object securityDomainAnnotation = resolveAnnotation(org.jboss.annotation.security.SecurityDomain.class); 516 517 getDeployment().getKernelAbstraction().installMBean(delegateObjectName, getDependencyPolicy(), delegate); 518 } 519 } 520 catch (Exception e) 521 { 522 throw new RuntimeException ("Problem registering @Management interface for @Service " + getBeanClass(), e); 523 } 524 } 525 526 private void unregisterManagementInterface() throws InstanceNotFoundException , MBeanRegistrationException 527 { 528 if (delegate != null) 529 { 530 getDeployment().getKernelAbstraction().uninstallMBean(delegateObjectName); 531 } 532 } 533 534 protected void removeHandle(Handle handle) 535 { 536 throw new RuntimeException ("Don't do this"); 537 } 538 } 539 | Popular Tags |