Skip to content

TLEJBAnnotation

Lenny Primak edited this page May 3, 2015 · 1 revision

Introduction

Ordinarily, if you try to use @EJB in your Tapestry page or component classes to reference your existing EJBs, it will not work because these annotations work only in JEE container-managed objects such as Servlets, JSPs, or other EJBs, which Tapestry objects are not. Flow Logix Tapestry Library (FTL) adds functionality to make the @EJB annotation work within Tapestry.

Details

The easiest way to reference a bean is by it's interface:

   private @EJB UserListLocal myUserList;

In this case, the bean type is UserList, and it is derived by stripping the Local postfix from the interface type name. Since Tapestry has no way of getting a list of bean types available, it basically is relegated to making a educated guess at the bean name, which actually works quite well by default.

You can provide your own bean name, and not have FTL guess it by the interface:

   private @EJB(beanName = "EmailManagerImpl") EmailManagerLocal eraserImpl;

Only the following @EJB annotation parameters are supported: beanName, name, and lookup. Other methods of locating beans are not applicable in Tapestry context. Any of these parameters are used identically to find the EJB bean name.

Using mappedName to call remote EJBs

mappedName is used to map JNDI configuration parameters in order to call remote EJBs in different modules:

Initialization:

    JNDIConfigurer config = JNDIConfigurer.getInstance();
        config.getConfiguration().put("myRemoteApp", 
                new JNDIConfigurer.Config("remote_host", null,
                "java:global/myapp"));

Usage:

private @EJB(mappedName = "myRemoteApp") @Getter EmailServiceBeanRemote emailService;

Stateful Session Bean (SFSB) support

In order to use a Stateful session bean, a slight variation to the above is required:

    private @EJB @Stateful UserSessionLocal myUserSession;

This will create a Stateful Session Bean that is stored as an Tapestry SessionState object, roughly equivalent of @SessionState Tapestry annotation.

You can also use a slight variation of the above to make it roughly equivalent to a @SessionAttribute object:

    private @EJB @Stateful(isSessionAttribute = true) UserSessionLocal myUserSession;

This will store the variable in the myUserSession session attribute. You can override this with sessionKey annotation parameter to the @Stateful annotation.


Unfortunately, there is no way for FTL to determine if the bean is stateful or not. Since the vast majority of the beans will be stateless, it will be the assumed default. To mark a bean as stateful, you can use com.flowlogix.web.services.annotations.Stateful annotation. The JEE @Stateful annotation cannot be used in the context of fields, so unfortunately we cannot reuse it.

SFSB Clustering / Failover Support

SFSB clustering and failover support requires special care. Since EJB failover is independent of web session failover, SFSBs must be configured to support high availability, otherwise when web session replicates, it will not be able to access attached SFSBs.

SFSB clustering and failover will work provided the following conditions are met:

  • SFSB is configured with HA enabled: WEB-INF/glassfish-ejb-jar.xml (GlassFish)
<?xml version="1.0" encoding="UTF-8"?>
<glassfish-ejb-jar>
    <enterprise-beans>
        <ejb availability-enabled="true">
            <ejb-name>UserSession</ejb-name>
        </ejb>
    </enterprise-beans>
</glassfish-ejb-jar>
  • SFSB local interface extends com.flowlogix.ejb.Pingable and implements the empty ping() method

  • SFSB timeout is greater than web session timeout:

@Stateful
@StatefulTimeout(value = 125, unit = TimeUnit.MINUTES)
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class UserSession implements UserSessionLocal
{
}
  • All methods must require new transaction, so multi-threaded access to the bean isn't going to fail due to transaction clash

Examples

Can be found Here

Clone this wiki locally