3.2. Changes Dependent on Your Application Architecture and Components
3.2.1. Review Changes Dependent on Your Application Architecture and Components
- Hibernate and JPA
- If your application uses Hibernate or JPA, your application may need some modifications. For more information, refer: Section 3.2.2.1, “Update Applications That Use Hibernate and/or JPA”.
- REST
- If your application uses JAX-RS, you should be aware that JBoss EAP 6 automatically sets up RESTEasy, so you no longer need to configure it yourself. For more information, refer: Section 3.2.7.1, “Configure JAX-RS and RESTEasy Changes”
- LDAP
- The LDAP security realm is configured differently in JBoss EAP 6. If your application uses LDAP, refer to the following topic for more information: Section 3.2.8.1, “Configure LDAP Security Realm Changes”.
- Messaging
- JBoss Messaging is no longer included in JBoss EAP 6. If your application uses JBoss Messaging as the messaging provider, you need to replace the JBoss Messaging code with HornetQ. The following topic describes what you need to do: Section 3.2.9.4, “Migrate Your Application to Use HornetQ as the JMS Provider”.
- Clustering
- The way you enable clustering has changed in JBoss EAP 6. For details, refer: Section 3.2.10.1, “Make Changes to Your Application for Clustering”.
- Service-style deployment
- Although JBoss EAP 6 no longer uses service-style descriptors, the container supports these service-style deployments without change where possible. For deployment information, refer: Section 3.2.11.1, “Update Applications That Use Service-style Deployments”
- Remote invocation
- If your application makes remote invocations, you can still use JNDI to lookup a proxy for your bean and invoke on that returned proxy. For more information about required syntax and namespaces changes, refer: Section 3.2.12.1, “Migrate JBoss EAP 5 Deployed Applications That Make Remote Invocations to JBoss EAP 6”.
- Seam 2.2
- If your application uses Seam 2.2, refer to the following topic for changes you need to make: Section 3.2.18.1, “Migrate Seam 2.2 Archives to JBoss EAP 6”.
- Spring
- If your application uses Spring, refer: Section 3.2.19.1, “Migrate Spring Applications”.
- Other changes that may impact your migration
- For additional changes in JBoss EAP 6 that may impact your application, refer: Section 3.2.20.1, “Become Familiar with Other Changes That May Affect Your Migration”.
3.2.2. Hibernate and JPA Changes
3.2.2.1. Update Applications That Use Hibernate and/or JPA
If your application uses Hibernate or JPA, read through the following sections and make any changes necessary to migrate to JBoss EAP 6.
3.2.2.2. Configure Changes for Applications That Use Hibernate and JPA
If your application contains a persistence.xml
file or the code uses the annotations @PersistenceContext
or @PersistenceUnit
, JBoss EAP 6 detects this during deployment and assumes the application uses JPA. It implicitly adds Hibernate 4 plus a few other dependencies to your application classpath.
ClassNotFoundExceptions
when you deploy your application, you can try to resolve them using one of the following approaches.
Important
Procedure 3.14. Configure the Application
- Copy the required Hibernate 3 JARs to your application library.You may be able to resolve the issue by copying the specific Hibernate 3 JARs that contain the missing classes into the application's
lib/
directory or by adding them to the classpath using some other method. In some cases this may result inClassCastExceptions
or other class loading issues due to the mixed use of the Hibernate versions. If that happens, you need to use the next approach. - Instruct the server to use only the Hibernate 3 libraries.JBoss EAP 6 allows you to package Hibernate 3.5 (or greater) persistence provider jars with the application. To direct the server to use only the Hibernate 3 libraries and to exclude the Hibernate 4 libraries, you need to set the
jboss.as.jpa.providerModule
tohibernate3-bundled
in thepersistence.xml
as follows:<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0"> <persistence-unit name="plannerdatasource_pu"> <description>Hibernate 3 Persistence Unit.</description> <jta-data-source>java:jboss/datasources/PlannerDS</jta-data-source> <properties> <property name="hibernate.show_sql" value="false" /> <property name="jboss.as.jpa.providerModule" value="hibernate3-bundled" /> </properties> </persistence-unit> </persistence>
The Java Persistence API (JPA) deployer will detect the presence of a persistence provider in the application and use the Hibernate 3 libraries. For more information on the JPA persistence properties, refer Section 3.2.2.3, “Persistence Unit Properties”. - Disable Hibernate second-level cache.Second-level cache for Hibernate 3 does not exhibit the same behavior with JBoss EAP 6 as it did in previous releases. If you are using Hibernate second-level cache with your application, you must disable it until you upgrade to Hibernate 4. To disable second-level cache, set the
<hibernate.cache.use_second_level_cache>
tofalse
in thepersistence.xml
file. - Replace references to
org.jboss.ejb3.entity.ExtendedEntityManager
.In JBoss EAP 5, theorg.jboss.ejb3.entity.ExtendedEntityManager
class extendedjavax.persistence.EntityManager
for extended persistence context management. In JBoss EAP 6, this class was replaced with theorg.jboss.as.jpa.container.ExtendedEntityManager
class. However, it is recommended that you update the code to use the standard Java EE 6 JPA APIjavax.persistence.EntityManager
class instead of the proprietary class.
3.2.2.3. Persistence Unit Properties
JBoss EAP 6 automatically sets the following Hibernate 4.x configuration properties:
Property Name | Default Value | Purpose |
---|---|---|
hibernate.id.new_generator_mappings | true |
This setting is relevant if you use
@GeneratedValue(AUTO) to generate unique index key values for new entities. New applications should keep the default value of true . Existing applications that used Hibernate 3.3.x might need to change it to false to continue using a sequence object or table based generator and maintain backward compatibility. The application can override this value in the persistence.xml file.
More information on this behavior is provided below.
|
hibernate.transaction.jta.platform | Instance of org.hibernate.service.jta.platform.spi.JtaPlatform Interface |
This class passes the transaction manager, user transaction, and transaction synchronization registry into Hibernate.
|
hibernate.ejb.resource_scanner | Instance of org.hibernate.ejb.packaging.Scanner Interface |
This class knows how to use the JBoss EAP 6 annotation indexer to provide faster deployment.
|
hibernate.transaction.manager_lookup_class |
This property is removed if found in the persistence.xml because it could conflict with
hibernate.transaction.jta.platform
| |
hibernate.session_factory_name | QUALIFIED_PERSISTENCE_UNIT_NAME |
This is set to the application name + persistence unit name. The application can specify a different value, but it must be unique across all application deployments on the JBoss EAP 6 instance.
|
hibernate.session_factory_name_is_jndi | false |
This is set only if the application did not specify a value for the
hibernate.session_factory_name .
|
hibernate.ejb.entitymanager_factory_name | QUALIFIED_PERSISTENCE_UNIT_NAME |
This is set to the application name + persistence unit name. The application can specify a different value but it needs to be unique across all application deployments on the JBoss EAP 6 instance.
|
new_generator_mappings
is set to true
:
@GeneratedValue(AUTO)
maps toorg.hibernate.id.enhanced.SequenceStyleGenerator
.@GeneratedValue(TABLE)
maps toorg.hibernate.id.enhanced.TableGenerator
.@GeneratedValue(SEQUENCE)
maps toorg.hibernate.id.enhanced.SequenceStyleGenerator
.
new_generator_mappings
is set to false
:
@GeneratedValue(AUTO)
maps to Hibernate "native".@GeneratedValue(TABLE)
maps toorg.hibernate.id.MultipleHiLoPerTableGenerator
.@GeneratedValue(SEQUENCE)
maps to Hibernate "seqhilo".
The following JPA properties are supported in the persistence unit definition in the persistence.xml
file:
Property Name | Default Value | Purpose |
---|---|---|
jboss.as.jpa.providerModule | org.hibernate |
The name of the persistence provider module.
The value should be
hibernate3-bundled if Hibernate 3 JARs are in the application archive.
If a persistence provider is packaged with the application, this value should be
application .
|
jboss.as.jpa.adapterModule | org.jboss.as.jpa.hibernate:4 |
The name of the integration classes that help JBoss EAP 6 to work with the persistence provider.
Current valid values are:
|
3.2.2.4. Update Your Hibernate 3 Application to Use Hibernate 4
When you update your application to use Hibernate 4, some updates are general and apply regardless of version of Hibernate currently used by the application. For other updates, you must determine which version the application currently uses.
Procedure 3.15. Update the application to use Hibernate 4
- The default behavior of autoincrement sequence generator has changed in JBoss EAP 6. For more information, refer Section 3.2.2.5, “Preserve the Existing Behavior of the Hibernate Identity Auto Generated Value”.
- Determine the version of Hibernate currently used by the application and choose the correct update procedure below.
- Refer Section 3.2.2.8, “Modify Persistence Properties for Migrated Seam and Hibernate Applications that Run in a Clustered Environment” if you plan to run your application in a clustered environment.
3.2.2.5. Preserve the Existing Behavior of the Hibernate Identity Auto Generated Value
hibernate.id.new_generator_mappings
that directs how identity or sequence columns are generated when using @GeneratedValue
. In JBoss EAP 6, the default value for this property is set as follows:
- When you deploy a native Hibernate application, the default value is
false
. - When you deploy a JPA application, the default value is
true
.
New applications that use the @GeneratedValue
annotation should set the value for the hibernate.id.new_generator_mappings
property to true
. This is the preferred setting because it is more portable across different databases. In most cases it is more efficient and, in some cases, it addresses compatibility with the JPA 2 specification.
- For new JPA applications, JBoss EAP 6 defaults the
hibernate.id.new_generator_mappings
property totrue
and it should not be changed. - For new native Hibernate applications, JBoss EAP 6 defaults the
hibernate.id.new_generator_mappings
property tofalse
. You should set this property totrue
.
Existing applications that use the @GeneratedValue
annotation should make sure that the same generator is used to create primary key values for new entities when the application is migrated to JBoss EAP 6.
- For existing JPA applications, JBoss EAP 6 defaults the
hibernate.id.new_generator_mappings
property totrue
. You should set this property tofalse
in thepersistence.xml
file. - For existing native Hibernate applications, JBoss EAP 6 defaults the
hibernate.id.new_generator_mappings
tofalse
and it should not be changed.
3.2.2.6. Migrate Your Hibernate 3.3.x Application to Hibernate 4.x
- Hibernate
text
types are now mapped toJDBC LONGVARCHAR
In versions of Hibernate prior to 3.5,text
type was mapped toJDBC CLOB
. A new Hibernate type,materialized_clob
, was added in Hibernate 4 to map JavaString
properties toJDBC CLOB
. If your application has properties configured astype="text"
that are intended to be mapped toJDBC CLOB
, you must do one of the following:- If your application uses hbm mapping files, change the property to
type="materialized_clob"
. - If your application uses annotations, you should replace
@Type(type = "text")
with@Lob
.
- Review code to find changes in returned value typesNumeric aggregate criteria projections now return the same value type as their HQL counterparts. As a result, the return types from the following projections in
org.hibernate.criterion
have changed.- Due to changes in
CountProjection
,Projections.rowCount()
,Projections.count(propertyName)
, andProjections.countDistinct(propertyName)
, thecount
andcount distinct
projections now return aLong
value. - Due to changes in
Projections.sum(propertyName)
, thesum
projections now return a value type that depends on the property type.Note
Failure to modify your application code could result in ajava.lang.ClassCastException
.- For properties mapped as Long, Short, Integer, or primitive integer types, a Long value is returned;
- For properties mapped as Float, Double, or primitive floating point types, a Double value is returned.
- Update the
UserType
signatures for thenullSafeGet()
andnullSafeSet()
methods.The signatures for thenullSafeGet()
andnullSafeSet()
methods in theUserType
class changed in Hibernate 4. Any application code that uses these methods must be updated to use the new signatures.The following is an example of the method signatures in Hibernate 3.x.public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException; public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException;
The following is an example of the new method signatures in Hibernate 4.public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException, SQLException; public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException, SQLException;
3.2.2.7. Migrate Your Hibernate 3.5.x Application to Hibernate 4.x
- AnnotationConfiguration was merged into ConfigurationAlthough
AnnotationConfiguration
is now deprecated, it should not affect your migration.- If you are still using an
hbm.xml
file, you should be aware that JBoss EAP 6 now uses theorg.hibernate.cfg.EJB3NamingStrategy
inAnnotationConfiguration
instead of theorg.hibernate.cfg.DefaultNamingStrategy
that was used in previous releases. This can result in naming mismatches. - If you rely on the naming strategy to default the name of an association (many-to-many and collections of elements) table, you may see this issue. To resolve it, you can tell Hibernate to use the legacy
org.hibernate.cfg.DefaultNamingStrategy
by callingConfiguration#setNamingStrategy
and passing itorg.hibernate.cfg.DefaultNamingStrategy#INSTANCE
.
- Modify the namespaces to conform to the new Hibernate DTD file names as noted in the following table.
Table 3.5. DTD Namespace Mapping Table Previous DTD Namespace New DTD Namespace http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd - Modify environment variables.
- If you are using Oracle and using the
materialized_clob
ormaterialized_blob
properties, the global environment variablehibernate.jdbc.use_streams_for_binary
must be set to true. - If you are using PostgreSQL and using the
CLOB
orBLOB
properties, the global environment variablehibernate.jdbc.use_streams_for_binary
must be set to false.
- Update the
UserType
signatures for thenullSafeGet()
andnullSafeSet()
methods.The signatures for thenullSafeGet()
andnullSafeSet()
methods in theUserType
class changed in Hibernate 4. Any application code that uses these methods must be updated to use the new signatures. See Section 3.2.2.6, “Migrate Your Hibernate 3.3.x Application to Hibernate 4.x” for details.
3.2.2.8. Modify Persistence Properties for Migrated Seam and Hibernate Applications that Run in a Clustered Environment
javax.ejb.EJBTransactionRolledbackException: JBAS010361: Failed to deserialize .... Caused by: java.io.InvalidObjectException: could not resolve session factory during session deserialization [uuid=8aa29e74373ce3a301373ce3a44b0000, name=null]To resolve these errors, you need to modify properties in the configuration file. In most cases this is the
persistence.xml
file. For native Hibernate API applications, this is the hibernate.cfg.xml
file.
Procedure 3.16. Set persistence properties to run in a clustered environment
- Set the
hibernate.session_factory_name
value to a unique name. This name must be unique across all application deployments on the JBoss EAP 6 instance. For example:<property name="hibernate.session_factory_name" value="jboss-seam-booking.ear_session_factory"/>
- Set the
hibernate.ejb.entitymanager_factory_name
value to a unique name. This name must be unique across all application deployments on the JBoss EAP 6 instance. For example:<property name="hibernate.ejb.entitymanager_factory_name" value="seam-booking.ear_PersistenceUnitName"/>
3.2.2.9. Update Your Application to Conform to the JPA 2.0 Specification
The JPA 2.0 specification requires that a persistence context cannot be propagated outside of a JTA transaction. If your application uses only transaction-scoped persistence contexts, the behavior is the same in JBoss EAP 6 as it was in previous versions of the application server and no changes are required. However, if your application uses an extended persistence context (XPC) to allow queuing or batching of data modifications, you may need to make changes to your application.
If your application has a stateful session bean, Bean1
, that uses an extended persistence context, and it calls a stateless session bean, Bean2
, that uses a transaction-scoped persistence context, you can expect the following behavior to occur:
- If
Bean1
starts a JTA transaction and makes theBean2
method invocation with the JTA transaction active, the behavior in JBoss EAP 6 is the same as previous releases and no change is necessary. - If
Bean1
does not start a JTA transaction and makes theBean2
method invocation, JBoss EAP 6 does not propagate the extended persistence context intoBean2
. This behavior is different than in previous releases which did propagate the extended persistence context intoBean2
. If your application expects the extended persistence context to be propagated to the bean with the transactional entity manager, you need to change your application to do the invocation within an active JTA transaction.
3.2.2.10. Replace JPA/Hibernate Second Level Cache with Infinispan
JBoss Cache has been replaced by Infinispan for second-level cache (2LC). This requires a change to the persistence.xml
file. The syntax is slightly different, depending on if you are using JPA or Hibernate second level cache. These examples assume you are using Hibernate.
persistence.xml
file in JBoss EAP 5.x.
<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.jbc2.JndiMultiplexedJBossCacheRegionFactory"/> <property name="hibernate.cache.region.jbc2.cachefactory" value="java:CacheManager"/> <property name="hibernate.cache.use_second_level_cache" value="true"/> <property name="hibernate.cache.region.jbc2.cfg.entity" value="mvcc-entity"/> <property name="hibernate.cache.region_prefix" value="services"/>The following steps will use this example to configure Infinispan in JBoss EAP 6.
Procedure 3.17. Modify the persistence.xml
file to use Infinispan
- Configure Infinispan for a JPA application in JBoss EAP 6This is an example of how properties to achieve the same configuration for a JPA application using Infinispan in JBoss EAP 6 can be specified:
<property name="hibernate.cache.use_second_level_cache" value="true"/>
In addition, you need to specify ashared-cache-mode
with a value ofENABLE_SELECTIVE
orALL
as follows:ENABLE_SELECTIVE
is the default and recommended value. It means entities are not cached unless you explicitly mark them as cacheable.<shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
ALL
means entities are always cached even if you mark them as not cacheable.<shared-cache-mode>ALL</shared-cache-mode>
- Configure Infinispan for a native Hibernate application in JBoss EAP 6This is an example of how the same configuration for a native Hibernate application using Infinispan with JBoss EAP 6 can be specified:
<property name="hibernate.cache.region.factory_class" value="org.jboss.as.jpa.hibernate4.infinispan.InfinispanRegionFactory"/> <property name="hibernate.cache.infinispan.cachemanager" value="java:jboss/infinispan/container/hibernate"/> <property name="hibernate.transaction.jta.platform" value="org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform"/> <property name="hibernate.cache.use_second_level_cache" value="true"/>
You must also add the following dependencies to theMANIFEST.MF
file:Manifest-Version: 1.0 Dependencies: org.infinispan, org.hibernate
3.2.2.11. Hibernate Cache Properties
Property Name | Description |
---|---|
hibernate.cache.region.factory_class |
The classname of a custom
CacheProvider .
|
hibernate.cache.use_minimal_puts |
Boolean. Optimizes second-level cache operation to minimize writes, at the cost of more frequent reads. This setting is most useful for clustered caches and, in Hibernate3, is enabled by default for clustered cache implementations.
|
hibernate.cache.use_query_cache |
Boolean. Enables the query cache. Individual queries still have to be set cacheable.
|
hibernate.cache.use_second_level_cache |
Boolean. Used to completely disable the second level cache, which is enabled by default for classes that specify a
<cache> mapping.
|
hibernate.cache.query_cache_factory |
The classname of a custom
QueryCache interface. The default value is the built-in StandardQueryCache .
|
hibernate.cache.region_prefix |
A prefix to use for second-level cache region names.
|
hibernate.cache.use_structured_entries |
Boolean. Forces Hibernate to store data in the second-level cache in a more human-friendly format.
|
hibernate.cache.default_cache_concurrency_strategy |
Setting used to give the name of the default
org.hibernate.annotations.CacheConcurrencyStrategy to use when either @Cacheable or @Cache is used. @Cache(strategy="..") is used to override this default.
|
3.2.2.12. Migrate to Hibernate Validator 4
Hibernate Validator 4.x is a completely new code base that implements JSR 303 - Bean Validation. The migration process from Validator 3.x to 4.x is fairly straightforward, but there are a few changes you must make when you migrate your application.
Procedure 3.18. You may need to perform one or more of the following tasks
- Access the default ValidatorFactoryJBoss EAP 6 binds a default ValidatorFactory to the JNDI context under the name
java:comp/ValidatorFactory
. - Understand life cycle triggered validationWhen used in combination with Hibernate Core 4, life-cycle based validation is automatically enabled by Hibernate Core.
- Validation occurs on entity
INSERT
,UPDATE
, andDELETE
operations. - You can configure the groups to be validated by event type using the following properties:The values of these properties are the comma-separated, fully qualified class names of the groups to validate.
javax.persistence.validation.group.pre-persist
,javax.persistence.validation.group.pre-update
, andjavax.persistence.validation.group.pre-remove
.
Validation groups are a new feature of the Bean Validation specification. If you do not want to take advantage of this new feature, no changes are required when you migrate to Hibernate Validator 4. - You can disable life-cycle based validation by setting the
javax.persistence.validation.mode
property tonone
. Other valid values for this property areauto
(the default),callback
andddl
.
- Configure your application to use manual validation
- To manually control validation, you can create a Validator in either of the following ways:
- Create a
Validator
instance from theValidatorFactory
using thegetValidator()
method. - Inject Validator instances in your EJB, CDI bean or any other Java EE injectable resource.
- You can use the
ValidatorContext
returned by theValidatorFactory.usingContext()
to customize your Validator instance. Using this API you can configure a customMessageInterpolator
,TraverableResolver
andConstraintValidatorFactory
. These interfaces are specified in the Bean Validation specification and are new to Hibernate Validator 4.
- Modify code to use the new Bean Validation constraintsThe new Bean level validation constraints require code changes when you migrate to Hibernate Validator 4.
- To upgrade to Hibernate Validator 4, you must use the constraints in the following packages:
javax.validation.constraints
org.hibernate.validator.constraints
- All constraints that existed in Hibernate Validator 3 are still available in Hibernate Validator 4. To use them, you need to import the specified class, and in some cases, change the name or type of the constraint parameter.
- Use custom constraintsIn Hibernate Validator 3, a custom constraint needed to implement the
org.hibernate.validator.Validator
interface. In Hibernate Validator 4, you need to implement thejavax.validation.ConstraintValidator
interface. This interface contains the sameinitialize()
andisValid()
methods as the previous interface, however, the method signature has changed. In addition,DDL
alteration is no longer supported in Hibernate Validator 4. - The following Hibernate 3.x
Validator
classes are obsolete.- Replace
org.hibernate.validator.NotNull
withjavax.validation.constraints.NotNull
. - Replace
org.hibernate.validator.ClassValidator
withjavax.validation.Validator.
. - Replace
org.hibernate.validator.InvalidValue
withjavax.validation.Validator.
.
For more information, see the Hibernate Valitator Reference Guide. - The
jboss-ejb3-ext-api-VERSION.jar
file removed many of the annotation extension APIs because they are no longer needed in JBoss EAP 6. For example, theorg.jboss.ejb3.annotation.IgnoreDependency
class is no longer available or needed because JBoss EAP 6 handles the interdependencies automatically.
3.2.3. JTS and JTA Changes
3.2.3.1. Migrate JBoss Transaction Service Configurations
In previous versions of JBoss EAP, the JBoss Transaction Service transaction manager was configured in one of the following XML files:
JBoss EAP Version Configuration File Name
- JBoss EAP 6 includes a default value for the node identifier, which is fine when running a single instance of the JBoss EAP server, but must be modified when running multiple instances of the server.
- JBoss EAP 6 ships with JTA transactions enabled by default. Additional steps are needed to configure JTS transactions.
JBoss EAP 6 ships with a default value setting for the node identifier. This is fine when running a single instance of the JBoss EAP server, but because the node identifier must be unique across all JBoss EAP server instances, the value must be modified when running multiple instances of the server.
Note
jbossts-properties.xml
file using the following property.
<property name="com.arjuna.ats.arjuna.xa.nodeIdentifier" value=UNIQUE_NODE_ID/>
transaction
subsystem of the server configuration file using Management CLI commands. The commands you use depend on whether you are running a managed domain or a standalone server.
/system-property=jboss.tx.node.id:add(value=UNIQUE_NODE_ID) /subsystem=transactions:write-attribute(name=node-identifier,value="${jboss.tx.node.id}") reload
/host=master/server-config=server-one/system-property=jboss.tx.node.id:add(boot-time=true,value=UNIQUE_NODE_ID) /profile=PROFILE_NAME/subsystem=transactions:write-attribute(name=node-identifier,value="${jboss.tx.node.id}") reload
In JBoss EAP 5, you enabled JTS transactions by running an Ant script located in the EAP5_HOME/docs/examples/transactions
directory and then performed some manual steps. The script updated the jbossts-properties.xml
and jacorb.properties
files for all JBoss EAP server configurations.
batch # Create a system property for the unique node identifier /system-property=jboss.tx.node.id:add(value=UNIQUE_NODE_ID) /system-property=jacorb.node.id:add(value=UNIQUE_JACORB_ID) # JacORB properties must be unique for each JBoss server instance # JacORB name must appear in JacORB context root i.e. ${jacorb.name}/Naming/root /subsystem=jacorb:write-attribute(name=transactions,value="on") /subsystem=jacorb:write-attribute(name="name",value="${jacorb.node.id}") /subsystem=jacorb:write-attribute(name="root-context",value="${jacorb.node.id}/Naming/root") /subsystem=transactions:write-attribute(name=jts,value=true) /subsystem=transactions:write-attribute(name=node-identifier,value="${jboss.tx.node.id}") run-batch reload
batch # # Define global system properties for the node identifier and JacORB implementation name. # /system-property=jboss.tx.node.id/:add(value="11",boot-time="true") /system-property=jacorb.node.id:add(value="mars",boot-time="true") /profile=PROFILE_NAME/subsystem=jacorb:write-attribute(name="security",value="on") /profile=PROFILE_NAME/subsystem=jacorb:write-attribute(name="transactions",value="on") /profile=PROFILE_NAME/subsystem=jacorb:write-attribute(name="name",value="${jacorb.node.id}") /profile=PROFILE_NAME/subsystem=jacorb:write-attribute(name="root-context",value="${jacorb.node.id}/Naming/root") /profile=PROFILE_NAME/subsystem=transactions:write-attribute(name="jts",value="true") /profile=PROFILE_NAME/subsystem=transactions:write-attribute(name="node-identifier",value="${jboss.tx.node.id:1}") run-batch reload --host=master
3.2.4. JSF changes
3.2.4.1. Enable Applications To Use Older Versions of JSF
If your application uses an older version of JSF, you do not need to upgrade to JSF 2.0. Instead, you can create a jboss-deployment-structure.xml
file to request that JBoss EAP 6 use JSF 1.2 rather than JSF 2.0 with your application deployment. This JBoss specific deployment descriptor is used to control class loading and is placed in the META-INF/
or WEB-INF/
directory of your WAR, or in the META-INF/
directory of your EAR.
jboss-deployment-structure.xml
file that adds a dependency for the JSF 1.2 module and excludes or 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>
3.2.5. Cache Changes
3.2.5.1. Replace JBoss Cache
infinispan
subsystem of the server configuration file. They should not be used directly by any application and are not supported for this purpose.
- Remote Client-Server
- This mode provides a managed, distributed and clusterable data grid server. Applications can remotely access the data grid server using Hot Rod, memcached or REST client APIs.
- Library
- This mode allows the user to build and deploy a custom runtime environment. The Library usage mode hosts a single data grid node in the applications process, with remote access to nodes hosted in other JVMs.
3.2.6. Web Services Changes
3.2.6.1. Web Services Changes
- JBossWS API Changes
- SPI and Common components were refactored in JBossWS 4. The following table lists API and packaging changes may affect your application migration.
Table 3.8. JBossWS API Changes Old JAR Old Package New JAR New Package JBossWS SPI org.jboss.wsf.spi.annotation.* JBossWS API org.jboss.ws.api.annotation.* JBossWS SPI org.jboss.wsf.spi.binding.* JBossWS API org.jboss.ws.api.binding.* JBossWS SPI org.jboss.wsf.spi.management.recording.* JBossWS API org.jboss.ws.api.monitoring.* JBossWS SPI org.jboss.wsf.spi.tools.* JBossWS API org.jboss.ws.api.tools.* JBossWS SPI org.jboss.wsf.spi.tools.ant.* JBossWS API org.jboss.ws.tools.ant.* JBossWS SPI org.jboss.wsf.spi.tools.cmd.* JBossWS API org.jboss.ws.tools.cmd.* JBossWS SPI org.jboss.wsf.spi.util.ServiceLoader JBossWS API org.jboss.ws.api.util.ServiceLoader JBossWS Common org.jboss.wsf.common.* JBossWS API org.jboss.ws.common.* JBossWS Common org.jboss.wsf.common.handler.* JBossWS API org.jboss.ws.api.handler.* JBossWS Common org.jboss.wsf.common.addressing.* JBossWS API org.jboss.ws.api.addressing.* JBossWS Common org.jboss.wsf.common.DOMUtils JBossWS API org.jboss.ws.api.util.DOMUtils JBossWS Native org.jboss.ws.annotation.EndpointConfig JBossWS API org.jboss.ws.api.annotation.EndpointConfig JBossWS Framework org.jboss.wsf.framework.invocation.RecordingServerHandler JBossWS Common org.jboss.ws.common.invocation.RecordingServerHandler - @WebContext Annotation
- In JBossWS 3.4.x, this annotation was packaged as
org.jboss.wsf.spi.annotation.WebContext
in the JBossWS SPI JAR. In JBossWS 4.0, this annotation was moved toorg.jboss.ws.api.annotation.WebContext
in the JBossWS API JAR. If your application includes the obsolete dependency, you must replace the imports and dependencies in your application source code and compile it against the new JBossWS API JAR.There is also a change to an attribute that is not backward compatible. TheString[] virtualHosts
attribute has been changed toString virtualHost
. In JBoss EAP 6, you can specify only one virtual host per deployment. If multiple webservices use the@WebContext
annotation, the virtualHost value must be identical for all endpoints defined in the deployment archive. - Endpoint Configuration
- JBossWS 4.0 provides integration of the JBoss Web Services stack with most of the Apache CXF modules. The integration layer allows the use of standard webservices APIs, including JAX-WS. It also allows the use of Apache CFX advanced features on top of the JBoss EAP 6 container without requiring complex configuration or setup.The
webservice
subsystem in the domain configuration of JBoss EAP 6 includes predefined endpoint configurations. You can also define your own additional endpoint configurations. The@org.jboss.ws.api.annotation.EndpointConfig
annotation is used to reference a given endpoint configuration.For more information on how to configure webservice endpoints in the JBoss server, see the chapter entitled JAX-WS Web Services 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-webservices.xml Deployment Descriptor
- JBossWS 4.0 introduces a new deployment descriptor to configure web services. The
jboss-webservices.xml
file provides additional information for the given deployment and partially replaces the obsoletejboss.xml
file.For EJB webservice deployments, the expected location of thejboss-webservices.xml
descriptor file is in theMETA-INF/
directory. For POJO and EJB webservice endpoints bundled in WAR file, the expected location of thejboss-webservices.xml
file is in theWEB-INF/
directory.The following is an example of ajboss-webservices.xml
descriptor file and a table describing the elements.<webservices> <context-root>foo<context-root> <config-name>Standard WSSecurity Endpoint</config-name> <config-file>META-INF/custom.xml</config-file> <property> <name>prop.name</name> <value>prop.value</value> </property> <port-component> <ejb-name>TestService</ejb-name> <port-component-name>TestServicePort</port-component-name> <port-component-uri>/*</port-component-uri> <auth-method>BASIC</auth-method> <transport-guarantee>NONE</transport-guarantee> <secure-wsdl-access>true</secure-wsdl-access> </port-component> <webservice-description> <webservice-description-name>TestService</webservice-description-name> <wsdl-publish-location>file:///bar/foo.wsdl</wsdl-publish-location> </webservice-description> </webservices>
Table 3.9. jboss-webservice.xml File Element Description Element Name Description context-rootUsed to customize the context root of the webservices deployment.config-nameconfig-fileUsed to associate an endpoint deployment with a given endpoint configuration. Endpoint configurations are specified in the referenced configuration file or in thewebservices
subsystem of the domain configuration.propertyUsed to set up simple property name value pairs to configure the webservice stack behavior.port-componentUsed to customize the EJB endpoint target URI or to configure security related properties.webservice-descriptionUsed to customize or override the webservice WSDL published location.
3.2.6.2. Use Apache Axis in JBoss EAP 6
It is recommended that you use JBossWS Apache CXF, which is bundled with JBoss EAP 6, for developing and deploying Web Service applications. The JBossWS Apache CXF that ships with JBoss EAP 6 is the supported configuration. If you prefer to use Axis, this topic describes how to use it in JBoss EAP 6. Be aware that this implementation is considered part of your application and is not a supported configuration.
Procedure 3.19. Configure JBoss EAP to Use Axis
- You must first disable the web services implementation that ships with JBoss EAP 6. For detailed instructions, see Section 3.2.6.3, “Disable JBossWS in JBoss EAP 6”.
- Rebuild and deploy the application. The Axis WS API implementation should now access the Java EE 6 API classes correctly.
3.2.6.3. Disable JBossWS in JBoss EAP 6
The Java Enterprise Edition Specification (Java EE) 6 requires that application servers provide an integrated JAX-WS implementation for developing and deploying Web Service applications. Applications that migrate from other containers, such as Servlet containers that do not provide support for JAX-WS, may be packaged with their own JAX-WS implementations. If you do not deploy anything that uses JBossWS CXF and plan to package your own JAX-WS implementation, you can disable the webservices
subsystem in JBoss EAP 6. Be aware that the JBossWS Apache CXF that ships with JBoss EAP 6 is the supported configuration. Any other implementation is considered part of your application and is not a supported configuration.
Procedure 3.20. Disable JBossWS for a Single Deployment
- Create a
jboss-deployment-structure.xml
file for your application.- If your application is packaged and deployed as a WAR, create the
jboss-deployment-structure.xml
file in either theMETA-INF/
or theWEB-INF/
directory of the WAR with the following contents.<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2"> <deployment> <!-- Exclude webservices subsystem so the implicit dependencies will not be added --> <exclude-subsystems> <subsystem name="webservices"/> </exclude-subsystems> </deployment> </jboss-deployment-structure>
- If your application is packaged and deployed in an EAR, create the
jboss-deployment-structure.xml
file in theMETA-INF/
directory of the EAR with contents similar to the following example.<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2"> ... <sub-deployment name="example.war"> <!-- Exclude webservices subsystem so the implicit dependencies will not be added --> <exclude-subsystems> <subsystem name="webservices"/> </exclude-subsystems> <dependencies> ... </dependencies> </sub-deployment> </jboss-deployment-structure>
- Deploy the application in the usual manner. JBossWS is now disabled for the application.
Procedure 3.21. Disable JBossWS for All Deployments to the Server
- Stop the JBoss EAP server.
- Open the server configuration file for editing. For a standalone server, this is the
EAP_HOME/standalone/configuration/standalone.xml
file. For a managed domain, this is theEAP_HOME/domain/configuration/domain.xml
file. - Find the
org.jboss.as.webservices
extension and either comment it out or remove it. - Find the
webservices
subsystem profile and either comment it out or remove it. - The following is an example of the changes maded to a
standalone.xml
file.<?xml version='1.0' encoding='UTF-8'?> <server xmlns="urn:jboss:domain:1.7"> <extensions> ... <!-- <extension module="org.jboss.as.webservices"/> --> ... </extensions> ... <profile> <!-- <subsystem xmlns="urn:jboss:domain:webservices:1.2"> <modify-wsdl-address>true</modify-wsdl-address> <wsdl-host>${jboss.bind.address:127.0.0.1}</wsdl-host> <endpoint-config name="Standard-Endpoint-Config"/> <endpoint-config name="Recording-Endpoint-Config"> <pre-handler-chain name="recording-handlers" protocol-bindings="##SOAP11_HTTP ##SOAP11_HTTP_MTOM ##SOAP12_HTTP ##SOAP12_HTTP_MTOM"> <handler name="RecordingHandler" class="org.jboss.ws.common.invocation.RecordingServerHandler"/> </pre-handler-chain> </endpoint-config> <client-config name="Standard-Client-Config"/> </subsystem> --> ... </profile> ... </server>
3.2.7. JAX-RS and RESTEasy Changes
3.2.7.1. Configure JAX-RS and RESTEasy Changes
web.xml
file and replace it with one of the following three options:
- Subclass
javax.ws.rs.core.Application
and use the@ApplicationPath
annotation.This is the easiest option and does not require any xml configuration. Simply subclassjavax.ws.rs.core.Application
in your application and annotate it with the path where you want to make your JAX-RS classes available. For example:@ApplicationPath("/mypath") public class MyApplication extends Application { }
In the above example, your JAX-RS resources are available in the path/MY_WEB_APP_CONTEXT/mypath/
.Note
Note the path should be specified as/mypath
, not/mypath/*
. There should be no trailing forward-slash or asterisk. - Subclass
javax.ws.rs.core.Application
and use theweb.xml
file to set up the JAX-RS mapping.If you do not wish to use the@ApplicationPath
annotation, you still need to subclassjavax.ws.rs.core.Application
. You then set up the JAX-RS mapping in theweb.xml
file. For example:public class MyApplication extends Application { }
<servlet-mapping> <servlet-name>com.acme.MyApplication</servlet-name> <url-pattern>/hello/*</url-pattern> </servlet-mapping>
In the above example, your JAX-RS resources are available in the path/MY_WEB_APP_CONTEXT/hello
.Note
You can also use this approach to override an application path that was set using the@ApplicationPath
annotation. - Modify the
web.xml
file.If you do not want to subclassApplication
, you can set up the JAX-RS mapping in theweb.xml
file as follows:<servlet-mapping> <servlet-name>javax.ws.rs.core.Application</servlet-name> <url-pattern>/hello/*</url-pattern> </servlet-mapping>
In the above example, your JAX-RS resources are available in the path/MY_WEB_APP_CONTEXT/hello
.Note
When you choose this option, you only need to add the mapping. You do not need to add the corresponding servlet. The server is responsible for adding the corresponding servlet automatically.
3.2.8. LDAP Security Realm Changes
3.2.8.1. Configure LDAP Security Realm Changes
<application-policy>
element in the login-config.xml
file. In JBoss EAP 6, the LDAP security realm is configured in the <security-domain>
element in the server configuration file. For a standalone server, this is the standalone/configuration/standalone.xml
file. If you are running your server in a managed domain, this is the domain/configuration/domain.xml
file.
login-config.xml
file in JBoss EAP 5:
<application-policy name="mcp_ldap_domain"> <authentication> <login-module code="org.jboss.security.auth.spi.LdapExtLoginModule" flag="required"> <module-option name="java.naming.factory.initial">com.sun.jndi.ldap.LdapCtxFactory</module-option> <module-option name="java.naming.security.authentication">simple</module-option> .... </login-module> </authentication> </application-policy>
<subsystem xmlns="urn:jboss:domain:security:1.2"> <security-domains> <security-domain name="mcp_ldap_domain" cache-type="default"> <authentication> <login-module code="org.jboss.security.auth.spi.LdapLoginModule" flag="required"> <module-option name="java.naming.factory.initial" value="com.sun.jndi.ldap.LdapCtxFactory"/> <module-option name="java.naming.security.authentication" value="simple"/> ... </login-module> </authentication> </security-domain> </security-domains> </subsystem>
Note
<module-option name="java.naming.factory.initial">com.sun.jndi.ldap.LdapCtxFactory</module-option>Now, the module options must be specified as element attributes with "value=" as follows:
<module-option name="java.naming.factory.initial" value="com.sun.jndi.ldap.LdapCtxFactory"/>
3.2.9. HornetQ Changes
3.2.9.1. About HornetQ and NFS
- The Red Hat Enterprise Linux NFS client cache must be disabled.
Important
Important
libaio
is installed on the Red Hat Enterprise Linux system where JBoss EAP 6 is running.
3.2.9.2. Configure a JMS Bridge to Migrate Existing JMS Messages to JBoss EAP 6
3.2.9.3. Create a JMS Bridge
A JMS bridge consumes messages from a source JMS queue or topic and sends them to a target JMS queue or topic, which is typically on a different server. It can be used to bridge messages between any JMS servers, as long as they are JMS 1.1 compliant. The source and destination JMS resources are looked up using JNDI and the client classes for the JNDI lookup must be bundled in a module. The module name is then declared in the JMS bridge configuration.
Procedure 3.22. Create a JMS Bridge
- Configure the Bridge on the Source JBoss EAP 5.x ServerTo avoid conflicts in classes between releases, you must follow these steps to configure the JMS bridge on JBoss EAP 5.x. The names of the SAR directory and bridge are arbitrary and can be changed if you prefer.
- Create a subdirectory in the JBoss EAP 5 deployment directory to contain the SAR, for example:
EAP5_HOME/server/PROFILE_NAME/deploy/myBridge.sar/
. - Create a subdirectory named
META-INF
inEAP5_HOME/server/PROFILE_NAME/deploy/myBridge.sar/
. - Create a
jboss-service.xml
file in theEAP5_HOME/server/PROFILE_NAME/deploy/myBridge.sar/META-INF/
directory. It should contain information similar to the following example.<server> <loader-repository> com.example:archive=unique-archive-name <loader-repository-config>java2ParentDelegation=false</loader-repository-config> </loader-repository> <!-- JBoss EAP 6 JMS Provider --> <mbean code="org.jboss.jms.jndi.JMSProviderLoader" name="jboss.messaging:service=JMSProviderLoader,name=EnterpriseApplicationPlatform6JMSProvider"> <attribute name="ProviderName">EnterpriseApplicationPlatform6JMSProvider</attribute> <attribute name="ProviderAdapterClass">org.jboss.jms.jndi.JNDIProviderAdapter</attribute> <attribute name="FactoryRef">jms/RemoteConnectionFactory</attribute> <attribute name="QueueFactoryRef">jms/RemoteConnectionFactory</attribute> <attribute name="TopicFactoryRef">jms/RemoteConnectionFactory</attribute> <attribute name="Properties"> java.naming.factory.initial=org.jboss.naming.remote.client.InitialContextFactory java.naming.provider.url=remote://EnterpriseApplicationPlatform6host:4447 java.naming.security.principal=jbossuser java.naming.security.credentials=jbosspass </attribute> </mbean> <mbean code="org.jboss.jms.server.bridge.BridgeService" name="jboss.jms:service=Bridge,name=MyBridgeName" xmbean-dd="xmdesc/Bridge-xmbean.xml"> <depends optional-attribute-name="SourceProviderLoader">jboss.messaging:service=JMSProviderLoader,name=JMSProvider</depends> <depends optional-attribute-name="TargetProviderLoader">jboss.messaging:service=JMSProviderLoader,name=EnterpriseApplicationPlatform6JMSProvider</depends> <attribute name="SourceDestinationLookup">/queue/A</attribute> <attribute name="TargetDestinationLookup">jms/queue/test</attribute> <attribute name="QualityOfServiceMode">1</attribute> <attribute name="MaxBatchSize">1</attribute> <attribute name="MaxBatchTime">-1</attribute> <attribute name="FailureRetryInterval">60000</attribute> <attribute name="MaxRetries">-1</attribute> <attribute name="AddMessageIDInHeader">false</attribute> <attribute name="TargetUsername">jbossuser</attribute> <attribute name="TargetPassword">jbosspass</attribute> </mbean> </server>
Note
Theload-repository
element is present to ensure the SAR has an isolated class loader. Also note both the JNDI look-up and the bridge "target" include security credentials for user "jbossuser" with password "jbosspass". This is because JBoss EAP 6 is secured by default. The user named "jbossuser" with password "jbosspass" was created in theApplicationRealm
with theguest
role using theEAP_HOME/bin/add_user.sh
script. - Copy the following JARs from the
EAP_HOME/modules/system/layers/base/
directory into theEAP5_HOME/server/PROFILE_NAME/deploy/myBridge.sar/
directory. Replace each VERSION_NUMBER with the actual version number in your JBoss EAP 6 distribution.org/hornetq/main/hornetq-core-VERSION_NUMBER.jar
org/hornetq/main/hornetq-jms-VERSION_NUMBER.jar
org/jboss/ejb-client/main/jboss-ejb-client-VERSION_NUMBER.jar
org/jboss/logging/main/jboss-logging-VERSION_NUMBER.jar
org/jboss/logmanager/main/jboss-logmanager-VERSION_NUMBER.jar
org/jboss/marshalling/main/jboss-marshalling-VERSION_NUMBER.jar
org/jboss/marshalling/river/main/jboss-marshalling-river-VERSION_NUMBER.jar
org/jboss/remote-naming/main/jboss-remote-naming-VERSION_NUMBER.jar
org/jboss/remoting3/main/jboss-remoting-VERSION_NUMBER.jar
org/jboss/sasl/main/jboss-sasl-VERSION_NUMBER.jar
org/jboss/netty/main/netty-VERSION_NUMBER.jar
org/jboss/remoting3/remote-jmx/main/remoting-jmx-VERSION_NUMBER.jar
org/jboss/xnio/main/xnio-api-VERSION_NUMBER.jar
org/jboss/xnio/nio/main.xnio-nio-VERSION_NUMBER.jar
Note
Do not simply copy theEAP_HOME/bin/client/jboss-client.jar
because the javax API classes will conflict with those in JBoss EAP 5.x.
- Configure the Bridge on the Destination JBoss EAP 6 ServerIn JBoss EAP 6.1 and later, the JMS bridge can be used to bridge messages from any JMS 1.1 compliant server. Because the source and target JMS resources are looked up using JNDI, the JNDI lookup classes of the source messaging provider, or message broker, must be bundled in a JBoss Module. The following steps use the fictitious 'MyCustomMQ' message broker as an example.
- Create the JBoss module for the messaging provider.
- Create a directory structure under
EAP_HOME/modules/system/layers/base/
for the new module. Themain/
subdirectory will contain the client JARs andmodule.xml
file. The following is an example of the directory structure created for the MyCustomMQ messaging provider:EAP_HOME/modules/system/layers/base/org/mycustommq/main/
- In the
main/
subdirectory, create amodule.xml
file containing the module definition for the messaging provider. The following is an example of themodule.xml
created for the MyCustomMQ messaging provider.<?xml version="1.0" encoding="UTF-8"?> <module xmlns="urn:jboss:module:1.1" name="org.mycustommq"> <properties> <property name="jboss.api" value="private"/> </properties> <resources> <!-- Insert resources required to connect to the source or target --> <resource-root path="mycustommq-1.2.3.jar" /> <resource-root path="mylogapi-0.0.1.jar" /> </resources> <dependencies> <!-- Add the dependencies required by JMS Bridge code --> <module name="javax.api" /> <module name="javax.jms.api" /> <module name="javax.transaction.api"/> <!-- Add a dependency on the org.hornetq module since we send --> <!-- messages tothe HornetQ server embedded in the local EAP instance --> <module name="org.hornetq" /> </dependencies> </module>
- Copy the messaging provider JARs required for the JNDI lookup of the source resources to the module's
main/
subdirectory. The directory structure for the MyCustomMQ module should now look like the following.modules/ `-- system `-- layers `-- base `-- org `-- mycustommq `-- main |-- mycustommq-1.2.3.jar |-- mylogapi-0.0.1.jar |-- module.xml
- Configure the JMS bridge in the
messaging
subsystem of the JBoss EAP 6 server.- Before you begin, stop the server and back up the current server configuration files. If you are running a standalone server, this is the
EAP_HOME/standalone/configuration/standalone-full-ha.xml
file. If you are running a managed domain, back up both theEAP_HOME/domain/configuration/domain.xml
and theEAP_HOME/domain/configuration/host.xml
files. - Add the
jms-bridge
element to themessaging
subsystem in the server configuration file. Thesource
andtarget
elements provide the names of the JMS resources used for JNDI lookups. Ifuser
andpassword
credentials are specified, they are passed as arguments when JMS connection is created.The following is an example of thejms-bridge
element configured for the MyCustomMQ messaging provider:<subsystem xmlns="urn:jboss:domain:messaging:1.3"> ... <jms-bridge name="myBridge" module="org.mycustommq"> <source> <connection-factory name="ConnectionFactory"/> <destination name="sourceQ"/> <user>user1</user> <password>pwd1</password> <context> <property key="java.naming.factory.initial" value="org.mycustommq.jndi.MyCustomMQInitialContextFactory"/> <property key="java.naming.provider.url" value="tcp://127.0.0.1:9292"/> </context> </source> <target> <connection-factory name="java:/ConnectionFactory"/> <destination name="/jms/targetQ"/> </target> <quality-of-service>DUPLICATES_OK</quality-of-service> <failure-retry-interval>500</failure-retry-interval> <max-retries>1</max-retries> <max-batch-size>500</max-batch-size> <max-batch-time>500</max-batch-time> <add-messageID-in-header>true</add-messageID-in-header> </jms-bridge> </subsystem>
In the above example, the JNDI properties are defined in thecontext
element for thesource
. If thecontext
element is omitted, as in thetarget
example above, the JMS resources are looked up in the local instance.
3.2.9.4. Migrate Your Application to Use HornetQ as the JMS Provider
Prerequisites
- Shut down the client and server.
- Make a backup copy of any JBoss Messaging data. The message data is stored in a database in tables prefixed with
JBM_
.
Procedure 3.23. Change Your Provider to HornetQ
- Transfer configurations.Transfer the existing JBoss Messaging configurations to the JBoss EAP 6 configuration. The following configurations can be found in deployment descriptors located on the JBoss Messaging server:
- Connection Factories Service ConfigurationThis configuration describes the JMS connection factories deployed with the JBoss Messaging server. JBoss Messaging configures connection factories in a file named
connection-factories-service.xml
which is located in the deployment directory of the application server. - Destination ConfigurationThis configuration describes JMS queues and topics deployed with JBoss Messaging server. By default, JBoss Messaging configures destinations in a file named
destinations-service.xml
which is located in the deployment directory of the application server. - Message Bridge Service ConfigurationThis configuration includes bridge services deployed with JBoss Messaging server. No bridges are deployed by default so the name of the deployment file varies depending on your JBoss Messaging installation.
- Modify your application code.If the application code uses standard JMS, no code changes are required. However, you must modify the application to use the new standardized JNDI namespaces as described in the section Section 3.1.8.2, “Portable EJB JNDI Names”. If the application uses features specific to JBoss Messaging, you must modify the code to use the equivalent features available in HornetQ.The following is an example of a JMS client that creates the
InitialContext
and looks up a queue in JBoss EAP 6.Hashtable<String, String> env = new Hashtable<String, String>(); String providerUrl = "remote:" + host + ":" + port; env.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming"); env.put("java.naming.factory.initial", "org.jboss.naming.remote.client.InitialContextFactory"); env.put("java.naming.provider.url", providerUrl); env.put(Context.SECURITY_PRINCIPAL, user); env.put(Context.SECURITY_CREDENTIALS, pass); InitialContext context = new InitialContext(env); Queue myTestQueue = (Queue) context.lookup("jms/queue/myTestQueue");
If the application will be connecting to a cluster, you must carefully review the HornetQ documentation on clustering semantics. Clustering is outside the scope of the JMS specification and HornetQ and JBoss Messaging have taken substantially different approaches in their respective implementations of clustering functionality.For more information on how to configure messaging with HornetQ, see: Section 3.2.9.5, “Configure Messaging with HornetQ” - Migrate existing messages.Move any messages in the JBoss Messaging database to the HornetQ journal using a JMS bridge. Instructions for configuring the JMS bridge can be found here: Section 3.2.9.2, “Configure a JMS Bridge to Migrate Existing JMS Messages to JBoss EAP 6”.
3.2.9.5. Configure Messaging with HornetQ
standalone.xml
or domain.xml
configuration files. It is useful however to familiarize yourself with the messaging components of the default configuration files, where documentation examples using management tools give configuration file snippets for reference.
3.2.9.6. Migrate JMS Destinations
<mbeans>
element of the jbossmq-destinations-service.xml
or destinations-service.xml
file. Because HornetQ replaces JBoss Messaging in JBoss EAP 6, JMS destinations are now configured in the messaging
subsystem of the server configuration file.
Example 3.3. JBoss EAP 4.2 Destination Configuration Example
jbossmq-destinations-service.xml
file in JBoss EAP 4.2. Note that if the JNDIName
attribute is not specified, the value defaults to the name shown in the example.
<mbean code="org.jboss.mq.server.jmx.Queue" name="jboss.mq.destination:service=Queue,name=DLQ"> <!-- The following JNDIName attribute shows the default JNDI binding name --> <attribute name="JNDIName">queue/DLQ</attribute> <depends optional-attribute-name="DestinationManager"> jboss.mq:service=DestinationManager </depends> </mbean> <mbean code="org.jboss.mq.server.jmx.Queue" name="jboss.mq.destination:service=Queue,name=ExpiryQueue"> <!-- The following JNDIName attribute shows the default JNDI binding name --> <attribute name="JNDIName">queue/ExpiryQueue</attribute> <depends optional-attribute-name="DestinationManager"> jboss.mq:service=DestinationManager </depends> </mbean>
Example 3.4. JBoss EAP 5 Destination Configuration Example
destinations-service.xml
file in JBoss EAP 5. Note that if the JNDIName
attribute
is not specified, the value defaults to the name shown in the example.
<mbean code="org.jboss.jms.server.destination.QueueService" name="jboss.messaging.destination:service=Queue,name=DLQ" xmbean-dd="xmdesc/Queue-xmbean.xml"> <!-- The following JNDIName attribute shows the default JNDI binding name --> <attribute name="JNDIName">queue/DLQ</attribute> <depends optional-attribute-name="ServerPeer"> jboss.messaging:service=ServerPeer </depends> <depends> jboss.messaging:service=PostOffice </depends> </mbean> <mbean code="org.jboss.jms.server.destination.QueueService" name="jboss.messaging.destination:service=Queue,name=ExpiryQueue" xmbean-dd="xmdesc/Queue-xmbean.xml"> <!-- The following JNDIName attribute shows the default JNDI binding name --> <attribute name="JNDIName">queue/ExpiryQueue</attribute> <depends optional-attribute-name="ServerPeer"> jboss.messaging:service=ServerPeer </depends> <depends> jboss.messaging:service=PostOffice </depends> </mbean>
Example 3.5. JBoss EAP 6 Destination Configuration Example
messaging
subsystem of the server configuration file in JBoss EAP 6. In JBoss EAP 6, the entry
element configures the name that is used to bind the queue to JNDI.
<subsystem xmlns="urn:jboss:domain:messaging:1.4"> <hornetq-server> ... <jms-destinations> <jms-queue name="ExpiryQueue"> <entry name="java:/jms/queue/ExpiryQueue"/> </jms-queue> <jms-queue name="DLQ"> <entry name="java:/jms/queue/DLQ"/> </jms-queue> </jms-destinations> </hornetq-server> </subsystem>
3.2.10. Clustering Changes
3.2.10.1. Make Changes to Your Application for Clustering
Start JBoss EAP 6 with clustering enabled
To enable clustering in JBoss EAP 5.x, you needed to start your server instances using theall
profile or some derivation of it, like this:$ EAP5_HOME/bin/run.sh -c all
In JBoss EAP 6, the method for enabling clustering depends on whether the servers are standalone or running in a managed domain.Enable clustering for servers running in a managed domain
To enable clustering for servers started using the domain controller, update yourdomain.xml
and designate a server group to use theha
profile andha-sockets
socket binding group. For example:<server-groups> <server-group name="main-server-group" profile="ha"> <jvm name="default"> <heap size="64m" max-size="512m"/> </jvm> <socket-binding-group ref="ha-sockets"/> </server-group> </server-group>
Enable clustering for standalone servers
To enable clustering for standalone servers, start the server using the appropriate configuration file as follows:$ EAP_HOME/bin/standalone.sh --server-config=standalone-ha.xml -Djboss.node.name=UNIQUE_NODE_NAME
Specify the bind address
In JBoss EAP 5.x, you would typically indicate the bind address used for clustering using the-b
command line argument like this:$ EAP5_HOME/bin/run.sh -c all -b 192.168.0.2
JBoss EAP 6 binds sockets to the IP addresses and interfaces contained in the<interfaces>
elements instandalone.xml
,domain.xml
andhost.xml
files. The standard configurations that ship with JBoss EAP include two interface configurations:<interfaces> <interface name="management"> <inet-address value="${jboss.bind.address.management:127.0.0.1}"/> </interface> <interface name="public"> <inet-address value="${jboss.bind.address:127.0.0.1}"/> </interface> </interfaces>
These interface configurations use the values of the system propertiesjboss.bind.address.management
andjboss.bind.address
. If these system properties are not set, the default127.0.0.1
is used for each value.You can also specify the bind address as a command line argument when you start the server or you can explicitly define it within the JBoss EAP 6 server configuration file.- Specify the bind argument on the command line when you start the JBoss EAP standalone server.The following is an example of how to specify the bind address on the command line for a standalone server:
EAP_HOME/bin/standalone.sh -Djboss.bind.address=127.0.0.1
Note
You can also use the-b
argument, which is a shortcut for-Djboss.bind.address=127.0.0.1
:EAP_HOME/bin/standalone.sh -b=127.0.0.1
The JBoss EAP 5 syntax format is also still supported:
Note that theEAP_HOME/bin/standalone.sh -b 127.0.0.1
-b
argument only changes thepublic
interface. It does not affect themanagement
interface. - Specify the bind address in the server configuration file.For servers running in a managed domain, specify the bind addresses in the
domain/configuration/host.xml
file. For standalone servers, specify the bind addresses in thestandalone-ha.xml
file.In the following example, thepublic
interface is specified as the default interface for all sockets within theha-sockets
socket binding group.<interfaces> <interface name="management"> <inet-address value="192.168.0.2"/> </interface> <interface name="public"> <inet-address value="192.168.0.2"/> </interface> </interfaces>
<socket-binding-groups> <socket-binding-group name="ha-sockets" default-interface="public"> <!-- ... --> </socket-binding-group> </socket-binding-groups>
Note
If you specify the bind address as a hard-coded value rather than a system property in the configuration file, you can not override it with a command line argument.
Configure
jvmRoute
to support mod_jk and mod_proxyIn JBoss EAP 5, the web serverjvmRoute
was configured using a property in theserver.xml
file. In JBoss EAP 6, thejvmRoute
attribute is configured in the web subsystem of the server configuration file using theinstance-id
attribute as follows:<subsystem xmlns="urn:jboss:domain:web:1.1" default-virtual-server="default-host" native="false" instance-id="{JVM_ROUTE_SERVER}">
The {JVM_ROUTE_SERVER} above should be replaced by the jvmRoute server ID.Theinstance-id
can also be set using the Management Console.Specify the multicast address and port
In JBoss EAP 5.x, you could specify the multicast address and port used for intra-cluster communication using the command line arguments-u
and-m
, respectively, like this:$ EAP5_HOME/bin/run.sh -c all -u 228.11.11.11 -m 45688
In JBoss EAP 6, the multicast address and port used for intra-cluster communication are defined by the socket-binding referenced by the relevant JGroups protocol stack as follows:<subsystem xmlns="urn:jboss:domain:jgroups:1.0" default-stack="udp"> <stack name="udp"> <transport type="UDP" socket-binding="jgroups-udp"/> <!-- ... --> </stack> </subsystem>
<socket-binding-groups> <socket-binding-group name="ha-sockets" default-interface="public"> <!-- ... --> <socket-binding name="jgroups-udp" port="55200" multicast-address="228.11.11.11" multicast-port="45688"/> <!-- ... --> </socket-binding-group> </socket-binding-groups>
If you prefer to specify the multicast address and port in the command line, you can define the multicast address and ports as system properties and then use those properties on the command line when you start the server. In the following example,jboss.mcast.addr
is the variable name for the multicast address andjboss.mcast.port
is the variable name for the port.<socket-binding name="jgroups-udp" port="55200" multicast-address="${jboss.mcast.addr:230.0.0.4}" multicast-port="${jboss.mcast.port:45688}"/>
You can then start your server using the following command line arguments:$ EAP_HOME/bin/domain.sh -Djboss.mcast.addr=228.11.11.11 -Djboss.mcast.port=45688
Use an alternate protocol stack
In JBoss EAP 5.x, you could manipulate the default protocol stack used for all clustering services using thejboss.default.jgroups.stack
system property.$ EAP5_HOME/bin/run.sh -c all -Djboss.default.jgroups.stack=tcp
In JBoss EAP 6, the default protocol stack is defined by the JGroups subsystem withindomain.xml
orstandalone-ha.xml
:<subsystem xmlns="urn:jboss:domain:jgroups:1.0" default-stack="udp"> <stack name="udp"> <!-- ... --> </stack> </subsystem>
Replace Buddy Replication
JBoss EAP 5.x used JBoss Cache Buddy Replication to suppress replication of data to all instances in a cluster.In JBoss EAP 6, Buddy Replication has been replaced by Infinispan's distributed cache, also known asDIST
mode. Distribution is a powerful clustering mode which allows Infinispan to scale linearly as more servers are added to the cluster. The following is an example of how to configure the server to use the DIST caching mode.- Open a command line and start the server with either the HA or Full Profile, for example:
EAP_HOME/bin/standalone.sh -c standalone-ha.xml
- Open another command line 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
- Issue the following commands to configure the cache tell the server to reload the new configuration:
/subsystem=infinispan/cache-container=web/:write-attribute(name=default-cache,value=dist) /subsystem=infinispan/cache-container=web/distributed-cache=dist/:write-attribute(name=owners,value=3) reload
You should see the following response after each command:"outcome" => "success"
These commands modify thedist
<distributed-cache>
element in theweb
<cache-container>
configuration in theinfinispan
subsystem of thestandalone-ha.xml
file as follows:<cache-container name="web" aliases="standard-session-cache" default-cache="dist" module="org.jboss.as.clustering.web.infinispan"> <transport lock-timeout="60000"/> <replicated-cache name="repl" mode="ASYNC" batching="true"> <file-store/> </replicated-cache> <replicated-cache name="sso" mode="SYNC" batching="true"/> <distributed-cache name="dist" owners="3" l1-lifespan="0" mode="ASYNC" batching="true"> <file-store/> </distributed-cache> </cache-container>
For more information, see the chapter entitled Clustering in Web Applications in the Development Guide for JBoss EAP 6 located on the Customer Portal at https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/?version=6.4.
3.2.10.2. Implement an HA Singleton
The following procedure demonstrates how to deploy a service that is wrapped with the SingletonService decorator and used as a cluster-wide singleton service. The service activates a scheduled timer, which is started only once in the cluster.
Procedure 3.24. Implement an HA Singleton Service
- Write the HA singleton service application.The following is a simple example of a
Service
that is wrapped with theSingletonService
decorator to be deployed as a singleton service. A complete example can be found in thecluster-ha-singleton
quickstart that ships with Red Hat JBoss Enterprise Application Platform 6. This quickstart contains all the instructions to build and deploy the application.- Create a service.The following listing is an example of a service:
package org.jboss.as.quickstarts.cluster.hasingleton.service.ejb; import java.util.Date; import java.util.concurrent.atomic.AtomicBoolean; import javax.naming.InitialContext; import javax.naming.NamingException; import org.jboss.logging.Logger; import org.jboss.msc.service.Service; import org.jboss.msc.service.ServiceName; import org.jboss.msc.service.StartContext; import org.jboss.msc.service.StartException; import org.jboss.msc.service.StopContext; /** * @author <a href="mailto:wfink@redhat.com">Wolf-Dieter Fink</a> */ public class HATimerService implements Service<String> { private static final Logger LOGGER = Logger.getLogger(HATimerService.class); public static final ServiceName SINGLETON_SERVICE_NAME = ServiceName.JBOSS.append("quickstart", "ha", "singleton", "timer"); /** * A flag whether the service is started. */ private final AtomicBoolean started = new AtomicBoolean(false); /** * @return the name of the server node */ public String getValue() throws IllegalStateException, IllegalArgumentException { LOGGER.infof("%s is %s at %s", HATimerService.class.getSimpleName(), (started.get() ? "started" : "not started"), System.getProperty("jboss.node.name")); return ""; } public void start(StartContext arg0) throws StartException { if (!started.compareAndSet(false, true)) { throw new StartException("The service is still started!"); } LOGGER.info("Start HASingleton timer service '" + this.getClass().getName() + "'"); final String node = System.getProperty("jboss.node.name"); try { InitialContext ic = new InitialContext(); ((Scheduler) ic.lookup("global/jboss-cluster-ha-singleton-service/SchedulerBean!org.jboss.as.quickstarts.cluster.hasingleton.service.ejb.Scheduler")).initialize("HASingleton timer @" + node + " " + new Date()); } catch (NamingException e) { throw new StartException("Could not initialize timer", e); } } public void stop(StopContext arg0) { if (!started.compareAndSet(true, false)) { LOGGER.warn("The service '" + this.getClass().getName() + "' is not active!"); } else { LOGGER.info("Stop HASingleton timer service '" + this.getClass().getName() + "'"); try { InitialContext ic = new InitialContext(); ((Scheduler) ic.lookup("global/jboss-cluster-ha-singleton-service/SchedulerBean!org.jboss.as.quickstarts.cluster.hasingleton.service.ejb.Scheduler")).stop(); } catch (NamingException e) { LOGGER.error("Could not stop timer", e); } } } }
- Create an activator that installs the
Service
as a clustered singleton.The following listing is an example of a Service activator that installs theHATimerService
as a clustered singleton service:package org.jboss.as.quickstarts.cluster.hasingleton.service.ejb; import org.jboss.as.clustering.singleton.SingletonService; import org.jboss.logging.Logger; import org.jboss.msc.service.DelegatingServiceContainer; import org.jboss.msc.service.ServiceActivator; import org.jboss.msc.service.ServiceActivatorContext; import org.jboss.msc.service.ServiceController; /** * Service activator that installs the HATimerService as a clustered singleton service * during deployment. * * @author Paul Ferraro */ public class HATimerServiceActivator implements ServiceActivator { private final Logger log = Logger.getLogger(this.getClass()); @Override public void activate(ServiceActivatorContext context) { log.info("HATimerService will be installed!"); HATimerService service = new HATimerService(); SingletonService<String> singleton = new SingletonService<String>(service, HATimerService.SINGLETON_SERVICE_NAME); /* * To pass a chain of election policies to the singleton, for example, * to tell JGroups to prefer running the singleton on a node with a * particular name, uncomment the following line: */ // singleton.setElectionPolicy(new PreferredSingletonElectionPolicy(new SimpleSingletonElectionPolicy(), new NamePreference("node1/singleton"))); singleton.build(new DelegatingServiceContainer(context.getServiceTarget(), context.getServiceRegistry())) .setInitialMode(ServiceController.Mode.ACTIVE) .install() ; } }
Note
The above code example uses a class,org.jboss.as.clustering.singleton.SingletonService
, that is part of the JBoss EAP private API. A public API will become available in the JBoss EAP 7 release and the private class will be deprecated, but these classes will be maintained and available for the duration of the JBoss EAP 6.x release cycle. - Create a ServiceActivator FileCreate a file named
org.jboss.msc.service.ServiceActivator
in the application'sresources/META-INF/services/
directory. Add a line containing the fully qualified name of the ServiceActivator class created in the previous step.org.jboss.as.quickstarts.cluster.hasingleton.service.ejb.HATimerServiceActivator
- Create a Singleton bean that implements a timer to be used as a cluster-wide singleton timer.This Singleton bean must not have a remote interface and you must not reference its local interface from another EJB in any application. This prevents a lookup by a client or other component and ensures the SingletonService has total control of the Singleton.
- Create the Scheduler interface
package org.jboss.as.quickstarts.cluster.hasingleton.service.ejb; /** * @author <a href="mailto:wfink@redhat.com">Wolf-Dieter Fink</a> */ public interface Scheduler { void initialize(String info); void stop(); }
- Create the Singleton bean that implements the cluster-wide singleton timer.
package org.jboss.as.quickstarts.cluster.hasingleton.service.ejb; import javax.annotation.Resource; import javax.ejb.ScheduleExpression; import javax.ejb.Singleton; import javax.ejb.Timeout; import javax.ejb.Timer; import javax.ejb.TimerConfig; import javax.ejb.TimerService; import org.jboss.logging.Logger; /** * A simple example to demonstrate a implementation of a cluster-wide singleton timer. * * @author <a href="mailto:wfink@redhat.com">Wolf-Dieter Fink</a> */ @Singleton public class SchedulerBean implements Scheduler { private static Logger LOGGER = Logger.getLogger(SchedulerBean.class); @Resource private TimerService timerService; @Timeout public void scheduler(Timer timer) { LOGGER.info("HASingletonTimer: Info=" + timer.getInfo()); } @Override public void initialize(String info) { ScheduleExpression sexpr = new ScheduleExpression(); // set schedule to every 10 seconds for demonstration sexpr.hour("*").minute("*").second("0/10"); // persistent must be false because the timer is started by the HASingleton service timerService.createCalendarTimer(sexpr, new TimerConfig(info, false)); } @Override public void stop() { LOGGER.info("Stop all existing HASingleton timers"); for (Timer timer : timerService.getTimers()) { LOGGER.trace("Stop HASingleton timer: " + timer.getInfo()); timer.cancel(); } } }
- Start each JBoss EAP 6 instance with clustering enabled.To enable clustering for standalone servers, you must start each server with the
HA
profile, using a unique node name and port offset for each instance.- For Linux, use the following command syntax to start the servers:
EAP_HOME/bin/standalone.sh --server-config=standalone-ha.xml -Djboss.node.name=UNIQUE_NODE_NAME -Djboss.socket.binding.port-offset=PORT_OFFSET
Example 3.6. Start multiple standalone servers on Linux
$ EAP_HOME/bin/standalone.sh --server-config=standalone-ha.xml -Djboss.node.name=node1
$ EAP_HOME/bin/standalone.sh --server-config=standalone-ha.xml -Djboss.node.name=node2 -Djboss.socket.binding.port-offset=100
- For Microsoft Windows, use the following command syntax to start the servers:
EAP_HOME\bin\standalone.bat --server-config=standalone-ha.xml -Djboss.node.name=UNIQUE_NODE_NAME -Djboss.socket.binding.port-offset=PORT_OFFSET
Example 3.7. Start multiple standalone servers on Microsoft Windows
C:> EAP_HOME\bin\standalone.bat --server-config=standalone-ha.xml -Djboss.node.name=node1
C:> EAP_HOME\bin\standalone.bat --server-config=standalone-ha.xml -Djboss.node.name=node2 -Djboss.socket.binding.port-offset=100
Note
If you prefer not to use command line arguments, you can configure thestandalone-ha.xml
file for each server instance to bind on a separate interface. - Deploy the application to the serversThe following Maven command deploys the application to a standalone server running on the default ports.
mvn clean install jboss-as:deploy
To deploy to additional servers, pass the server name. if it is on a different host, pass the host name and port number on the command line:mvn clean package jboss-as:deploy -Djboss-as.hostname=localhost -Djboss-as.port=10099
See thecluster-ha-singleton
quickstart that ships with JBoss EAP 6 for Maven configuration and deployment details.
3.2.11. Service-style Deployment Changes
3.2.11.1. Update Applications That Use Service-style Deployments
MBeans were part of the core architecture in previous versions of Red Hat JBoss Enterprise Application Platform. JBoss Service Archive (SAR) deployments using the JBoss specific jboss-service.xml
and jboss-beans.xml
service-style descriptors were used by the application server to create MBeans based on JBoss Beans. The internal architecture has changed in JBoss EAP 6 and is no longer based on an MBean JMX architecture. MBeans are no longer part of the core architecture. They are now a wrapper for the management API.
jboss-service.xml
files.
The JBoss Service Archive (SAR) and service-style descriptors used in previous versions of JBoss EAP are not a part of the Java EE 6 specification and are not recommended for use in JBoss EAP 6. It is recommended that you modify your application to the Java EE 6 specification. For MBeans singletons, you should modify the code to use the more portable Java EE 6 @Singleton
instead of the JBoss EAP proprietary *-beans.xml
and *-service.xml
files. For more information about creating and deploying MBean services, see the chapter entitled JBoss MBean Services in the Development Guide for JBoss EAP 6 located on the Customer Portal at https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/?version=6.4.
If choose not to modify the code to use the standard Java EE 6 EJB @Singleton
, be aware that the jboss-beans.xml
and jboss-service.xml
files changed between JBoss EAP 5 and JBoss EAP 6.
- The XML declaration in
jboss-beans.xml
file changed between JBoss EAP 5 and JBoss EAP 6. - The following is an example of a
jboss-beans.xml
file in JBoss EAP 5.<?xml version="1.0" encoding="UTF-8"?> <deployment xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:jboss:bean-deployer:2.0 bean-deployer_2_0.xsd" xmlns="urn:jboss:bean-deployer:2.0"> <bean name="TestServantBean" class="org.jboss.test.iiop.jbpapp6462.servant.TestServantBean"/> </deployment>
The following is an example of ajboss-beans.xml
file in JBoss EAP 6.<deployment xmlns="urn:jboss:pojo:7.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:jboss:pojo:7.0 jboss-mc_7_0.xsd"> ... <bean name="Bean"> <alias>Alias-Bean</alias> <constructor factory-class="org.jboss.as.test.integration.pojo.support.TFactory" factory-method="createBean"> <parameter><value>test</value></parameter> </constructor> <property name="injectee"><inject bean="Injectee"/></property> <start> <parameter><value>start</value></parameter> </start> <stop> <parameter><value>stop</value></parameter> </stop> <install method="install" state="CREATE"> <parameter><value>install</value></parameter> </install> <install bean="Alias-Injectee" method="sayHello"> <parameter><value>from-other-bean</value></parameter> </install> </bean> </deployment>
- The DTD for the
jboss-service.xml
file changed between JBoss EAP 5 and JBoss EAP 6. - The following is an example of a
jboss-service.xml
file in JBoss EAP 5.<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE server PUBLIC "-//JBoss//DTD MBean Service 5.0//EN" "http://www.jboss.org/j2ee/dtd/jboss-service_5_0.dtd"> <server> ... </server>
The following is an example of ajboss-service.xml
file in JBoss EAP 6.<server xmlns="urn:jboss:service:7.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:jboss:service:7.0 jboss-service_7_0.xsd"> <mbean name="jboss.test:service=testdeployments" code="org.jboss.as.test.integration.mgmt.access.deployment.sar.Simple"/> </server>
3.2.12. Remote Invocation Changes
3.2.12.1. Migrate JBoss EAP 5 Deployed Applications That Make Remote Invocations to JBoss EAP 6
In JBoss EAP 5, the EJB remote interface was bound in JNDI, by default, under the name EJB_NAME/local
for local interfaces, and EJB_NAME/remote
for remote interfaces. The client application then looked up the bean using EJB_NAME/remote
.
ejb:
BEAN_REFERENCE for remote access to EJBs using the following syntax.
ejb:
BEAN_REFERENCE syntax is:
ejb:<app-name>/<module-name>/<distinct-name>/<bean-name>!<fully-qualified-classname-of-the-remote-interface>For stateful beans, the
ejb:
BEAN_REFERENCE syntax is:
ejb:<app-name>/<module-name>/<distinct-name>/<bean-name>!<fully-qualified-classname-of-the-remote-interface>?stateful
<app-name>
- the application name of the deployed EJBs. This is typically the ear name without the .ear suffix, however, the name can be overridden in the application.xml file. If the application is not deployed as a .ear, this value is an empty string. Assume this example was not deployed as an EAR.<module-name>
- the module name of the deployed EJBs on the server. This is typically the jar name of the EJB deployment, without the .jar suffix, but can be overridden using the ejb-jar.xml. In this example, assume the EJBs were deployed in a jboss-ejb-remote-app.jar, so the module name is jboss-ejb-remote-app.<distinct-name>
- an optional distinct name for the EJB. This example does not use a distinct name, so it uses an empty string.<bean-name>
- by default, is the simple class name of the bean implementation class.<fully-qualified-classname-of-the-remote-interface>
- the remote view fully qualified class name.
The client code examples below assume you deployed the following stateless EJB to a JBoss EAP 6 server. Note that it exposes a remote view for the bean using the @Remote
annotation.
Example 3.8. Stateless Session Bean Code Example
@Stateless @Remote(RemoteCalculator.class) public class CalculatorBean implements RemoteCalculator { @Override public int add(int a, int b) { return a + b; } @Override public int subtract(int a, int b) { return a - b; } }
InitialContext
and looked up the EJB using its JNDI name.
Example 3.9. JBoss EAP 5 Client Example
InitialContext ctx = new InitialContext(); RemoteCalculator calculator = (RemoteCalculator) ctx.lookup("CalculatorBean/remote"); int a = 204; int b = 340; int sum = calculator.add(a, b);
Hashtable
and set the properties for the bean reference as described above. The following is an example of the client lookup and invocation.
Example 3.10. JBoss EAP 6 Stateless Client Example
final Hashtable jndiProperties = new Hashtable(); jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming"); final Context context = new InitialContext(jndiProperties); final String appName = ""; final String moduleName = "jboss-ejb-remote-app"; final String distinctName = ""; final String beanName = CalculatorBean.class.getSimpleName(); final String viewClassName = RemoteCalculator.class.getName(); final RemoteCalculator statelessRemoteCalculator = (RemoteCalculator) context.lookup("ejb:" + appName + "/" + moduleName + "/" + distinctName + "/" + beanName + "!" + viewClassName); int a = 204; int b = 340; int sum = statelessRemoteCalculator.add(a, b);
Example 3.11. JBoss EAP 6 Stateful Client Example
final RemoteCalculator statefulRemoteCalculator = (RemoteCalculator) context.lookup("ejb:" + appName + "/" + moduleName + "/" + distinctName + "/" + beanName + "!" + viewClassName + "?stateful")
3.2.12.2. Invoke a Session Bean Remotely using JNDI
ejb-remote
quickstart contains working Maven projects that demonstrate this functionality. The quickstart contains projects for both the session beans to deploy and the remote client. The code samples below are taken from the remote client project.
Warning
Prerequisites
- You must already have a Maven project created ready to use.
- Configuration for the JBoss EAP 6 Maven repository has already been added.
- The session beans that you want to invoke are already deployed.
- The deployed session beans implement remote business interfaces.
- The remote business interfaces of the session beans are available as a Maven dependency. If the remote business interfaces are only available as a JAR file then it is recommended to add the JAR to your Maven repository as an artifact. Refer to the Maven documentation for the
install:install-file
goal for directions, http://maven.apache.org/plugins/maven-install-plugin/usage.html - You need to know the hostname and JNDI port of the server hosting the session beans.
Procedure 3.25. Add Maven Project Configuration for Remote Invocation of Session Beans
- Add the required project dependenciesThe
pom.xml
for the project must be updated to include the necessary dependencies. - Add the
jboss-ejb-client.properties
fileThe JBoss EJB client API expects to find a file in the root of the project namedjboss-ejb-client.properties
that contains the connection information for the JNDI service. Add this file to thesrc/main/resources/
directory of your project with the following content.# In the following line, set SSL_ENABLED to true for SSL remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED=false remote.connections=default # Uncomment the following line to set SSL_STARTTLS to true for SSL # remote.connection.default.connect.options.org.xnio.Options.SSL_STARTTLS=true remote.connection.default.host=localhost remote.connection.default.port = 4447 remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false # Add any of the following SASL options if required # remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOANONYMOUS=false # remote.connection.default.connect.options.org.xnio.Options.SASL_POLICY_NOPLAINTEXT=false # remote.connection.default.connect.options.org.xnio.Options.SASL_DISALLOWED_MECHANISMS=JBOSS-LOCAL-USER
Change the host name and port to match your server.4447
is the default port number. For a secure connection, set theSSL_ENABLED
line totrue
and uncomment theSSL_STARTTLS
line. The Remoting interface in the container supports secured and unsecured connections using the same port. - Add dependencies for the remote business interfacesAdd the Maven dependencies to the
pom.xml
for the remote business interfaces of the session beans.<dependency> <groupId>org.jboss.as.quickstarts</groupId> <artifactId>jboss-ejb-remote-server-side</artifactId> <type>ejb-client</type> <version>${project.version}</version> </dependency>
Procedure 3.26. Obtain a Bean Proxy using JNDI and Invoke Methods of the Bean
- Handle checked exceptionsTwo of the methods used in the following code (
InitialContext()
andlookup()
) have a checked exception of typejavax.naming.NamingException
. These method calls must either be enclosed in a try/catch block that catchesNamingException
or in a method that is declared to throwNamingException
. Theejb-remote
quickstart uses the second technique. - Create a JNDI ContextA JNDI Context object provides the mechanism for requesting resources from the server. Create a JNDI context using the following code:
final Hashtable jndiProperties = new Hashtable(); jndiProperties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming"); final Context context = new InitialContext(jndiProperties);
The connection properties for the JNDI service are read from thejboss-ejb-client.properties
file. - Use the JNDI Context's lookup() method to obtain a bean proxyInvoke the
lookup()
method of the bean proxy and pass it the JNDI name of the session bean you require. This will return an object that must be cast to the type of the remote business interface that contains the methods you want to invoke.final RemoteCalculator statelessRemoteCalculator = (RemoteCalculator) context.lookup( "ejb:/jboss-ejb-remote-server-side//CalculatorBean!" + RemoteCalculator.class.getName());
Session bean JNDI names are defined using a special syntax. For more information, see Section 3.2.12.3, “EJB JNDI Naming Reference” . - Invoke methodsNow that you have a proxy bean object you can invoke any of the methods contained in the remote business interface.
int a = 204; int b = 340; System.out.println("Adding " + a + " and " + b + " via the remote stateless calculator deployed on the server"); int sum = statelessRemoteCalculator.add(a, b); System.out.println("Remote calculator returned sum = " + sum);
The proxy bean passes the method invocation request to the session bean on the server, where it is executed. The result is returned to the proxy bean which then returns it to the caller. The communication between the proxy bean and the remote session bean is transparent to the caller.
3.2.12.3. EJB JNDI Naming Reference
ejb:<appName>/<moduleName>/<distinctName>/<beanName>!<viewClassName>?stateful
<appName>
- If the session bean's JAR file has been deployed within an enterprise archive (EAR) then this is the name of that EAR. By default, the name of an EAR is its filename without the
.ear
suffix. The application name can also be overridden in itsapplication.xml
file. If the session bean is not deployed in an EAR then leave this blank. <moduleName>
- The module name is the name of the JAR file that the session bean is deployed in. By the default, the name of the JAR file is its filename without the
.jar
suffix. The module name can also be overridden in the JAR'sejb-jar.xml
file. <distinctName>
- JBoss EAP 6 allows each deployment to specify an optional distinct name. If the deployment does not have a distinct name then leave this blank.
<beanName>
- The bean name is the classname of the session bean to be invoked.
<viewClassName>
- The view class name is the fully qualified classname of the remote interface. This includes the package name of the interface.
?stateful
- The
?stateful
suffix is required when the JNDI name refers to a stateful session bean. It is not included for other bean types.
3.2.12.4. Migrate EJB Asynchronous Method Calls
The EJB 3.1 specification introduced the ability to make asynchronous methods calls. Prior to the introduction of this feature, some application servers provided proprietary asynchronous functionality. JBoss EAP 4.x provided classes in the org.jboss.ejb3.asynchronous
package and JBoss EAP 5.x provided the org.jboss.ejb3.common.proxy.plugins.async.AsyncUtils
class for this purpose. These classes are not supported in JBoss EAP 6 and must be replaced. The following is an example of how to make an asynchronous method call in JBoss EAP 6.
Procedure 3.27. Create the Asynchronous Session Bean and Client
- Create the Asynchronous session bean method.In the following example, the
sayHelloAsync()
method is marked as asynchronous using the@Asynchronous
annotation. It returns the requiredFuture
class implementation with a result of typeString
.import javax.ejb.Remote; import javax.ejb.SessionContext; import javax.ejb.Stateless; import javax.ejb.TransactionAttribute; import javax.ejb.TransactionAttributeType; import javax.interceptor.Interceptors; import java.util.concurrent.Future; import javax.ejb.AsyncResult; import javax.ejb.Asynchronous; @Stateless(name="Hello") @Remote(Hello.class) public class HelloBean implements Hello { @Asynchronous public Future<String> sayHelloAsync() { return new AsyncResult<String>("Hello"); } }
- Create the client code.Look up the EJB and call its asynchronous method using one of the available
Future.get()
methods. The following example limits the wait time to the values specified by the timeout and unit arguments.Future<String> future = ejbObject.sayHelloAsync(); String response = future.get(timeout, unit);
3.2.13. EJB Changes
3.2.13.1. Migrate Stateful EJB Cache Configuration
container-cache-conf
element in the jboss.xml
file. The following is an example of stateful cache configuration in JBoss EAP 5.
<container-cache-conf> <cache-policy>org.jboss.ejb.plugins.LRUStatefulContextCachePolicy</cache-policy> <cache-policy-conf> <min-capacity>50</min-capacity> <max-capacity>200</max-capacity> <remover-period>1800</remover-period> <max-bean-life>1320</max-bean-life> <overager-period>300</overager-period> <max-bean-age>1260</max-bean-age> </cache-policy-conf> </container-cache-conf>
ejb3
subsystem of the server configuration file. For detailed instructions, see Section 3.2.13.2, “Configure Stateful Session Bean Cache”. The instructions also describe how to configure stateful-timeout
, which replaces the <max-bean-age>
that was specified in JBoss EAP 5.
3.2.13.2. Configure Stateful Session Bean Cache
ejb3
subsystem of the server configuration file. The following procedure describes how to configure stateful EJB cache and stateful timeout.
Procedure 3.28. Configure Stateful EJB Cache
- Find the
<caches>
element in theejb3
subsystem of the server configuration file. Add a<cache>
element. The following example creates a cache named "my=cache".<cache name="my-cache" passivation-store-ref="my-cache-file" aliases="my-custom-cache"/>
- Find the
<passivation-stores>
element in theejb3
subsystem of the server configuration file. Create a<file-passivation-store>
for the cache defined in the previous step.<file-passivation-store name="my-cache-file" idle-timeout="1260" idle-timeout-unit="SECONDS" max-size="200"/>
- The
ejb3
subsystem configuration should now look like the following example.<subsystem xmlns="urn:jboss:domain:ejb3:1.4"> ... <caches> <cache name="simple" aliases="NoPassivationCache"/> <cache name="passivating" passivation-store-ref="file" aliases="SimpleStatefulCache"/> <cache name="clustered" passivation-store-ref="infinispan" aliases="StatefulTreeCache"/> <cache name="my-cache" passivation-store-ref="my-cache-file" aliases="my-custom-cache"/> </caches> <passivation-stores> <file-passivation-store name="file" idle-timeout="120" idle-timeout-unit="SECONDS" max-size="500"/> <cluster-passivation-store name="infinispan" cache-container="ejb"/> <file-passivation-store name="my-cache-file" idle-timeout="1260" idle-timeout-unit="SECONDS" max-size="200"/> </passivation-stores> ... </subsystem>
The passivating cache, "my-cache", passivates stateful session beans to the file system as configured in the "my-cache-file" passivation store, which has theidle-timeout
,idle-timeout-unit
andmax-size
options. - Create a
jboss-ejb3.xml
file in the EJB JARMETA-INF/
directory. The following example configures the EJBs to use the cache defined in the previous steps.<jboss:ejb-jar xmlns:jboss="http://www.jboss.com/xml/ns/javaee" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:c="urn:ejb-cache:1.0" xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee http://www.jboss.org/j2ee/schema/jboss-ejb3-2_0.xsd http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd" version="3.1" impl-version="2.0"> <assembly-descriptor> <c:cache> <ejb-name>*</ejb-name> <c:cache-ref>my-cache</c:cache-ref> </c:cache> </assembly-descriptor> </jboss:ejb-jar>
- To method to configure a timeout value depends on whether you are implementing EJB 2 or EJB 3.
- EJB 3 introduced annotations, so you can specify the
javax.ejb.StatefulTimeout
annotation in the EJB code as follows.@StatefulTimeout(value = 1320, unit=java.util.concurrent.TimeUnit.SECONDS) @Stateful @Remote(MyStatefulEJBRemote.class) public class MyStatefulEJB implements MyStatefulEJBRemote { ... }
The@StatefulTimeout
value can be set to one of the following.- A value of
0
means the bean is immediately eligible for removal. - A value greater than
0
indicates a timeout value in the units specified by theunit
parameter. The default timeout unit isMINUTES
. If you are using a passivating cache configuration and theidle-timeout
value is less than theStatefulTimeout
value, JBoss EAP will passivate the bean when it is idle for theidle-timeout
period specified. The bean is then eligible for removal after theStatefulTimeout
period specified. - A value of
-1
means the bean will never be removed due to timeout. If you are using a passivating cache configuration and the bean is idle foridle-timeout
, JBoss EAP will passivate the bean instance to thepassivation-store
. - Values less than
-1
are not valid.
- For both EJB 2 and EJB 3, you can configure the stateful timeout in the
ejb-jar.xml
file.<?xml version="1.0" encoding="UTF-8"?> <ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd" version="3.1"> <enterprise-beans> <session> <ejb-name>HelloBean</ejb-name> <session-type>Stateful</session-type> <stateful-timeout> <timeout>1320</timeout> <unit>Seconds</unit> </stateful-timeout> </session> </enterprise-beans> </ejb-jar>
- For both EJB 2 and EJB 3, you can configure the stateful timeout in the
jboss-ejb3.xml
file.<jboss:ejb-jar xmlns:jboss="http://www.jboss.com/xml/ns/javaee" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:c="urn:ejb-cache:1.0" xsi:schemaLocation="http://www.jboss.com/xml/ns/javaee http://www.jboss.org/j2ee/schema/jboss-ejb3-2_0.xsd http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_1.xsd" version="3.1" impl-version="2.0"> <enterprise-beans> <session> <ejb-name>HelloBean</ejb-name> <session-type>Stateful</session-type> <stateful-timeout> <timeout>1320</timeout> <unit>Seconds</unit> </stateful-timeout> </session> </enterprise-beans> <assembly-descriptor> <c:cache> <ejb-name>*</ejb-name> <c:cache-ref>my-cache</c:cache-ref> </c:cache> </assembly-descriptor> </jboss:ejb-jar>
- To disable passivation of stateful session beans, do one of the following:
- If you implement stateful session beans using EJB 3 annotations, you can disable the passivation of the stateful session bean the annotation
@org.jboss.ejb3.annotation.Cache("NoPassivationCache")
- If the stateful session bean is configured in the
jboss-ejb3.xml
file, set the<c:cache-ref>
element value to "simple", which is the equivalent ofNoPassivationCache
.<c:cache-ref>simple</c:cache-ref>
- EJB cache policy "LRUStatefulContextCachePolicy" has been changed in JBoss EAP 6 so it is impossible to have 1-to-1 configuration mapping in JBoss EAP 6.
- In JBoss EAP 6, you can set up the following cache properties:
- Bean life time is configured using the @StatefulTimeout in EJB 3.1.
- Configure passivation of a bean to disk in the
ejb3
subsystem of the server configuration file using theidle-timeout
attribute of the<file-passivation-store>
element. - Configure the maximum size of the passivation store in the
ejb3
subsystem of the server configuration file using themax-size
attribute of the<file-passivation-store>
element.
- In JBoss EAP 6, you can not configure the following cache properties:
- The minimum and maximum numbers in memory cache.
- The minimum numbers in passivation store.
- The
*-period
configurations that control the frequency of cache operations.
3.2.13.3. Configure Stateless Session Bean Pool Size
In JBoss EAP 5, stateless EJB pool defaults were configured in EAP_HOME/server/PROFILE/deploy/ejb3-interceptors-aop.xml
file. The following is an example of pool configuration in JBoss EAP 5.
<domain name="Stateless Bean" extends="Intercepted Bean" inheritBindings="true"> ... <annotation expr="class(*) AND !class(@org.jboss.ejb3.annotation.Pool)"> @org.jboss.ejb3.annotation.Pool (value="ThreadlocalPool", maxSize=30, timeout=10000) </annotation> </domain>This topic describes how to configure EJB session bean stateless pools in JBoss EAP 6.
In JBoss EAP 6, stateless session bean pools are configured in the <bean-instance-pools>
section of the ejb3
subsytem in the server configuration file. The default pool for stateless session beans is the "slsb-strict-max-pool". You can define additional configurations in the <bean-instance-pools>
. The following example defines a new configuration named "my-stateless-bean-pool" in JBoss EAP 6.
<subsystem xmlns="urn:jboss:domain:ejb3:1.3"> <session-bean> <stateless> <bean-instance-pool-ref pool-name="slsb-strict-max-pool"/> </stateless> <stateful default-access-timeout="5000" cache-ref="simple"/> <singleton default-access-timeout="5000"/> </session-bean> <pools> <bean-instance-pools> <strict-max-pool name="slsb-strict-max-pool" max-pool-size="20" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/> <strict-max-pool name="mdb-strict-max-pool" max-pool-size="20" instance-acquisition-timeout="5" instance-acquisition-timeout-unit="MINUTES"/> <strict-max-pool name="my-stateless-bean-pool" max-pool-size="50" instance-acquisition-timeout="20" instance-acquisition-timeout-unit="SECONDS"/> </bean-instance-pools> </pools> ... </subsystem>
You can associate an EJB with a pool using one of the following approaches.
- Associate the EJB to the pool using annotations, where the value is the name of the pool defined in the server configuration file. The following is an example that associates the EJB to the "my-stateless-bean-pool" in JBoss EAP 6.
@Stateless @org.jboss.ejb3.annotation.Pool(value="my-stateless-bean-pool") public class MyBean....
- Associate the EJB to the pool by configuring the
jboss-ejb3.xml
file in the EJB JARMETA-INF/
directory. The following example associates the EJB to the pool using the jboss-ejb3.xml file in JBoss EAP 6.<jboss xmlns="http://java.sun.com/xml/ns/javaee" xmlns:p="urn:ejb-pool:1.0"> .... <assembly-descriptor> <p:pool> <ejb-name>MyBean</ejb-name> <p:bean-instance-pool-ref>my-stateless-bean-pool</p:bean-instance-pool-ref> </p:pool> </assembly-descriptor> </jboss>
If EJB instance memory is not an issue and the EJB instance is not doing costly initialization in its PostConstruct
method, it can be useful to disable pooling by default. When the pool is not used, any thread that invokes a method on an EJB simply creates an instance of the EJB, invokes the method on it, and then destroys the EJB instance.
<bean-instance-pool-ref>
element in the ejb3
subsystem of the server configuration file.
<subsystem xmlns="urn:jboss:domain:ejb3:1.3"> <session-bean> <stateless> <!-- Remove the following line --> <bean-instance-pool-ref pool-name="slsb-strict-max-pool"/> </stateless> ...
3.2.13.4. Replace the jboss.xml File
The jboss-ejb3.xml
deployment descriptor replaces the jboss.xml
deployment descriptor file. This file is used to override and add to the features provided by the Java Enterprise Edition (EE) defined ejb-jar.xml
deployment descriptor. The new file is incompatible with jboss.xml
, and the jboss.xml
is now ignored in deployments.
jboss.xml
file with the jboss-ejb3.xml
deployment descriptor file. If your application uses EJB 3.x, you can use the jboss-ejb3.xml
file, or you might be able eliminate it entirely by using EJB3 annotations.
In previous releases of JBoss EAP, if you defined a <resource-ref>
in the ejb-jar.xml
file, you needed a corresponding resource definition for the JNDI name in the jboss.xml
file. XDoclet automatically generated both of these deployment descriptor files. In JBoss EAP 6, the JNDI mapping information is now defined in the jboss-ejb3.xml
file. Assume the datasource is defined in the Java source code as follows.
DataSource ds1 = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/Resource1"); DataSource ds2 = (DataSource) new InitialContext().lookup("java:comp/env/jdbc/Resource2");The
ejb-jar.xml
defines the following resource references.
<resource-ref > <res-ref-name>jdbc/Resource1</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref> <resource-ref > <res-ref-name>java:comp/env/jdbc/Resource2</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref>
jboss-ejb3.jxml
file maps the JNDI names to the references using the following XML syntax.
<resource-ref> <res-ref-name>jdbc/Resource1</res-ref-name> <jndi-name>java:jboss/datasources/ExampleDS</jndi-name> </resource-ref> <resource-ref> <res-ref-name>java:comp/env/jdbc/Resource2</res-ref-name> <jndi-name>java:jboss/datasources/ExampleDS</jndi-name> </resource-ref>
Some of the configuration options that were available in the JBoss EAP 5.x jboss.xml
file were not implemented in JBoss EAP 6. The following list describes some of the commonly used attributes in the jboss.xml
file and whether there is an alternate way to achieve them in JBoss EAP 6.
- The
method-attribute
element was used to configure individual entity and session beans methods.- The
read-only
andidempotent
configuration options were not ported to JBoss EAP 6. - The
transaction-timeout
option is now configured in thejboss-ejb3.xml
file.
- The
missing-method-permission-exclude-mode
attribute changed the behavior of methods without implementing explicit security metadata on a secured bean. In JBoss EAP 6, the absence of a@RolesAllowed
annotation is currently treated in a similar manner to the@PermitAll
jboss-ejb3.xml
file configuration are located in the topics entitled Specifying a Resource Adapter in jboss-ejb3.xml for an MDB, Configure a Container Interceptor, and jboss-ejb3.xml Deployment Descriptor Reference in the Enterprise JavaBeans chapter of the Development Guide for JBoss EAP.
3.2.14. EJB 2.x and Earlier Changes
3.2.14.1. EJB 1.x and EJB 2.x Deprecated Features
- EJB 2.1 and earlier CMP and BMP entity bean
- Client view of an EJB 2.1 entity bean
- EJB QL for CMP entity bean queries
- JAX-RPC-based web service endpoints and client view
3.2.14.2. Changes Required for Applications That Use EJB 1.x and EJB 2.x
3.2.14.2.1. Configuration Changes Required to Run EJB 2.x
EJB 2.x Container Managed Persistence (CMP) beans require the Java Enterprise Edition 6 Full Profile. This profile contains configuration elements that are needed to run CMP EJBs.
org.jboss.as.cmp
extension module:
<extensions> ... <extension module="org.jboss.as.cmp"/> ... </extensions>It also contains the
cmp
subsystem:
<profiles> ... <subsystem xmlns="urn:jboss:domain:cmp:1.1"/> ... </profiles>.
-c standalone-full.xml
or -c standalone-full-ha.xml
argument on the command line when you start the server.
In previous versions of JBoss EAP, it was possible to configure a different container for CMP entity and other beans and use it by setting references inside the jboss.xml
application deployment descriptor file. For example, there were different configurations for SLSB to session beans in general.
- Pessimistic locking is active by default. This can result in deadlocks.
- The deadlock detection code that was in the CMP layer in JBoss EAP 5.x is no longer in JBoss EAP 6.
commit-options
, and the interceptor stack. In JBoss EAP 6, this is no longer possible. There is only one implementation, which is similar to the Instance Per Transaction
policy with commit-option
C
. If you migrate an application that uses the cmp2.x jdbc2 pm
entity bean container configuration, which uses CMP2.x compatible JDBC based persistence manager, there will be a performance impact. This container was optimized for performance. It is recommended that you migrate these entities to EJB 3 before migrating the application.
JBoss EAP 6 supports the standard Java EE Interceptor
using the @Interceptors
and @AroundInvoke
annotations. However, this does not allow manipulation outside the Security or Transaction.
- Use the
InitialContext
TransactionSynchronizationRegistry tsr = (TransactionSynchronizationRegistry) new InitialContext().lookup("java:jboss/TransactionSynchronizationRegistry"); tsr.registerInterposedSynchronization(new MyTxCallback());
- Use Injection
@Resource(mappedName = "java:comp/TransactionSynchronizationRegistry") TransactionSynchronizationRegistry tsr; ... tsr.registerInterposedSynchronization(new MyTxCallback());
javax.transaction.Synchronization
Interface. Use the beforeCompletion{}
method to perform any checks before the transaction is committed or rolled back. If a RuntimeException
is thrown from this method, the transaction is rolled back and the client is informed with a EJBTransactionRolledbackException
. In case of an XA-Transaction, all resources will be rolled back according to the XA contract. It is also possible for enable business logic to depend on the transaction state using the afterCompletion(int txStatus)
method. If a RuntimeException
is thrown from this method, the transaction remains in the former state, either committed or rolled-back, and the client is not informed. Only the transaction manager shows a warning within the server log files.
In previous versions of JBoss EAP, it was possible to configure the client interceptors within the server configuration and provide only the classes with the client API.
Entity bean pool configuration is not recommended in JBoss EAP 6. Because it is limited to configuration of the <strict-max-pool>
element, deadlocks and other issues can occur if the pool is too small to load all entities in the result set. Entity beans do not have large lifecycle methods during initialization, so creating the instance and surrounding container is no slower than when using a pooled entity bean instance.
The jboss-ejb3.xml
deployment descriptor replaces the jboss.xml
deployment descriptor file. This file is used to override and add to the features provided by the Java Enterprise Edition (EE) defined ejb-jar.xml
deployment descriptor. The new jboss-ejb3.xml
file is incompatible with the jboss.xml
file, which is now ignored in deployments. For more information, see Section 3.2.13.4, “Replace the jboss.xml File”.
In previous versions of JBoss EAP, it was possible to configure the datasource type-mapping within the *-ds.xml
datasource deployment configuration file.
jbosscmp-jdbc.xml
deployment descriptor file.
<defaults> <datasource-mapping>mySQL</datasource-mapping> <create-table>true</create-table> .... </defaults>
standardjbosscmp-jdbc.xml
file. This file is no longer available and mapping is now done in the jbosscmp-jdbc.xml
deployment descriptor file.
3.2.14.2.2. Container-Managed Persistence and Container-Managed Relationship Changes Required for EJB 2.x
In previous releases of JBoss EAP, it was possible for some containers, for example the cmp2.x jdbc2 pm
container, to iterate CMR collections and remove or add relations. Because container configuration is not supported, this is no longer possible in JBoss EAP 6. For information about how to achieve this same functionality in the application code, see EJB2.1 Finder for CMP entities with relations (CMR) returns duplicates in EAP6 in the Support Knowledgebase Solutions section of the Customer Portal .
In previous versions of JBoss EAP, it was possible to select different CMP containers which used different persistence strategies. The cmp2.x jdbc2 pm
container in JBoss EAP 5.x used optimized SQL-92
to generate optimized LEFT OUTER JOIN syntax for finders. Because JBoss EAP 6.x only supports the standard container for CMP and CMR, the implementation does not contain these optimizations. The finder should include the keyword DISTINCT
in the SELECT
statement to avoid cartesian product in the result set. For more information , see EJB2.1 Finder for CMP entities with relations (CMR) returns duplicates in EAP6 in the Support Knowledgebase Solutions section of the Customer Portal.
The cascade delete default value has changed to false
. This can result in delete failures in JBoss EAP 6. If entity relations are marked as cascade-delete
, you must explicitly set the batch-cascade-delete
to true
in the jbosscmp-jdbc.xml
file. For more information , see cascade delete fail for EJB2 CMP Entities after migration to EAP6 in the Support Knowledgebase Solutions section of the Customer Portal.
If you used customer mapper classes such as JDBCParameterSetter
, JDBCResultSetReader
and Mapper
in your JBoss EAP 5.x application, you might see java.lang.ClassNotFoundException
when you deploy your application to JBoss EAP 6. This is because the package names for the interfaces were changed from org.jboss.ejb.plugins.cmp.jdbc.Mapper
to org.jboss.as.cmp.jdbc.Mapper
. For more information , see How to use Field mapping for custom classes in an EJB2 CMP application in EAP6 in the Support Knowledgebase Solutions section of the Customer Portal.
If your JBoss EAP 5 application uses entity-commands
to generate primary keys, for example Sequence
or Auto-increment
, you might see a ClassNotFoundException
for the JDBCOracleSequenceCreateCommand
class when you migrate your application to JBoss EAP 6. This is because the class package was changed from org.jboss.ejb.plugins.cmp.jdbc
to org.jboss.as.cmp.jdbc.keygen
. If you use this class in your JBoss EAP 6 application, you must also add a dependency on the EAP_HOME/modules/system/layers/base/org/jboss/as/cmp
module.
3.2.14.2.3. Application Changes Required to Run EJB 2.x
As with EJB 3.0, you must use the full JNDI prefix with EJB 2.x. For more information on the new JNDI namespace rules and code examples, see Section 3.1.8.1, “Update Application JNDI Namespace Names”.
Modify the <jndi-name>
for each <ejb-ref>
to use the new JNDI fully qualified lookup format.
With EJB 2, it was very common to use the Locator
pattern to look up Beans. If you used this pattern in your application, rather than modify application code, you can use XDoclet to generate a map for the new JNDI names.
@ejb.bean name="UserAttribute" display-name="UserAttribute" local-jndi-name="ejb21/UserAttributeEntity" view-type="local" type="CMP" cmp-version="2.x" primkey-field="id"The JNDI name
ejb21/UserAttributeEntity
in the above example is no longer valid in JBoss EAP 6. You can map this name to a valid JNDI name using the naming
subsystem in the server configuration and a patch for XDoclet.
Procedure 3.29. Change the XDoclet Generated Code and Use the Naming Subsystem
- Extract the XDoclet
lookup.xdt
template located in theejb-module.jar
and modify thelookup()
in thelookupHome
as follows:private static Object lookupHome(java.util.Hashtable environment, String jndiName, Class narrowTo) throws javax.naming.NamingException { // Obtain initial context javax.naming.InitialContext initialContext = new javax.naming.InitialContext(environment); try { // Replace the existing lookup // Object objRef = initialContext.lookup(jndiName); // This is the new mapped lookup Object objRef; try { // try JBoss EAP mapping objRef = initialContext.lookup("global/"+jndiName); } catch(java.lang.Exception e) { objRef = initialContext.lookup(jndiName); } // only narrow if necessary if (java.rmi.Remote.class.isAssignableFrom(narrowTo)) return javax.rmi.PortableRemoteObject.narrow(objRef, narrowTo); else return objRef; } finally { initialContext.close(); } }
- Run Ant, setting the template attribute to use the modified
lookup.xdt
for theejbdoclet
task. - Modify the
naming
subsystem in the server configuration file to map the old JNDI name to the new valid JNDI name.<subsystem xmlns="urn:jboss:domain:naming:1.2"> <bindings> <lookup name="java:global/ejb21/UserAttributeEntity" lookup="java:global/ejb2CMP/ejb/UserAttribute!de.wfink.ejb21.cmp.cmr.UserAttributeLocalHome"/> </bindings> <remote-naming/> </subsystem>
3.2.14.2.4. Known Issues with EJB 2.x
ejb-jar.xml
descriptor files that define Message Driven Beans (MDBs) in releases of JBoss EAP 6.3 and older. The server throws a parsing error at the time of deployment and you see the following output in the server log.
ERROR [org.jboss.msc.service.fail] (MSC service thread 1-7) MSC000001: Failed to start service jboss.deployment.unit."EJB_JAR_NAME.jar".PARSE: org.jboss.msc.service.StartException in service jboss.deployment.unit."EJB_JAR_NAMEjar".PARSE: JBAS018733: Failed to process phase PARSE of deployment "EJB_JAR_NAME.jar"This issue was fixed in JBoss EAP 6.4. See Bugzilla 1057835 for details.
3.2.14.2.5. Summary of Obsolete EJB 2.x Files
- jboss.xml
- The
jboss.xml
application deployment descriptor file is no longer supported and ignored if included in the deployed archive. This file has been replaced by thejboss-ejb3.xml
deployment descriptor file. - standardjbosscmp-jdbc.xml
- The
standardjbosscmp-jdbc.xml
server configuration file is no longer supported. This configuration information is now included in theorg.jboss.as.cmp
module and it is no longer customizable. - standardjboss.xml
- The
standardjboss.xml
server configuration file is no longer supported. This configuration information is now included in thestandalone.xml
file when running a standalone server or thedomain.xml
file when running in a managed domain..
3.2.15. JBoss AOP Changes
3.2.15.1. Update Applications That Use JBoss AOP
- Standard EJB3 configurations that were previously made in the
ejb3-interceptors-aop.xml
file are now configured in the server configuration file. For a standalone server, this is thestandalone/configuration/standalone-full.xml
file. If you are running your server in a managed domain, this is thedomain/configuration/domain.xml
file. - Server side AOP Interceptors should be modified to use the standard Java EE
Interceptor
. For more information about container interceptors and how to use a client side interceptor in an application, see the chapter entitled Container Interceptors in the Development Guide for JBoss EAP 6 located on the Customer Portal at https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/?version=6.4.
- If you are not able to refactor the code, you can obtain a copy of the JBoss AOP libraries and bundle them with the application. The AOP libraries may work in JBoss EAP 6, but are not deployed. You can manually deploy them by using the following command line argument when you start your server:
-Djboss.aop.path=PATH_TO_AOP_CONFIG
Note
Although the JBoss AOP libraries may work in JBoss EAP 6, this not a supported configuration.
3.2.16. JacORB Changes
3.2.16.1. JacORB Configuration Changes
EAP_HOME/server/production/conf/jacorb.properties
file. The following is an example of JacORB properties configured in that file.
jacorb.connection.client.pending_reply_timeout=600000 jacorb.connection.client.idle_timeout=120000 jacorb.connection.server.timeout=300000 jacorb.native_char_codeset=UTF8 jacorb.native_wchar_codeset=UTF16
3.2.17. JBoss Web Component Changes
3.2.17.1. Map HTTP/HTTPS/AJP Connector Attributes
Attribute Name in Previous Release | Equivalent in JBoss EAP 6 | Details |
---|---|---|
maxThreads | max-connections | This attribute sizes the JBossWeb level thread/connection pool. It is set on the connectors in the web subsystem. The default is 512 per CPU core.
<connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http" enabled="true" max-connections="200" /> |
minSpareThreads
maxSpareThreads
| N/A | There is no equivalent for minSpareThreads or maxSpareThreads since there is little incentive to reclaim threads. If you use an executor for the connector instead of the default worker thread pool, The closest thing to this would be the core-threads size and keepalive-time attributes. |
proxyName
proxyPort
|
proxy-name
proxy-port
| This attribute is set on the connector in the web subsystem.
<connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http" enabled="true" proxy-name="proxy.com" proxy-port="80"/> |
redirectPort
|
redirect-port
|
This attribute is set on the
connector in the web subsystem.
connector name="http" protocol="HTTP/1.1" scheme="https" secure="true" socket-binding="http" redirect-port="8443" proxy-name="loadbalancer.hostname.com" proxy-port="443" |
enableLookups
|
enable-lookups
|
This attribute is set on the
connector in the web subsystem.
<connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http" enable-lookups="true"/>" |
MaxHttpHeaderSize
| System Property | This attribute is set using System Properties. The default value is 8 KB.
<system-properties> <property name="org.apache.coyote.http11.Http11Protocol.MAX_HEADER_SIZE" value="8192"/> </system-properties> |
maxKeepAliveRequests
| System Property | This attribute is set using System Properties.
<system-properties> <property name="org.apache.coyote.http11.Http11Protocol.MAX_KEEP_ALIVE_REQUESTS" value="1"/> </system-properties> |
connectionTimeout
| System Property | This attribute is set using System Properties. The following configurations set the AJP connectionTimeout to 600000 milliseconds (10 minutes) and the HTTP connectionTimeout to 120000 milliseconds (2 minutes).
<system-properties> <!-- connectionTimeout for AJP connector. Default value is "-1" (no timeout). --> <property name="org.apache.coyote.ajp.DEFAULT_CONNECTION_TIMEOUT" value="600000"/> <!-- connectionTimeout for HTTP connector. Default value is "60000". --> <property name="org.apache.coyote.http11.DEFAULT_CONNECTION_TIMEOUT" value="120000"/> </system-properties> |
compression
| System Property | This attribute enables compression. You can specify the content type, which defaults to text/html,text/xml,text/plain . You can also specify the minimum size of content that is to be compressed, which defaults to 2048 bytes. Compression is set using System Properties.
<system-properties> <property name="org.apache.coyote.http11.Http11Protocol.COMPRESSION" value="on"/> <property name="org.apache.coyote.http11.Http11Protocol.COMPRESSION_MIN_SIZE" value="4096"/> <property name="org.apache.coyote.http11.Http11Protocol.COMPRESSION_MIME_TYPES" value="text/javascript,text/css,text/html"/> </system-properties> |
URIEncoding
| System Property | This attribute is set using System Properties.
<system-properties> <property name="org.apache.catalina.connector.URI_ENCODING" value="UTF-8"/> </system-properties> |
useBodyEncodingForURI
| System Property | This attribute is set using System Properties.
<system-properties> <property name="org.apache.catalina.connector.USE_BODY_ENCODING_FOR_QUERY_STRING" value="true"/> </system-properties> |
server
| System Property | This attribute is set using System Properties.
<system-properties> <property name="org.apache.coyote.http11.Http11Protocol.SERVER" value="NewServerHeader"/> </system-properties> |
allowTrace
| System Property | This attribute is set using System Properties.
<system-properties> <property name="org.apache.catalina.connector.ALLOW_TRACE " value="true"/> </system-properties> |
xpoweredby
| System Property | This attribute is set using System Properties.
<system-properties> <property name="org.apache.catalina.connector.X_POWERED_BY " value="true"/> </system-properties> |
keepAliveTimeout
| N/A |
Prior to JBoss EAP 6.4, there was no equivalent parameter in JBoss EAP 6. Internally, it defaulted to the
connectionTimeout value.
In JBoss EAP 6.4, a new system property,
org.apache.coyote.http11.DEFAULT_KEEP_ALIVE_TIMEOUT , was introduced to control keepAliveTimeout. The -Dorg.apache.coyote.http11.DEFAULT_KEEP_ALIVE_TIMEOUT argument takes affect when used with the -Dorg.apache.coyote.http11.DEFAULT_DISABLE_UPLOAD_TIMEOUT=true argument.
|
disableUploadTimeout
connectionUploadTimeout
| N/A |
There are currently no equivalent parameters in JBoss EAP 6. The
disableUploadTimeout is true by default and the connectionUploadTimeout internally uses the connectionTimeout value.
|
packetSize
| System Property | This attribute is set using System Properties. The following configurations set the AJP packetSize to 20000
<system-properties> <property name="org.apache.coyote.ajp.MAX_PACKET_SIZE" value="20000"/> </system-properties> |
maxPostSize
maxSavePostSize
|
max-post-size
max-save-post-size
| A value of 0 means unlimited. Note that this parameter can limit data size only when Content-Type is application/x-www-form-urlencoded . For more information, see this solution on the Customer Portal: How to limit data size of HTTP POST method from a client to JBoss |
tomcatAuthentication
| System Property |
Depending on the version of JBoss EAP 6, this attribute is set using the System Property
org.apache.coyote.ajp.AprProcessor.TOMCATAUTHENTICATION or org.apache.coyote.ajp.DEFAULT_TOMCAT_AUTHENTICATION . A patch or upgrade is required for all versions of the server.
In JBoss EAP 6.0.1, tomcatAuthentication is configured using the following property.
<system-properties> <property name="org.apache.coyote.ajp.AprProcessor.TOMCATAUTHENTICATION" value="false"/> </system-properties>
In JBoss EAP 6.1 and later, tomcatAuthentication is configured as follows:
<system-properties> <property name="org.apache.coyote.ajp.DEFAULT_TOMCAT_AUTHENTICATION" value="false"/> </system-properties>
For more information, see this solution on the Customer Portal: How to configure tomcatAuthentication in JBoss EAP 6
|
3.2.17.2. Configure 1-Way SSL
keystore.jks
file created by that process was placed in the EAP_HOME/server/PROFILE/conf/
directory. You then configured the HTTP connector in the EAP_HOME/server/PROFILE/deploy/jbossweb.sar/server.xml
file as follows.
<Connector protocol="HTTP/1.1" SSLEnabled="true" port="8443" address="${jboss.bind.address}" scheme="https" secure="true" clientAuth="false" keystoreFile="${jboss.server.home.dir}/conf/keystore.jks" keystorePass="password" SSLProtocol = "TLS" />
keystore.jks
file created by that process is placed in the EAP_HOME/standalone/configuration/
or EAP_HOME/domain/configuration/
directory. The HTTP connector is then configured in the web
subsystem of the server configuration file as follows.
<connector name="https" protocol="HTTP/1.1" scheme="https" socket-binding="https"> <ssl name="ssl" key-alias="jboss" password="password" certificate-key-file="${jboss.server.config.dir}/keystore.jks" protocol="TLSv1" verify-client="false"/> </connector>
web
subsystem of the server configuration file, however, the connector protocol is set to "org.apache.coyote.http11.Http11AprProtocol".
3.2.17.3. Migrate Valve Configuration
EAP_HOME/server/PROFILE/lib
directory and then configuring the one of the following files.
- For JBoss EAP 4.x, valves were configured in either the
EAP_HOME/server/PROFILEdeploy/jboss-web.deployer/server.xml
orEAP_HOME/server/PROFILEdeploy/jboss-web.deployer/context.xml
file. - For JBoss EAP 5.x, valves were configured in the
EAP_HOME/server/PROFILEdeploy/jbossweb.sar/server.xml
file.
web
subsystem of the server configuration file. For detailed instructions on how to configure valves, see the chapter entitled Global Valves in the Administration and Configuration Guide for JBoss EAP located on the Customer Portal at https://access.redhat.com/documentation/en-us/red_hat_jboss_enterprise_application_platform/?version=6.4
Note
3.2.17.4. Configure the CertificatePrincipal Class
CertificatePrincipal
class was configured on the JBossWeb container by setting the certificatePrincipal
attribute for the Realm
in the jbossweb-tomcat.sar/server.xml
file as in the following example.
<Realm className="org.jboss.web.tomcat.security.JBossWebRealm" certificatePrincipal="org.jboss.security.auth.certs.SubjectDNMapping" allRolesMode="authOnly"/>
3.2.18. Migrate Seam 2.2 Applications
3.2.18.1. Migrate Seam 2.2 Archives to JBoss EAP 6
When you migrate a Seam 2.2 application, you need to configure the datasource and specify any module dependencies. You also need to determine if the application has any dependencies on archives that do not ship with JBoss EAP 6 and copy any dependent JARs into the application lib/
directory.
Important
Procedure 3.30. Migrate Seam 2.2 Archives
- Update the datasource configuration.Some Seam 2.2 examples use the default JDBC datasource named
java:/ExampleDS
. This default datasource has changed in JBoss EAP 6 tojava:jboss/datasources/ExampleDS
. If your application uses the example database, you can do one of the following.For more information on how to configure a datasource, see Section 3.1.6.2, “Update the DataSource Configuration”.- If you want to use the example database that ships with JBoss EAP 6, modify the
META-INF/persistence.xml
file to replace the existingjta-data-source
element with the example database datasource JNDI name.<!-- <jta-data-source>java:/ExampleDS</jta-data-source> --> <jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>
- If you prefer to keep your existing database, you can add the datasource definition to the
EAP_HOME/standalone/configuration/standalone.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 definition is a copy of the default HSQL datasource defined in JBoss EAP 6.<datasource name="ExampleDS" jndi-name="java:/ExampleDS" enabled="true" jta="true" use-java-context="true" use-ccm="true"> <connection-url>jdbc:h2:mem:test;DB_CLOSE_DELAY=-1</connection-url> <driver>h2</driver> <security> <user-name>sa</user-name> <password>sa</password> </security> </datasource>
- You can also add the datasource definition using the Management CLI command line interface. The following is an example of the syntax you must use to add a datasource. The "\" at the end of line indicates the continuation of the command on the following line.
Example 3.12. Example of syntax to add the datasource definition
$ EAP_HOME/bin/jboss-cli --connect [standalone@localhost:9999 /] data-source add --name=ExampleDS --jndi-name=java:/ExampleDS \ --connection-url=jdbc:h2:mem:test;DB_CLOSE_DELAY=-1 --driver-name=h2 \ --user-name=sa --password=sa
- Add any required dependencies.Because Seam 2.2 applications use JSF 1.2, you need to add dependencies for the JSF 1.2 modules and exclude the JSF 2.0 modules. To accomplish this, you need to create a
jboss-deployment-structure.xml
file in the EAR'sMETA-INF/
directory that contains the following data.<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>
If your application uses any third-party logging frameworks you need to add those dependencies as described here: Section 3.1.4.1, “Modify Logging Dependencies”. - If your application uses Hibernate 3.x, first try to run the application using the Hibernate 4 libraries.If your application does not use the Seam Managed Persistence Context, Hibernate search, validation, or other features that have changed with Hibernate 4, you may be able to run with the Hibernate 4 libraries. However, if you see
ClassNotFoundExceptions
orClassCastExceptions
that point to Hibernate classes, or see errors similar to the following, you may have to follow the instructions in the next step and modify the application to use Hibernate 3.3 libraries.Caused by: java.lang.LinkageError: loader constraint violation in interface itable initialization: when resolving method "org.jboss.seam.persistence.HibernateSessionProxy.getSession(Lorg/hibernate/EntityMode;)Lorg/hibernate/Session;" the class loader (instance of org/jboss/modules/ModuleClassLoader) of the current class, org/jboss/seam/persistence/HibernateSessionProxy, and the class loader (instance of org/jboss/modules/ModuleClassLoader) for interface org/hibernate/Session have different Class objects for the type org/hibernate/Session used in the signature
- Copy dependent archives from outside frameworks or other locations.If your application uses Hibernate 3.x and you are not able to use Hibernate 4 successfully with your application, you will need to copy the Hibernate 3.x JARs into the
/lib
directory and exclude the Hibernate module in the deployments section of theMETA-INF/jboss-deployment-structure.xml
as follows.<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.0"> <deployment> <exclusions> <module name="org.hibernate"/> </exclusions> <deployment> </jboss-deployment-structure>
There are additional steps you must take when you bundle Hibernate 3.x with your application. For more information, see Section 3.2.2.2, “Configure Changes for Applications That Use Hibernate and JPA”. - Debug and resolve Seam 2.2 JNDI errors.When you migrate a Seam 2.2 application, you may see
javax.naming.NameNotFoundException
errors in the log like the following.javax.naming.NameNotFoundException: Name 'jboss-seam-booking' not found in context ''
If you don't want to modify JNDI lookups throughout the code, you can modify the application'scomponents.xml
file as follows.- Replace the existing core-init element.First, you need to replace the existing core-init element as follows:
<!-- <core:init jndi-pattern="jboss-seam-booking/#{ejbName}/local" debug="true" distributable="false"/> --> <core:init debug="true" distributable="false"/>
- Find the JNDI binding INFO messages in the server logNext, find the JNDI binding INFO messages that are printed in the server log when the application is deployed. The JNDI binding messages should look similar to the following.
INFO org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor (MSC service thread 1-1) JNDI bindings for session bean named AuthenticatorAction in deployment unit subdeployment "jboss-seam-booking.jar" of deployment "jboss-seam-booking.ear" are as follows. java:global/jboss-seam-booking/jboss-seam-booking.jar/AuthenticatorAction!org.jboss.seam.example.booking.Authenticator java:app/jboss-seam-booking.jar/AuthenticatorAction!org.jboss.seam.example.booking.Authenticator java:module/AuthenticatorAction!org.jboss.seam.example.booking.Authenticator java:global/jboss-seam-booking/jboss-seam-booking.jar/AuthenticatorAction java:app/jboss-seam-booking.jar/AuthenticatorAction java:module/AuthenticatorAction
- Add component elements.For each JNDI binding INFO message in the log, add a matching
component
element to thecomponents.xml
file.<component class="org.jboss.seam.example.booking.AuthenticatorAction" jndi-name="java:app/jboss-seam-booking.jar/AuthenticatorAction" />
For more information on how to debug and resolve migration issues, see Section 4.2.1, “Debug and Resolve Migration Issues”.For a list of known migration issues with Seam 2 archives, see Section 3.2.18.2, “Seam 2.2 Archive Migration Issues”.
The Seam 2.2 archive deploys and runs successfully on JBoss EAP 6.
3.2.18.2. Seam 2.2 Archive Migration Issues
- Seam 2.2 Drools and Java 7 are not compatible
- Seam 2.2 Drools and Java 7 are incompatible and fail with an org.drools.RuntimeDroolsException: value '1.7' is not a valid language level error.
- Seam 2.2.5 signed
cglib.jar
prevents the Spring example from working - When the Spring example is run using the signed
cglib.jar
that shipped with Seam 2.2.5 in JBoss EAP 5, it fails with the following root cause:java.lang.SecurityException: class "org.jboss.seam.example.spring.UserService$$EnhancerByCGLIB$$7d6c3d12"'s signer information does not match signer information of other classes in the same package
The work around for this issue is to unsign thecglib.jar
as follows:zip -d $SEAM_DIR/lib/cglib.jar META-INF/JBOSSCOD\*
- Seambay example fails with
NotLoggedInException
- The cause of this issue is the SOAP message header being null when processing the message in the SOAPRequestHandler and consequently, the conversation ID not being set.The work around for this issue is to override
org.jboss.seam.webservice.SOAPRequestHandler.handleOutbound
, as described in https://issues.jboss.org/browse/JBPAPP-8376. - Seambay example fails with
UnsupportedOperationException
: no transaction - This bug is caused by changes in the JNDI name of UserTransaction in JBoss EAP 6.The work around for this issue is to override
org.jboss.seam.transaction.Transaction.getUserTransaction
, as described in https://issues.jboss.org/browse/JBPAPP-8322. - Tasks example throws
org.jboss.resteasy.spi.UnhandledException
: Unable to unmarshall request body - This bug is caused by the incompatibility between seam-resteasy-2.2.5 included in JBoss EAP 5.1.2) and RESTEasy 2.3.1.GA included in JBoss EAP 6.The work around for this issue is to use the
jboss-deployment-structure.xml
to exclude resteasy-jaxrs, resteasy-jettison-provider, and resteasy-jaxb-provider from the main deployment and resteasy-jaxrs, resteasy-jettison-provider, resteasy-jaxb-provider, and resteasy-yaml-provider from thejboss-seam-tasks.war
as described in https://issues.jboss.org/browse/JBPAPP-8315. It is then necessary to include the RESTEasy libraries bundled with Seam 2.2 in the EAR. - Deadlock between
org.jboss.seam.core.SynchronizationInterceptor
and stateful component instance EJB lock during an AJAX request - An error page with "Caused by javax.servlet.ServletException with message: "javax.el.ELException: /main.xhtml @36,71 value="#{hotelSearch.pageSize}": org.jboss.seam.core.LockTimeoutException: could not acquire lock on @Synchronized component: hotelSearch" or similar error message is displayed.The problem is that Seam 2 does its own locking outside the stateful session bean (SFSB) lock and with a different scope. This means that if a thread accesses an EJB twice in the same transaction, after the first invocation it will have the SFSB lock, but not the seam lock. A second thread can then acquire the seam lock, which will then hit the EJB lock and wait. When the first thread attempts its second invocation it will block on the seam 2 interceptor and deadlock. In Java EE 5, EJBs would throw an exception immediately on concurrent access. This behavior has changed in Java EE 6.The work around for this issue is to add @AccessTimeout(0) to the EJB. This will cause it to throw a
ConcurrentAccessException
immediately when this situation occurs. - Dvdstore example create order fails with a
javax.ejb.EJBTransactionRolledbackException
- The dvdstore example displays the following error:
JBAS011437: Found extended persistence context in SFSB invocation call stack but that cannot be used because the transaction already has a transactional context associated with it. This can be avoided by changing application code, either eliminate the extended persistence context or the transactional context. See JPA spec 2.0 section 7.6.3.1.
This problem is due to changes in the JPA specification.The fix for this issue is to change the persistence context totransactional
in theCheckoutAction
andShowOrdersAction
classes and use the entity manager merge operation in thecancelOrder
anddetailOrder
methods. - JBoss Cache Seam Cache provider cannot be used in JBoss EAP 6
- JBoss Cache is not supported in JBoss EAP 6. This causes JBoss Cache Seam Cache provider to fail in a Seam application on the application server with a
java.lang.NoClassDefFoundError: org/jboss/util/xml/JBossEntityResolver
. - Hibernate 3.3.x Auto scan for JPA entities issue with JBoss EAP 6
- The fix for this issue is to list all the entity classes in the persistence.xml file manually. For example:
<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0"> <persistence-unit name="example_pu"> <description>Hibernate 3 Persistence Unit.</description> <jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source> <properties> <property name="jboss.as.jpa.providerModule" value="hibernate3-bundled" /> </properties> <class>com.acme.Foo</class> <class>com.acme.Bar</class> </persistence-unit> </persistence>
- Calling EJB Seam components from non-EJB Threads results in a javax.naming.NameNotFoundException
- This issue is a result of changes in JBoss EAP 6 to implement the new modular class loading system and to adopt the new standardized JNDI namespace conventions. The
java:app
namespace is designated for names shared by all components in a single application. Non-EE threads, such as Quartz asynchronous threads, must use thejava:global
namespace, which is shared by all applications deployed in an application server instance.If you receive ajavax.naming.NameNotFoundException
when you try to call EJB Seam components from Quartz asynchronous methods, you must modify thecomponents.xml
file to use the global JNDI name, for example:<component class="org.jboss.seam.example.quartz.MyBean" jndi-name="java:global/seam-quartz/quartz-ejb/myBean"/>
For more information on JNDI changes, refer to the following topic: Section 3.1.8.1, “Update Application JNDI Namespace Names” . For more information on this specific issue, refer to BZ#948215 - Seam2.3 javax.naming.NameNotFoundException trying to call EJB Seam components from quartz asynchronous methods in the 2.2.0 Release Notes for Red Hat JBoss Web Framework Kit on the Red Hat Customer Portal.
3.2.19. Migrate Spring Applications
3.2.19.1. Migrate Spring Applications
3.2.20. Other Changes That Affect Migration
3.2.20.1. Become Familiar with Other Changes That May Affect Your Migration
3.2.20.2. Change the Maven Plug-in Name
jboss-maven-plugin
has not been updated and does not work in JBoss EAP 6. You must now use org.jboss.as.plugins:jboss-as-maven-plugin
to deploy to the correct directory.
3.2.20.3. Modify Client Applications
jboss-client.jar
and is located in the EAP_HOME/bin/client/
directory. It replaces the EAP_HOME/client/jbossall-client.jar
and contains all the dependencies required to connect to JBoss EAP 6 from a remote client.