Hello... i'm facing a problem when looking up my bean in test phase.
To stress this bean, I'm using a JMeter test case with 100 simultaneously threads. Each thread perform an EJB lookUp for myWorkerBean defined in my applicationContext.xml as follows
Each looked up instance performs a call to MyWorkerInterface.execute(WorkRequest) method that slleps around 60.000 mills. But only first 30 lookups will perform succesfully and the remaining 70 will fail with "Fail to aquire pool semaphore, strictTimeout=-1" error because my bean class is annotated with strict max pool size = 30 and will be discarded.HTML Code:<jee:local-slsb lookup-home-on-startup="false" id="myWorkerBean" business-interface="MyWorkerInterface" jndi-name="MyWorkerBean/local" />
At this moment, I have 30 bean instances filling the pool during 60 seconds and if I check the MBean for MyWorkerBean in jmx-console shows AvailableCount attribute equals 30.
After 60 seconds all 30 instances perform succesfully. Then, I run 100 more jmeter threads again, but this time all lookups blows with "Fail to aquire pool semaphore, strictTimeout=-1" and the MBean for MyWorkerBean in jmx-console shows AvailableCount equals 0 (but it should mark 30 again). What it means: for some reason that first 30 bean instances were not released.
See the code:
Code:public interface MyWorkerInterface { public WorkResponse execute(WorkRequest request); }Code:@javax.jws.WebService(portName = "MyWorkerWSPort", name = "MyWorker", serviceName = "MyWorker") public class MyWorkerWS extends SpringSupport implements MyWorkerInterface { @javax.jws.WebMethod(operationName = "execute") @javax.jws.soap.SOAPBinding(parameterStyle = ParameterStyle.BARE) @javax.jws.WebResult(name = "workResponse", partName = "workResponse", targetNamespace = "http://ws.working.my.com/") public WorkResponse execute( @javax.jws.WebParam(mode = Mode.IN, name = "work", partName = "work") WorkRequest request) { final int startingDepth = NDC.getDepth(); WorkResponse response = null; try { //Here I'm looking up my bean via Spring MyWorkerInterface worker = (MyWorkerInterface) super.getBeanFactory().getBean("myWorkerBean"); //Performs around 60.000ms response = worker.execute(request); } catch (org.springframework.beans.BeansException beansException) { LoggerHelper.error("Application error", beansException); } catch (EJBException ejbException) { final String errorMessage = org.apache.commons.lang.StringUtils.defaultString(ejbException.getMessage()); if (errorMessage.startsWith("Failed to acquire the pool semaphore")) { // MyWorkerInterface.execute(WorkRequest) method is delayed for more than 20000ms. // When the execute method backs to its normal execution time this EJBException is still happening // but the pool seems to be empty LoggerHelper.error("Pool is full because MyWorkerInterface.execute(WorkRequest) is" + "taking more time than normal to perform.", ejbException); } else { LoggerHelper.error("ejb error", ejbException); } } return response; } }Code:@Clustered @Local(MyWorkerInterface.class) @Stateless(name = "MyWorkerBean") @Interceptors(value = { SpringBeanAutowiringInterceptor.class, LoggingInterceptor.class }) @RolesAllowed(value = "client") @Pool(value = PoolDefaults.POOL_IMPLEMENTATION_STRICTMAX, maxSize = 30) public class MyWorkerBean implements MyWorkerInterface { @RolesAllowed("client") @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) public WorkResponse execute(final WorkRequest workRequest) { long start = System.currentTimeMillis(); WorkExchange exchange = new WorkExchange(); exchange.setWorkRequest(workRequest); //Please ignore try/catch Thread.sleep(60000); LoggerUtil.info("Operation time: " + (System.currentTimeMillis() - start)); // WorkExchange.workResponse have been set by MDB WorkResponse response = exhange.getWorkResponse(); return response; } }I appreciate any helpCode:public class SpringSupport { protected final org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(this.getClass()); @javax.annotation.Resource private javax.xml.ws.WebServiceContext webServiceContext; private org.springframework.context.ApplicationContext cachedApplicationContext; protected org.springframework.beans.factory.BeanFactory getBeanFactory() { if (cachedApplicationContext != null) { return cachedApplicationContext; } if (webServiceContext == null) { return null; } javax.xml.ws.handler.MessageContext messageContext = webServiceContext.getMessageContext(); if (messageContext == null) { return null; } javax.servlet.ServletContext servletContext = (javax.servlet.ServletContext) messageContext.get( javax.xml.ws.handler.MessageContext.SERVLET_CONTEXT); if (servletContext == null) { return null; } this.cachedApplicationContext = (org.springframework.context.ApplicationContext) servletContext .getAttribute( org.springframework.web.context.WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); return cachedApplicationContext; } }
thanks


Reply With Quote