Five Steps to use Apache Cactus with WebSphere Application Server 7

This post illustrates setting up the Apache Cactus on WebSphere 7.0 to test some JPA managers in an existing web application.

Let’s go through the steps, so you can do them directly in maximum 5 minutes:

1. Download the Apache Cactus 1.8.0.zip from here.

2. Place ONLY the following jars in the lib folder of your web application:

    2.1. aspectjrt-1.5.3.jar
    2.2. cactus.core.framework.uberjar.javaEE.14-1.8.0.jar
    2.3. cactus.integration.ant-1.8.0.jar
    2.4. cactus.integration.shared.api-1.8.0.jar
    2.5. cargo-ant-0.9.jar
    2.6. cargo-core-uberjar-0.9.jar
    2.7. commons-codec-1.3.jar
    2.8. commons-httpclient-3.1.jar
    2.9. commons-logging-1.1.jar
    2.10. httpunit-1.6.jar
    2.11. js-14.jar (You will have to download this file manually to avoid OutOfMemory Exception on WebSphere).
    2.12. junit-3.8.2.jar
    2.13. nekohtml-1.9.6.jar
    2.14. org.mortbay.jetty-5.1.9.jar
    2.15. xbean-1.0.3.jar (You will have to download this file manually to avoid OutOfMemory Exception on WebSphere).

3. Copy the following servlets declaration to your web.xml file:

<!-- [Start] Cactus Configuration -->
	<servlet>
	  <servlet-name>ServletRedirector</servlet-name>
	  <servlet-class>org.apache.cactus.server.ServletTestRedirector</servlet-class>
	</servlet>
	<servlet>
	  <servlet-name>ServletTestRunner</servlet-name>
	  <servlet-class>org.apache.cactus.server.runner.ServletTestRunner</servlet-class>
	</servlet>
	<servlet-mapping>
	    <servlet-name>ServletRedirector</servlet-name>
	    <url-pattern>/ServletRedirector</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
	    <servlet-name>ServletTestRunner</servlet-name>
	    <url-pattern>/ServletTestRunner</url-pattern>
	</servlet-mapping>
<!-- [End] Cactus Configuration -->

4. Write your web test cases.

public class TestServlet extends ServletTestCase {
    public void testCreatePerson() {
        try {
            FacesContext  facesContext  = JSFUtil.getFacesContext(config.getServletContext(), request, response);
            PersonManager personManager = (PersonManager) JSFUtil.getManagedBean(facesContext, "personManager");            
            Person person = new Person();
            person.setPersonName("Hazem" + System.currentTimeMillis());
            person.setPersonNationalId(System.currentTimeMillis() + "");
            personManager.createPerson(person);
        } catch (Exception exception) {
            exception.printStackTrace();
            fail(exception.getMessage());
        }
    } 
    // Other test cases ...
}

As you notice, Cactus is much similiar to JUnit, Your web testcases class should just extend the (org.apache.cactus.ServletTestCase).

5. Finally, deploy the web application war to the WAS 7.0, and access your web testcases class through the (ServletTestRunner) by using the following URL:
http://localhost:9080/testWebProject/ServletTestRunner?suite=entities.controller.test.TestServlet.

As you see here, you just set the suite parameter to the fully-qualified name of your web testcases class.

Here is the sample output:

If you want a nicer output, then make sure to include the cactus-report.xsl [This file is included in the sample] directly under the (Web Content) folder of your application, and add the xsl parameter as follows:
http://localhost:9082/testWebProject/ServletTestRunner?suite=entities.controller.test.TestServlet&xsl=cactus-report.xsl.

Here is the cooler output:

I included all of the project source code including the dependency jars in the following zip file for your reference. I wish that this tip can be helpful to you.

Using JTA inside OpenJPA in the WebSphere 7 Environment (Without EJBs)

In some situations, you may need to manage the JTA transactions manually without using EJBs. In this post, I will show you how to do this.

Let’s see an example of a (persistence.xml) file that uses a JTA data source:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
	<persistence-unit name="SchoolTestJPA" transaction-type="JTA">
		<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>	
		<jta-data-source>jdbc/school</jta-data-source>			
		<class>jpa.beans.Address</class>
		<class>jpa.beans.Person</class>
		<properties>
			<property name="openjpa.TransactionMode" value="managed"/>
    		        <property name="openjpa.ConnectionFactoryMode" value="managed"/>
		</properties>		
	</persistence-unit>
</persistence>

Thanks to the joinTransaction API of the JPA EntityManager, you can make the EntityManager able to join the current active JTA transaction. Let’s see how you can do this.

EntityManagerFactory emf = PersistentManager.getInstance().getEntityManagerFactory();
EntityManager entityManager = emf.createEntityManager();
UserTransaction userTransaction = null;

try {
        
	Context context = new InitialContext();
	userTransaction = (UserTransaction) context.lookup("java:comp/UserTransaction");
	
	userTransaction.begin();

	entityManager.joinTransaction();
        
	
        // Perform the operations here ...
	entityManager.persist(someThing);
	
	userTransaction.commit();
} catch (Exception exception) {
	exception.printStackTrace();
	
	try {
		if (userTransaction != null && userTransaction.getStatus() == Status.STATUS_ACTIVE) {
			userTransaction.rollback();
		}
	} catch (Exception rollbackException) {
		rollbackException.printStackTrace();
	}
} finally {
	if (entityManager != null) {
		entityManager.close();
	}
}

As you see here, by performing the JNDI lookup on the “java:comp/UserTransaction”, you can get the WebSphere JTA UserTransaction and use it instead of the JPA EntityTransaction.