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.

Protect your Java web application from the consequences of uploading large files

Problem Description:
Sometimes in our web applications, we provide HTML file inputs to our application users so they can upload their documents to the server.

BUT what will happen if a user or more upload a 3 or 4 or more giga bytes files to the server in the same time?
Unfortunately the server may have an OutOfMemory exception.

Another problem is that the client side file size validation is not supported on all browsers for security reasons (Actually the only allowed file size validation is on IE through the “Scripting.FileSystemObject” ActiveX control). So this sort of validation unfortunately has to be done on the server side???

Problem Solution:
Limiting the HTTP post size through setting a value for the (PostSizeLimit) parameter in the HTTP server.
In the IBM HTTP server (for example), this parameter exists in a file called (plugin-cfg.xml) under (/WebSphere/AppServer/config/cells).

Setting the PostSizeLimit to “20971520” means that the maximum file size to be allowed is 20 MB.
And setting the PostSizeLimit parameter to “-1” means unlimited post size.

I wish that this tip can be useful to you guys.