Este contenido no está disponible en el idioma seleccionado.
Chapter 3. Migrate Your Application
3.1. Changes Required by Most Applications
3.1.1. Review Changes Required by Most Applications
3.1.2. Class Loading Changes
3.1.2.1. Update the Application Due to Class Loading Changes
- First, look at the packaging of your application and its dependencies. For more information, see: Section 3.1.2.3, “Update Application Dependencies Due to Class Loading Changes”
- If your application does logging, you need to specify the correct module dependencies. For more information, see: Section 3.1.4.1, “Modify Logging Dependencies”
- Due to the modular class loading changes, you may have to change the packaging structure of your EAR or WAR. For more information, see: Section 3.1.5.1, “Modify Packaging of EARs and WARs”
3.1.2.2. Understand Module Dependencies
A module is only able to access its own classes and the classes of any module on which it has an explicit or implicit dependency.
The deployers within the server implicitly automatically add some commonly used module dependencies, like the javax.api
and sun.jdk
. This makes the classes visible to the deployment at runtime and relieves the developer of the task of explicitly adding the dependencies. For details on how and when these implicit dependencies are added, refer to Implicit Module Dependencies 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.
For other classes, the modules must be specified explicitly or else the missing dependencies result in deployment or runtime errors. If a dependency is missing, you see ClassNotFoundExceptions
or NoClassDefFoundErrors
traces in the server log. If more than one module loads the same JAR or a module loads a class that extends a class loaded by a different module, you see ClassCastExceptions
traces in the server log. To specify dependencies explicitly, modify the MANIFEST.MF
or create a JBoss specific deployment descriptor file jboss-deployment-structure.xml
. For more information on module dependencies, see Overview of Class Loading and Modules in the chapter entitled Class Loading and Module 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.1.2.3. Update Application Dependencies Due to Class Loading Changes
Class loading in JBoss EAP 6 is considerably different from previous versions of JBoss EAP. Class loading is now based on the JBoss Modules project. Rather than a single, hierarchical class loader that loads all JARs into a flat class path, each library becomes a module that only links against the exact modules on which it depends. Deployments in JBoss EAP 6 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. Some module dependencies 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 is added automatically, or implicitly. For the complete list of dependencies automatically added by the server, see Implicit Module Dependencies 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.
When you migrate your application to JBoss EAP 6, you might need to perform one or more of the following tasks due to the modular class loading changes:
3.1.3. Configuration File Changes
3.1.3.1. Create or Modify Files That Control Class Loading in JBoss EAP 6
Due to the change in JBoss EAP 6 to use modular class loading, you might need to create or modify one or more files to add dependencies or to prevent automatic dependencies from loading. For more information on class loading and class loading precedence, see 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.
- jboss-web.xml
- If you have defined a
<class-loading>
element in thejboss-web.xml
file, you need to remove it. The behavior that this evoked in JBoss EAP 5 is now the default class loading behavior in JBoss EAP 6, so it is no longer necessary. If you do not remove this element, you see a ParseError and XMLStreamException in your server log.This is an example of a<class-loading>
element in thejboss-web.xml
file that is commented out.<!DOCTYPE jboss-web PUBLIC "-//JBoss//DTD Web Application 4.2//EN" "http://www.jboss.org/j2ee/dtd/jboss-web_4_2.dtd"> <jboss-web> <!-- <class-loading java2ClassLoadingCompliance="false"> <loader-repository> seam.jboss.org:loader=MyApplication <loader-repository-config>java2ParentDelegation=false</loader-repository-config> </loader-repository> </class-loading> --> </jboss-web>
- MANIFEST.MF
- Manually edited
- Depending on which components or modules your application uses, you might need to add one or more dependencies to this file. You can add them as either
Dependencies
orClass-Path
entries.The following is an example ofMANIFEST.MF
edited by a developer:Manifest-Version: 1.0 Dependencies: org.jboss.logmanager Class-Path: OrderManagerEJB.jar
If you modify this file, be sure to include a newline character at the end of the file. - Generated using Maven
- If you use Maven, you need to modify your
pom.xml
file to generate the dependencies for theMANIFEST.MF
file. If your application uses EJB 3.0, you might have a section in thepom.xml
file that looks like the following:<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-ejb-plugin</artifactId> <configuration> <ejbVersion>3.0</ejbVersion> </configuration> </plugin>
If the EJB 3.0 code usesorg.apache.commons.log
, you need that dependency in theMANIFEST.MF
file. To generate that dependency, add the<plugin>
element to thepom.xml
file as follows:<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-ejb-plugin</artifactId> <configuration> <ejbVersion>3.0</ejbVersion> <archive> <manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile> </archive> </configuration> </plugin>
In the above example, thesrc/main/resources/META-INF/MANIFEST.MF
file only needs to contain the dependency entry:Dependencies: org.apache.commons.logging
Maven will generate the completeMANIFEST.MF
file:Manifest-Version: 1.0 Dependencies: org.apache.commons.logging
- jboss-deployment-structure.xml
- This file is a JBoss specific deployment descriptor that can be used to control class loading in a fine grained manner. Like the
MANIFEST.MF
, this file can be used to add dependencies. It can also prevent automatic dependencies from being added, define additional modules, change an EAR deployment's isolated class loading behavior, and add additional resource roots to a module.The following is an example of ajboss-deployment-structure.xml
file that adds a dependency for JSF 1.2 module and prevents the automatic loading of the JSF 2.0 module.<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.0"> <deployment> <dependencies> <module name="javax.faces.api" slot="1.2" export="true"/> <module name="com.sun.jsf-impl" slot="1.2" export="true"/> </dependencies> </deployment> <sub-deployment name="jboss-seam-booking.war"> <exclusions> <module name="javax.faces.api" slot="main"/> <module name="com.sun.jsf-impl" slot="main"/> </exclusions> <dependencies> <module name="javax.faces.api" slot="1.2"/> <module name="com.sun.jsf-impl" slot="1.2"/> </dependencies> </sub-deployment> </jboss-deployment-structure>
For additional information about this file, see: Section 3.1.3.2, “jboss-deployment-structure.xml”. - application.xml
- In previous versions of JBoss EAP, you controlled the order of deployments within an EAR using the
jboss-app.xml
file. This is no longer the case. The Java EE6 spec provides the<initialize-in-order>
element in theapplication.xml
which allows control of the order in which the Java EE modules within an EAR are deployed.In most cases you do not need to specify deployment order. If your application uses dependency injections and resource-refs to refer to components in external modules, in most cases the<initialize-in-order>
element is not required because the application server is able to implicitly determine the correct and optimal way of ordering the components.Let's assume you have an application that contains amyBeans.jar
and amyApp.war
that are packaged within amyApp.ear
. A servlet in themyApp.war
uses an@EJB
annotation to inject a bean from themyBeans.jar
. In this case, the application server has the appropriate knowledge to be sure that the EJB component is available before the servlet is started and you do not have to use the<initialize-in-order>
element.However, if that servlet uses legacy JNDI lookup style remote references like the following to access the bean, you might need to specify module order.init() { Context ctx = new InitialContext(); ctx.lookup("TheBeanInMyBeansModule"); }
In this case, the server is not able to determine that the EJB component is in themyBeans.jar
and you need to enforce that the components in themyBeans.jar
are initialized and started before the components inmyApp.war
. To do this, you set the<initialize-in-order>
element totrue
and specify the order of themyBeans.jar
andmyApp.war
modules in theapplication.xml
file.The following is an example that uses the<initialize-in-order>
element to control deployment order. ThemyBeans.jar
is deployed before themyApp.war
file.<application xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="6" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd"> <application-name>myApp</application-name> <initialize-in-order>true</initialize-in-order> <module> <ejb>myBeans.jar</ejb> </module> <module> <web> <web-uri>myApp.war</web-uri> <context-root>myApp</context-root> </web> </module> </application>
The schema for theapplication.xml
file can be found here at http://java.sun.com/xml/ns/javaee/application_6.xsd.Note
Be aware that setting the<initialize-in-order>
element totrue
slows down deployment. It is preferable to define proper dependencies using dependency injections or resource-refs because it allows the container more flexibility in optimizing deployments. - jboss-ejb3.xml
- The
jboss-ejb3.xml
deployment descriptor replaces thejboss.xml
deployment descriptor to override and add to the features provided by the Java Enterprise Edition (EE) definedejb-jar.xml
deployment descriptor. The new file is incompatible withjboss.xml
, and thejboss.xml
is now ignored in deployments. - login-config.xml
- The
login-config.xml
file is no longer used for security configuration. Security is now configured in the<security-domain>
element in the server configuration file. For a standalone server, this is thestandalone/configuration/standalone.xml
file. If you are running your server in a managed domain, this is thedomain/configuration/domain.xml
file.
3.1.3.2. jboss-deployment-structure.xml
jboss-deployment-structure.xml
is a new optional deployment descriptor for JBoss EAP 6. This deployment descriptor provides control over class loading in the deployment.
EAP_HOME/docs/schema/jboss-deployment-structure-1_2.xsd
3.1.3.3. Package Resources for the New Modular Class Loading System
In previous versions of JBoss EAP, all resources inside the WEB-INF/
directory were added to the WAR classpath. In JBoss EAP 6, web application artifacts are only loaded from the WEB-INF/classes
and WEB-INF/lib
directories. Failure to package application artifacts in the specified locations can result in ClassNotFoundException
, NoClassDefError
, or other runtime errors.
- Modify the Resource Packaging
- To make the resources available only to the application, you must bundle the properties files, JARs, or other artifacts with the WAR by moving them to the
WEB-INF/classes/
orWEB-INF/lib/
directory. This approach is described in more detail here: Section 3.1.3.4, “Change ResourceBundle Properties Location” - Create a Custom Module
- If you want make custom resources available to all applications running on the JBoss EAP 6 server, you must create a custom module. This approach is described in more detail here: Section 3.1.3.5, “Create a Custom Module”
3.1.3.4. Change ResourceBundle Properties Location
In previous versions of JBoss EAP, the EAP_HOME/server/SERVER_NAME/conf/
directory was in the classpath and available to the application. To make properties available to the classpath of the application in JBoss EAP 6, you must package them within your application.
Procedure 3.1. Change the ResourceBundle Properties Location
- If you are deploying a WAR archive, you must package those properties in the WAR's
WEB-INF/classes/
folder. - If you want those properties accessible to all components in an EAR, then you must package them at the root of a JAR and then place the JAR in EAR's
lib/
folder.
3.1.3.5. Create a Custom Module
Procedure 3.2. Create a Custom Module
- Create and populate the
module/
directory structure.- Create a directory structure under the
EAP_HOME/module
directory to contain the files and JARs. For example:$ cd EAP_HOME/modules/
$ mkdir -p myorg-conf/main/properties
- Move the properties files to the
EAP_HOME/modules/myorg-conf/main/properties/
directory you created in the previous step. - Create a
module.xml
file in theEAP_HOME/modules/myorg-conf/main/
directory containing the following XML:<module xmlns="urn:jboss:module:1.1" name="myorg-conf"> <resources> <resource-root path="properties"/> </resources> </module>
- Modify the
ee
subsystem in the server configuration file. You can use the Managemet CLI or you can manually edit the file.- Follow these steps to modify the server configuration file using the Management CLI.
- Start the server and connect to the Management CLI.
- For Linux, enter the following at the command line:
EAP_HOME/bin/jboss-cli.sh --connect
- For Windows, enter the following at a command line:
C:\>EAP_HOME\bin\jboss-cli.bat --connect
You should see the following response:Connected to standalone controller at localhost:9999
- To create the
myorg-conf
<global-modules> element in theee
subsystem, type the following in the command line:/subsystem=ee:write-attribute(name=global-modules, value=[{"name"=>"myorg-conf","slot"=>"main"}])
You should see the following result:{"outcome" => "success"}
- Follow these steps if you prefer to manually edit the server configuration file.
- Stop the server and open the server configuration file in a text editor. If you are running a standalone server, this is the
EAP_HOME/standalone/configuration/standalone.xml
file, or theEAP_HOME/domain/configuration/domain.xml
file if you are running a managed domain. - Find the
ee
subsystem and add the global module formyorg-conf
. The following is an example of theee
subsystem element, modified to include themyorg-conf
element:Example 3.1.
myorg-conf
element<subsystem xmlns="urn:jboss:domain:ee:1.0" > <global-modules> <module name="myorg-conf" slot="main" /> </global-modules> </subsystem>
- Assuming you copied a file named
my.properties
into the correct module location, you are now able to load properties files using code similar to the following:Example 3.2. Load properties file
Thread.currentThread().getContextClassLoader().getResource("my.properties");
3.1.4. Logging Changes
3.1.4.1. Modify Logging Dependencies
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 probably need to modify your application to add the required dependencies.
Procedure 3.3. Update application logging code
3.1.4.2. Update Application Code for Third-party Logging Frameworks
In JBoss EAP 6, logging dependencies for common third-party frameworks like Apache Commons Logging, Apache log4j, SLF4J, and Java Logging are added by default. In most cases, it is preferable to use the logging framework provided by the JBoss EAP container. However, if you require specific functionality provided by a third-party framework, you must exclude the corresponding JBoss EAP module from your deployment. Note that although your deployment uses the third-party logging framework, the server logs continue to use the JBoss EAP logging subsystem configuration.
org.apache.log4j
module from your deployment. The first procedure works on any release of JBoss EAP 6. The second procedure applies only to JBoss EAP 6.3 or later.
Procedure 3.4. Configure JBoss EAP 6 to use a log4j.properties or log4j.xml file
Note
- Create a
jboss-deployment-structure.xml
with the following content:<jboss-deployment-structure> <deployment> <!-- Exclusions allow you to prevent the server from automatically adding some dependencies --> <exclusions> <module name="org.apache.log4j" /> </exclusions> </deployment> </jboss-deployment-structure>
- Place the
jboss-deployment-structure.xml
file in either theMETA-INF/
directory or theWEB-INF/
directory if you are deploying a WAR, or in theMETA-INF/
directory if you are deploying an EAR. If your deployment includes dependent child deployments, you must also exclude the module for each subdeployment. - Include the
log4j.properties
orlog4j.xml
file in thelib/
directory of your EAR, or theWEB-INF/classes/
directory of your WAR deployment. If you prefer to place the file inlib/
directory of your WAR, you must specify the<resource-root>
path in thejboss-deployment-structure.xml
file.<jboss-deployment-structure> <deployment> <!-- Exclusions allow you to prevent the server from automatically adding some dependencies --> <exclusions> <module name="org.apache.log4j" /> </exclusions> <resources> <resource-root path="lib" /> </resources> </deployment> </jboss-deployment-structure>
- Start the JBoss EAP 6 server with the following runtime argument to prevent a
ClassCastException
from appearing in the console when you deploy the application:-Dorg.jboss.as.logging.per-deployment=false
- Deploy your application.
Procedure 3.5. Configure Logging Dependencies for JBoss EAP 6.3 or later
add-logging-api-dependencies
logging system attribute to exclude third party logging framework dependencies. The following steps demonstrate how to modify this logging attribute on a JBoss EAP standalone server.
- Start the JBoss EAP 6 server with the following runtime argument to prevent a
ClassCastException
from appearing in the console when you deploy the application:-Dorg.jboss.as.logging.per-deployment=false
- Open a terminal and connect to the Management CLI.
- For Linux, enter the following at the command line:
$ EAP_HOME/bin/jboss-cli.sh --connect
- For Windows, enter the following at a command line:
C:\>EAP_HOME\bin\jboss-cli.bat --connect
- Modify the
add-logging-api-dependencies
attribute in the logging subsystem.This attribute controls whether the container adds implicit logging API dependencies to your deployments.- If set to
true
, which is the default, all implicit logging API dependencies are added. - If set to
false
, the dependencies are not added to your deployments.
To exclude the third-party logging framework dependencies, you must set this attribute tofalse
using the following command:/subsystem=logging:write-attribute(name=add-logging-api-dependencies, value=false)
This command adds the<add-logging-api-dependencies>
element to thelogging
subsystem of thestandalone.xml
configuration file.<subsystem xmlns="urn:jboss:domain:logging:1.4"> <add-logging-api-dependencies value="false"/> .... </subsystem>
- Deploy your application.
3.1.4.3. Modify Code to Use the New JBoss Logging Framework
To use the new framework, change your imports and code as described in the following procedure.
Procedure 3.6. Modify Code and Dependencies to Use the JBoss Logging Framework
- Change your imports and logging code.The following is an example of code that uses the new JBoss Logging framework.
import org.jboss.logging.Level; import org.jboss.logging.Logger; private static final Logger logger = Logger.getLogger(MyClass.class.toString()); if(logger.isTraceEnabled()) { logger.tracef("Starting...", subsystem); }
- Add the logging dependency.The JAR containing the JBoss Logging classes is located in the module named
org.jboss.logging
. YourMANIFEST-MF
file should look like the following.Manifest-Version: 1.0 Dependencies: org.jboss.logging
For more information on how to find the module dependency, refer Section 3.1.2.3, “Update Application Dependencies Due to Class Loading Changes” and Section 4.2.1, “Debug and Resolve Migration Issues”.
3.1.5. Application Packaging Changes
3.1.5.1. Modify Packaging of EARs and WARs
When you migrate your application, you might have to change the packaging structure of your EAR or WAR due to the change to modular class loading. Module dependencies are loaded in this specific order:
- System dependencies
- User dependencies
- Local resources
- Inter-deployment dependencies
Procedure 3.7. Modify archive packaging
- Package a WAR.A WAR is a single module and all classes in the WAR are loaded with the same class loader. This means classes packaged in the
WEB-INF/lib/
directory are treated the same as classes in theWEB-INF/classes
directory. - Package an EAR.An EAR consists of multiple modules. The
EAR/lib/
directory is a single module and every WAR or EJB jar subdeployment within the EAR is a separate module. Classes do not have access to classes in other modules within the EAR unless explicit dependencies have been defined. Subdeployments always have an automatic dependency on the parent module which gives them access to classes in theEAR/lib/
directory. However, subdeployments do not always have an automatic dependency to allow them to access each other. This behavior is controlled by setting the<ear-subdeployments-isolated>
element in theee
subsystem configuration as follows.<subsystem xmlns="urn:jboss:domain:ee:1.0" > <ear-subdeployments-isolated>false</ear-subdeployments-isolated> </subsystem>
By default this is set to false which allows the subdeployments to see classes belonging to other subdeployments within the EAR.For more information on class loading, see 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.1.5.2. Change in Precedence of Root Context
<context-root>
element defined in the jboss-web.xml
WAR file took precedence over a <context-root>
element defined in the application.xml
EAR file.
<context-root>
element defined in the application.xml
EAR file takes precedence over a <context-root>
element defined in the jboss-web.xml
WAR file. If a WAR file is deployed within an EAR archive, define the <context-root>
element in the application.xml
file.
3.1.6. Datasource and Resource Adapter Configuration Changes
3.1.6.1. Update the Application Due to Configuration Changes
- If your application uses a datasource, see: Section 3.1.6.2, “Update the DataSource Configuration”.
- If your application uses JPA and currently bundles the Hibernate JARs, see the following for your migration options: Section 3.1.6.4, “Configure the Datasource for Hibernate or JPA”.
- If your application uses a resource adapter, see: Section 3.1.6.5, “Update the Resource Adapter Configuration”.
- Review the following for information on how to configure changes for basic security: Section 3.1.7.1, “Configure Application Security Changes”.
3.1.6.2. Update the DataSource Configuration
In previous versions of JBoss EAP, the JCA DataSource configuration is defined in a file with a suffix of *-ds.xml
. This file is then deployed in the server's deploy/
directory or packaged with the application. The JDBC driver is copied to the server/lib/
directory or packaged in the application's WEB-INF/lib/
directory. While this method of configuring a DataSource is still supported for development, it is not recommended for production because it is not supported by the JBoss administrative and management tools.
domain/configuration/domain.xml
file. If the JBoss EAP 6 instance is running as a standalone server, the DataSource is configured in the standalone/configuration/standalone.xml file
. DataSources configured this way can be managed and controlled using the JBoss management interfaces, including the Web Management Console and command line interface (CLI). These tools make it easy to manage deployments and configure multiple servers running in a managed domain.
A JDBC 4.0 compliant driver can be installed as a deployment or as a core module. A driver that is JDBC 4.0 compliant contains a META-INF/services/java.sql.Driver
file that specifies the driver class name. A driver that is not JDBC 4.0 compliant requires additional steps. For details on how to make a driver JDBC 4.0 compliant and how update your current DataSource configuration to one that is manageable by the Web Management Console and CLI, see Section 3.1.6.3, “Install and Configure the JDBC Driver”.
You can use the IronJacamar tool to migrate DataSource and ResourceAdapter configurations. This tool converts the *-ds.xml
style configuration files into the format expected by JBoss EAP 6. For more information, see: Section 4.1.6, “Use the IronJacamar Tool to Migrate Datasource and Resource Adapter Configurations”.
In previous versions of JBoss EAP, is possible to perform a JNDI remote lookup of DataSource objects, however it is never a recommended practice for the following reasons.
- Client control of a server resource is unreliable and can result in leaked connections if the client crashes or loses the connection to the server.
- Performance is very slow because all database operations are proxied through an
MBean
. - Transaction propagation is not supported.
NotSerializableException
when you migrate your application. The recommended approach is to create an EJB to access the DataSource and then call the EJB remotely. For more information, see the section in this book entitled Remote Invocation Changes. Additional information can be found 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.1.6.3. Install and Configure the JDBC Driver
The JDBC driver can be installed into the container in one of the following two ways:
- As a deployment
- As a core module
domain/configuration/domain.xml
file. If the JBoss EAP 6 instance is running as a standalone server, the datasource is configured in the standalone/configuration/standalone.xml
file. Schema reference information, which is the same for both modes, can be found in the docs/schema/
directory of the JBoss EAP 6 install. For purposes of this discussion, assume the server is running as standalone server and the datasource is configured in the standalone.xml
file.
Procedure 3.8. Install and Configure the JDBC Driver
- Install the JDBC Driver.
- Install the JDBC Driver as a deployment.This is the recommended way to install the driver. When the JDBC driver is installed as a deployment, it is deployed as a regular JAR. If the JBoss EAP 6 instance is running as a standalone server, copy the JDBC 4.0 compliant JAR into the
EAP_HOME/standalone/deployments/
directory. For a managed domain, you must use the Management Console or Management CLI to deploy the JAR to the server groups.The following is an example of a MySQL JDBC driver installed as a deployment to a standalone server:$cp mysql-connector-java-5.1.15.jar
EAP_HOME/standalone/deployments/
Any JDBC 4.0 compliant driver is automatically recognized and installed into the system by name and version. A JDBC 4.0 compliant JAR contains a text file namedMETA-INF/services/java.sql.Driver
which specifies the driver class name(s). If the driver is not JDBC 4.0 compliant, it can be made deployable in one of the following ways:- Create and add a
java.sql.Driver
file to the JAR under theMETA-INF/services/
path. This file should contain the driver class name, for example:com.mysql.jdbc.Driver
- Create a
java.sql.Driver
file in the deployment directory. For a JBoss EAP 6 instance running as a standalone server, the file should be placed here:EAP_HOME/standalone/deployments/META-INF/services/java.sql.Driver
. If the server is in a managed domain, you must use the Management Console or Management CLI to deploy the file.
The pros of this approach are:The cons of this approach are:- This is the easiest method because there is no need to define a module.
- When the server is running in a managed domain, deployments that use this approach are automatically propagated to all servers in the domain. This means the administrator does not need to distribute the driver JAR manually.
- If the JDBC driver consists of more than one JAR, for example the driver JAR plus a dependent license JAR or localization JAR, you can not install the driver as a deployment. You must install the JDBC driver as a core module.
- If the driver is not JDBC 4.0 compliant, a file must be created containing the driver class name(s) and must be imported into the JAR or overlayed in the
deployments/
directory.
- Install the JDBC Driver as a core module.To install a JDBC driver as a core module, you must create a file path structure under the
EAP_HOME/modules/
directory. This structure contains the JDBC driver JAR, any additional vendor license or localization JARs, and amodule.xml
file to define the module.- Install the MySQL JDBC Driver as a core module
- Create the directory structure
EAP_HOME/modules/com/mysql/main/
- In the
main/
subdirectory, create amodule.xml
file containing the following module definition for the MySQL JDBC driver:<?xml version="1.0" encoding="UTF-8"?> <module xmlns="urn:jboss:module:1.0" name="com.mysql"> <resources> <resource-root path="mysql-connector-java-5.1.15.jar"/> </resources> <dependencies> <module name="javax.api"/> </dependencies> </module>
The module name, "com.mysql", matches the directory structure for this module. The<dependencies>
element is used to specify this module's dependencies on other modules. In this case, as is the case with all JDBC datasources, it is dependent on the Java JDBC APIs which are defined in another module namedjavax.api
. That module is located under themodules/system/layers/base/javax/api/main/
directory.Note
Make sure you do NOT have a space at the beginning ofmodule.xml
file or you will get a "New missing/unsatisfied dependencies" error for this driver. - Copy the MySQL JDBC driver JAR into the
EAP_HOME/modules/com/mysql/main/
directory:$ cp mysql-connector-java-5.1.15.jar
EAP_HOME/modules/com/mysql/main/
- Install the IBM DB2 JDBC driver and license JAR as a core module.This example is provided to only demonstrate how to deploy drivers that require JARs in addition to the JDBC Driver JAR.
- Create the directory structure
EAP_HOME/modules/com/ibm/db2/main/
. - In the
main/
subdirectory, create amodule.xml
file containing the following module definition for the IBM DB2 JDBC driver and license:<?xml version="1.0" encoding="UTF-8"?> <module xmlns="urn:jboss:module:1.1" name="com.ibm.db2"> <resources> <resource-root path="db2jcc.jar"/> <resource-root path="db2jcc_license_cisuz.jar"/> </resources> <dependencies> <module name="javax.api"/> <module name="javax.transaction.api"/> </dependencies> </module>
Note
Make sure you do NOT have a space at the beginning ofmodule.xml
file or you will get a "New missing/unsatisfied dependencies" error for this driver. - Copy the JDBC driver and license JAR to the
EAP_HOME/modules/com/ibm/db2/main/
directory.$ cp db2jcc.jar
EAP_HOME/modules/com/ibm/db2/main/
$ cp db2jcc_license_cisuz.jarEAP_HOME/modules/com/ibm/db2/main/
The pros of this approach are:The cons of this approach are:- This is the only approach that works when the JDBC driver consists of more than one JAR.
- With this approach, drivers that are not JDBC 4.0 compliant can be installed without modifying the driver JAR or creating a file overlay.
- It is more difficult to set up a module.
- The module must be manually copied to every server running in a managed domain.
- Configure the datasource.
- Add the database driver.Add the
<driver>
element to the<drivers>
element of the same file. Again, this contains some of the same datasource information that was previously defined in the*-ds.xml
file.First determine if the driver JAR is JDBC 4.0 compliant. A JAR that is JDBC 4.0 compliant contains aMETA-INF/services/java.sql.Driver
file that specifies the driver class name. The server uses this file to find the name of the driver class(es) in the JAR. A driver that is JDBC 4.0 compliant does not require a<driver-class>
element since it is already specified in the JAR. This is an example of the driver element for a JDBC 4.0 compliant MySQL driver:<driver name="mysql-connector-java-5.1.15.jar" module="com.mysql"/>
A driver that is not JDBC 4.0 compliant requires a<driver-class>
attribute to identify the driver class since there is noMETA-INF/services/java.sql.Driver
file that specifies the driver class name. This is an example of the driver element for driver that is not JDBC 4.0 compliant:<driver name="mysql-connector-java-5.1.15.jar" module="com.mysql"> <driver-class>com.mysql.jdbc.Driver</driver-class></driver>
- Create the datasource.Create a
<datasource>
element in the<datasources>
section of thestandalone.xml
file. This file contains much of the same datasource information that was previously defined in the*-ds.xml
file.Important
You must stop the server before editing the server configuration file for your change to be persisted on server restart.The following is an example of a MySQL datasource element in thestandalone.xml
file:<datasource jndi-name="java:/YourDatasourceName" pool-name="YourDatasourceName"> <connection-url>jdbc:mysql://localhost:3306/YourApplicationURL</connection-url> <driver>mysql-connector-java-5.1.15.jar</driver> <transaction-isolation>TRANSACTION_READ_COMMITTED</transaction-isolation> <pool> <min-pool-size>100</min-pool-size> <max-pool-size>200</max-pool-size> </pool> <security> <user-name>USERID</user-name> <password>PASSWORD</password> </security> <statement> <prepared-statement-cache-size>100</prepared-statement-cache-size> <share-prepared-statements/> </statement> </datasource>
- Update JNDI references in the application code.You must replace outdated JNDI lookup names in the application source code to use the new JNDI standardized datasource names you have defined. For more information, see: Section 3.1.8.4, “Modify the Application to Follow the New JNDI Namespace Rules”.You must also replace any existing
@Resource
annotations that access the datasource to use the new JNDI name. For example:@Resource(name = "java:/YourDatasourceName").
3.1.6.4. Configure the Datasource for Hibernate or JPA
Procedure 3.9. Remove the Hibernate bundle
- Remove the Hibernate JARs from your application library folders.
- Remove or comment out the
<hibernate.transaction.manager_lookup_class>
element in yourpersistence.xml
file as this element is not needed.
3.1.6.5. Update the Resource Adapter Configuration
In previous versions of the application server, the resource adapter configuration was defined in a file with a suffix of *-ds.xml
. In JBoss EAP 6, a resource adapter is configured in the server configuration file. If you are running in a managed domain, the configuration file is the EAP_HOME/domain/configuration/domain.xml
file. If you are running as a standalone server, configure the resource adapter in the EAP_HOME/standalone/configuration/standalone.xml
file. Schema reference information, which is the same for both modes, can be found under Schemas on the IronJacamar web site here: http://www.ironjacamar.org/documentation.html.
Important
The resource adapter descriptor information is defined under the following subsystem element in the server configuration file:
<subsystem xmlns="urn:jboss:domain:resource-adapters:1.1"/>You will use some of the same information that was previously defined in the resource adapter
*-ds.xml
file.
<resource-adapters> <resource-adapter> <archive>multiple-full.rar</archive> <config-property name="Name">ResourceAdapterValue</config-property> <transaction-support>NoTransaction</transaction-support> <connection-definitions> <connection-definition class-name="org.jboss.jca.test.deployers.spec.rars.multiple.MultipleManagedConnectionFactory1" enabled="true" jndi-name="java:/eis/MultipleConnectionFactory1" pool-name="MultipleConnectionFactory1"> <config-property name="Name">MultipleConnectionFactory1Value</config-property> </connection-definition> <connection-definition class-name="org.jboss.jca.test.deployers.spec.rars.multiple.MultipleManagedConnectionFactory2" enabled="true" jndi-name="java:/eis/MultipleConnectionFactory2" pool-name="MultipleConnectionFactory2"> <config-property name="Name">MultipleConnectionFactory2Value</config-property> </connection-definition> </connection-definitions> <admin-objects> <admin-object class-name="org.jboss.jca.test.deployers.spec.rars.multiple.MultipleAdminObject1Impl" jndi-name="java:/eis/MultipleAdminObject1"> <config-property name="Name">MultipleAdminObject1Value</config-property> </admin-object> <admin-object class-name="org.jboss.jca.test.deployers.spec.rars.multiple.MultipleAdminObject2Impl" jndi-name="java:/eis/MultipleAdminObject2"> <config-property name="Name">MultipleAdminObject2Value</config-property> </admin-object> </admin-objects> </resource-adapter> </resource-adapters>
3.1.6.6. Detect Leaked Datasource Connections
In JBoss EAP 6, you can detect leaked datasource connections using the Cached Connection Manager (CCM) debug utility. This topic describes how to enable and debug the CCM utility.
Procedure 3.10. Enable the Cached Connection Manager
- Enable CCM in the
datasources
subsystem of the server configuration file by setting<use-ccm="true"
. This is the default value and does not need to be set explicitly.<subsystem xmlns="urn:jboss:domain:datasources:1.2"> <datasources> <datasource ... enabled="true" use-ccm="true"> ... </datasource> </datasources> </subsystem>
- Verify that the
<cached-connection-manager>
exists in thejca
subsystem of the server configuration file. Set thedebug
attribute totrue
.<subsystem xmlns="urn:jboss:domain:jca:1.1"> ... <cached-connection-manager debug="true" error="true"/> ... </subsystem>
Settingdebug="true"
causes the following to happen.The additional property- An
INFO
message is logged with the following message: "Closing a connection for you. Please close them yourself" - A stacktrace is generated for the code that opened the leaked connection.
- The leaked connection is closed.
error="true"
can be used to raise aRuntimeException
and generate anERROR
message in the log. - Activating debug will have some impact on performance and log file size, so it is only recommended for use during testing. After verifying that no leaks remain and before deploying applications to production, restore the configuration by removing the
debug="true"
setting or using<cached-connection-manager debug="false"/>
.
Procedure 3.11. Debug Leaks Not Reported by Cached Connection Manager
- Be sure the
datasource
subsystem of the server configuration file is not configured withuse-ccm="false"
- Be sure the
datasource
subsystem of the server configuration file is not configured withjta="false"
- Be sure the minimum logging level is set to
INFO
fororg.jboss.jca
.
3.1.7. Security Changes
3.1.7.1. Configure Application Security Changes
In previous versions of JBoss EAP, properties files placed in the EAP_HOME/server/SERVER_NAME/conf/
directory were on classpath and could be easily found by the UsersRolesLoginModule
. In JBoss EAP 6, the directory structure has changed. Properties files must be packaged within the application to make them available in the classpath.
Important
security-domains
to the standalone/configuration/standalone.xml
or the domain/configuration/domain.xml
server configuration file:
<security-domain name="example"> <authentication> <login-module code="UsersRoles" flag="required"> <module-option name="usersProperties" value="${jboss.server.config.dir}/example-users.properties"/> <module-option name="rolesProperties" value="${jboss.server.config.dir}/example-roles.properties"/> </login-module> </authentication> </security-domain>
${jboss.server.config.dir}
refers to the EAP_HOME/standalone/configuration/
directory. If the instance is running in a managed domain, ${jboss.server.config.dir}
refers to the EAP_HOME/domain/configuration/
directory.
In JBoss EAP 6, security domains no longer use the prefix java:/jaas/
in their names.
- For Web applications, you must remove this prefix from the security domain configurations in the
jboss-web.xml
. - For Enterprise applications, you must remove this prefix from the security domain configurations in the
jboss-ejb3.xml
file. This file has replaced thejboss.xml
in JBoss EAP 6.
3.1.7.2. Update Applications That Use PicketLink STS and Web Services
If your JBoss EAP 6.1 application uses PicketLink STS and Web services, you might need to make changes when you migrate to JBoss EAP 6.2 or later. A fix applied to JBoss EAP to address CVE-2013-2133 enforces authorization checks by the container before running any JAXWS handlers attached to EJB3-based WS endpoints. As a consequence, some PicketLink STS functionality can be affected because the PicketLink SAML2Handler
establishes a security principal that is intended to be used later in the process. You might see a NullPointerException
in the server log because the principal is NULL
when the HandlerAuthInterceptor
accesses the SAML2Handler
. You must disable this security check to fix this problem.
Procedure 3.12. Disable Additional Authorization Checks
- You can disable the additional authorization checks and keep using the existing PicketLink deployments by using one of the following methods.
- Set a system-wide property.You can disable additional authorization checks at the server level by setting the
org.jboss.ws.cxf.disableHandlerAuthChecks
system property value totrue
. This method affects any deployment made to the application server.For information on how to set a system property, see the topic entitled Configure System Properties Using the Management CLI in the Administration and Configuration Guide for JBoss EAP. - Create a property in the deployment's web services descriptor file.You can disable additional authorization checks at the deployment level by setting the
org.jboss.ws.cxf.disableHandlerAuthChecks
property value totrue
in thejboss-webservices.xml
file. This method impacts only the specific deployment.- Create a
jboss-webservices.xml
file in theMETA-INF/
directory of the deployment in which you want to disable additional authorization checks. - Add the following content.
<?xml version="1.1" encoding="UTF-8"?> <webservices xmlns="http://www.jboss.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee"> <property> <name>org.jboss.ws.cxf.disableHandlerAuthChecks</name> <value>true</value> </property> </webservices>
Note
org.jboss.ws.cxf.disableHandlerAuthChecks
property renders a system vulnerable to CVE-2013-2133. If the application expects security restrictions declared on EJB methods to be applied and does not apply them independent to the JAX-WS handler, then the property should not be enabled. The property should only be used for purposes of backwards compatibility when needed to avoid breaking the application.
3.1.8. JNDI Changes
3.1.8.1. Update Application JNDI Namespace Names
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. Portable EJB names only get bound to three of them: java:global
, java:module
, and java:app
. Applications with EJBs that use JNDI must be changed to follow the new standardized JNDI namespace convention.
Procedure 3.13. Modify JNDI lookups
- Learn more about Section 3.1.8.2, “Portable EJB JNDI Names”
Examples of JNDI namespaces in previous releases and how they are specified in JBoss EAP 6 can be found here: Section 3.1.8.5, “Examples of JNDI Namespaces in Previous Releases and How They are Specified in JBoss EAP 6”
3.1.8.2. Portable EJB JNDI Names
The Java EE 6 specification defines four logical namespaces, each with its own scope, but portable EJB names only get bound to three of them. The following table details when and how to use each namespace.
JNDI Namespace | Description |
---|---|
java:global |
Names in this namespace are shared by all applications deployed in an application server instance. Use names in this namespace to find EJBs external archives deployed to the same server.
The following is an example of a java:global namespace:
java:global/jboss-seam-booking/jboss-seam-booking-jar/HotelBookingAction
|
java:module |
Names in this namespace are shared by all components in a module, for example, all enterprise beans in a single EJB module or all components in a web module.
The following is an example of a java:module namespace:
java:module/HotelBookingAction!org.jboss.seam.example.booking.HotelBooking
|
java:app |
Names in this namespace are shared by all components in all modules in a single application. For example, a WAR and an EJB jar file in the same EAR file would have access to resources in the java:app namespace.
The following is an example of a java:app namespace:
java:app/jboss-seam-booking-jar/HotelBookingAction
|
3.1.8.3. Review the JNDI Namespace Rules
JBoss EAP 6 has improved upon JNDI namespace names, not only to provide predictable and consistent rules for every name bound in the application server, but also to prevent future compatibility issues. This means you might run into issues with the current namespaces in your application if they don't follow the new rules.
- Unqualified relative names like
DefaultDS
orjdbc/DefaultDS
should be qualified relative tojava:comp/env
,java:module/env
, orjava:jboss/env
, depending on the context. - Unqualified
absolute
names like/jdbc/DefaultDS
should be qualified relative to ajava:jboss/root
name. - Qualified
absolute
names likejava:/jdbc/DefaultDS
should be qualified the same way as Unqualifiedabsolute
names above. - The special
java:jboss
namespace is shared across the entire AS server instance. - Any
relative
name with ajava:
prefix must be in one of the five namespaces:comp
,module
,app
,global
, or the proprietaryjboss
. Any name starting withjava:xxx
where xxx does not match any of the above five would result in an invalid name error.
3.1.8.4. Modify the Application to Follow the New JNDI Namespace Rules
- Here is an example of a JNDI lookup in JBoss EAP 5.1. This code is usually found in an initialization method.
private ProductManager productManager; try { context = new InitialContext(); productManager = (ProductManager) context.lookup("OrderManagerApp/ProductManagerBean/local"); } catch(Exception lookupError) { throw new ServletException("Unable to find the ProductManager bean", lookupError); }
Note the lookup name isOrderManagerApp/ProductManagerBean/local
. - The following is an example of how the same lookup would be coded in JBoss EAP 6 using dependency injection.
@EJB(lookup="java:app/OrderManagerEJB/ProductManagerBean!services.ejb.ProductManager") private ProductManager productManager;
The lookup values are now defined as member variables and use the new portablejava:app
JNDI namespace namejava:app/OrderManagerEJB/ProductManagerBean!services.ejb.ProductManager
. - If you prefer not to use dependency injection, you can continue to create the new InitialContext as above and modify the lookup to use the new JNDI namespace name.
private ProductManager productManager; try { context = new InitialContext(); productManager = (ProductManager) context.lookup("java:app/OrderManagerEJB/ProductManagerBean!services.ejb.ProductManager"); } catch(Exception lookupError) { throw new ServletException("Unable to find the ProductManager bean", lookupError); }
3.1.8.5. Examples of JNDI Namespaces in Previous Releases and How They are Specified in JBoss EAP 6
Namespace in JBoss EAP 5.x | Namespace in JBoss EAP 6 | Additional Comments |
---|---|---|
OrderManagerApp/ProductManagerBean/local | java:module/ProductManagerBean!services.ejb.ProductManager | Java EE 6 standard binding. Scoped to the current module and only accessible within the same module. |
OrderManagerApp/ProductManagerBean/local | java:app/OrderManagerEJB/ProductManagerBean!services.ejb.ProductManager | Java EE 6 standard binding. Scoped to the current application and only accessible within the same application. |
OrderManagerApp/ProductManagerBean/local | java:global/OrderManagerApp/OrderManagerEJB/ProductManagerBean!services.ejb.ProductManager | Java EE 6 standard binding. Scoped to the application server and globally accessible. |
java:comp/UserTransaction | java:comp/UserTransaction | Namespace is scoped to the current component. Not accessible for threads that are not Java EE 6, for example, threads created directly by your application. |
java:comp/UserTransaction | java:jboss/UserTransaction | Globally accessible. Use this if java:comp/UserTransaction is not available. |
java:/TransactionManager | java:jboss/TransactionManager | |
java:/TransactionSynchronizationRegistry | java:jboss/TransactionSynchronizationRegistry |