This document details the main points that need to be considered by Spring developers that wish to develop new applications or to migrate existing applications to be run into JBoss Application Server 7 (AS7).
AS7 has a modular class loading strategy, different from previous versions of JBoss AS, which enforces a better class loading isolation between deployments and the application server itself. A detailed description can be found in the documentation dedicated to class loading in AS7.
This reduces significantly the risk of running into a class loading conflict and allows applications to package their own dependencies if they choose to do so. This makes it easier for Spring applications that package their own dependencies - such as logging frameworks or persistence providers to run on JBoss AS.
At the same time, this does not mean that duplications and conflicts cannot exist on the classpath. Some module dependencies are implicit, depending on the type of deployment as shown here.
Depending on the strategy being used, Spring applications can be:
- native Hibernate applications;
- JPA-based applications;
- native JDBC applications;
Applications that use the Hibernate API directly with Spring (i.e. through either one of LocalSessionFactoryBean or AnnotationSessionFactoryBean) may use a version of Hibernate 3 packaged inside the application. Hibernate 4 (which is provided through the 'org.hibernate' module of AS7) is not supported by Spring 3.0 and Spring 3.1 (and may be supported by Spring 3.2 as described in SPR-8096), so adding this module as a dependency is not a solution.
Spring applications using JPA may choose between:
- using a server-deployed persistence unit;
- using a Spring-managed persistence unit.
Applications that use a server-deployed persistence unit must observe the typical Java EE rules in what concerns dependency management, i.e. the javax.persistence classes and persistence provider (Hibernate) are contained in modules which are added automatically by the application when the persistence unit is deployed.
In order to use the server-deployed persistence units from within Spring, either the persistence context or the persistence unit need to be registered in JNDI via web.xml as follows:
When doing so, the persistence context or persistence unit are available to be looked up in JNDI, as follows:
JNDI binding via persistence.xml properties is not supported in JBoss AS 7.0
Spring applications running in JBoss AS7 may also create persistence units on their own, using the LocalContainerEntityManagerFactoryBean. This is what these applications need to consider:
When the application server encounters a deployment that has a file named META-INF/persistence.xml (or, for that matter, WEB-INF/classes/META-INF/persistence.xml), it will attempt to create a persistence unit based on what is provided in the file. In most cases, such definition files are not compliant with the Java EE requirements, mostly because required elements such as the datasource of the persistence unit are supposed to be provided by the Spring context definitions, which will fail the deployment of the persistence unit, and consequently of the entire deployment.
Spring applications can easily avoid this type of conflict, by using a feature of the LocalContainerEntityManagerFactoryBean which is designed for this purpose. Persistence unit definition files can exist in other locations than META-INF/persistence.xml and the location can be indicated through the persistenceXmlLocation property of the factory bean class.
Assuming that the persistence unit is in the META-INF/jpa-persistence.xml, the corresponding definition can be:
Since the LocalContainerEntityManagerFactoryBean and the corresponding HibernateJpaVendorAdapter are based on Hibernate 3, it is required to use that version with the application. Therefore, the Hibernate 3 jars must be included in the deployment. At the same time, due the presence of @PersistenceUnit or @PersistenceContext annotations on the application classes, the application server will automatically add the 'org.hibernate' module as a dependency.
This can be avoided by instructing the server to exclude the module from the deployment's list of dependencies. In order to do so, include a META-INF/jboss-deployment-structure.xml or, for web applications, WEB-INF/jboss-deployment-structure.xml with the following content: