1 22 package org.jboss.ejb; 23 24 import java.lang.reflect.Method ; 25 import java.lang.reflect.InvocationTargetException ; 26 import java.util.Map ; 27 import java.util.HashMap ; 28 import java.util.Hashtable ; 29 import java.util.Set ; 30 import java.rmi.RemoteException ; 31 32 import javax.ejb.EJBObject ; 33 import javax.ejb.EJBLocalObject ; 34 import javax.ejb.RemoveException ; 35 import javax.ejb.EJBException ; 36 import javax.ejb.Handle ; 37 import javax.management.ObjectName ; 38 39 import org.jboss.invocation.Invocation; 40 import org.jboss.invocation.InvocationType; 41 import org.jboss.util.UnreachableStatementException; 42 43 54 55 public class StatefulSessionContainer 56 extends SessionContainer 57 implements EJBProxyFactoryContainer, InstancePoolContainer 58 { 59 62 protected StatefulSessionPersistenceManager persistenceManager; 63 64 67 protected InstanceCache instanceCache; 68 protected Method getEJBObject; 69 70 public void setInstanceCache(InstanceCache ic) 71 { 72 this.instanceCache = ic; 73 ic.setContainer(this); 74 } 75 76 public InstanceCache getInstanceCache() 77 { 78 return instanceCache; 79 } 80 81 public StatefulSessionPersistenceManager getPersistenceManager() 82 { 83 return persistenceManager; 84 } 85 86 public void setPersistenceManager(StatefulSessionPersistenceManager pm) 87 { 88 persistenceManager = pm; 89 pm.setContainer(this); 90 } 91 92 101 public Set getMethodPermissions(Method m, InvocationType iface) 102 { 103 if (m.equals(getEJBObject) == false) 104 return super.getMethodPermissions(m, iface); 105 106 Class [] sig = {}; 107 Set permissions = getBeanMetaData().getMethodPermissions("create", 108 sig, iface); 109 return permissions; 110 } 111 112 protected void createService() throws Exception 114 { 115 super.createService(); 116 try 118 { 119 getEJBObject = Handle .class.getMethod("getEJBObject", 120 new Class [0]); 121 } 122 catch (Exception e) 123 { 124 log.warn("Failed to grant access to the Handle.getEJBObject method"); 125 } 126 } 127 128 131 protected void createInstanceCache() throws Exception 132 { 133 try 135 { 136 ObjectName containerName = super.getJmxName(); 137 Hashtable props = containerName.getKeyPropertyList(); 138 props.put("plugin", "cache"); 139 ObjectName cacheName = new ObjectName (containerName.getDomain(), props); 140 server.registerMBean(instanceCache, cacheName); 141 } 142 catch (Throwable t) 143 { 144 log.debug("Failed to register cache as mbean", t); 145 } 146 instanceCache.create(); 148 } 149 150 153 protected void createPersistenceManager() throws Exception 154 { 155 persistenceManager.create(); 156 } 157 158 161 protected void startPersistenceManager() throws Exception 162 { 163 persistenceManager.start(); 164 } 165 166 169 protected void startInstanceCache() throws Exception 170 { 171 instanceCache.start(); 172 } 173 174 177 protected void stopPersistenceManager() 178 { 179 persistenceManager.stop(); 180 } 181 182 185 protected void stopInstanceCache() 186 { 187 instanceCache.stop(); 188 } 189 190 protected void destroyPersistenceManager() 191 { 192 persistenceManager.destroy(); 194 persistenceManager.setContainer(null); 195 } 196 197 protected void destroyInstanceCache() 198 { 199 instanceCache.destroy(); 201 instanceCache.setContainer(null); 202 try 203 { 204 ObjectName containerName = super.getJmxName(); 205 Hashtable props = containerName.getKeyPropertyList(); 206 props.put("plugin", "cache"); 207 ObjectName cacheName = new ObjectName (containerName.getDomain(), props); 208 server.unregisterMBean(cacheName); 209 } 210 catch (Throwable ignore) 211 { 212 } 213 } 214 215 217 public void remove(Invocation mi) 218 throws RemoteException , RemoveException 219 { 220 224 StatefulSessionEnterpriseContext ctx = (StatefulSessionEnterpriseContext) mi.getEnterpriseContext(); 226 if (ctx.getId() == null) 227 { 228 throw new RemoveException ("SFSB has been removed already"); 229 } 230 231 try 233 { 234 AllowedOperationsAssociation.pushInMethodFlag(IN_EJB_REMOVE); 235 getPersistenceManager().removeSession(ctx); 236 } 237 finally 238 { 239 AllowedOperationsAssociation.popInMethodFlag(); 240 } 241 242 ctx.setId(null); 244 removeCount++; 245 } 246 247 249 private void createSession(final Method m, 250 final Object [] args, 251 final StatefulSessionEnterpriseContext ctx) 252 throws Exception 253 { 254 Object id = getPersistenceManager().createId(ctx); 256 log.debug("Created new session ID: " + id); 257 ctx.setId(id); 258 259 try 261 { 262 AllowedOperationsAssociation.pushInMethodFlag(IN_EJB_CREATE); 263 264 String createName = m.getName(); 266 Object instance = ctx.getInstance(); 267 String ejbCreateName = "ejbC" + createName.substring(1); 268 Method createMethod = instance.getClass().getMethod(ejbCreateName, m.getParameterTypes()); 269 log.debug("Using create method for session: " + createMethod); 270 createMethod.invoke(instance, args); 271 createCount++; 272 } 273 catch (IllegalAccessException e) 274 { 275 ctx.setId(null); 276 277 throw new EJBException (e); 278 } 279 catch (InvocationTargetException e) 280 { 281 ctx.setId(null); 282 283 Throwable t = e.getTargetException(); 284 if (t instanceof RuntimeException ) 285 { 286 if (t instanceof EJBException ) 287 throw (EJBException ) t; 288 throw new EJBException ((Exception ) t); 290 } 291 else if (t instanceof Exception ) 292 { 293 throw (Exception ) t; 295 } 296 else if (t instanceof Error ) 297 { 298 throw (Error ) t; 299 } 300 else 301 { 302 throw new org.jboss.util.UnexpectedThrowable(t); 303 } 304 } 305 finally 306 { 307 AllowedOperationsAssociation.popInMethodFlag(); 308 } 309 310 getPersistenceManager().createdSession(ctx); 312 313 getInstanceCache().insert(ctx); 315 316 if (getProxyFactory() != null) 318 ctx.setEJBObject((EJBObject ) getProxyFactory().getStatefulSessionEJBObject(id)); 319 320 if (getLocalHomeClass() != null) 322 ctx.setEJBLocalObject(getLocalProxyFactory().getStatefulSessionEJBLocalObject(id)); 323 } 324 325 public EJBObject createHome(Invocation mi) 326 throws Exception 327 { 328 StatefulSessionEnterpriseContext ctx = (StatefulSessionEnterpriseContext) mi.getEnterpriseContext(); 329 createSession(mi.getMethod(), mi.getArguments(), ctx); 330 return ctx.getEJBObject(); 331 } 332 333 334 336 339 public void removeLocalHome(Invocation mi) 340 throws RemoteException , RemoveException 341 { 342 throw new UnreachableStatementException(); 343 } 344 345 public EJBLocalObject createLocalHome(Invocation mi) 346 throws Exception 347 { 348 StatefulSessionEnterpriseContext ctx = (StatefulSessionEnterpriseContext) mi.getEnterpriseContext(); 349 createSession(mi.getMethod(), mi.getArguments(), ctx); 350 return ctx.getEJBLocalObject(); 351 } 352 353 356 public EJBObject getEJBObject(Invocation mi) throws RemoteException 357 { 358 EJBProxyFactory ci = getProxyFactory(); 360 if (ci == null) 361 { 362 String msg = "No ProxyFactory, check for ProxyFactoryFinderInterceptor"; 363 throw new IllegalStateException (msg); 364 } 365 366 Object id = mi.getArguments()[0]; 367 if (id == null) 368 throw new IllegalStateException ("Cannot get a session interface with a null id"); 369 370 InstanceCache cache = getInstanceCache(); 372 BeanLock lock = getLockManager().getLock(id); 373 lock.sync(); 374 try 375 { 376 if (cache.get(id) == null) 377 throw new RemoteException ("Session no longer exists: " + id); 378 } 379 finally 380 { 381 lock.releaseSync(); 382 getLockManager().removeLockRef(id); 383 } 384 385 return (EJBObject ) ci.getStatefulSessionEJBObject(id); 387 } 388 389 390 392 396 399 public void removeHome(Invocation mi) 400 throws RemoteException , RemoveException 401 { 402 throw new Error ("Not Yet Implemented"); 403 } 404 405 407 protected void setupHomeMapping() throws Exception 408 { 409 boolean isEJB1x = metaData.getApplicationMetaData().isEJB1x(); 411 412 Map map = new HashMap (); 413 414 if (homeInterface != null) 415 { 416 417 Method [] m = homeInterface.getMethods(); 418 for (int i = 0; i < m.length; i++) 419 { 420 try 421 { 422 if (isEJB1x == false && m[i].getName().startsWith("create")) 424 { 425 map.put(m[i], getClass().getMethod("createHome", 426 new Class []{Invocation.class})); 427 } 428 else 429 { 430 map.put(m[i], getClass().getMethod(m[i].getName() + "Home", 431 new Class []{Invocation.class})); 432 } 433 } 434 catch (NoSuchMethodException e) 435 { 436 log.info(m[i].getName() + " in bean has not been mapped"); 437 } 438 } 439 } 440 441 if (localHomeInterface != null) 442 { 443 Method [] m = localHomeInterface.getMethods(); 444 for (int i = 0; i < m.length; i++) 445 { 446 try 447 { 448 if (isEJB1x == false && m[i].getName().startsWith("create")) 450 { 451 map.put(m[i], getClass().getMethod("createLocalHome", 452 new Class []{Invocation.class})); 453 } 454 else 455 { 456 map.put(m[i], getClass().getMethod(m[i].getName() + "LocalHome", 457 new Class []{Invocation.class})); 458 } 459 } 460 catch (NoSuchMethodException e) 461 { 462 log.info(m[i].getName() + " in bean has not been mapped"); 463 } 464 } 465 } 466 467 try 468 { 469 Class handleClass = Class.forName("javax.ejb.Handle"); 471 472 Method getEJBObjectMethod = handleClass.getMethod("getEJBObject", new Class [0]); 474 475 map.put(getEJBObjectMethod, getClass().getMethod("getEJBObject", 477 new Class []{Invocation.class})); 478 } 479 catch (NoSuchMethodException e) 480 { 481 log.debug("Couldn't find getEJBObject method on container"); 482 } 483 484 homeMapping = map; 485 } 486 487 protected Interceptor createContainerInterceptor() 488 { 489 return new ContainerInterceptor(); 490 } 491 492 495 class ContainerInterceptor 496 extends AbstractContainerInterceptor 497 { 498 public Object invokeHome(Invocation mi) throws Exception 499 { 500 boolean trace = log.isTraceEnabled(); 501 502 if (trace) 503 { 504 log.trace("HOMEMETHOD coming in "); 505 log.trace("" + mi.getMethod()); 506 log.trace("HOMEMETHOD coming in hashcode" + mi.getMethod().hashCode()); 507 log.trace("HOMEMETHOD coming in classloader" + mi.getMethod().getDeclaringClass().getClassLoader().hashCode()); 508 log.trace("CONTAINS " + getHomeMapping().containsKey(mi.getMethod())); 509 } 510 511 Method miMethod = mi.getMethod(); 512 Method m = (Method ) getHomeMapping().get(miMethod); 513 if (m == null) 514 { 515 String msg = "Invalid invocation, check your deployment packaging" 516 + ", method=" + miMethod; 517 throw new EJBException (msg); 518 } 519 520 if (trace) 522 { 523 log.trace("HOMEMETHOD m " + m); 524 java.util.Iterator iterator = getHomeMapping().keySet().iterator(); 525 while (iterator.hasNext()) 526 { 527 Method me = (Method ) iterator.next(); 528 529 if (me.getName().endsWith("create")) 530 { 531 log.trace(me.toString()); 532 log.trace("" + me.hashCode()); 533 log.trace("" + me.getDeclaringClass().getClassLoader().hashCode()); 534 log.trace("equals " + me.equals(mi.getMethod()) + " " + mi.getMethod().equals(me)); 535 } 536 } 537 } 538 539 try 540 { 541 return mi.performCall(StatefulSessionContainer.this, m, new Object []{mi}); 542 } 543 catch (Exception e) 544 { 545 rethrow(e); 546 } 547 548 throw new org.jboss.util.UnreachableStatementException(); 550 } 551 552 public Object invoke(Invocation mi) throws Exception 553 { 554 EnterpriseContext ctx = (EnterpriseContext) mi.getEnterpriseContext(); 557 if (ctx.getTransaction() == null) 558 ctx.setTransaction(mi.getTransaction()); 559 560 Method miMethod = mi.getMethod(); 562 Method m = (Method ) getBeanMapping().get(miMethod); 563 if (m == null) 564 { 565 String msg = "Invalid invocation, check your deployment packaging" 566 + ", method=" + miMethod; 567 throw new EJBException (msg); 568 } 569 570 if (m.getDeclaringClass().equals(StatefulSessionContainer.class) 572 || m.getDeclaringClass().equals(SessionContainer.class)) 573 { 574 try 576 { 577 return mi.performCall(StatefulSessionContainer.this, m, new Object []{mi}); 578 } 579 catch (Exception e) 580 { 581 rethrow(e); 582 } 583 } 584 else 585 { 586 try 588 { 589 Object bean = ctx.getInstance(); 590 return mi.performCall(bean, m, mi.getArguments()); 591 } 592 catch (Exception e) 593 { 594 rethrow(e); 595 } 596 } 597 598 throw new org.jboss.util.UnreachableStatementException(); 600 } 601 } 602 } 603 | Popular Tags |