1 25 26 package org.objectweb.jonas_ejb.container; 27 28 import java.lang.reflect.InvocationTargetException ; 29 import java.rmi.RemoteException ; 30 import java.util.ArrayList ; 31 import java.util.List ; 32 import java.util.ListIterator ; 33 34 import javax.ejb.EJBException ; 35 import javax.ejb.SessionBean ; 36 import javax.ejb.TimedObject ; 37 import javax.ejb.Timer ; 38 import javax.ejb.TimerService ; 39 import javax.naming.Context ; 40 import javax.transaction.Status ; 41 import javax.transaction.SystemException ; 42 43 import org.objectweb.jonas_timer.TraceTimer; 44 45 import org.objectweb.jonas_ejb.deployment.api.SessionStatelessDesc; 46 47 import org.objectweb.util.monolog.api.BasicLevel; 48 49 53 public class JStatelessFactory extends JSessionFactory { 54 55 60 protected List bctxlist = new ArrayList (); 61 62 protected JServiceEndpointHome sehome = null; 64 65 protected int instanceCount = 0; 66 67 protected int minPoolSize = 0; 69 70 protected int maxCacheSize = 0; 72 73 private static final int MAX_NB_RETRY = 2; 74 75 76 81 public JStatelessFactory(SessionStatelessDesc dd, JContainer cont) { 82 super(dd, cont); 83 if (TraceEjb.isDebugIc()) { 84 TraceEjb.interp.log(BasicLevel.DEBUG, ""); 85 } 86 87 Class sehomeclass = null; 89 String clname = dd.getFullWrpSEHomeName(); 90 if (clname != null) { 91 try { 92 sehomeclass = cont.getClassLoader().loadClass(clname); 93 } catch (ClassNotFoundException e) { 94 throw new EJBException (ejbname + " Cannot load " + clname, e); 95 } 96 if (TraceEjb.isDebugIc()) { 97 TraceEjb.interp.log(BasicLevel.DEBUG, ejbname + ": " + clname + " loaded"); 98 } 99 try { 100 int nbp = 2; 102 Class [] ptype = new Class [nbp]; 103 Object [] pobj = new Object [nbp]; 104 ptype[0] = org.objectweb.jonas_ejb.deployment.api.SessionStatelessDesc.class; 105 pobj[0] = (Object ) dd; 106 ptype[1] = org.objectweb.jonas_ejb.container.JStatelessFactory.class; 107 pobj[1] = (Object ) this; 108 sehome = (JServiceEndpointHome) sehomeclass.getConstructor(ptype).newInstance(pobj); 109 } catch (Exception e) { 110 throw new EJBException (ejbname + " Cannot create serviceEndpointHome ", e); 111 } 112 try { 114 sehome.register(); 115 } catch (Exception e) { 116 throw new EJBException (ejbname + " Cannot register serviceEndpointHome ", e); 117 } 118 } 119 120 isStateful = false; 121 maxCacheSize = dd.getCacheMax(); 122 minPoolSize = dd.getPoolMin(); 123 if (TraceEjb.isDebugSwapper()) { 124 TraceEjb.swapper.log(BasicLevel.DEBUG, " maxCacheSize = " + maxCacheSize); 125 } 126 } 127 128 131 public void initInstancePool() { 132 if (minPoolSize != 0) { 134 TraceEjb.interp.log(BasicLevel.INFO, "pre-allocate a set of " + minPoolSize 135 + " stateless session instances"); 136 JSessionSwitch ss = null; 137 try { 138 ss = createNewSession(); 139 } catch (RemoteException e) { 140 TraceEjb.logger.log(BasicLevel.ERROR, ejbname + " cannot create new session", e); 141 throw new EJBException (ejbname + " Cannot create session for pool: ", e); 142 } 143 Context bnctx = setComponentContext(); ClassLoader old = Thread.currentThread().getContextClassLoader(); 146 Thread.currentThread().setContextClassLoader(this.myClassLoader()); 147 try { 148 synchronized (bctxlist) { 149 for (int i = 0; i < minPoolSize; i++) { 150 JSessionContext ctx = null; 151 try { 152 ctx = createNewInstance(ss); 154 bctxlist.add(ctx); 155 } catch (Exception e) { 156 TraceEjb.logger.log(BasicLevel.ERROR, ejbname + " cannot create new instance", e); 157 throw new EJBException (ejbname + " Cannot init pool of instances ", e); 158 } 159 } 160 } 161 } finally { 162 Thread.currentThread().setContextClassLoader(old); 164 165 resetComponentContext(bnctx); 167 } 168 169 } 170 } 171 172 public JServiceEndpointHome getSEHome() { 173 return sehome; 174 } 175 176 180 183 public int getPoolSize() { 184 return bctxlist.size(); 185 } 186 187 191 public void reduceCache() { 192 if (TraceEjb.isDebugSwapper()) { 193 TraceEjb.swapper.log(BasicLevel.DEBUG, ""); 194 } 195 int poolsz = minPoolSize; 197 synchronized (bctxlist) { 198 if (TraceEjb.isDebugSwapper()) { 199 TraceEjb.swapper.log(BasicLevel.DEBUG, "try to reduce " + bctxlist.size() + " to " + poolsz); 200 } 201 while (bctxlist.size() > poolsz) { 202 ListIterator i = bctxlist.listIterator(); 203 if (i.hasNext()) { 204 i.next(); 205 i.remove(); 206 instanceCount--; 207 } 208 } 209 } 210 if (TraceEjb.isDebugSwapper()) { 211 TraceEjb.swapper.log(BasicLevel.DEBUG, "cacheSize= " + getCacheSize()); 212 } 213 214 } 215 216 220 224 public TimerService getTimerService() { 225 if (myTimerService == null) { 226 myTimerService = new JTimerService(this); 228 } 229 return myTimerService; 230 } 231 232 236 public JSessionSwitch createNewSession() throws RemoteException { 237 if (TraceEjb.isDebugIc()) { 238 TraceEjb.interp.log(BasicLevel.DEBUG, ""); 239 } 240 JStatelessSwitch bs = new JStatelessSwitch(this); 241 return bs; 242 } 243 244 247 public JSessionContext getJContext(JSessionSwitch ss) { 248 if (TraceEjb.isDebugIc()) { 249 TraceEjb.interp.log(BasicLevel.DEBUG, ""); 250 } 251 JStatelessContext bctx = null; 252 253 synchronized (bctxlist) { 255 try { 256 ListIterator i = bctxlist.listIterator(); 257 if (i.hasNext()) { 258 bctx = (JStatelessContext) i.next(); 259 bctx.initSessionContext(ss); 260 i.remove(); 261 } 262 } catch (IndexOutOfBoundsException ex) { 263 } 265 } 266 267 if (bctx == null) { 268 try { 270 bctx = createNewInstance(ss); 271 } catch (Exception e) { 272 TraceEjb.logger.log(BasicLevel.ERROR, "exception:" + e); 273 throw new EJBException ("Cannot create a new instance", e); 274 } 275 } 276 if (TraceEjb.isDebugSwapper()) { 277 TraceEjb.swapper.log(BasicLevel.DEBUG, "nb instances " + getCacheSize()); 278 } 279 return bctx; 280 } 281 282 286 public void releaseJContext(JContext ctx) { 287 if (ctx == null) { 288 TraceEjb.swapper.log(BasicLevel.ERROR, "null ctx!"); 289 return; 290 } 291 TraceEjb.swapper.log(BasicLevel.DEBUG, ""); 292 JStatelessContext bctx = (JStatelessContext) ctx; 293 294 synchronized (bctxlist) { 297 if (maxCacheSize != 0 && instanceCount > maxCacheSize) { 298 if (TraceEjb.isDebugSwapper()) { 299 TraceEjb.swapper.log(BasicLevel.DEBUG, "too much instances :" + instanceCount + ", max=" 300 + maxCacheSize); 301 } 302 instanceCount--; 303 } else { 304 bctxlist.add(bctx); 305 } 306 } 307 if (TraceEjb.isDebugSwapper()) { 308 TraceEjb.swapper.log(BasicLevel.DEBUG, "nb instances " + getCacheSize()); 309 } 310 } 311 312 316 public void notifyTimeout(Timer timer) { 317 if (TraceTimer.isDebug()) { 318 TraceTimer.logger.log(BasicLevel.DEBUG, ""); 319 } 320 321 JSessionSwitch bs = null; 325 if (sessionList.size() > 0) { 326 if (TraceEjb.isDebugIc()) { 327 TraceEjb.interp.log(BasicLevel.DEBUG, "get a JStatelessSwitch from the pool"); 328 } 329 bs = (JSessionSwitch) sessionList.remove(0); 330 JSessionRemote remote = bs.getRemote(); 333 if (remote != null) { 334 if (!remote.exportObject()) { 335 TraceEjb.logger.log(BasicLevel.ERROR, "bad JSessionSwitch found in pool."); 336 } 337 } 338 } else { 339 if (TraceEjb.isDebugIc()) { 340 TraceEjb.interp.log(BasicLevel.DEBUG, "create a new JStatelessSwitch"); 341 } 342 try { 343 bs = new JStatelessSwitch(this); 344 } catch (RemoteException e) { 345 TraceEjb.logger.log(BasicLevel.ERROR, "Notify Timeout - Unexpected : ", e); 346 return; 347 } 348 } 349 353 for (int nbretry = 0; nbretry < MAX_NB_RETRY; nbretry++) { 354 RequestCtx rctx = preInvoke(getTimerTxAttribute()); 355 JSessionContext bctx = null; 356 try { 357 bctx = bs.getICtx(rctx.currTx); 358 TimedObject instance = (TimedObject ) bctx.getInstance(); 359 checkSecurity(null); 361 instance.ejbTimeout(timer); 362 if (rctx.currTx == null 363 || (rctx.currTx.getStatus() != Status.STATUS_MARKED_ROLLBACK)) { 364 break; 365 } 366 } catch (EJBException e) { 367 rctx.sysExc = e; 368 throw e; 369 } catch (RuntimeException e) { 370 rctx.sysExc = e; 371 throw new EJBException ("RuntimeException thrown by an enterprise Bean", e); 372 } catch (Error e) { 373 rctx.sysExc = e; 374 throw new EJBException ("Error thrown by an enterprise Bean" + e); 375 } catch (RemoteException e) { 376 rctx.sysExc = e; 377 throw new EJBException ("Remote Exception raised:", e); 378 } catch (SystemException e) { 379 rctx.sysExc = e; 380 throw new EJBException ("Cannot get transaction status:", e); 381 } finally { 382 postInvoke(rctx); 383 } 384 } 385 386 bs.timeoutExpired(null); 389 } 390 391 394 public int getMinPoolSize() { 395 return minPoolSize; 396 } 397 398 401 public int getMaxCacheSize() { 402 return maxCacheSize; 403 } 404 405 408 public int getCacheSize() { 409 return instanceCount; 410 } 411 412 416 419 private JStatelessContext createNewInstance(JSessionSwitch ss) throws Exception { 420 if (TraceEjb.isDebugIc()) { 421 TraceEjb.interp.log(BasicLevel.DEBUG, ""); 422 } 423 SessionBean bean = null; 425 try { 426 bean = (SessionBean ) beanclass.newInstance(); 427 } catch (InstantiationException e) { 428 TraceEjb.logger.log(BasicLevel.ERROR, ejbname + " cannot instantiate session bean"); 429 throw e; 430 } catch (IllegalAccessException e) { 431 TraceEjb.logger.log(BasicLevel.ERROR, ejbname + " Cannot instantiate SessionBean"); 432 throw e; 433 } 434 435 JStatelessContext bctx = new JStatelessContext(this, bean); 437 bean.setSessionContext(bctx); 438 bctx.setState(1); 439 bctx.initSessionContext(ss); 440 if (TraceEjb.isDebugIc()) { 442 TraceEjb.interp.log(BasicLevel.DEBUG, "call ejbCreate on the instance"); 443 } 444 try { 445 beanclass.getMethod("ejbCreate", (Class []) null).invoke(bean, (Object []) null); 446 } catch (InvocationTargetException ite) { 447 Throwable t = ite.getTargetException(); 449 TraceEjb.logger.log(BasicLevel.ERROR, ejbname + " cannot call ejbCreate on Stateless Session " + t.getMessage(), t); 450 } catch (Exception e) { 451 TraceEjb.logger.log(BasicLevel.ERROR, ejbname + " cannot call ejbCreate on Stateless Session " + e.getMessage(), e); 452 } 453 bctx.setState(2); 454 455 synchronized (bctxlist) { 458 instanceCount++; 459 } 460 return bctx; 461 } 462 463 } 464 | Popular Tags |