Hi David,
thanks for the directions. I think thats a good task for me to have a global
view of the system. I think its becoming more clear how to implement the
fix. Please, verify it for me...
************************************
add new class org.apache.openejb.jee.StatefulTimeoutConfig
class StatefulTimeoutConfig {
@XmlEnumValue("timeout") TIMEOUT,
@XmlEnumValue("unit") UNIT;
}
************************************
TransactionType
Add a new property (say statefulTimeout) to
the org.apache.openejb.jee.SessionBean class (below)
@XmlElement(name = "stateful-timeout")
protected StatefulTimeoutConfig statefulTimeout;
************************************
Add the new entry (on bold - same org.apache.openejb.jee.SessionBean class)
to the "session-beanType" annotation
@XmlType(name = "session-beanType", propOrder = {
"descriptions",
"displayNames",
"icon",
"ejbName",
"mappedName",
"home",
"remote",
"localHome",
"local",
"businessLocal",
"businessRemote",
"localBean",
"serviceEndpoint",
"ejbClass",
"sessionType",
"loadOnStartup",
"timeoutMethod",
"initMethod",
"removeMethod",
"transactionType",
"concurrencyType",
"aroundInvoke",
"envEntry",
"ejbRef",
"ejbLocalRef",
"serviceRef",
"resourceRef",
"resourceEnvRef",
"messageDestinationRef",
"persistenceContextRef",
"persistenceUnitRef",
"postConstruct",
"preDestroy",
"postActivate",
"prePassivate",
"securityRoleRef",
"securityIdentity",
"dependsOn",
*"statefulTimeout"*
})
************************************
Create a new Class...
class AccessTimeoutValue {
long time;
TimeUnit unit;
}
************************************
add new property to org.apache.openejb.core.CoreDeploymentInfo class
private AccessTimeoutValue accessTimeoutValue;
AccessTimeoutValue getAccessTimeoutValue() {
return this.accessTimeoutValue;
}
void setAccessTimeoutValue(AccessTimeoutValue accessTimeoutValue) {
this.accessTimeoutValue = accessTimeoutValue;
}
************************************
Class org.apache.openejb.assembler.classic.EnterpriseBeanInfo
add new property
public AccessTimeoutValue accessTimeout;
************************************
Class org.apache.openejb.config.EjbJarInfoBuilder (line 564)
bean.accessTimeout = new AccessTimeoutValue(
Long.valueof(s.geStatefulTimeout().TIMEOUT),
Long.valueof(s.geStatefulTimeout().UNIT));
************************************
class org.apache.openejb.assembler.classic.EnterpriseBeanBuilder (line
165)...
deployment.setAccessTimeoutValue(bean.accessTimeout);
************************************
Class org.apache.openejb.core.stateful.StatefulContainer. Instead of using
(bold code) ...
synchronized (instance) {
* ** **final Class<?> beanCls = instance.bean.getClass();*
* ** **final AccessTimeout accessTimeout =
beanCls.getAnnotation(AccessTimeout.class);*
Lock currLock = instance.getLock();
final boolean lockAcquired;
if(accessTimeout == null) {
// returns immediately true if the lock is available
lockAcquired = currLock.tryLock();
} else {
// AccessTimeout annotation found.
// Trying to get the lock within the specified period.
try {
lockAcquired = currLock.tryLock(accessTimeout.value(),
accessTimeout.unit());
} catch (InterruptedException e) {
throw new ApplicationException("Unable to get lock.", e);
}
}
// Did we acquire the lock to the current execution?
if (!lockAcquired) {
throw new ApplicationException(
new ConcurrentAccessTimeoutException("Unable to get lock."));
}
.
.
.
Use...
synchronized (instance) {
*final AccessTimeoutValue accessTimeout =
instance.deploymentInfo.getAccessTimeoutValue();*
Lock currLock = instance.getLock();
final boolean lockAcquired;
if(accessTimeout == null) {
// returns immediately true if the lock is available
lockAcquired = currLock.tryLock();
} else {
// AccessTimeout annotation found.
// Trying to get the lock within the specified period.
try {
lockAcquired = currLock.tryLock(accessTimeout.value(),
accessTimeout.unit());
} catch (InterruptedException e) {
throw new ApplicationException("Unable to get lock.", e);
}
}
// Did we acquire the lock to the current execution?
if (!lockAcquired) {
throw new ApplicationException(
new ConcurrentAccessTimeoutException("Unable to get lock."));
}
************************************
Tkx,
Thiago.
On Wed, May 26, 2010 at 11:23 PM, David Blevins <[email protected]>wrote:
>
> On May 26, 2010, at 4:35 PM, Thiago Veronezi wrote:
>
> > Nevermind...
> > Just found the problem...
> > I was not calling
> >
> > ejbJar.addEnterpriseBean(new StatefulBean(MySessionBean.class));
>
> Yep, that's the one :)
>
> On the question in for OPENEJB-1099. Yeah, there are some usage for
> @AccessTimeout in Stateful beans to basically specify how concurrent calls
> should be handled. Specifically should they wait or immediately get an
> exception, and if they wait how long should they wait. Previously the spec
> was vague and said it was up to the container and this annotation finally
> puts it in the hands of users to decide.
>
> Anyway, check out section 4.3.14.1 "Stateful Session Bean Concurrent Access
> Timeouts" of the EJB 3.1 spec.
>
> On the note of checking for the annotation directly in the runtime code is
> a fine first start. Java EE has the notion that any annotation can be
> overridden with xml, which obviously makes things tricky. Basically we deal
> with it by reading in the xml via a nice clean JAXB tree (the
> org.apache.openejb.jee.* code from that test), then we merge in the
> annotation data we find in the classes (see AnnotationDeployer), and then we
> sort of pull it through the system and into the container. That last part
> is probably the hardest and least fun.
>
> This doc details that last step a bit:
>
> http://openejb.apache.org/configuration-and-assembly.html
>
> No worries though, I can totally help you with that last bit. I can help
> you out on IRC and if needed we can do the skype thing too. More than code,
> we need some more good developers so I'm more than happy to show you around.
>
> There's some related AccessTimeout code in the StatelessInstanceManager for
> pulling an instance from the pool (see the deploy() method) that's sort of
> half finished. I'll see if I can finish that loop so that we can use it as
> a model for the Stateful/Singleton varieties.
>
> -David
>
>
> >
> > On Wed, May 26, 2010 at 7:18 PM, Thiago Veronezi <[email protected]
> >wrote:
> >
> >> Guys,
> >> Im trying to add a unit test to the *
> >> org.apache.openejb.core.stateful.StatefulContainerTest* class, but I
> cant
> >> create a simple stateful bean.
> >> I've added the following code to the test class...
> >>
> >> *******************************************
> >> .
> >> .
> >> .
> >> @Local
> >> public static interface MySession {
> >> void method1();
> >> void method2();
> >> }
> >>
> >> @Stateful
> >> public static class MySessionBean implements MySession {
> >> @Resource
> >> private SessionContext myctx;
> >>
> >> public void method1() {
> >> System.out.println("Method 1 invoked!");
> >> myctx.getBusinessObject(MySession.class).method2();
> >> }
> >>
> >> public void method2() {
> >> System.out.println("Method 2 invoked!");
> >> }
> >>
> >> }
> >> }
> >> //End of file
> >> *******************************************
> >>
> >> When executing the test, I can see that the *WidgetBean* (an existing
> bean
> >> within the same class) has been created, but my *MySessionBean* is
> nowhere
> >> to be found. Could you help me?
> >> tkx,
> >> Thiago.
> >>
> >> *The log...*
> >> INFO - Configuring Service(id=Default JDK 1.3 ProxyFactory,
> >> type=ProxyFactory, provider-id=Default JDK 1.3 ProxyFactory)
> >> INFO - Configuring Service(id=Default Transaction Manager,
> >> type=TransactionManager, provider-id=Default Transaction Manager)
> >> INFO - Configuring Service(id=Default Security Service,
> >> type=SecurityService, provider-id=Default Security Service)
> >> INFO - Configuring Service(id=Default Stateful Container,
> type=Container,
> >> provider-id=Default Stateful Container)
> >> WARN - Property "PoolSize" not supported by "Default Stateful Container"
> >> INFO - Configuring enterprise application:
> >> org.apache.openejb.jee.ejb...@6de1dadb
> >> WARN - Unable to scrape for @Stateful, @Stateless or @MessageDriven
> >> annotations. Invalid EjbModule URL:
> org.apache.openejb.jee.ejb...@6de1dadb
> >> INFO - Enterprise application "org.apache.openejb.jee.ejb...@6de1dadb"
> >> loaded.
> >> INFO - Assembling app: org.apache.openejb.jee.ejb...@6de1dadb
> >> INFO - Jndi(name=WidgetBeanLocal) --> Ejb(deployment-id=WidgetBean)
> >> INFO - Jndi(name=WidgetBeanRemote) --> Ejb(deployment-id=WidgetBean)
> >> INFO - Jndi(name=WidgetBeanLocalBean) --> Ejb(deployment-id=WidgetBean)
> >> INFO - Created Ejb(deployment-id=WidgetBean, ejb-name=WidgetBean,
> >> container=Default Stateful Container)
> >> INFO - Deployed Application(path=org.apache.openejb.jee.ejb...@6de1dadb
> )
> >> INFO - Configuring Service(id=Default JDK 1.3 ProxyFactory,
> >> type=ProxyFactory, provider-id=Default JDK 1.3 ProxyFactory)
> >> INFO - Configuring Service(id=Default Transaction Manager,
> >> type=TransactionManager, provider-id=Default Transaction Manager)
> >> INFO - Configuring Service(id=Default Security Service,
> >> type=SecurityService, provider-id=Default Security Service)
> >> INFO - Configuring Service(id=Default Stateful Container,
> type=Container,
> >> provider-id=Default Stateful Container)
> >> WARN - Property "PoolSize" not supported by "Default Stateful Container"
> >> INFO - Configuring enterprise application:
> >> org.apache.openejb.jee.ejb...@40b86944
> >> WARN - Unable to scrape for @Stateful, @Stateless or @MessageDriven
> >> annotations. Invalid EjbModule URL:
> org.apache.openejb.jee.ejb...@40b86944
> >> INFO - Enterprise application "org.apache.openejb.jee.ejb...@40b86944"
> >> loaded.
> >> INFO - Assembling app: org.apache.openejb.jee.ejb...@40b86944
> >> INFO - Jndi(name=WidgetBeanLocal) --> Ejb(deployment-id=WidgetBean)
> >> INFO - Jndi(name=WidgetBeanRemote) --> Ejb(deployment-id=WidgetBean)
> >> INFO - Jndi(name=WidgetBeanLocalBean) --> Ejb(deployment-id=WidgetBean)
> >> INFO - Created Ejb(deployment-id=WidgetBean, ejb-name=WidgetBean,
> >> container=Default Stateful Container)
> >> INFO - Deployed Application(path=org.apache.openejb.jee.ejb...@40b86944
> )
> >> INFO - Configuring Service(id=Default JDK 1.3 ProxyFactory,
> >> type=ProxyFactory, provider-id=Default JDK 1.3 ProxyFactory)
> >> INFO - Configuring Service(id=Default Transaction Manager,
> >> type=TransactionManager, provider-id=Default Transaction Manager)
> >> INFO - Configuring Service(id=Default Security Service,
> >> type=SecurityService, provider-id=Default Security Service)
> >> INFO - Configuring Service(id=Default Stateful Container,
> type=Container,
> >> provider-id=Default Stateful Container)
> >> WARN - Property "PoolSize" not supported by "Default Stateful Container"
> >> INFO - Configuring enterprise application:
> >> org.apache.openejb.jee.ejb...@242da5a6
> >> WARN - Unable to scrape for @Stateful, @Stateless or @MessageDriven
> >> annotations. Invalid EjbModule URL:
> org.apache.openejb.jee.ejb...@242da5a6
> >> INFO - Enterprise application "org.apache.openejb.jee.ejb...@242da5a6"
> >> loaded.
> >> INFO - Assembling app: org.apache.openejb.jee.ejb...@242da5a6
> >> INFO - Jndi(name=WidgetBeanLocal) --> Ejb(deployment-id=WidgetBean)
> >> INFO - Jndi(name=WidgetBeanRemote) --> Ejb(deployment-id=WidgetBean)
> >> INFO - Jndi(name=WidgetBeanLocalBean) --> Ejb(deployment-id=WidgetBean)
> >> INFO - Created Ejb(deployment-id=WidgetBean, ejb-name=WidgetBean,
> >> container=Default Stateful Container)
> >> INFO - Deployed Application(path=org.apache.openejb.jee.ejb...@242da5a6
> )
> >> ERROR - An unexpected exception occured while invoking the preDestroy
> >> method on the removed Stateful SessionBean instance;
> >> java.lang.NullPointerException null
> >> INFO - Configuring Service(id=Default JDK 1.3 ProxyFactory,
> >> type=ProxyFactory, provider-id=Default JDK 1.3 ProxyFactory)
> >> INFO - Configuring Service(id=Default Transaction Manager,
> >> type=TransactionManager, provider-id=Default Transaction Manager)
> >> INFO - Configuring Service(id=Default Security Service,
> >> type=SecurityService, provider-id=Default Security Service)
> >> INFO - Configuring Service(id=Default Stateful Container,
> type=Container,
> >> provider-id=Default Stateful Container)
> >> WARN - Property "PoolSize" not supported by "Default Stateful Container"
> >> INFO - Configuring enterprise application:
> >> org.apache.openejb.jee.ejb...@5c5ddd3
> >> WARN - Unable to scrape for @Stateful, @Stateless or @MessageDriven
> >> annotations. Invalid EjbModule URL:
> org.apache.openejb.jee.ejb...@5c5ddd3
> >> INFO - Enterprise application "org.apache.openejb.jee.ejb...@5c5ddd3"
> >> loaded.
> >> INFO - Assembling app: org.apache.openejb.jee.ejb...@5c5ddd3
> >> INFO - Jndi(name=WidgetBeanLocal) --> Ejb(deployment-id=WidgetBean)
> >> INFO - Jndi(name=WidgetBeanRemote) --> Ejb(deployment-id=WidgetBean)
> >> INFO - Jndi(name=WidgetBeanLocalBean) --> Ejb(deployment-id=WidgetBean)
> >> INFO - Created Ejb(deployment-id=WidgetBean, ejb-name=WidgetBean,
> >> container=Default Stateful Container)
> >> INFO - Deployed Application(path=org.apache.openejb.jee.ejb...@5c5ddd3)
> >> ERROR - An unexpected exception occured while invoking the preDestroy
> >> method on the removed Stateful SessionBean instance;
> >> java.lang.NullPointerException null
> >> INFO - Configuring Service(id=Default JDK 1.3 ProxyFactory,
> >> type=ProxyFactory, provider-id=Default JDK 1.3 ProxyFactory)
> >> INFO - Configuring Service(id=Default Transaction Manager,
> >> type=TransactionManager, provider-id=Default Transaction Manager)
> >> INFO - Configuring Service(id=Default Security Service,
> >> type=SecurityService, provider-id=Default Security Service)
> >> INFO - Configuring Service(id=Default Stateful Container,
> type=Container,
> >> provider-id=Default Stateful Container)
> >> WARN - Property "PoolSize" not supported by "Default Stateful Container"
> >> INFO - Configuring enterprise application:
> >> org.apache.openejb.jee.ejb...@2e39060b
> >> WARN - Unable to scrape for @Stateful, @Stateless or @MessageDriven
> >> annotations. Invalid EjbModule URL:
> org.apache.openejb.jee.ejb...@2e39060b
> >> INFO - Enterprise application "org.apache.openejb.jee.ejb...@2e39060b"
> >> loaded.
> >> INFO - Assembling app: org.apache.openejb.jee.ejb...@2e39060b
> >> INFO - Jndi(name=WidgetBeanLocal) --> Ejb(deployment-id=WidgetBean)
> >> INFO - Jndi(name=WidgetBeanRemote) --> Ejb(deployment-id=WidgetBean)
> >> INFO - Jndi(name=WidgetBeanLocalBean) --> Ejb(deployment-id=WidgetBean)
> >> INFO - Created Ejb(deployment-id=WidgetBean, ejb-name=WidgetBean,
> >> container=Default Stateful Container)
> >> INFO - Deployed Application(path=org.apache.openejb.jee.ejb...@2e39060b
> )
> >> INFO - Configuring Service(id=Default JDK 1.3 ProxyFactory,
> >> type=ProxyFactory, provider-id=Default JDK 1.3 ProxyFactory)
> >> INFO - Configuring Service(id=Default Transaction Manager,
> >> type=TransactionManager, provider-id=Default Transaction Manager)
> >> INFO - Configuring Service(id=Default Security Service,
> >> type=SecurityService, provider-id=Default Security Service)
> >> INFO - Configuring Service(id=Default Stateful Container,
> type=Container,
> >> provider-id=Default Stateful Container)
> >> WARN - Property "PoolSize" not supported by "Default Stateful Container"
> >> INFO - Configuring enterprise application:
> >> org.apache.openejb.jee.ejb...@5059cbda
> >> WARN - Unable to scrape for @Stateful, @Stateless or @MessageDriven
> >> annotations. Invalid EjbModule URL:
> org.apache.openejb.jee.ejb...@5059cbda
> >> INFO - Enterprise application "org.apache.openejb.jee.ejb...@5059cbda"
> >> loaded.
> >> INFO - Assembling app: org.apache.openejb.jee.ejb...@5059cbda
> >> INFO - Jndi(name=WidgetBeanLocal) --> Ejb(deployment-id=WidgetBean)
> >> INFO - Jndi(name=WidgetBeanRemote) --> Ejb(deployment-id=WidgetBean)
> >> INFO - Jndi(name=WidgetBeanLocalBean) --> Ejb(deployment-id=WidgetBean)
> >> INFO - Created Ejb(deployment-id=WidgetBean, ejb-name=WidgetBean,
> >> container=Default Stateful Container)
> >> INFO - Deployed Application(path=org.apache.openejb.jee.ejb...@5059cbda
> )
> >> INFO - Configuring Service(id=Default JDK 1.3 ProxyFactory,
> >> type=ProxyFactory, provider-id=Default JDK 1.3 ProxyFactory)
> >> INFO - Configuring Service(id=Default Transaction Manager,
> >> type=TransactionManager, provider-id=Default Transaction Manager)
> >> INFO - Configuring Service(id=Default Security Service,
> >> type=SecurityService, provider-id=Default Security Service)
> >> INFO - Configuring Service(id=Default Stateful Container,
> type=Container,
> >> provider-id=Default Stateful Container)
> >> WARN - Property "PoolSize" not supported by "Default Stateful Container"
> >> INFO - Configuring enterprise application:
> >> org.apache.openejb.jee.ejb...@12b31a7c
> >> WARN - Unable to scrape for @Stateful, @Stateless or @MessageDriven
> >> annotations. Invalid EjbModule URL:
> org.apache.openejb.jee.ejb...@12b31a7c
> >> INFO - Enterprise application "org.apache.openejb.jee.ejb...@12b31a7c"
> >> loaded.
> >> INFO - Assembling app: org.apache.openejb.jee.ejb...@12b31a7c
> >> INFO - Jndi(name=WidgetBeanLocal) --> Ejb(deployment-id=*WidgetBean*)
> >> INFO - Jndi(name=WidgetBeanRemote) --> Ejb(deployment-id=*WidgetBean*)
> >> INFO - Jndi(name=WidgetBeanLocalBean) -->
> Ejb(deployment-id=*WidgetBean*)
> >> INFO - Created Ejb(deployment-id=WidgetBean, ejb-name=WidgetBean,
> >> container=Default Stateful Container)
> >> INFO - Deployed Application(path=org.apache.openejb.jee.ejb...@12b31a7c
> )
> >>
> >>
> >>
> >>
> >> *The test method...*
> >> *
> >> public void testMySessionBean() throws Exception {
> >> InitialContext ctx = new InitialContext();
> >> Object object = ctx.lookup("MySessionBeanLocal");
> >> MySession bean = (MySession) object;
> >> bean.method1();
> >> assertTrue(true);
> >> }
> >> *
> >>
> >>
>
>