JBoss Community Archive (Read Only)

JBoss AS 7.2

Porting the Order Application from EAP 5.1 to AS 7

Andy Miller ported an example Order application that was used for performance testing from EAP 5.1 to AS 7. These are the notes he made during the migration process.

Overview of the application

The application is relatively simple. it contains three servlets, some stateless session beans, a stateful session bean, and some entities.

In addition to application code changes, modifications were made to the way the EAR was packaged. This is because AS7 removed support of some proprietary features that were available in EAP 5.1.

Summary of changes

Code Changes

Modify JNDI lookup code

Since this application was first written for EAP 4.2/4.3, which did not support EJB reference injection, the servlets were using pre-EE 5 methods for looking up stateless and stateful session bean interfaces. While migrating to AS7, it seemed a good time to change the code to use the @EJB annotation, although this was not a required change.

The real difference is in the lookup name. AS 7 only supports the new EE 6 portable JNDI names rather than the old EAR structure based names. The JNDI lookup code changed as follows:

Example of code in the EAP 5.1 version:

try {
    context = new InitialContext();
    distributionCenterManager = (DistributionCenterManager) context.lookup("OrderManagerApp/DistributionCenterManagerBean/local");
} catch(Exception lookupError) {
    throw new ServletException("Couldn't find DistributionCenterManager bean", lookupError);
}
try {
    customerManager = (CustomerManager) context.lookup("OrderManagerApp/CustomerManagerBean/local");
} catch(Exception lookupError) {
    throw new ServletException("Couldn't find CustomerManager bean", lookupError);
}

try {
    productManager = (ProductManager) context.lookup("OrderManagerApp/ProductManagerBean/local");
} catch(Exception lookupError) {
    throw new ServletException("Couldn't find the ProductManager bean", lookupError);
}

Example of how this is now coded in AS7:

@EJB(lookup="java:app/OrderManagerEJB/DistributionCenterManagerBean!services.ejb.DistributionCenterManager")
private DistributionCenterManager distributionCenterManager;

@EJB(lookup="java:app/OrderManagerEJB/CustomerManagerBean!services.ejb.CustomerManager")
private CustomerManager customerManager;

@EJB(lookup="java:app/OrderManagerEJB/ProductManagerBean!services.ejb.ProductManager")
private ProductManager productManager;

In addition to the change to injection, which was supported in EAP 5.1.0, the lookup name changed from:

OrderManagerApp/DistributionCenterManagerBean/local

to:

java:app/OrderManagerEJB/DistributionCenterManagerBean!services.ejb.DistributionCenterManager

All the other beans were changed in a similar manner. They are now based on the portable JNDI names described in EE 6.

Modify logging code

The next major change was to logging within the application. The old version was using the commons logging infrastructure and Log4J that is bundled in the application server. Rather than bundling third-party logging, the application was modified to use the new JBoss Logging infrastructure.

The code changes themselves are rather trivial, as this example illustrates:

Old JBoss Commons Logging/Log4J:

private static Log log = LogFactory.getLog(CustomerManagerBean.class);

New JBoss Logging

private static Logger logger = Logger.getLogger(CustomerManagerBean.class.toString());

Old JBoss Commons Logging/Log4J:

if(log.isTraceEnabled()) {
    log.trace("Just flushed " + batchSize + " rows to the database.");
    log.trace("Total rows flushed is " + (i+1));
}

New JBoss Logging:

if(logger.isLoggable(Level.TRACE)) {
    logger.log(Level.TRACE, "Just flushed " + batchSize + " rows to the database.");
    logger.log(Level.TRACE, "Total rows flushed is " + (i+1));
}

In addition to the code changes made to use the new AS7 JBoss log manager module, you must add this dependency to the MANIFEST.MF file as follows:

Manifest-Version: 1.0
Dependencies: org.jboss.logmanager

Modify the code to use Infinispan for 2nd level cache

Jboss Cache has been replaced by Infinispan for 2nd level cache. This requires modification of the persistence.xml file.

This is what the file looked like in EAP 5.1:

<properties>
<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.jbc2.JndiMultiplexedJBossCacheRegionFactory"/>
<property name="hibernate.cache.region.jbc2.cachefactory" value="java:CacheManager"/>
<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.use_query_cache" value="false"/>
<property name="hibernate.cache.use_minimal_puts" value="true"/>
<property name="hibernate.cache.region.jbc2.cfg.entity" value="mvcc-entity"/>
<property name="hibernate.cache.region_prefix" value="services"/>
</properties>

This is how it was modified to use Infinispan for the same configuration:

<properties>
<property name="hibernate.cache.use_second_level_cache" value="true"/>
<property name="hibernate.cache.use_minimal_puts" value="true"/>
</properties>
<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>

Most of the properties are removed since they will default to the correct values for the second level cache.  See "Using the Infinispan second level cache" for more details.

That was the extent of the code changes required to migrate the application to AS7.

EAR Packaging Changes

Due to modular class loading changes, the structure of the existing EAR failed to deploy successfully in AS7.

The old structure of the EAR was as follows:

$ jar tf OrderManagerApp.ear
META-INF/MANIFEST.MF
META-INF/application.xml
OrderManagerWeb.war
OrderManagerEntities.jar
OrderManagerEJB.jar
META-INF/

In this structure, the entities and the persistence.xml were in one jar file, OrderManagerEntities.jar, and the stateless and stateful session beans were in another jar file, OrderManagerEJB.jar. This did not work due to modular class loading changes in AS 7. There are a couple of ways to resolve this issue:

  1. Modify the class path in the MANIFEST.MF

  2. Flatten the code and put all the beans in one JAR file.

The second approach was selected because it simplified the EAR structure:

$ jar tf OrderManagerApp.ear
META-INF/application.xml
OrderManagerWeb.war
OrderManagerEJB.jar
META-INF/

Since there is no longer an OrderManagerEntities.jar file, the applcation.xml file was modified to remove the entry.

An entry was added to the MANIFEST.MF file in the OrderManagerWeb.war to resolve another class loading issue resulting from the modification to use EJB reference injection in the servlets.

Manifest-Version: 1.0
Dependencies: org.jboss.logmanager
Class-Path: OrderManagerEJB.jar

The Class-Path entry tells the application to look in the OrderManagerEJB.jar file for the injected beans.

Summary

Although the existing EAR structure could have worked with additional modifications to the MANIFEST.MF file, this approach seemed more appealing because it simplified the structure while maintaining the web tier in its own WAR.

The source files for both versions is attached so you can view the changes that were made to the application.

JBoss.org Content Archive (Read Only), exported from JBoss Community Documentation Editor at 2020-03-13 13:27:53 UTC, last content change 2012-05-15 17:44:27 UTC.