Migrating a transactional portlet

Transactions are an important part of applications. The standard specification for transactions in Java EE is JTA (Java Transaction API). All full-profile Java EE-certified servers implement it. Tomcat and Jetty are not fully Java enterprise certified, so they don't strictly implement JTA. Because of this, GateIn is bundled with a transaction service that loads the JBoss transaction manager that is bundled in GateIn. All portals need a transaction service, and this can be called in different manners.

Getting ready

In this recipe, you will see how to migrate a transactional portlet from JBoss Portal to GateIn.

Note

JBoss Portal is the old portal of the JBoss community distributed by Red Hat until EPP (Enterprise Portal Platform) 4, before the union with the eXo Portal. GateIn can be considered as the new version of JBoss Portal because it integrates the portlet container of JBoss Portal, but the portlet extensions and the administration tools are completely new.

How to do it...

  1. JBoss Portal uses an extension file where the transactional mode for a portlet is declared. Here is an example:
    <?xml version="1.0" standalone="yes"?>
    <!DOCTYPE portlet-app PUBLIC
       "-//&PRODUCT;//DTD JBoss Portlet 2.6//EN"
       "http://www.jboss.org/portal/dtd/jboss-portlet_2_6.dtd">
    <portlet-app>
       <portlet>
          <portlet-name>MyPortlet</portlet-name>
          <trans-attribute>Required</trans-attribute>
       </portlet>
    </portlet-app>
  2. In GateIn, the transaction mode is not declarative. It must therefore be put in the code of the portlet. Here is an example:
    import javax.transaction.SystemException;
    import javax.transaction.Transaction;
    import javax.transaction.TransactionManager;
    import javax.transaction.TransactionRequiredException;
    
    import org.exoplatform.container.ExoContainer;
    import org.exoplatform.portal.application.PortalRequestContext;
    import org.exoplatform.webui.application.WebuiRequestContext;
    import org.jboss.cache.transaction.TransactionManagerLookup;
    ...
    @Override
    protected void doDispatch(RenderRequest request, RenderResponse response)
          throws PortletException, IOException {
       PortalRequestContext context = (PortalRequestContext)  
          WebuiRequestContext.getCurrentInstance();
      ExoContainer pcontainer = context.getApplication()
            .getApplicationServiceContainer();
      TransactionManagerLookup tsLookup = 
          (TransactionManagerLookup) pcontainer
      .getComponentInstanceOfType(TransactionManagerLookup.class);
      TransactionManager tManager;
      Transaction transaction = null;
    
      try {
        tManager = tsLookup.getTransactionManager();
        transaction = tManager.getTransaction();
         if (transaction == null)
           throw new TransactionRequiredException();
        super.doDispatch(request, response);
        transaction.commit();
      } catch (Exception e1) {
        try {
          if (transaction != null)
            transaction.rollback();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (SystemException e) {
            e.printStackTrace();
        }
    }

    In this case, we implement a transaction of type Required. The code will throw an exception if the transaction is null.

Note

The Required type is an attribute declared in the JTA specifications. If it is set and the current transaction doesn't exist, then the transaction manager will throw an exception. More information on JTA attributes is available on the Oracle page at the following URL:

http://www.oracle.com/technetwork/java/javaee/jta/index.html

How it works...

In the portal/WEB-INF/conf/common/common-configuration.xml file, you can see the configuration of the transaction service. There are two services:

  • org.jboss.cache.transaction.TransactionManagerLookup: Used to get the current Transaction Manager through the getTransactionManager() method
  • org.exoplatform.services.transaction.TransactionService: Manages the JTA Transaction Manager. Usually, the client uses it to get UserTransaction to manage the transactions. Here is an example of UserTransaction:
    TransactionService ts = (TransactionService) pcontainer
       .getComponentInstanceOfType(TransactionService.class);
    UserTransaction ut = ts.getUserTransaction();
    try {
      ut.begin();
      ...
      ut.commit();
    } catch (Exception e1) {
      try {
        ut.rollback();
      } catch (Exception e) {
        e.printStackTrace();
       }
    } 

In the configuration of the service, you can set the timeout of the transaction. If not set, the timeout is 60 seconds, after which the transaction expires. The configured default is 300 seconds.

Arjuna implements the Transaction Manager. Arjuna is an open source company that developed the Transaction Manager and donated it to JBoss Application Server. If you use JBoss, you can configure the Transaction Manager in the files transaction-jboss-beans.xml and transaction-service.xml in the folder $JBOSS_HOME/server/$CONFIG/deploy.

If you use Tomcat or Jetty, no customization is possible, so always remember to take care regarding the requirements for your application.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.139.67.5