Class loading in AS7 is considerably different to previous versions of JBoss AS. Class loading is 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.

Deployment Module Names

Module names for top level deployments follow the format deployment.myarchive.war while sub deployments are named like deployment.myear.ear.mywar.war.

This means that it is possible for a deployment to import classes from another deployment using the other deployments module name, the details of how to add an explicit module dependency are explained below.

Automatic Dependencies

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 this page.

Automatic dependencies can be excluded through the use of jboss-deployment-structure.xml.

Class Loading Precedence

A common source of errors in Java applications is including API classes in a deployment that are also provided by the container. This can result in multiple versions of the class being created and the deployment failing to deploy properly. To prevent this in AS7, module dependencies are added in a specific order that should prevent this situation from occurring.

In order of highest priority to lowest priority

System Dependencies - These are dependencies that are added to the module automatically by the container, including the Java EE api's.

User Dependencies - These are dependencies that are added through jboss-deployment-structure.xml or through the Dependencies: manifest entry.

Local Resource - Class files packaged up inside the deployment itself, e.g. class files from WEB-INF/classes or WEB-INF/lib of a war.

Inter deployment dependencies - These are dependencies on other deployments in an ear deployment. This can include classes in an ear's lib directory, or classes defined in other ejb jars.

WAR Class Loading

The war is considered to be a single module, so classes defined in WEB-INF/lib are treated the same as classes in WEB-INF/classes. All classes packaged in the war will be loaded with the same class loader.

EAR Class Loading

Ear deployments are multi-module deployments. This means that not all classes inside an ear will necessarily have access to all other classes in the ear, unless explicit dependencies have been defined. By default the EAR/lib directory is a single module, and every WAR or EJB jar deployment is also a separate module. Sub deployments (wars and ejb-jars) always have a dependency on the parent module, which gives them access to classes in EAR/lib, however they do not always have an automatic dependency on each other. This behaviour is controlled via the ear-subdeployments-isolated setting in the ee subsystem configuration:

By default this is set to false, which allows the sub-deployments to see classes belonging to other sub-deployments within the .ear.

For example, consider the following .ear deployment:

If the ear-subdeployments-isolated is set to false, then the classes in web.war can access classes belonging to ejb1.jar and ejb2.jar. Similarly, classes from ejb1.jar can access classes from ejb2.jar (and vice-versa).

The ear-subdeployments-isolated element value has no effect on the isolated classloader of the .war file(s). i.e. irrespective of whether this flag is set to true or false, the .war within a .ear will have an isolated classloader and other sub-deployments within that .ear will not be able to access classes from that .war. This is as per spec.

If the ear-subdeployments-isolated is set to true then no automatic module dependencies between the sub-deployments are set up. User must manually setup the dependency with Class-Path entries, or by setting up explicit module dependencies.

PortabilityThe Java EE specification says that portable applications should not rely on sub deployments having access to other sub deployments unless an explicit Class-Path entry is set in the MANIFEST.MF. So portable applications should always use Class-Path entry to explicitly state their dependencies.

It is also possible to override the ear-subdeployments-isolated element value at a per deployment level. See the section on jboss-deployment-structure.xml below.

Dependencies: Manifest Entries

Deployments (or more correctly modules within a deployment) may set up dependencies on other modules by adding a Dependencies: manifest entry. This entry consists of a comma separated list of module names that the deployment requires. The available modules can be seen under the modules directory in the application server distribution. For example to add a dependency on javassist and apache velocity you can add a manifest entry as follows:

Each dependency entry may also specify some of the following parameters by adding them after the module name:

export This means that the dependencies will be exported, so any module that depends on this module will also get access to the dependency.

services By default items in META-INF of a dependency are not accessible, this makes items from META-INF/services accessible so services in the modules can be loaded.

optional If this is specified the deployment will not fail if the module is not available.

annotations If a jandex index has be created for the module these annotations will be merged into the deployments annotation index. The Jandex index can be generated using the Jandex ant task , and must be named META-INF/jandex.idx. Note that it is not necessary to break open the jar being indexed to add this to the modules class path, a better approach is to create a jar containing just this index, and adding it as an additional resource root in the module.xml file.

Adding a dependency to all modules in an EARUsing the export parameter it is possible to add a dependency to all sub deployments in an ear. If a module is exported from a Dependencies: entry in the top level of the ear (or by a jar in the ear/lib directory) it will be available to all sub deployments as well.

To generate a MANIFEST.MF entry when using maven put the following in your pom.xml:

pom.xml

If your deployment is a jar you must use the maven-jar-plugin rather than the maven-war-plugin.

Class Path Entries

It is also possible to add module dependencies on other modules inside the deployment using the Class-Path manifest entry. This can be used within an ear to set up dependencies between sub deployments, and also to allow modules access to additional jars deployed in an ear that are not sub deployments and are not in the EAR/lib directory. If a jar in the EAR/lib directory references a jar via Class-Path: then this additional jar is merged into the parent ear's module, and is accessible to all sub deployments in the ear.

Global Modules

It is also possible to set up global modules, that are accessible to all deployments. This is done by modifying the configuration file (standalone/domain.xml).

For example, to add javassist to all deployments you can use the following XML:

standalone.xml/domain.xml

Note that the slot field is optional and defaults to main.

JBoss Deployment Structure File

jboss-deployment-structure.xml is a JBoss specific deployment descriptor that can be used to control class loading in a fine grained manner. It should be placed in the top level deployment, in META-INF (or WEB-INF for web deployments). It can do the following:

Prevent automatic dependencies from being added

Add additional dependencies

Define additional modules

Change an EAR deployments isolated class loading behaviour

Add additional resource roots to a module

Exclude Subsystem DependencyTo exclude subsystem within a module, you will will want to exclude the entire module and then add back in each of the subsystems that make the module minus the subsystem that needs to be excluded.

e.g. exclude javax.ws.rs.api from javaee.api module

jboss-deployment-structure

An example of a complete jboss-deployment-structure.xml file for an ear deployment is as follows:

It will be helpful to have an example indicating how to specify dependencies across multiple deployments.

For example an EAR deployed share some of the EJBs from another EAR deployed within the same container.

If I have an EAR which is essentially a library(a set of generic EJBs and Webservices shared between several other applications), is it possible to install it as a separate module ? Will those EJBs still be deployed ? Will it continue to provide a web-context for accessing web services ?

I built my own jboss-deployment-structure.xml using the XSD as reference, but I kept getting this error (which in my past experience comes from an XML not conforming to the expected schema), so I loaded up just the example above (not caring about anything past parsing) and I still get there error. Is this a problem with EAP6?

In our application we've an jboss-deployment-structure.xml file deployed within the EAR file which disables Weld. Thats how it is and because im not allowed to remove it i've to find a workaround.

Within my EAR file i want to deploy a WAR file which should be able to use CDI. How to enable Weld/CDI for this specific WAR file? I've allready tried to put a jboss-deployment-structure.xml inside the WAR file, but it seems to be irrelevant for JBoss.

I am FINALLY upgrading from JBoss 5.x to JBoss EAP 7.x. In JBoss 5, I had an myapp.ear and an executable data.jar - both in the deploy directory. The classes in the ear call/reference classes from the jar. I can get the executable jar to deploy in 7.x, but when I add the ear, the ear doesn't deploy because of a ClassNotFoundException for a class from the jar. I cannot find an example of how to properly deploy both of these items in AS7 and enable the ear to see the jar's classes.