The purpose of this document is to list changes needed to run AS 5 applications in AS 7.
- 1 Class Loading Changes
- 1.1 Modular class loading
- 1.1.1 Overview
- 1.1.2 Files You May Need to Change
- 1.1.3 Module Dependencies
- 1.1.4 How to Resolve ClassNotFoundExceptions and NoCLassDefFoundErrors
- 1.1.5 How to Resolve ClassCastExceptions
- 1.1.6 How to Resolve JBoss Seam Debug Page Errors.
- 1.1.7 Where to Find Additional Information
- 2 DataSource Configuration
- 2.1 Overview
- 2.2 Define the DataSource
- 2.3 Install the JDBC Driver
- 2.4 Where to Find Additional Information
- 3 JNDI - Portable JNDI Syntax
- 4 JBoss Logging
- 4.1 Overview
- 4.2 Code Changes Required for Older Logging Frameworks
- 4.3 Code Changes Required for the New JBoss Logging Framework
- 4.4 Where to Find Additional Information
- 5 Infinispan Replacement for JPA/Hibernate Second Level Cache
- 6 Running Seam 2 archives on JBoss 7
- 7 Other Components?
Class loading in AS7 is considerably different than in previous versions of JBoss AS. Class loading is now based on the JBoss Modules project. Instead of the more familiar hierarchical class loading environment, AS7's class loading is based on modules that have to define explicit dependencies on other modules. Deployments in AS7 are also modules, and do not have access to classes that are defined in jars in the application server unless an explicit dependency on those classes is defined. Instead of the more familiar hierarchical class loading environment, AS7's class loading is based on modules that need to define explicit dependencies on other modules. Deployments in AS7 are also modules and do not have access to classes that are defined in JARs in the application server unless an explicit dependency on those classes is defined.
Even though in AS7 modules are isolated by default, as part of the deployment process some dependencies on modules defined by the application server are set up for you automatically. For instance, if you are deploying a Java EE application, a dependency on the Java EE API's will be added to your module automatically. Similarly if your module contains a beans.xml file, a dependency on Weld will be added automatically, along with any supporting modules that weld needs to operate. For a complete list of the automatic dependencies that are added see Implicit module dependencies for deployments.
If you have defined a <class-loading> element, you need to remove it. The behaviour that this provokes in EAP 5 is now the default class-loading behaviour in AS 7, so it is no longer necessary. If you do not remove this element, you will see a ParseError and XMLStreamException in your server log.
Depending on which components your application uses, you may need to add one or more dependencies to this file. There is more information about these dependencies in the following paragraphs.
The deployers within the server "implicitly" add some commonly used module dependencies, like the javax.api and sun.jdk, to the deployment so that the classes are visible to the deployment at runtime. This way the application developer doesn't have to worry about adding them explicitly. How and when these implicit dependencies are added is explained in Implicit module dependencies for deployments.
For some classes, the modules must be specified explicitly in the MANIFEST.MF as Dependencies: or “Class-Path:” entries. Otherwise you may see ClassNotFoundExceptions, NoClassDefFoundErrors, or ClassCastExceptions. You may also see runtime errors and page redirects to the JBoss Seam Debug Page. Manifest entries are explained in more detail here: Class Loading in AS7.
ClassNotFoundExceptions usually occur due to an unresolved dependency. This means you must explicitly define the dependencies on other modules.
To resolve the dependency, first, try to find the JAR that contains the class specified by the ClassNotFoundException by looking in the JBoss AS7 modules 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]
Find the JBoss module containing this class by doing the following:
1. Open a terminal and navigate to the <jboss-as7>/modules directory.
2. Issue the command: grep 'org.apache.commons.logging.Log' `find . -name '*.jar'`
3. You should see this for the result:
Binary file ./org/slf4j/jcl-over-slf4j/main/jcl-over-slf4j-1.5.10.jar matches
4. Navigate to the slf4j/jcl-over-slf4j/main directory and open the module.xml file.
The module name is "org.slf4j.jcl-over-slf4j".
5. Add the module name to the Dependencies in the MANIFEST.MF file.
6. The line in the MANIFEST.MF file will look something like this:
If the class is not found in a JAR packaged in a module defined by the AS7 server, find the JAR in your EAP5.1 install or your prior server's lib directory.
For example, you see this ClassNotFoundException in the log:
Caused by: java.lang.NoClassDefFoundError: org/hibernate/validator/ClassValidator
at java.lang.Class.getDeclaredMethods0(Native Method) [:1.6.0_25]
Find the JAR containing this class by doing the following:
1. Open a terminal and navigate to the <EAP5.1>/ directory.
2. Issue the command:
grep 'org.hibernate.validator.ClassValidator r' `find . -name '*.jar'`
3. You should see this (one of many) for the result:
Binary file ./jboss-eap-5.1/seam/lib/hibernate-validator.jar matches
4. Copy this JAR to the application's WebContent/WEB-INF/lib directory.
5. Rebuild and redeploy the application
This usually happens because the class is being loaded by a different class loader than the class it extends. First find the JAR that contains the class and determine how it is being loaded. Often you need to find and remove the JAR from the application's WAR or EAR. Then you must find the dependent JBoss module containing the class, and explicitly define the dependency in the MANIFEST.MF file.
Usually the root cause of the exception can be found in one of the links on this page, for example, under the Component org.jboss.seam.caughtException. Use the same technique above under “How to Resolve ClassNotFoundExceptions or NoCLassDefFoundErrors” to resolve the dependencies.
For more information about the class loading changes in AS7, see Class Loading in AS7.
For more information about modular class loading, see the Module Compatible Classloading Guide.
For information about deployment module dependencies, see Deployment Module Dependencies.
In previous versions of the application server, the JCA data source configuration was defined in a file with a suffix of *-ds.xml. This file was then deployed in the server's deploy directory. The JDBC driver was copied to the server lib directory or packaged in the application's WEB-INF/lib directory.
In AS7, this has all changed. You will no longer package the JDBC driver with the application or in the server/lib directory. The *-ds.xml file is now obsolete and the datasource configuration information is now defined in the standalone/configuration/standalone.xml file. JDBC driver can be installed as a deployment or as a core module.
In AS7, a datasource is configured in the server configuration file. For domain mode, this is the domain/configuration/domain.xml file. For standalone mode, this is the standalone/configuration/standalone.xml file. Schema reference information, which is the same for both modes, can be found here: Datasource Descriptors.
In AS7, you will need to create a <datasource> element and a <driver> element for your JDBC driver and datasource information in the standalone.xml file. You will use some of the same information that was previously defined in the *-ds.xml file.
The following is an example of a MySQL <datasource> element:
This is an example of the MySQL <driver> element:
The JDBC driver can be installed in one of two ways: either as a deployment or as a core module.
When you install the JDBC driver as a deployment, it is deployed as a regular JAR. This is the recommended way to install the driver. When you run your application server in domain mode, deployments are automatically propagated to all servers to which the deployment applies; thus distribution of the driver JAR is one less thing for administrators to worry about.
Any JDBC 4-compliant driver will automatically be recognized and installed into the system by name and version. A JDBC compliant JAR is identified using the Java service provider mechanism. It contains a text a file named "META-INF/services/java.sql.Driver", which contains the name of the class(es) of the Drivers which exist in that JAR. If your JDBC driver JAR is not JDBC 4-compliant, it can be made deployable by adding the java.sql.Driver file to the JAR or by deploying the JAR with an overlay. More information on that topic can be found here: Installing a JDBC Driver as a Deployment.
In AS7 standalone mode, you simply copy the JDBC 4-compliant JAR into the standalone/deployments directory. Here is an example of a MySQL JDBC driver installed as a deployment:
To install the driver as a module, you will need to create a directory structure under the modules folder. This structure will contain the driver and a module.xml file to define the module.
For example, using the MySQL JDBC driver above, you would create a directory structure as follows:
In the main directory, you then create the following module.xml file:
The module name, “com.mysql”, matches the directory structure for this module. Under dependencies, you specify the module's dependencies on other modules. In this case, as the case with all JDBC data sources, it is dependent on the Java JDBC APIs which are defined in another module named javax.api that is located under modules/javax/api/main.
EJB 3.1 introduced a standardized global JNDI namespace and a series of related namespaces that map to the various scopes of a Java EE application. The three JNDI namespaces used for portable JNDI lookups are java:global, java:module, and java:app. If you use JNDI lookups in your application, you will need to change them to follow the new standardized JNDI namespace convention.
Here's an example of a JNDI lookup in EAP 5.1. This code is usually found in an initialization method. Note, the lookup name is: “OrderManagerApp/ProductManagerBean/local”.
Here is an example of how the same lookup would be coded in AS7. This code is defined as member variables. The lookup name now uses the new portable java:app JNDI namespace: “java:app/OrderManagerEJB/ProductManagerBean!services.ejb.ProductManager”
JBoss LogManager supports front ends for all logging frameworks, so you can keep your current logging code or move to the new JBoss logging infrastructure. Regardless of your decision, because of the modular class loading changes, you will probably need to modify your application to add the required dependencies.
If you are using the commons logging, your code will look something like the following:
To avoid a ClassNotFoundException, you will need to add a dependency for the JBoss module that contains those classes. The JAR containing the commons logging classes is the jcl-over-slf4j-1.5.10.jar and it is located under module/org/slf4j/jcl-over-slf4j/main. The module name, taken from the module.xml file located in that directory is ”org.slf4j.jcl-over-slf4j”, so your our MANIFEST-MF file will look like this:
To use the new framework, you will need the change your imports and code as follows to achieve the same results as above:
The JAR containing the JBoss LogManager classes is jboss-logmanager-1.2.0.CR7.jar and is located under modules/org/jboss/logmanager/main. The module name, taken from the module.xml file located in that directory is ”org.jboss.logmanager”, so your MANIFEST-MF file will look like this:
For more information on how to find the module dependency, please see “How to Resolve ClassNotFoundExceptions” under the “Modular Class Loading” above.
JBoss Cache has been replaced by Infinispan for 2nd level cache. This requires a change to the persistence.xml file. The syntax is slightly different, depending on if you're using JPA or Hibernate second level cache. These examples assume you are using Hibernate.
Here's an example of the persistence.xml file in EAP 5.1:
Here is what is needed to configure the same thing using Infinispan:
Many of the properties are the same. However, there are a few changes:
- You need to you need to select the correct Hibernate transaction factory using the hibernate.transaction.factory_class property.
- You need to select the correct Hibernate transaction manager lookup class using the hibernate.transaction.manager_lookup_class property.
- You need to configure the Infinispan cache region factory using one of the two options below:
- If the Infinispan CacheManager is bound to JNDI, select JndiInfinispanRegionFactory as the cache region factory and add the cache manager’s JNDI name
- If running JPA/Hibernate and Infinispan standalone or within third party application server, select InfinispanRegionFactory as the cache region factory