Red Hat Training

A Red Hat training course is available for Red Hat JBoss Enterprise Application Platform

4.2. Debug Migration Issues

4.2.1. Debug and Resolve Migration Issues

Due to class loading, JNDI naming rules, and other changes in the application server, you may encounter exceptions or other errors if you try to deploy your application "as-is". The following describes how to resolve some of the more common exceptions and errors you might encounter.

4.2.2. Debug and Resolve ClassNotFoundExceptions and NoClassDefFoundErrors

Summary

ClassNotFoundExceptions usually occur due to an unresolved dependency. This means you must explicitly define the dependencies on other modules or copy JARs from external sources.

  1. First, try to find the missing dependency. This is described in more detail here: Section 4.2.3, “Find the JBoss Module Dependency”
  2. If there is not a module for the missing class, find the JAR in the previous install. For more information, see Section 4.2.4, “Find the JAR in the Previous Install”

4.2.3. Find the JBoss Module Dependency

To resolve the dependency, first, try to find the module that contains the class specified by the ClassNotFoundException by looking in the EAP_HOME/modules/system/layers/base/ directory. If you find a module for the class, you must add a dependency to the manifest entry.
For example, if you see this ClassNotFoundException trace in the log:
Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.Log 
    from [Module "deployment.TopicIndex.war:main" from Service Module Loader]
    at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:188)
Find the JBoss module containing this class by doing the following:

Procedure 4.5. Find the Dependency

  1. First determine if there is an obvious module for the class.
    1. Navigate to the EAP_HOME/modules/system/layers/base/ directory and look for the module path matching class named in the ClassNotFoundException.
      You find the module path org/apache/commons/logging/.
    2. Open the EAP_HOME/modules/system/layers/base/org/apache/commons/logging/main/module.xml file and find the module name. In this case, it is "org.apache.commons.logging".
    3. Add the module name to the Dependencies in the MANIFEST.MF file:
      Manifest-Version: 1.0
      Dependencies: org.apache.commons.logging
      
  2. If there is no obvious module path for the class, you may need to find the dependency in another location.
    1. Find the class named by the ClassNotFoundException in the Tattletale report.
    2. Find the module containing the JAR in the EAP_HOME/modules directory and find the module name as in the previous step.

4.2.4. Find the JAR in the Previous Install

If the class is not found in a JAR packaged in a module defined by the server, find the JAR in your EAP5_HOME install or your prior server's lib/ directory.
For example, if you see this ClassNotFoundException trace in the log:
Caused by: java.lang.NoClassDefFoundError: org/hibernate/validator/ClassValidator at java.lang.Class.getDeclaredMethods0(Native Method)
Find the JAR containing this class by doing the following:
  1. Open a terminal and navigate to the EAP5_HOME/ directory.
  2. Issue the command:
    grep 'org.hibernate.validator.ClassValidator' `find . \-name '*.jar'`
  3. You might see more than one result. In this case, the following result is the JAR we need:
    Binary file ./jboss-eap-5.1/seam/lib/hibernate-validator.jar matches
  4. Copy this JAR to the application's lib/ directory.
    If you find that you need a large number of JARs, it may be easier to define a module for the classes. For more information, see Modules in the chapter entitled Get Started Developing Applications in the Development Guide for JBoss EAP 6 on https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/?version=6.4.
  5. Rebuild and redeploy the application.

4.2.5. Debug and Resolve ClassCastExceptions

ClassCastExceptions often happen because a class is being loaded by a different class loader than the class it extends. They can also be a result of the same class existing in multiple JARs.
  1. Search the application to find all JAR(s) that contain the class named by the ClassCastException. If there is a module defined for the class, find and remove the duplicate JAR(s) from the application's WAR or EAR.
  2. Find the JBoss module containing the class and explicitly define the dependency in the MANIFEST.MF file or in the jboss-deployment-structure.xml file. For more information, see Class Loading and Subdeployments in the chapter entitled Class Loading and Modules in the Development Guide for JBoss EAP 6 on https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/?version=6.4.
  3. If you are not able to resolve it using the steps above, you can often determine the cause of the problem by printing the class loader information to the log. For example, you see the following ClassCastException in the log:
    java.lang.ClassCastException: com.example1.CustomClass1 cannot be cast to com.example2.CustomClass2
    1. In your code, print the class loader information for the classes named by the ClassCastException to the log, for example:
      logger.info("Class loader for CustomClass1: " + 
            com.example1.CustomClass1.getClass().getClassLoader().toString());
      logger.info("Class loader for CustomClass2: " + 
            com.example2.CustomClass2.getClass().getClassLoader().toString());
      
    2. The information in the log shows which modules are loading the classes and, based on your application, you need to remove or move the conflicting JAR(s).

4.2.6. Debug and Resolve DuplicateServiceExceptions

If you get a DuplicateServiceException for a subdeployment of a JAR or a message that the WAR application has already been installed when you deploy your EAR in JBoss EAP 6, it may be due to changes in the way JBossWS handles the deployment.
The JBossWS 3.3.0 release introduced a new Context Root Mapping Algorithm for servlet based endpoints to allow it to become seamlessly compatible with TCK6. If the application EAR archive contains a WAR and a JAR with the same name, JBossWS may create a WAR context and web context with the same name. The web context conflicts with the WAR context and this results in deployment errors. Resolve the deployment issues in one of the following ways:
  • Rename the JAR file to a name that is different than the WAR so the generated web and WAR contexts is unique.
  • Provide a <context-root> element in the jboss-web.xml file.
  • Provide a <context-root> element in the jboss-webservices.xml file.
  • Customize the <context-root> element for the WAR in the application.xml file.

4.2.7. Debug and Resolve JBoss Seam Debug Page Errors

After you migrate and successfully deploy your application, you may encounter a runtime error that redirects you to the "JBoss Seam Debug" page. The URL for this page is "http://localhost:8080/APPLICATION_CONTEXT/debug.seam". This page allows you to view and inspect the Seam components in any of the Seam contexts associated with your current login session.
JBoss Seam Debug Page

Figure 4.1. JBoss Seam Debug Page

The most likely reason you are redirected to this page is because Seam has caught an Exception that was not handled in the application code. The root cause of the exception can often be found in one of the links on the "JBoss Seam Debug Page".
  1. Expand the Component section on the page and look for the org.jboss.seam.caughtException component.
  2. The cause and stack trace should point you to the missing dependencies.
    Component org.jboss.seam.caughtException information

    Figure 4.2. Component org.jboss.seam.caughtException information

  3. Use the technique described in Section 4.2.2, “Debug and Resolve ClassNotFoundExceptions and NoClassDefFoundErrors” to resolve module dependencies.
    In the example above, the simplest solution is to add org.slf4j to the MANIFEST.MF
    Manifest-Version: 1.0
    Dependencies: org.slf4j
    
    Another option is to add a dependency for the module to the jboss-deployment-structure.xml file:
    <jboss-deployment-structure>
       <deployment>
            <dependencies>
              <module name="org.slf4j" />
            </dependencies>
        </deployment>
    </jboss-deployment-structure>