27.03.2013 Views

JBoss Enterprise Application Platform Common Criteria Certification ...

JBoss Enterprise Application Platform Common Criteria Certification ...

JBoss Enterprise Application Platform Common Criteria Certification ...

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 1<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong><br />

<strong>Criteria</strong> <strong>Certification</strong> 5<br />

Administration And Configuration Guide<br />

for <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5 <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong><br />

Copyright © 2010 Red Hat, Inc<br />

Edition 5.1.0<br />

<strong>JBoss</strong> Community<br />

Edited by<br />

<strong>JBoss</strong> Community<br />

Edited by<br />

Red Hat Documentation Group


2 Legal Notice<br />

Legal Notice<br />

Copyright © 2010 Red Hat, Inc.<br />

The text of and illustrations in this document are licensed by Red Hat under a Creative <strong>Common</strong>s<br />

Attribution–Share Alike 3.0 Unported license ("CC-BY-SA"). An explanation of CC-BY-SA is available at<br />

http://creativecommons.org/licenses/by-sa/3.0/. In accordance with CC-BY-SA, if you distribute this<br />

document or an adaptation of it, you must provide the URL for the original version.<br />

Red Hat, as the licensor of this document, waives the right to enforce, and agrees not to assert, Section<br />

4d of CC-BY-SA to the fullest extent permitted by applicable law.<br />

Red Hat, Red Hat <strong>Enterprise</strong> Linux, the Shadowman logo, <strong>JBoss</strong>, MetaMatrix, Fedora, the Infinity Logo,<br />

and RHCE are trademarks of Red Hat, Inc., registered in the United States and other countries.<br />

Linux® is the registered trademark of Linus Torvalds in the United States and other countries.<br />

Java® is a registered trademark of Oracle and/or its affiliates.<br />

XFS® is a trademark of Silicon Graphics International Corp. or its subsidiaries in the United States<br />

and/or other countries.<br />

MySQL® is a registered trademark of MySQL AB in the United States, the European Union and other<br />

countries.<br />

All other trademarks are the property of their respective owners.


Abstract<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 3<br />

This book is a guide to the administration and configuration of <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong><br />

5.1.0.


4 Table of Contents<br />

Table of Contents<br />

What this Book Covers<br />

1. Introduction<br />

1.1. <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> Use Cases<br />

I. <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> Infrastructure<br />

2. <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5 architecture<br />

2.1. The <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> Bootstrap<br />

2.2. Hot Deployment<br />

II. <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5 Configuration<br />

3. Logging<br />

3.1. Logging Defaults<br />

3.2. Component-Specific Logging<br />

3.2.1. SQL Logging with Hibernate<br />

3.2.2. Transaction Service Logging<br />

4. Deployment<br />

4.1. Deployable <strong>Application</strong> Types<br />

4.2. Standard Server Profiles<br />

5. Microcontainer<br />

6. The JNDI Naming Service<br />

6.1. An Overview of JNDI<br />

6.1.1. Names<br />

6.1.2. Contexts<br />

6.2. The <strong>JBoss</strong> Naming Service Architecture<br />

6.3. The Naming InitialContext Factories<br />

6.3.1. The standard naming context factory<br />

6.3.2. The org.jboss.naming.NamingContextFactory<br />

6.3.3. Naming Discovery in Clustered Environments<br />

6.3.4. The HTTP InitialContext Factory Implementation<br />

6.3.5. The Login InitialContext Factory Implementation<br />

6.3.6. The ORBInitialContextFactory<br />

6.4. JNDI over HTTP<br />

6.4.1. Accessing JNDI over HTTP<br />

6.4.2. Accessing JNDI over HTTPS<br />

6.4.3. Securing Access to JNDI over HTTP<br />

6.4.4. Securing Access to JNDI with a Read-Only Unsecured Context<br />

6.5. Additional Naming MBeans<br />

6.5.1. JNDI Binding Manager<br />

6.5.2. The org.jboss.naming.NamingAlias MBean<br />

6.5.3. org.jboss.naming.ExternalContext MBean<br />

6.5.4. The org.jboss.naming.JNDIView MBean<br />

6.6. J2EE and JNDI - The <strong>Application</strong> Component Environment<br />

6.6.1. ENC Usage Conventions<br />

7. Web Services<br />

7.1. The need for web services<br />

7.2. What web services are not<br />

7.3. Document/Literal<br />

7.4. Document/Literal (Bare)<br />

7.5. Document/Literal (Wrapped)<br />

7.6. RPC/Literal<br />

7.7. RPC/Encoded<br />

7.8. Web Service Endpoints<br />

7.9. Plain old Java Object (POJO)<br />

7.10. The endpoint as a web application<br />

7.11. Packaging the endpoint


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 5<br />

7.12. Accessing the generated WSDL<br />

7.13. EJB3 Stateless Session Bean (SLSB)<br />

7.14. Endpoint Provider<br />

7.15. WebServiceContext<br />

7.16. Web Service Clients<br />

7.16.1. Service<br />

7.16.2. Dynamic Proxy<br />

7.16.3. WebServiceRef<br />

7.16.4. Dispatch<br />

7.16.5. Asynchronous Invocations<br />

7.16.6. Oneway Invocations<br />

7.17. <strong>Common</strong> API<br />

7.17.1. Handler Framework<br />

7.17.2. Message Context<br />

7.17.3. Fault Handling<br />

7.18. DataBinding<br />

7.18.1. Using JAXB with non annotated classes<br />

7.19. Attachments<br />

7.19.1. MTOM/XOP<br />

7.19.2. SwaRef<br />

7.20. Tools<br />

7.20.1. Bottom-Up (Using wsprovide)<br />

7.20.2. Top-Down (Using wsconsume)<br />

7.20.3. Client Side<br />

7.20.4. Command-line & Ant Task Reference<br />

7.20.5. JAX-WS binding customization<br />

7.21. Web Service Extensions<br />

7.21.1. WS-Addressing<br />

7.21.2. WS-Security<br />

7.21.3. XML Registries<br />

7.22. <strong>JBoss</strong>WS Extensions<br />

7.22.1. Proprietary Annotations<br />

7.23. Web Services Appendix<br />

7.24. References<br />

8. <strong>JBoss</strong> AOP<br />

8.1. Some key terms<br />

8.2. Creating Aspects in <strong>JBoss</strong> AOP<br />

8.3. Applying Aspects in <strong>JBoss</strong> AOP<br />

8.4. Packaging AOP <strong>Application</strong>s<br />

8.5. The <strong>JBoss</strong> AspectManager Service<br />

8.6. Loadtime transformation in the <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> Using Sun JDK<br />

8.7. JRockit<br />

8.8. Improving Loadtime Performance in the <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> Environment<br />

8.9. Scoping the AOP to the classloader<br />

8.9.1. Deploying as part of a scoped classloader<br />

8.9.2. Attaching to a scoped deployment<br />

9. Transaction Management<br />

9.1. Overview<br />

9.2. Configuration Essentials<br />

9.3. Transactional Resources<br />

9.4. Last Resource Commit Optimization (LRCO)<br />

9.5. Transaction Timeout Handling<br />

9.6. Recovery Configuration<br />

9.7. Transaction Service FAQ<br />

9.8. Using the JTS Module<br />

9.9. Using the XTS Module<br />

9.10. Transaction Management Console<br />

9.11. Experimental Components<br />

9.12. Source Code and Upgrading


6 Table of Contents<br />

10. Remoting<br />

10.1. Background<br />

10.2. <strong>JBoss</strong> Remoting Configuration<br />

10.2.1. MBeans<br />

10.2.2. POJOs<br />

10.3. Multihomed servers<br />

10.4. Address translation<br />

10.5. Where are they now?<br />

10.6. Further information.<br />

11. <strong>JBoss</strong> Messaging<br />

12. Use Alternative Databases with <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong><br />

12.1. How to Use Alternative Databases<br />

12.2. Install JDBC Drivers<br />

12.2.1. Special Notes on Sybase<br />

12.2.2. Configuring JDBC DataSources<br />

12.3. <strong>Common</strong> Database-Related Tasks<br />

12.3.1. Security and Pooling<br />

12.3.2. Change Database for the JMS Services<br />

12.3.3. Support Foreign Keys in CMP Services<br />

12.3.4. Specify Database Dialect for Java Persistence API<br />

12.3.5. Change Other <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> Services to use the External<br />

Database<br />

12.3.6. A Special Note About Oracle Databases<br />

13. Datasource Configuration<br />

13.1. Types of Datasources<br />

13.2. Datasource Parameters<br />

13.3. Datasource Examples<br />

13.3.1. Generic Datasource Example<br />

13.3.2. Configuring a DataSource for Remote Usage<br />

13.3.3. Configuring a Datasource to Use Login Modules<br />

14. Pooling<br />

14.1. Strategy<br />

14.2. Transaction stickness<br />

14.3. Workaround for Oracle<br />

14.4. Pool Access<br />

14.5. Pool Filling<br />

14.6. Idle Connections<br />

14.7. Dead connections<br />

14.7.1. Valid connection checking<br />

14.7.2. Errors during SQL queries<br />

14.7.3. Changing/Closing/Flushing the pool<br />

14.7.4. Other pooling<br />

15. Frequently Asked Questions<br />

15.1. I have problems with Oracle XA?<br />

III. Clustering Guide<br />

16. Introduction and Quick Start<br />

16.1. Quick Start Guide<br />

16.1.1. Initial Preparation<br />

16.1.2. Launching a <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> Cluster<br />

16.1.3. Web <strong>Application</strong> Clustering Quick Start<br />

16.1.4. EJB Session Bean Clustering Quick Start<br />

16.1.5. Entity Clustering Quick Start<br />

17. Clustering Concepts<br />

17.1. Cluster Definition<br />

17.2. Service Architectures<br />

17.2.1. Client-side interceptor architecture<br />

17.2.2. External Load Balancer Architecture


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 7<br />

17.3. Load Balancing Policies<br />

17.3.1. Client-side interceptor architecture<br />

17.3.2. External load balancer architecture<br />

18. Clustering Building Blocks<br />

18.1. Group Communication with JGroups<br />

18.1.1. The Channel Factory Service<br />

18.1.2. The JGroups Shared Transport<br />

18.2. Distributed Caching with <strong>JBoss</strong> Cache<br />

18.2.1. The <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> CacheManager Service<br />

18.3. The HAPartition Service<br />

18.3.1. DistributedReplicantManager Service<br />

18.3.2. DistributedState Service<br />

18.3.3. Custom Use of HAPartition<br />

19. Clustered JNDI Services<br />

19.1. How it works<br />

19.2. Client configuration<br />

19.2.1. For clients running inside the <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong><br />

19.2.2. For clients running outside the <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong><br />

19.3. <strong>JBoss</strong> configuration<br />

19.3.1. Adding a Second HA-JNDI Service<br />

20. Clustered Session EJBs<br />

20.1. Stateless Session Bean in EJB 3.0<br />

20.2. Stateful Session Beans in EJB 3.0<br />

20.2.1. The EJB application configuration<br />

20.2.2. Optimize state replication<br />

20.2.3. CacheManager service configuration<br />

20.3. Stateless Session Bean in EJB 2.x<br />

20.4. Stateful Session Bean in EJB 2.x<br />

20.4.1. The EJB application configuration<br />

20.4.2. Optimize state replication<br />

20.4.3. The HASessionStateService configuration<br />

20.4.4. Handling Cluster Restart<br />

20.4.5. JNDI Lookup Process<br />

20.4.6. SingleRetryInterceptor<br />

21. Clustered Entity EJBs<br />

21.1. Entity Bean in EJB 3.0<br />

21.1.1. Configure the distributed cache<br />

21.1.2. Configure the entity beans for cache<br />

21.1.3. Query result caching<br />

21.2. Entity Bean in EJB 2.x<br />

22. HTTP Services<br />

22.1. Configuring load balancing using Apache and mod_jk<br />

22.1.1. Download the software<br />

22.1.2. Configure Apache to load mod_jk<br />

22.1.3. Configure worker nodes in mod_jk<br />

22.1.4. Configuring <strong>JBoss</strong> to work with mod_jk<br />

22.1.5. Configuring the NSAPI connector on Solaris<br />

22.2. Configuring HTTP session state replication<br />

22.2.1. Enabling session replication in your application<br />

22.2.2. HttpSession Passivation and Activation<br />

22.2.3. Configuring the <strong>JBoss</strong> Cache instance used for session state replication<br />

22.3. Using FIELD-level replication<br />

22.4. Using Clustered Single Sign-on (SSO)<br />

22.4.1. Configuration<br />

22.4.2. SSO Behavior<br />

22.4.3. Limitations


8 Table of Contents<br />

22.4.4. Configuring the Cookie Domain<br />

23. <strong>JBoss</strong> Messaging Clustering Notes<br />

24. Clustered Deployment Options<br />

24.1. Clustered Singleton Services<br />

24.1.1. HASingleton Deployment Options<br />

24.1.2. Determining the master node<br />

24.2. Farming Deployment<br />

25. JGroups Services<br />

25.1. Configuring a JGroups Channel's Protocol Stack<br />

25.1.1. <strong>Common</strong> Configuration Properties<br />

25.1.2. Transport Protocols<br />

25.1.3. Discovery Protocols<br />

25.1.4. Failure Detection Protocols<br />

25.1.5. Reliable Delivery Protocols<br />

25.1.6. Group Membership (GMS)<br />

25.1.7. Flow Control (FC)<br />

25.2. Fragmentation (FRAG2)<br />

25.3. State Transfer<br />

25.4. Distributed Garbage Collection (STABLE)<br />

25.5. Merging (MERGE2)<br />

25.6. Other Configuration Issues<br />

25.6.1. Binding JGroups Channels to a Particular Interface<br />

25.6.2. Isolating JGroups Channels<br />

25.6.3. JGroups Troubleshooting<br />

26. <strong>JBoss</strong> Cache Configuration and Deployment<br />

26.1. Key <strong>JBoss</strong> Cache Configuration Options<br />

26.1.1. Editing the CacheManager Configuration<br />

26.1.2. Cache Mode<br />

26.1.3. Transaction Handling<br />

26.1.4. Concurrent Access<br />

26.1.5. JGroups Integration<br />

26.1.6. Eviction<br />

26.1.7. Cache Loaders<br />

26.1.8. Buddy Replication<br />

IV. Appendices<br />

26.2. Deploying Your Own <strong>JBoss</strong> Cache Instance<br />

26.2.1. Deployment Via the CacheManager Service<br />

26.2.2. Deployment Via a -service.xml File<br />

26.2.3. Deployment Via a -jboss-beans.xml File<br />

A. Vendor-Specific Datasource Definitions<br />

A.1. Deployer Location and Naming<br />

A.2. DB2<br />

A.3. Oracle<br />

A.3.1. Changes in Oracle 10g JDBC Driver<br />

A.3.2. Type Mapping for Oracle 10g<br />

A.3.3. Retrieving the Underlying Oracle Connection Object<br />

A.4. Sybase<br />

A.5. Microsoft SQL Server<br />

A.5.1. Microsoft JDBC Drivers<br />

A.5.2. JSQL Drivers<br />

A.5.3. jTDS JDBC Driver<br />

A.5.4. "Invalid object name 'JMS_SUBSCRIPTIONS' Exception<br />

A.6. MySQL Datasource<br />

A.6.1. Installing the Driver<br />

A.6.2. MySQL Local-TX Datasource<br />

A.6.3. MySQL Using a Named Pipe


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 9<br />

A.7. PostgreSQL<br />

A.8. Ingres<br />

B. Logging Information and Recipes<br />

B.1. Log Level Descriptions<br />

B.2. Separate Log Files Per <strong>Application</strong><br />

B.3. Redirecting Category Output


10 What this Book Covers<br />

What this Book Covers<br />

The primary focus of this book is the presentation of the standard <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong><br />

5.0 architecture components from both the perspective of their configuration and architecture. As a user<br />

of a standard <strong>JBoss</strong> distribution you will be given an understanding of how to configure the standard<br />

components. This book is not an introduction to JavaEE or how to use JavaEE in applications. It focuses<br />

on the internal details of the <strong>JBoss</strong> server architecture and how our implementation of a given JavaEE<br />

container can be configured and extended.<br />

As a <strong>JBoss</strong> developer, you will be given a good understanding of the architecture and integration of the<br />

standard components to enable you to extend or replace the standard components for your<br />

infrastructure needs. We also show you how to obtain the <strong>JBoss</strong> source code, along with how to build<br />

and debug the <strong>JBoss</strong> server.


Chapter 1. Introduction<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5 is built on top of the new <strong>JBoss</strong> Microcontainer. The <strong>JBoss</strong><br />

Microcontainer is a lightweight container that supports direct deployment, configuration and lifecycle of<br />

plain old Java objects (POJOs). The <strong>JBoss</strong> Microcontainer project is standalone and replaces the <strong>JBoss</strong><br />

JMX Microkernel used in the 4.x <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>s.<br />

The <strong>JBoss</strong> Microcontainer integrates nicely with the <strong>JBoss</strong> Aspect Oriented Programming framework<br />

(<strong>JBoss</strong> AOP). <strong>JBoss</strong> AOP is discussed in Chapter 8, <strong>JBoss</strong> AOP Support for JMX in <strong>JBoss</strong> <strong>Enterprise</strong><br />

<strong>Application</strong> <strong>Platform</strong> 5 remains strong and MBean services written against the old Microkernel are<br />

expected to work.<br />

A sample Java EE 5 application that can be run on top of <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5.0.0.GA<br />

and above which demonstrates many interesting technologies is the Seam Booking <strong>Application</strong> available<br />

with this distribution. This example application makes use of the following technologies running on<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5:<br />

EJB3<br />

Stateful Session Beans<br />

Stateless Session Beans<br />

JPA (w/ Hibernate validation)<br />

JSF<br />

Facelets<br />

Ajax4JSF<br />

Seam<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 11<br />

Many key features of <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5 are provided by integrating standalone<br />

<strong>JBoss</strong> projects which include:<br />

<strong>JBoss</strong> EJB3 included with <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5 provides the implementation of the<br />

latest revision of the <strong>Enterprise</strong> Java Beans (EJB) specification. EJB 3.0 is a deep overhaul and<br />

simplification of the EJB specification. EJB 3.0's goals are to simplify development, facilitate a test<br />

driven approach, and focus more on writing plain old java objects (POJOs) rather than coding against<br />

complex EJB APIs.<br />

<strong>JBoss</strong> Messaging is a high performance JMS provider included in <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong><br />

<strong>Platform</strong> 5 as the default messaging provider. It is also the backbone of the <strong>JBoss</strong> ESB infrastructure.<br />

<strong>JBoss</strong> Messaging is a complete rewrite of <strong>JBoss</strong>MQ, which is the default JMS provider for <strong>JBoss</strong><br />

<strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 4.2.<br />

<strong>JBoss</strong> Cache comes in two flavors: a traditional tree-structured node-based cache, and a PojoCache,<br />

an in-memory, transactional, and replicated cache system that allows users to operate on simple<br />

POJOs transparently without active user management of either replication or persistency aspects.<br />

<strong>JBoss</strong>WS 3.x is the web services stack for <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5 providing Java<br />

EE compatible web services, JAXWS-2.x.<br />

<strong>JBoss</strong> Transactions is the default transaction manager for <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5.<br />

<strong>JBoss</strong> Transactions is founded on industry proven technology and 18 year history as a leader in<br />

distributed transactions, and is one of the most interoperable implementations available.<br />

<strong>JBoss</strong> Web is the Web container in <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5, an implementation<br />

based on Apache Tomcat that includes the Apache Portable Runtime (APR) and Tomcat native<br />

technologies to achieve scalability and performance characteristics that match and exceed the<br />

Apache Http server.<br />

1.1. <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> Use Cases<br />

99% of web applications involving a database<br />

Mission critical web applications likely to be clustered.<br />

Simple web applications with JSPs/Servlets upgrades to <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> with<br />

Tomcat Embedded.<br />

Intermediate web applications with JSPs/Servlets using a web framework such as Struts, Java Server<br />

Faces, Cocoon, Tapestry, Spring, Expresso, Avalon, Turbine.<br />

Complex web applications with JSPs/Servlets, SEAM, <strong>Enterprise</strong> Java Beans (EJB), Java Messaging<br />

(JMS), caching etc.<br />

Cross application middleware (JMS, Corba, JMX etc).


12 Chapter 1. Introduction


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 13<br />

Part I. <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> Infrastructure


14 Chapter 2. <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5 architecture<br />

Chapter 2. <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5<br />

architecture<br />

The following diagram illustrates an overview of the <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> Server and its<br />

components.<br />

The directory structure of <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5 resembles that of the 4.x series with<br />

some notable differences:<br />

-jboss-as - the path to your <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> Server.<br />

|-- bin - contains start scripts and run.jar<br />

|-- client - client jars<br />

|-- common/lib - static jars shared across server profile<br />

|-- docs - schemas/dtds, examples<br />

|-- lib - core bootstrap jars<br />

| lib/endorsed - added to the server JVM java.endorsed.dirs path<br />

`-- server - server profile directories. See Section 3.2<br />

for details of the server profiles included in this release.<br />

-seam - the path to <strong>JBoss</strong> SEAM application framework<br />

|-- bootstrap<br />

|-- build<br />

|-- examples - examples demonstrating uses of SEAM's features<br />

|-- extras<br />

|-- lib - library directory<br />

|-- seam-gen - command-line utility used to generate simple skeletal SEAM code<br />

to get your project started<br />

|-- ui -<br />

-resteasy - RESTEasy - a portable implementation of JSR-311 JAX-RS Specification<br />

|-- embedded-lib<br />

|-- lib<br />

|-- resteasy-jaxrs.war<br />

2.1. The <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> Bootstrap<br />

The <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5 bootstrap is similar to the <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong><br />

<strong>Platform</strong> 4.x versions in that the org.jboss.Main entry point loads an org.jboss.system.server.Server<br />

implementation. In <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 4.x this was a JMX based microkernel. In <strong>JBoss</strong><br />

<strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5 this is a <strong>JBoss</strong> Microcontainer.<br />

The default <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5 org.jboss.system.server.Server<br />

implementation is org.jboss.bootstrap.microcontainer.ServerImpl. This<br />

implementation is an extension of the kernel basic bootstrap that boots the MC from the bootstrap beans<br />

declared in {jboss.server.config.url}/bootstrap.xml descriptors using a<br />

BasicXMLDeployer. In addition, the ServerImpl registers install callbacks for any beans that<br />

implement the org.jboss.bootstrap.spi.Bootstrap interface. The


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 15<br />

bootstrap/profile*.xml configurations include a ProfileServiceBootstrap bean that<br />

implements the Bootstrap interface.<br />

The org.jboss.system.server.profileservice.ProfileServiceBootstrap is an<br />

implementation of the org.jboss.bootstrap.spi.Bootstrap interface that loads the deployments<br />

associated with the current profile. The {profile-name} is the name of the profile being loaded and<br />

corresponds to the server -c command line argument. The default {profile-name} is default. The<br />

deployers, deploy<br />

2.2. Hot Deployment<br />

Hot deployment in <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5 is controlled by the Profile<br />

implementations associated with the ProfileService. The HDScanner bean deployed via the<br />

deploy/hdscanner-jboss-beans.xml MC deployment, queries the profile service for changes in<br />

application directory contents and redeploys updated content, undeploys removed content, and adds<br />

new deployment content to the current profile via the ProfileService.<br />

Disabling hot deployment is achieved by removing the hdscanner-jboss-beans.xml file from<br />

deployment.


16 Part II. <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5 Configuration<br />

Part II. <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5 Configuration


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 17<br />

Chapter 3. Logging<br />

Logging is the most important tool to troubleshoot errors and monitor the status of the components of<br />

the <strong>Platform</strong>. log4 j provides a familiar, flexible framework, familiar to Java developers.<br />

Section 3.1, “Logging Defaults” contains information about customizing the default logging behavior for<br />

the <strong>Platform</strong>. See Section 3.2, “Component-Specific Logging” for additional customization. Appendix B,<br />

Logging Information and Recipes provides some logging recipes, which you can customize to your<br />

needs.<br />

3.1. Logging Defaults<br />

The log4 j configuration is loaded from the JBOSS_HOME/server/PROFILE/conf/jboss-log4j.xml<br />

deployment descriptor. log4 j uses appenders to control its logging behavior. An appender is a directive<br />

for where to log information, and how to do it. The jboss-log4j.xml file contains many sample<br />

appenders, including FILE, CONSOLE, and SMTP.<br />

Table 3.1. <strong>Common</strong> log4 j Configuration Directives<br />

Configuration Option Description<br />

appender The main appender. Gives the name and the<br />

implementing class.<br />

errorHandler Delegates an external class to handle exceptions<br />

passed to the logger, especially if the appender<br />

cannot write the log for some reason.<br />

param Options specific to the type of appender. In this<br />

instance, the is the name of the file that<br />

stores the logs for the FILE appender.<br />

layout Controls the logging format. Tweak this to work<br />

with your log-parsing software of choice.<br />

Example 3.1. Sample Appender<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

For more information on configuring log4 j, see http://logging.apache.org/log4j/1.2/.<br />

3.2. Component-Specific Logging<br />

Some <strong>Platform</strong> components have extra logging options available, or extra mechanisms for customizing<br />

logging.<br />

3.2.1. SQL Logging with Hibernate<br />

Hibernate has two ways to enable logging of SQL statements. These statements are most useful during<br />

the testing and debugging phases of application development.


18 Chapter 3. Logging<br />

The first way is to explicitly enable it in your code.<br />

SessionFactory sf = new Configuration()<br />

.setProperty("hibernate.show_sql", "true")<br />

// ...<br />

.buildSessionFactory();<br />

Alternately, you can configure Hibernate to send all SQL messages to log4 j, using a specific facility:<br />

log4j.logger.org.hibernate.SQL=DEBUG, SQL_APPENDER<br />

log4j.additivity.org.hibernate.SQL=false<br />

The additivity option controls whether these log messages are propagated upward to parent<br />

handlers, and is a matter of preference.<br />

3.2.2. Transaction Service Logging<br />

The TransactionManagerService included with the <strong>Enterprise</strong> <strong>Platform</strong> handles logging differently than<br />

the stand-alone Transaction Service. Specifically, it overrides the value of the<br />

com.arjuna.common.util.logger property given in the jbossjta-properties.xml file, forcing use of<br />

the log4 j_releveler logger. All INFO level messages in the transaction code behave as DEBUG<br />

messages. Therefore, these messages are only present in log files if the filter level is DEBUG. All other<br />

log messages behave as normal.


Chapter 4. Deployment<br />

Deploying applications on <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> is achieved by copying the application<br />

into the $JBOSS_HOME/server/default/deploy directory. You can replace default with different<br />

server profiles such as all or minimal (profiles are covered later in this guide). The <strong>JBoss</strong> <strong>Enterprise</strong><br />

<strong>Application</strong> <strong>Platform</strong> constantly scans the deploy directory to pick up new applications or any changes to<br />

existing applications. This enables hot deployment of applications on the fly, while <strong>JBoss</strong> <strong>Enterprise</strong><br />

<strong>Application</strong> <strong>Platform</strong> is still running.<br />

4.1. Deployable <strong>Application</strong> Types<br />

With <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 4.x, a deployer existed to handle a specified deployment type<br />

and that was the only deployer that would process the deployment. In <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong><br />

<strong>Platform</strong> 5, multiple deployers transform the metadata associated with a deployment until its processed<br />

by a deployer that creates a runtime component from the metadata. Deployment has to contain a<br />

descriptor that causes the component metadata to be added to the deployment. The types of<br />

deployments for which deployers exists by default in the <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> include:<br />

WAR<br />

EAR<br />

The WAR application archive (e.g., myapp.war) packages Java EE web applications in a JAR<br />

file. It contains servlet classes, view pages, libraries, and deployment descriptors in WEB-INF<br />

such as web.xml, faces-config.xml, and jboss-web.xml etc..<br />

The EAR application archive (e.g., myapp.ear) packages a Java EE enterprise application in a<br />

JAR file. It typically contains a WAR file for the web module, JAR files for EJB modules, as well<br />

as META-INF deployment descriptors such as application.xml and jboss-app.xml etc.<br />

<strong>JBoss</strong> Microcontainer<br />

SAR<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 19<br />

The <strong>JBoss</strong> Microcontainer (MC) beans archive (typical suffixes include, .beans, .deployer)<br />

packages a POJO deployment in a JAR file with a META-INF/jboss-beans.xml descriptor.<br />

This format is commonly used by the <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> component<br />

deployers.<br />

You can deploy *-jboss-beans.xml files with MC beans definitions. If you have the<br />

approriate JAR files available in the deploy or lib directories, the MC beans can be deployed<br />

using such a standalone XML file.<br />

The SAR application archive (e.g., myservice.sar) packages a <strong>JBoss</strong> service in a JAR file. It is<br />

mostly used by <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> internal services that have not been<br />

updated to support MC beans style deployments.<br />

You can deploy *-service.xml files with MBean service definitions. If you have the<br />

appropriate JAR files available in the deploy or lib directories, the MBeans specified in the XML<br />

files will be started. This is the way you deploy many <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong><br />

internal services that have not been updated to support POJO style deployment, such as the<br />

JMS queues.<br />

You can also deploy JAR files containing EJBs or other service objects directly in <strong>JBoss</strong><br />

<strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>. The list of suffixes that are recognized as JAR files is specified<br />

in the conf/bootstrap/deployers.xml JARStructure bean constructor set.<br />

DataSource<br />

The *-ds.xml file defines connections to external databases. The data source can then be<br />

reused by all applications and services in <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> via the internal<br />

JNDI.


20 Chapter 4. Deployment<br />

Exploded Deployment<br />

The WAR, EAR, MC beans and SAR deployment packages are really just JAR files with special<br />

XML deployment descriptors in directories like META-INF and WEB-INF. <strong>JBoss</strong> <strong>Enterprise</strong><br />

<strong>Application</strong> <strong>Platform</strong> allows you to deploy those archives as expanded directories instead of JAR<br />

files. That allows you to make changes to web pages etc on the fly without re-deploying the entire<br />

application. If you do need to re-deploy the exploded directory without re-start the server, you can<br />

just touch the deployment descriptors (e.g., the WEB-INF/web.xml in a WAR and the META-<br />

INF/application.xml in an EAR) to update their timestamps.<br />

4.2. Standard Server Profiles<br />

The <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> ships with six server profiles. You can choose which<br />

configuration to start by passing the -c parameter to the server startup script. For instance, the run.sh<br />

-c all command starts the server in the all profile.<br />

Each profile is contained in a directory named install_directory/server/[profile name]/. You<br />

can look into each server profile's directory to see the services, applications, and libraries included in the<br />

profile.<br />

Note<br />

The exact contents of the server/[profile name] directory depends on the profile service<br />

implementation and is subject to change as the management layer and embedded server evolve.<br />

all<br />

Default profile loaded when run.sh is executed without the -c parameter. The profile provides<br />

clustering support and other enterprise extensions.<br />

production<br />

The production profile is based on the all profile and provides configuration optimized for<br />

production environments.<br />

minimal<br />

default<br />

Starts the core server container without any of the enterprise services. Use the minimal<br />

profile as a base to build a customized version of <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> that<br />

only contains the services you need.<br />

The default profile is the mostly common used profile for application developers. It supports<br />

the standard Java EE 5.0 programming APIs (e.g., Annotations, JPA, and EJB3).<br />

standard<br />

Note<br />

The default profile is a misnomer; it is not loaded automatically if you do not specify a<br />

profile at start up. The all profile is loaded when you do not specify a profile at startup.<br />

The standard profile is the profile that has been tested for Java EE compliance. The major<br />

differences with the existing configurations is that call-by-value and deployment isolation are<br />

enabled by default, along with support for rmiiiop and juddi (taken from the all config).


web<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 21<br />

The web profile is an experimental, lightweight configuration created around <strong>JBoss</strong> Web that will<br />

follow the developments of the Java EE 6 web profile. Except for the servlet/jsp container, it<br />

provides support for JTA/JCA and JPA. It also limits itself to allowing access to the server only<br />

through the http port. Please note that this configuration is not Java EE certified and will most<br />

likely change in the following releases.<br />

The detailed services and APIs supported in each of those profiles will be discussed throughout.


22 Chapter 5. Microcontainer<br />

Chapter 5. Microcontainer<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5.0 uses the Microcontainer to integrate enterprise services<br />

together with a Servlet/JSP container, EJB container, deployers and management utilities in order to<br />

provide a standard Java EE environment. If you need additional services, you can deploy these on top of<br />

Java EE to provide the functionality you need. Likewise any services that you do not need can be<br />

removed by changing the configuration. You can even use the Microcontainer to do this in other<br />

environments such as Tomcat and GlassFish by plugging in different classloading models during the<br />

service deployment phase.<br />

Since <strong>JBoss</strong> Microcontainer is very lightweight and deals with POJOs, it can also be used to deploy<br />

services into a Java ME runtime environment. This opens up new possibilities for mobile applications<br />

that can now take advantage of enterprise services without requiring a full JEE application server. As<br />

with other lightweight containers, <strong>JBoss</strong> Microcontainer uses dependency injection to wire individual<br />

POJOs together to create services. Configuration is performed using either annotations or XML<br />

depending on where the information is best located. Unit testing is made extremely simple thanks to a<br />

helper class that extends JUnit to setup the test environment, allowing you to access POJOs and<br />

services from your test methods using just a few lines of code.<br />

Note<br />

For detailed information regarding the Microcontainer architecture, refer to the Microcontainer<br />

User Guide hosted on docs.redhat.com.


Chapter 6. The JNDI Naming Service<br />

The naming service plays a key role in enterprise Java applications, providing the core infrastructure<br />

that is used to locate objects or services in an application server. It is also the mechanism that clients<br />

external to the application server use to locate services inside the application server. <strong>Application</strong> code,<br />

whether it is internal or external to the <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> instance, needs only know<br />

that it needs to talk to the a message queue named queue/IncomingOrders and need not worry<br />

about any of the queue's configuration details.<br />

In a clustered environment, naming services are even more valuable. A client of a service must be able<br />

to look up a ProductCatalog session bean from the cluster without needing to know which machine it<br />

resides on. Whether it is a large clustered service, a local resource or an application component that is<br />

needed, the JNDI naming service provides the glue that lets code find the objects in the system by name.<br />

6.1. An Overview of JNDI<br />

JNDI is a standard Java API that is bundled with the Java Development Kit. JNDI provides a common<br />

interface to a variety of existing naming services: DNS, LDAP, Active Directory, RMI registry, COS<br />

registry, NIS, and file systems. The JNDI API is divided logically into a client API that is used to access<br />

naming services, and a service provider interface (SPI) that allows the user to create JNDI<br />

implementations for naming services.<br />

The SPI layer is an abstraction that naming service providers must implement to enable the core JNDI<br />

classes to expose the naming service using the common JNDI client interface. An implementation of JNDI<br />

for a naming service is referred to as a JNDI provider. <strong>JBoss</strong> naming is an example JNDI implementation,<br />

based on the SPI classes. Note that the JNDI SPI is not needed by J2EE component developers.<br />

The main JNDI API package is the javax.naming package. It contains five interfaces, 10 classes, and<br />

several exceptions. There is one key class, InitialContext, and two key interfaces, Context and<br />

Name<br />

6.1.1. Names<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 23<br />

The notion of a name is of fundamental importance in JNDI. The naming system determines the syntax<br />

that the name must follow. The syntax of the naming system allows the user to parse string<br />

representations of names into its components. A name is used with a naming system to locate objects.<br />

In the simplest sense, a naming system is just a collection of objects with unique names. To locate an<br />

object in a naming system you provide a name to the naming system, and the naming system returns the<br />

object store under the name.<br />

As an example, consider the Unix file system's naming convention. Each file is named from its path<br />

relative to the root of the file system, with each component in the path separated by the forward slash<br />

character ("/"). The file's path is ordered from left to right. The pathname /usr/jboss/readme.txt,<br />

for example, names a file readme.txt in the directory jboss, under the directory usr, located in the<br />

root of the file system. <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> naming uses a Unix-style namespace as<br />

its naming convention.<br />

The javax.naming.Name interface represents a generic name as an ordered sequence of<br />

components. It can be a composite name (one that spans multiple namespaces), or a compound name<br />

(one that is used within a single hierarchical naming system). The components of a name are numbered.<br />

The indexes of a name with N components range from 0 up to, but not including, N. The most significant<br />

component is at index 0. An empty name has no components.<br />

A composite name is a sequence of component names that span multiple namespaces. An example of a<br />

composite name would be the hostname and file combination commonly used with Unix commands like<br />

scp. For example, the following command copies localfile.txt to the file remotefile.txt in the<br />

tmp directory on host ahost.someorg.org:<br />

scp localfile.txt ahost.someorg.org:/tmp/remotefile.txt<br />

A compound name is derived from a hierarchical namespace. Each component in a compound name is<br />

an atomic name, meaning a string that cannot be parsed into smaller components. A file pathname in the<br />

Unix file system is an example of a compound name. ahost.someorg.org:/tmp/remotefile.txt<br />

is a composite name that spans the DNS and Unix file system namespaces. The components of the<br />

composite name are ahost.someorg.org and /tmp/remotefile.txt. A component is a string


24 Chapter 6. The JNDI Naming Service<br />

name from the namespace of a naming system. If the component comes from a hierarchical namespace,<br />

that component can be further parsed into its atomic parts by using the<br />

javax.naming.CompoundName class. The JNDI API provides the<br />

javax.naming.CompositeName class as the implementation of the Name interface for composite<br />

names.<br />

6.1.2. Contexts<br />

The javax.naming.Context interface is the primary interface for interacting with a naming service.<br />

The Context interface represents a set of name-to-object bindings. Every context has an associated<br />

naming convention that determines how the context parses string names into javax.naming.Name<br />

instances. To create a name-to-object binding you invoke the bind method of a Context and specify a<br />

name and an object as arguments. The object can later be retrieved using its name using the Context<br />

lookup method. A Context will typically provide operations for binding a name to an object, unbinding a<br />

name, and obtaining a listing of all name-to-object bindings. The object you bind into a Context can<br />

itself be of type Context. The Context object that is bound is referred to as a subcontext of the<br />

Context on which the bind method was invoked.<br />

As an example, consider a file directory with a pathname /usr, which is a context in the Unix file system.<br />

A file directory named relative to another file directory is a subcontext (commonly referred to as a<br />

subdirectory). A file directory with a pathname /usr/jboss names a jboss context that is a subcontext<br />

of usr. In another example, a DNS domain, such as org, is a context. A DNS domain named relative to<br />

another DNS domain is another example of a subcontext. In the DNS domain jboss.org, the DNS<br />

domain jboss is a subcontext of org because DNS names are parsed right to left.<br />

6.1.2.1. Obtaining a Context using InitialContext<br />

All naming service operations are performed on some implementation of the Context interface.<br />

Therefore, you need a way to obtain a Context for the naming service you are interested in using. The<br />

javax.naming.IntialContext class implements the Context interface, and provides the starting<br />

point for interacting with a naming service.<br />

When you create an InitialContext, it is initialized with properties from the environment. JNDI<br />

determines each property's value by merging the values from the following two sources, in order.<br />

The first occurrence of the property from the constructor's environment parameter and (for<br />

appropriate properties) the applet parameters and system properties.<br />

All jndi.properties resource files found on the classpath.<br />

For each property found in both of these two sources, the property's value is determined as follows. If<br />

the property is one of the standard JNDI properties that specify a list of JNDI factories, all of the values<br />

are concatenated into a single colon-separated list. For other properties, only the first value found is<br />

used. The preferred method of specifying the JNDI environment properties is through a<br />

jndi.properties file, which allows your code to externalize the JNDI provider specific information so<br />

that changing JNDI providers will not require changes to your code or recompilation.<br />

The Context implementation used internally by the InitialContext class is determined at runtime.<br />

The default policy uses the environment property java.naming.factory.initial, which contains<br />

the class name of the javax.naming.spi.InitialContextFactory implementation. You obtain<br />

the name of the InitialContextFactory class from the naming service provider you are using.<br />

Example 6.1, “A sample jndi.properties file” gives a sample jndi.properties file a client application<br />

would use to connect to a <strong>JBoss</strong>NS service running on the local host at port 1099. The client application<br />

would need to have the jndi.properties file available on the application classpath. These are the<br />

properties that the <strong>JBoss</strong>NS JNDI implementation requires. Other JNDI providers will have different<br />

properties and values.<br />

Example 6.1. A sample jndi.properties file<br />

### <strong>JBoss</strong>NS properties<br />

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory<br />

java.naming.provider.url=jnp://localhost:1099<br />

java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 25<br />

6.2. The <strong>JBoss</strong> Naming Service Architecture<br />

The <strong>JBoss</strong> Naming Service (<strong>JBoss</strong>NS) architecture is a Java socket/RMI based implementation of the<br />

javax.naming.Context interface. It is a client/server implementation that can be accessed remotely.<br />

The implementation is optimized so that access from within the same VM in which the <strong>JBoss</strong>NS server is<br />

running does not involve sockets. Same VM access occurs through an object reference available as a<br />

global singleton. Figure 6.1, “Key components in the <strong>JBoss</strong> Naming Service architecture.” illustrates<br />

some of the key classes in the <strong>JBoss</strong>NS implementation and their relationships.<br />

Figure 6.1. Key components in the <strong>JBoss</strong> Naming Service architecture.<br />

We will start with the NamingService MBean. The NamingService MBean provides the JNDI<br />

naming service. This is a key service used pervasively by the J2EE technology components. The<br />

configurable attributes for the NamingService are as follows.<br />

Port: The jnp protocol listening port for the NamingService. If not specified default is 1099, the<br />

same as the RMI registry default port.<br />

RmiPort: The RMI port on which the RMI Naming implementation will be exported. If not specified the<br />

default is 0 which means use any available port.<br />

BindAddress: The specific address the NamingService listens on. This can be used on a multihomed<br />

host for a java.net.ServerSocket that will only accept connect requests on one of its<br />

addresses.<br />

RmiBindAddress: The specific address the RMI server portion of the NamingService listens on.<br />

This can be used on a multi-homed host for a java.net.ServerSocket that will only accept<br />

connect requests on one of its addresses. If this is not specified and the BindAddress is, the<br />

RmiBindAddress defaults to the BindAddress value.<br />

Backlog: The maximum queue length for incoming connection indications (a request to connect) is<br />

set to the backlog parameter. If a connection indication arrives when the queue is full, the<br />

connection is refused.<br />

ClientSocketFactory: An optional custom java.rmi.server.RMIClientSocketFactory<br />

implementation class name. If not specified the default RMIClientSocketFactory is used.<br />

ServerSocketFactory: An optional custom java.rmi.server.RMIServerSocketFactory<br />

implementation class name. If not specified the default RMIServerSocketFactory is used.<br />

JNPServerSocketFactory: An optional custom javax.net.ServerSocketFactory<br />

implementation class name. This is the factory for the ServerSocket used to bootstrap the<br />

download of the <strong>JBoss</strong> Naming Service Naming interface. If not specified the<br />

javax.net.ServerSocketFactory.getDefault() method value is used.<br />

The NamingService also creates the java:comp context such that access to this context is isolated


26 Chapter 6. The JNDI Naming Service<br />

based on the context class loader of the thread that accesses the java:comp context. This provides<br />

the application component private ENC that is required by the J2EE specs. This segregation is<br />

accomplished by binding a javax.naming.Reference to a context that uses the<br />

org.jboss.naming.ENCFactory as its javax.naming.ObjectFactory. When a client performs<br />

a lookup of java:comp, or any subcontext, the ENCFactory checks the thread context<br />

ClassLoader, and performs a lookup into a map using the ClassLoader as the key.<br />

If a context instance does not exist for the class loader instance, one is created and associated with that<br />

class loader in the ENCFactory map. Thus, correct isolation of an application component's ENC relies<br />

on each component receiving a unique ClassLoader that is associated with the component threads of<br />

execution.<br />

The NamingService delegates its functionality to an org.jnp.server.Main MBean. The reason<br />

for the duplicate MBeans is because <strong>JBoss</strong> Naming Service started out as a stand-alone JNDI<br />

implementation, and can still be run as such. The NamingService MBean embeds the Main instance<br />

into the <strong>JBoss</strong> server so that usage of JNDI with the same VM as the <strong>JBoss</strong> server does not incur any<br />

socket overhead. The configurable attributes of the NamingService are really the configurable attributes<br />

of the <strong>JBoss</strong> Naming Service Main MBean. The setting of any attributes on the NamingService<br />

MBean simply set the corresponding attributes on the Main MBean the NamingService contains.<br />

When the NamingService is started, it starts the contained Main MBean to activate the JNDI naming<br />

service.<br />

In addition, the NamingService exposes the Naming interface operations through a JMX detyped<br />

invoke operation. This allows the naming service to be accessed via JMX adaptors for arbitrary<br />

protocols. We will look at an example of how HTTP can be used to access the naming service using the<br />

invoke operation later in this chapter.<br />

When the Main MBean is started, it performs the following tasks:<br />

Instantiates an org.jnp.naming.NamingService instance and sets this as the local VM server<br />

instance. This is used by any org.jnp.interfaces.NamingContext instances that are<br />

created within the <strong>JBoss</strong> server VM to avoid RMI calls over TCP/IP.<br />

Exports the NamingServer instance's org.jnp.naming.interfaces.Naming RMI interface<br />

using the configured RmiPort, ClientSocketFactory, ServerSocketFactory attributes.<br />

Creates a socket that listens on the interface given by the BindAddress and Port attributes.<br />

Spawns a thread to accept connections on the socket.<br />

6.3. The Naming InitialContext Factories<br />

The <strong>JBoss</strong> JNDI provider currently supports several different InitialContext factory<br />

implementations.<br />

6.3.1. The standard naming context factory<br />

The most commonly used factory is the org.jnp.interfaces.NamingContextFactory<br />

implementation. Its properties include:<br />

java.naming.factory.initial: The name of the environment property for specifying the initial context<br />

factory to use. The value of the property should be the fully qualified class name of the factory class<br />

that will create an initial context. If it is not specified, a<br />

javax.naming.NoInitialContextException will be thrown when an InitialContext<br />

object is created.<br />

java.naming.provider.url: The name of the environment property for specifying the location of the<br />

<strong>JBoss</strong> JNDI service provider the client will use. The NamingContextFactory class uses this<br />

information to know which <strong>JBoss</strong>NS server to connect to. The value of the property should be a URL<br />

string. For <strong>JBoss</strong>NS the URL format is jnp://host:port/[jndi_path]. The jnp: portion of the<br />

URL is the protocol and refers to the socket/RMI based protocol used by <strong>JBoss</strong>. The jndi_path<br />

portion of the URL is an optional JNDI name relative to the root context, for example, apps or<br />

apps/tmp. Everything but the host component is optional. The following examples are equivalent<br />

because the default port value is 1099.<br />

jnp://www.jboss.org:1099/<br />

www.jboss.org:1099<br />

www.jboss.org


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 27<br />

java.naming.factory.url.pkgs: The name of the environment property for specifying the list of<br />

package prefixes to use when loading in URL context factories. The value of the property should be<br />

a colon-separated list of package prefixes for the class name of the factory class that will create a<br />

URL context factory. For the <strong>JBoss</strong> JNDI provider this must be<br />

org.jboss.naming:org.jnp.interfaces. This property is essential for locating the jnp: and<br />

java: URL context factories of the <strong>JBoss</strong> JNDI provider.<br />

jnp.socketFactory: The fully qualified class name of the javax.net.SocketFactory<br />

implementation to use to create the bootstrap socket. The default value is<br />

org.jnp.interfaces.TimedSocketFactory. The TimedSocketFactory is a simple<br />

SocketFactory implementation that supports the specification of a connection and read timeout.<br />

These two properties are specified by:<br />

jnp.timeout: The connection timeout in milliseconds. The default value is 0 which means the<br />

connection will block until the VM TCP/IP layer times out.<br />

jnp.sotimeout: The connected socket read timeout in milliseconds. The default value is 0 which<br />

means reads will block. This is the value passed to the Socket.setSoTimeout on the newly<br />

connected socket.<br />

When a client creates an InitialContext with these <strong>JBoss</strong>NS properties available, the<br />

org.jnp.interfaces.NamingContextFactory object is used to create the Context instance<br />

that will be used in subsequent operations. The NamingContextFactory is the <strong>JBoss</strong>NS<br />

implementation of the javax.naming.spi.InitialContextFactory interface. When the<br />

NamingContextFactory class is asked to create a Context, it creates an<br />

org.jnp.interfaces.NamingContext instance with the InitialContext environment and<br />

name of the context in the global JNDI namespace. It is the NamingContext instance that actually<br />

performs the task of connecting to the <strong>JBoss</strong>NS server, and implements the Context interface. The<br />

Context.PROVIDER_URL information from the environment indicates from which server to obtain a<br />

NamingServer RMI reference.<br />

The association of the NamingContext instance to a NamingServer instance is done in a lazy<br />

fashion on the first Context operation that is performed. When a Context operation is performed and<br />

the NamingContext has no NamingServer associated with it, it looks to see if its environment<br />

properties define a Context.PROVIDER_URL. A Context.PROVIDER_URL defines the host and port<br />

of the <strong>JBoss</strong>NS server the Context is to use. If there is a provider URL, the NamingContext first<br />

checks to see if a Naming instance keyed by the host and port pair has already been created by<br />

checking a NamingContext class static map. It simply uses the existing Naming instance if one for<br />

the host port pair has already been obtained. If no Naming instance has been created for the given<br />

host and port, the NamingContext connects to the host and port using a java.net.Socket, and<br />

retrieves a Naming RMI stub from the server by reading a java.rmi.MarshalledObject from the<br />

socket and invoking its get method. The newly obtained Naming instance is cached in the<br />

NamingContext server map under the host and port pair. If no provider URL was specified in the JNDI<br />

environment associated with the context, the NamingContext simply uses the in VM Naming instance<br />

set by the Main MBean.<br />

The NamingContext implementation of the Context interface delegates all operations to the Naming<br />

instance associated with the NamingContext. The NamingServer class that implements the<br />

Naming interface uses a java.util.Hashtable as the Context store. There is one unique<br />

NamingServer instance for each distinct JNDI Name for a given <strong>JBoss</strong>NS server. There are zero or<br />

more transient NamingContext instances active at any given moment that refers to a NamingServer<br />

instance. The purpose of the NamingContext is to act as a Context to the Naming interface adaptor<br />

that manages translation of the JNDI names passed to the NamingContext . Because a JNDI name<br />

can be relative or a URL, it needs to be converted into an absolute name in the context of the <strong>JBoss</strong>NS<br />

server to which it refers. This translation is a key function of the NamingContext.<br />

6.3.2. The org.jboss.naming.NamingContextFactory<br />

This version of the InitialContextFactory implementation is a simple extension of the jnp version<br />

which differs from the jnp version in that it stores the last configuration passed to its<br />

InitialContextFactory.getInitialContext(Hashtable env) method in a public thread local<br />

variable. This is used by EJB handles and other JNDI sensitive objects like the UserTransaction<br />

factory to keep track of the JNDI context that was in effect when they were created. If you want this<br />

environment to be bound to the object even after its serialized across vm boundaries, then you should<br />

the org.jboss.naming.NamingContextFactory. If you want the environment that is defined in the<br />

current VM jndi.properties or system properties, then you should use the


28 Chapter 6. The JNDI Naming Service<br />

org.jnp.interfaces.NamingContextFactory version.<br />

6.3.3. Naming Discovery in Clustered Environments<br />

When running in a clustered <strong>JBoss</strong> environment, you can choose not to specify a<br />

Context.PROVIDER_URL value and let the client query the network for available naming services. This<br />

only works with <strong>JBoss</strong> servers running with the all configuration, or an equivalent configuration that<br />

has org.jboss.ha.framework.server.ClusterPartition and<br />

org.jboss.ha.jndi.HANamingService services deployed. The discovery process consists of<br />

sending a multicast request packet to the discovery address/port and waiting for any node to respond.<br />

The response is a HA-RMI version of the Naming interface. The following InitialContext<br />

properties affect the discovery configuration:<br />

jnp.partitionName: The cluster partition name discovery should be restricted to. If you are running<br />

in an environment with multiple clusters, you may want to restrict the naming discovery to a particular<br />

cluster. There is no default value, meaning that any cluster response will be accepted.<br />

jnp.discoveryGroup: The multicast IP/address to which the discovery query is sent. The default is<br />

230.0.0.4.<br />

jnp.discoveryPort: The port to which the discovery query is sent. The default is 1102.<br />

jnp.discoveryTimeout: The time in milliseconds to wait for a discovery query response. The default<br />

value is 5000 (5 seconds).<br />

jnp.disableDiscovery: A flag indicating if the discovery process should be avoided. Discovery<br />

occurs when either no Context.PROVIDER_URL is specified, or no valid naming service could be<br />

located among the URLs specified. If the jnp.disableDiscovery flag is true, then discovery will<br />

not be attempted.<br />

6.3.4 . The HTTP InitialContext Factory Implementation<br />

The JNDI naming service can be accessed over HTTP. From a JNDI client's perspective this is a<br />

transparent change as they continue to use the JNDI Context interface. Operations through the<br />

Context interface are translated into HTTP posts to a servlet that passes the request to the<br />

NamingService using its JMX invoke operation. Advantages of using HTTP as the access protocol<br />

include better access through firewalls and proxies setup to allow HTTP, as well as the ability to secure<br />

access to the JNDI service using standard servlet role based security.<br />

To access JNDI over HTTP you use the org.jboss.naming.HttpNamingContextFactory as the<br />

factory implementation. The complete set of support InitialContext environment properties for this<br />

factory are:<br />

java.naming.factory.initial: The name of the environment property for specifying the initial context<br />

factory, which must be org.jboss.naming.HttpNamingContextFactory.<br />

java.naming.provider.url (or Context.PROVIDER_URL): This must be set to the HTTP URL of<br />

the JNDI factory. The full HTTP URL would be the public URL of the <strong>JBoss</strong> servlet container plus<br />

/invoker/JNDIFactory. Examples include:<br />

http://www.jboss.org:8080/invoker/JNDIFactory<br />

http://www.jboss.org/invoker/JNDIFactory<br />

https://www.jboss.org/invoker/JNDIFactory<br />

The first example accesses the servlet using the port 8080. The second uses the standard HTTP<br />

port 80, and the third uses an SSL encrypted connection to the standard HTTPS port 443.<br />

java.naming.factory.url.pkgs: For all <strong>JBoss</strong> JNDI provider this must be<br />

org.jboss.naming:org.jnp.interfaces. This property is essential for locating the jnp: and<br />

java: URL context factories of the <strong>JBoss</strong> JNDI provider.<br />

The JNDI Context implementation returned by the HttpNamingContextFactory is a proxy that<br />

delegates invocations made on it to a bridge servlet which forwards the invocation to the<br />

NamingService through the JMX bus and marshalls the reply back over HTTP. The proxy needs to<br />

know what the URL of the bridge servlet is in order to operate. This value may have been bound on the<br />

server side if the <strong>JBoss</strong> web server has a well known public interface. If the <strong>JBoss</strong> web server is sitting<br />

behind one or more firewalls or proxies, the proxy cannot know what URL is required. In this case, the<br />

proxy will be associated with a system property value that must be set in the client VM. For more<br />

information on the operation of JNDI over HTTP see Section 6.4.1, “Accessing JNDI over HTTP”.<br />

6.3.5. The Login InitialContext Factory Implementation


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 29<br />

JAAS is the preferred method for authenticating a remote client to <strong>JBoss</strong>. However, for simplicity and to<br />

ease the migration from other application server environment that do not use JAAS, <strong>JBoss</strong> allows you<br />

the security credentials to be passed through the InitialContext. JAAS is still used under the<br />

covers, but there is no manifest use of the JAAS interfaces in the client application.<br />

The factory class that provides this capability is the<br />

org.jboss.security.jndi.LoginInitialContextFactory. The complete set of support<br />

InitialContext environment properties for this factory are:<br />

java.naming.factory.initial: The name of the environment property for specifying the initial context<br />

factory, which must be org.jboss.security.jndi.LoginInitialContextFactory.<br />

java.naming.provider.url: This must be set to a NamingContextFactory provider URL. The<br />

LoginIntialContext is really just a wrapper around the NamingContextFactory that adds a<br />

JAAS login to the existing NamingContextFactory behavior.<br />

java.naming.factory.url.pkgs: For all <strong>JBoss</strong> JNDI provider this must be<br />

org.jboss.naming:org.jnp.interfaces. This property is essential for locating the jnp: and<br />

java: URL context factories of the <strong>JBoss</strong> JNDI provider.<br />

java.naming.security.principal (or Context.SECURITY_PRINCIPAL): The principal to<br />

authenticate. This may be either a java.security.Principal implementation or a string<br />

representing the name of a principal.<br />

java.naming.security.credentials (or Context.SECURITY_CREDENTIALS), The credentials<br />

that should be used to authenticate the principal, e.g., password, session key, etc.<br />

java.naming.security.protocol: (Context.SECURITY_PROTOCOL) This gives the name of the<br />

JAAS login module to use for the authentication of the principal and credentials.<br />

6.3.6. The ORBInitialContextFactory<br />

When using Sun's CosNaming it is necessary to use a different naming context factory from the default.<br />

CosNaming looks for the ORB in JNDI instead of using the the ORB configured in deploy/iiopservice.xml?.<br />

It is necessary to set the global context factory to<br />

org.jboss.iiop.naming.ORBInitialContextFactory, which sets the ORB to <strong>JBoss</strong>'s ORB.<br />

This is done in the conf/jndi.properties file:<br />

# DO NOT EDIT THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING<br />

#<br />

java.naming.factory.initial=org.jboss.iiop.naming.ORBInitialContextFactory<br />

java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces<br />

It is also necessary to use ORBInitialContextFactory when using CosNaming in an application<br />

client.<br />

6.4. JNDI over HTTP<br />

In addition to the legacy RMI/JRMP with a socket bootstrap protocol, <strong>JBoss</strong> provides support for<br />

accessing its JNDI naming service over HTTP.<br />

6.4 .1. Accessing JNDI over HTTP<br />

This capability is provided by http-invoker.sar. The structure of the http-invoker.sar is:<br />

http-invoker.sar<br />

+- META-INF/jboss-service.xml<br />

+- invoker.war<br />

| +- WEB-INF/jboss-web.xml<br />

| +- WEB-INF/classes/org/jboss/invocation/http/servlet/InvokerServlet.class<br />

| +- WEB-INF/classes/org/jboss/invocation/http/servlet/NamingFactoryServlet.class<br />

| +- WEB-INF/classes/org/jboss/invocation/http/servlet/ReadOnlyAccessFilter.class<br />

| +- WEB-INF/classes/roles.properties<br />

| +- WEB-INF/classes/users.properties<br />

| +- WEB-INF/web.xml<br />

| +- META-INF/MANIFEST.MF<br />

+- META-INF/MANIFEST.MF<br />

The jboss-service.xml descriptor defines the HttpInvoker and HttpInvokerHA MBeans.


30 Chapter 6. The JNDI Naming Service<br />

These services handle the routing of methods invocations that are sent via HTTP to the appropriate<br />

target MBean on the JMX bus.<br />

The http-invoker.war web application contains servlets that handle the details of the HTTP<br />

transport. The NamingFactoryServlet handles creation requests for the <strong>JBoss</strong> JNDI naming<br />

service javax.naming.Context implementation. The InvokerServlet handles invocations made<br />

by RMI/HTTP clients. The ReadOnlyAccessFilter allows one to secure the JNDI naming service<br />

while making a single JNDI context available for read-only access by unauthenticated clients.<br />

Figure 6.2. The HTTP invoker proxy/server structure for a JNDI Context<br />

Before looking at the configurations let's look at the operation of the http-invoker services.<br />

Figure 6.2, “The HTTP invoker proxy/server structure for a JNDI Context” shows a logical view of the<br />

structure of a <strong>JBoss</strong> JNDI proxy and its relationship to the <strong>JBoss</strong> server side components of the httpinvoker.<br />

The proxy is obtained from the NamingFactoryServlet using an InitialContext with<br />

the Context.INITIAL_CONTEXT_FACTORY property set to<br />

org.jboss.naming.HttpNamingContextFactory, and the Context.PROVIDER_URL property<br />

set to the HTTP URL of the NamingFactoryServlet. The resulting proxy is embedded in an<br />

org.jnp.interfaces.NamingContext instance that provides the Context interface<br />

implementation.<br />

The proxy is an instance of org.jboss.invocation.http.interfaces.HttpInvokerProxy,<br />

and implements the org.jnp.interfaces.Naming interface. Internally the HttpInvokerProxy<br />

contains an invoker that marshalls the Naming interface method invocations to the InvokerServlet<br />

via HTTP posts. The InvokerServlet translates these posts into JMX invocations to the<br />

NamingService, and returns the invocation response back to the proxy in the HTTP post response.<br />

There are several configuration values that need to be set to tie all of these components together and<br />

Figure 6.3, “The relationship between configuration files and JNDI/HTTP component” illustrates the<br />

relationship between configuration files and the corresponding components.<br />

Figure 6.3. The relationship between configuration files and JNDI/HTTP component


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 31<br />

The http-invoker.sar/META-INF/jboss-service.xml descriptor defines the<br />

HttpProxyFactory that creates the HttpInvokerProxy for the NamingService. The attributes<br />

that need to be configured for the HttpProxyFactory include:<br />

InvokerName: The JMX ObjectName of the NamingService defined in the conf/jbossservice.xml<br />

descriptor. The standard setting used in the <strong>JBoss</strong> distributions is<br />

jboss:service=Naming.<br />

InvokerURL or InvokerURLPrefix + InvokerURLSuffix + UseHostName. You can specify the full<br />

HTTP URL to the InvokerServlet using the InvokerURL attribute, or you can specify the<br />

hostname independent parts of the URL and have the HttpProxyFactory fill them in. An example<br />

InvokerURL value would be<br />

http://jbosshost1.dot.com:8080/invoker/JMXInvokerServlet. This can be broken<br />

down into:<br />

InvokerURLPrefix: the URL prefix prior to the hostname. Typically this will be http:// or<br />

https:// if SSL is to be used.<br />

InvokerURLSuffix: the URL suffix after the hostname. This will include the port number of the<br />

web server as well as the deployed path to the InvokerServlet. For the example<br />

InvokerURL value the InvokerURLSuffix would be<br />

:8080/invoker/JMXInvokerServlet without the quotes. The port number is determined by<br />

the web container service settings. The path to the InvokerServlet is specified in the httpinvoker.sar/invoker.war/WEB-INF/web.xml<br />

descriptor.<br />

UseHostName: a flag indicating if the hostname should be used in place of the host IP address<br />

when building the hostname portion of the full InvokerURL. If true,<br />

InetAddress.getLocalHost().getHostName method will be used. Otherwise, the<br />

InetAddress.getLocalHost().getHostAddress() method is used.<br />

ExportedInterface: The org.jnp.interfaces.Naming interface the proxy will expose to<br />

clients. The actual client of this proxy is the <strong>JBoss</strong> JNDI implementation NamingContext class,<br />

which JNDI client obtain from InitialContext lookups when using the <strong>JBoss</strong> JNDI provider.<br />

JndiName: The name in JNDI under which the proxy is bound. This needs to be set to a blank/empty<br />

string to indicate the interface should not be bound into JNDI. We can't use the JNDI to bootstrap<br />

itself. This is the role of the NamingFactoryServlet.<br />

The http-invoker.sar/invoker.war/WEB-INF/web.xml descriptor defines the mappings of the<br />

NamingFactoryServlet and InvokerServlet along with their initialization parameters. The<br />

configuration of the NamingFactoryServlet relevant to JNDI/HTTP is the JNDIFactory entry<br />

which defines:<br />

A namingProxyMBean initialization parameter that maps to the HttpProxyFactory MBean name.<br />

This is used by the NamingFactoryServlet to obtain the Naming proxy which it will return in<br />

response to HTTP posts. For the default http-invoker.sar/META-INF/jboss-service.xml<br />

settings the name jboss:service=invoker,type=http,target=Naming.<br />

A proxy initialization parameter that defines the name of the namingProxyMBean attribute to query<br />

for the Naming proxy value. This defaults to an attribute name of Proxy.<br />

The servlet mapping for the JNDIFactory configuration. The default setting for the unsecured<br />

mapping is /JNDIFactory/*. This is relative to the context root of the httpinvoker.sar/invoker.war,<br />

which by default is the WAR name minus the .war suffix.<br />

The configuration of the InvokerServlet relevant to JNDI/HTTP is the JMXInvokerServlet which<br />

defines:<br />

The servlet mapping of the InvokerServlet. The default setting for the unsecured mapping is<br />

/JMXInvokerServlet/*. This is relative to the context root of the httpinvoker.sar/invoker.war,<br />

which by default is the WAR name minus the .war suffix.<br />

6.4 .2. Accessing JNDI over HTTPS<br />

To be able to access JNDI over HTTP/SSL you need to enable an SSL connector on the web container.<br />

The details of this are covered in the Integrating Servlet Containers for Tomcat. We will demonstrate the<br />

use of HTTPS with a simple example client that uses an HTTPS URL as the JNDI provider URL. We will<br />

provide an SSL connector configuration for the example, so unless you are interested in the details of<br />

the SSL connector setup, the example is self contained.<br />

We also provide a configuration of the HttpProxyFactory setup to use an HTTPS URL. The following


32 Chapter 6. The JNDI Naming Service<br />

example shows the section of the http-invoker.sarjboss-service.xml descriptor that the<br />

example installs to provide this configuration. All that has changed relative to the standard HTTP<br />

configuration are the InvokerURLPrefix and InvokerURLSuffix attributes, which setup an HTTPS<br />

URL using the 8443 port.<br />

<br />

<br />

<br />

jboss:service=Naming<br />

<br />

https://<br />

:8443/invoker/JMXInvokerServlet<br />

<br />

true<br />

org.jnp.interfaces.Naming<br />

<br />

<br />

<br />

<br />

org.jboss.proxy.ClientMethodInterceptor<br />

<br />

org.jboss.proxy.SecurityInterceptor<br />

<br />

org.jboss.naming.interceptors.ExceptionInterceptor<br />

<br />

org.jboss.invocation.InvokerInterceptor<br />

<br />

<br />

<br />

<br />

At a minimum, a JNDI client using HTTPS requires setting up a HTTPS URL protocol handler. We will be<br />

using the Java Secure Socket Extension (JSSE) for HTTPS. The JSSE documentation does a good job<br />

of describing what is necessary to use HTTPS, and the following steps were needed to configure the<br />

example client shown in Example 6.2, “A JNDI client that uses HTTPS as the transport”:<br />

A protocol handler for HTTPS URLs must be made available to Java. The JSSE release includes an<br />

HTTPS handler in the com.sun.net.ssl.internal.www.protocol package. To enable the<br />

use of HTTPS URLs you include this package in the standard URL protocol handler search property,<br />

java.protocol.handler.pkgs. We set the java.protocol.handler.pkgs property in the<br />

Ant script.<br />

The JSSE security provider must be installed in order for SSL to work. This can be done either by<br />

installing the JSSE jars as an extension package, or programatically. We use the programatic<br />

approach in the example since this is less intrusive. Line 18 of the ExClient code demonstrates<br />

how this is done.<br />

The JNDI provider URL must use HTTPS as the protocol. Lines 24-25 of the ExClient code specify<br />

an HTTP/SSL connection to the localhost on port 8443. The hostname and port are defined by the<br />

web container SSL connector.<br />

The validation of the HTTPS URL hostname against the server certificate must be disabled. By<br />

default, the JSSE HTTPS protocol handler employs a strict validation of the hostname portion of the<br />

HTTPS URL against the common name of the server certificate. This is the same check done by web<br />

browsers when you connect to secured web site. We are using a self-signed server certificate that<br />

uses a common name of "Chapter 8 SSL Example" rather than a particular hostname, and this<br />

is likely to be common in development environments or intranets. The <strong>JBoss</strong> HttpInvokerProxy<br />

will override the default hostname checking if a org.jboss.security.ignoreHttpsHost system<br />

property exists and has a value of true. We set the org.jboss.security.ignoreHttpsHost<br />

property to true in the Ant script.


Example 6.2. A JNDI client that uses HTTPS as the transport<br />

package org.jboss.chap3.ex1;<br />

import java.security.Security;<br />

import java.util.Properties;<br />

import javax.naming.Context;<br />

import javax.naming.InitialContext;<br />

public class ExClient<br />

{<br />

public static void main(String args[]) throws Exception<br />

{<br />

Properties env = new Properties();<br />

env.setProperty(Context.INITIAL_CONTEXT_FACTORY,<br />

"org.jboss.naming.HttpNamingContextFactory");<br />

env.setProperty(Context.PROVIDER_URL,<br />

"https://localhost:8443/invoker/JNDIFactorySSL");<br />

}<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 33<br />

}<br />

Context ctx = new InitialContext(env);<br />

System.out.println("Created InitialContext, env=" + env);<br />

Object data = ctx.lookup("jmx/invoker/RMIAdaptor");<br />

System.out.println("lookup(jmx/invoker/RMIAdaptor): " + data);<br />

To test the client, first build the chapter 3 example to create the chap3 configuration fileset.<br />

[examples]$ ant -Dchap=naming config<br />

Next, start the <strong>JBoss</strong> server using the naming configuration fileset:<br />

[bin]$ sh run.sh -c naming<br />

And finally, run the ExClient using:<br />

[examples]$ ant -Dchap=naming -Dex=1 run-example<br />

...<br />

run-example1:<br />

[java] Created InitialContext, env={java.naming. \<br />

provider.url=https://localhost:8443/invoker/JNDIFactorySSL, java.naming. \<br />

factory.initial=org.jboss.naming.HttpNamingContextFactory}<br />

[java] lookup(jmx/invoker/RMIAdaptor): org.jboss.invocation.jrmp. \<br />

interfaces.JRMPInvokerP<br />

roxy@cac3fa<br />

6.4 .3. Securing Access to JNDI over HTTP<br />

One benefit to accessing JNDI over HTTP is that it is easy to secure access to the JNDI<br />

InitialContext factory as well as the naming operations using standard web declarative security.<br />

This is possible because the server side handling of the JNDI/HTTP transport is implemented with two<br />

servlets. These servlets are included in the http-invoker.sar/invoker.war directory found in the<br />

default and all configuration deploy directories as shown previously. To enable secured access to<br />

JNDI you need to edit the invoker.war/WEB-INF/web.xml descriptor and remove all unsecured<br />

servlet mappings. For example, the web.xml descriptor shown in Example 6.3, “An example web.xml<br />

descriptor for secured access to the JNDI servlets” only allows access to the invoker.war servlets if<br />

the user has been authenticated and has a role of HttpInvoker.


34 Chapter 6. The JNDI Naming Service<br />

Example 6.3. An example web.xml descriptor for secured access to the JNDI servlets<br />

<br />

<br />

<br />

<br />

<br />

JMXInvokerServlet<br />

<br />

org.jboss.invocation.http.servlet.InvokerServlet<br />

<br />

1<br />

<br />

JNDIFactory<br />

<br />

org.jboss.invocation.http.servlet.NamingFactoryServlet<br />

<br />

<br />

namingProxyMBean<br />

jboss:service=invoker,type=http,target=Naming<br />

<br />

<br />

proxyAttribute<br />

Proxy<br />

<br />

2<br />

<br />

<br />

<br />

JNDIFactory<br />

/restricted/JNDIFactory/*<br />

<br />

<br />

JMXInvokerServlet<br />

/restricted/JMXInvokerServlet/*<br />

<br />

<br />

HttpInvokers<br />

An example security config that only allows users with<br />

the role HttpInvoker to access the HTTP invoker servlets<br />

<br />

/restricted/*<br />

GET<br />

POST<br />

<br />

<br />

HttpInvoker<br />

<br />

<br />

<br />

BASIC<br />

<strong>JBoss</strong> HTTP Invoker<br />

<br />

HttpInvoker<br />

<br />

<br />

The web.xml descriptor only defines which sevlets are secured, and which roles are allowed to access<br />

the secured servlets. You must additionally define the security domain that will handle the authentication<br />

and authorization for the war. This is done through the jboss-web.xml descriptor, and an example<br />

that uses the http-invoker security domain is given below.<br />

<br />

java:/jaas/http-invoker<br />


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 35<br />

The security-domain element defines the name of the security domain that will be used for the JAAS<br />

login module configuration used for authentication and authorization.<br />

6.4 .4 . Securing Access to JNDI with a Read-Only Unsecured Context<br />

Another feature available for the JNDI/HTTP naming service is the ability to define a context that can be<br />

accessed by unauthenticated users in read-only mode. This can be important for services used by the<br />

authentication layer. For example, the SRPLoginModule needs to lookup the SRP server interface<br />

used to perform authentication. The rest of this section explains how read-only works in <strong>JBoss</strong><br />

<strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>.<br />

First, the ReadOnlyJNDIFactory is declared in invoker.sar/WEB-INF/web.xml. It will be mapped<br />

to /invoker/ReadOnlyJNDIFactory.<br />

<br />

ReadOnlyJNDIFactory<br />

A servlet that exposes the <strong>JBoss</strong> JNDI Naming service stub<br />

through http, but only for a single read-only context. The return content<br />

is serialized MarshalledValue containing the org.jnp.interfaces.Naming<br />

stub.<br />

<br />

org.jboss.invocation.http.servlet.NamingFactoryServlet<br />

<br />

namingProxyMBean<br />

jboss:service=invoker,type=http,target=Naming,readonly=true<br />

<br />

<br />

proxyAttribute<br />

Proxy<br />

<br />

2<br />

<br />

<br />

<br />

ReadOnlyJNDIFactory<br />

/ReadOnlyJNDIFactory/*<br />

<br />

The factory only provides a JNDI stub which needs to be connected to an invoker. Here the invoker is<br />

jboss:service=invoker,type=http,target=Naming,readonly=true. This invoker is<br />

declared in the http-invoker.sar/META-INF/jboss-service.xml file.<br />

<br />

jboss:service=Naming<br />

http://<br />

:8080/invoker/readonly/JMXInvokerServlet<br />

true<br />

org.jnp.interfaces.Naming<br />

<br />

<br />

<br />

org.jboss.proxy.ClientMethodInterceptor<br />

org.jboss.proxy.SecurityInterceptor<br />

org.jboss.naming.interceptors.ExceptionInterceptor<br />

org.jboss.invocation.InvokerInterceptor<br />

<br />

<br />

<br />

The proxy on the client side needs to talk back to a specific invoker servlet on the server side. The<br />

configuration here has the actual invocations going to /invoker/readonly/JMXInvokerServlet.<br />

This is actually the standard JMXInvokerServlet with a read-only filter attached.


36 Chapter 6. The JNDI Naming Service<br />

<br />

ReadOnlyAccessFilter<br />

org.jboss.invocation.http.servlet.ReadOnlyAccessFilter<br />

<br />

readOnlyContext<br />

readonly<br />

The top level JNDI context the filter will enforce<br />

read-only access on. If specified only Context.lookup operations<br />

will be allowed on this context. Another other operations or<br />

lookups on any other context will fail. Do not associate this<br />

filter with the JMXInvokerServlets if you want unrestricted<br />

access. <br />

<br />

<br />

invokerName<br />

jboss:service=Naming<br />

The JMX ObjectName of the naming service mbean<br />

<br />

<br />

<br />

<br />

ReadOnlyAccessFilter<br />

/readonly/*<br />

<br />

<br />

<br />

<br />

JMXInvokerServlet<br />

/readonly/JMXInvokerServlet/*<br />

<br />

The readOnlyContext parameter is set to readonly which means that when you access <strong>JBoss</strong><br />

through the ReadOnlyJNDIFactory, you will only be able to access data in the readonly context.<br />

Here is a code fragment that illustrates the usage:<br />

Properties env = new Properties();<br />

env.setProperty(Context.INITIAL_CONTEXT_FACTORY,<br />

"org.jboss.naming.HttpNamingContextFactory");<br />

env.setProperty(Context.PROVIDER_URL,<br />

"http://localhost:8080/invoker/ReadOnlyJNDIFactory");<br />

Context ctx2 = new InitialContext(env);<br />

Object data = ctx2.lookup("readonly/data");<br />

Attempts to look up any objects outside of the readonly context will fail. Note that <strong>JBoss</strong> doesn't ship with<br />

any data in the readonly context, so the readonly context won't be bound usable unless you create it.<br />

6.5. Additional Naming MBeans<br />

In addition to the NamingService MBean that configures an embedded <strong>JBoss</strong>NS server within <strong>JBoss</strong>,<br />

there are several additional MBean services related to naming that ship with <strong>JBoss</strong>. They are<br />

JndiBindingServiceMgr, NamingAlias, ExternalContext, and JNDIView.<br />

6.5.1. JNDI Binding Manager<br />

The JNDI binding manager service allows you to quickly bind objects into JNDI for use by application<br />

code. The MBean class for the binding service is org.jboss.naming.JNDIBindingServiceMgr. It<br />

has a single attribute, BindingsConfig, which accepts an XML document that conforms to the jndibinding-service_1_0.xsd<br />

schema. The content of the BindingsConfig attribute is<br />

unmarshalled using the <strong>JBoss</strong>XB framework. The following is an MBean definition that shows the most<br />

basic form usage of the JNDI binding manager service.


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 37<br />

<br />

<br />

<br />

<br />

<br />

Hello, JNDI!<br />

<br />

<br />

<br />

<br />

<br />

This binds the text string "Hello, JNDI!" under the JNDI name bindexample/message. An<br />

application would look up the value just as it would for any other JNDI value. The trim attribute<br />

specifies that leading and trailing whitespace should be ignored. The use of the attribute here is purely<br />

for illustrative purposes as the default value is true.<br />

InitialContext ctx = new InitialContext();<br />

String text = (String) ctx.lookup("bindexample/message");<br />

String values themselves are not that interesting. If a JavaBeans property editor is available, the desired<br />

class name can be specified using the type attribute<br />

<br />

http://www.jboss.org<br />

<br />

The editor attribute can be used to specify a particular property editor to use.<br />

<br />

<br />

127.0.0.1<br />

<br />

<br />

For more complicated structures, any <strong>JBoss</strong>XB-ready schema may be used. The following example<br />

shows how a java.util.Properties object would be mapped.<br />

<br />

<br />

<br />

key1<br />

value1<br />

<br />

<br />

key2<br />

value2<br />

<br />

<br />

<br />

6.5.2. The org.jboss.naming.NamingAlias MBean<br />

The NamingAlias MBean is a simple utility service that allows you to create an alias in the form of a<br />

JNDI javax.naming.LinkRef from one JNDI name to another. This is similar to a symbolic link in the<br />

Unix file system. To an alias you add a configuration of the NamingAlias MBean to the jbossservice.xml<br />

configuration file. The configurable attributes of the NamingAlias service are as<br />

follows:<br />

FromName: The location where the LinkRef is bound under JNDI.<br />

ToName: The to name of the alias. This is the target name to which the LinkRef refers. The name


38 Chapter 6. The JNDI Naming Service<br />

is a URL, or a name to be resolved relative to the InitialContext, or if the first character of the<br />

name is a dot (.), the name is relative to the context in which the link is bound.<br />

The following example provides a mapping of the JNDI name QueueConnectionFactory to the name<br />

ConnectionFactory.<br />

<br />

ConnectionFactory<br />

QueueConnectionFactory<br />

<br />

6.5.3. org.jboss.naming.ExternalContext MBean<br />

The ExternalContext MBean allows you to federate external JNDI contexts into the <strong>JBoss</strong> server<br />

JNDI namespace. The term external refers to any naming service external to the <strong>JBoss</strong>NS naming<br />

service running inside of the <strong>JBoss</strong> server VM. You can incorporate LDAP servers, file systems, DNS<br />

servers, and so on, even if the JNDI provider root context is not serializable. The federation can be<br />

made available to remote clients if the naming service supports remote access.<br />

To incorporate an external JNDI naming service, you have to add a configuration of the<br />

ExternalContext MBean service to the jboss-service.xml configuration file. The configurable<br />

attributes of the ExternalContext service are as follows:<br />

JndiName: The JNDI name under which the external context is to be bound.<br />

RemoteAccess: A boolean flag indicating if the external InitialContext should be bound using<br />

a Serializable form that allows a remote client to create the external InitialContext . When<br />

a remote client looks up the external context via the <strong>JBoss</strong> JNDI InitialContext, they effectively<br />

create an instance of the external InitialContext using the same env properties passed to the<br />

ExternalContext MBean. This will only work if the client can do a new InitialContext(env)<br />

remotely. This requires that the Context.PROVIDER_URL value of env is resolvable in the remote<br />

VM that is accessing the context. This should work for the LDAP example. For the file system<br />

example this most likely won't work unless the file system path refers to a common network path. If<br />

this property is not given it defaults to false.<br />

CacheContext: The cacheContext flag. When set to true, the external Context is only created<br />

when the MBean is started and then stored as an in memory object until the MBean is stopped. If<br />

cacheContext is set to false, the external Context is created on each lookup using the MBean<br />

properties and InitialContext class. When the uncached Context is looked up by a client, the client<br />

should invoke close() on the Context to prevent resource leaks.<br />

InitialContext: The fully qualified class name of the InitialContext implementation to use. Must<br />

be one of: javax.naming.InitialContext,<br />

javax.naming.directory.InitialDirContext or<br />

javax.naming.ldap.InitialLdapContext. In the case of the InitialLdapContext a null<br />

Controls array is used. The default is javax.naming.InitialContex.<br />

Properties: The Properties attribute contains the JNDI properties for the external<br />

InitialContext. The input should be the text equivalent to what would go into a<br />

jndi.properties file.<br />

PropertiesURL: This set the jndi.properties information for the external InitialContext<br />

from an external properties file. This is either a URL, string or a classpath resource name. Examples<br />

are as follows:<br />

file:///config/myldap.properties<br />

http://config.mycompany.com/myldap.properties<br />

/conf/myldap.properties<br />

myldap.properties<br />

The MBean definition below shows a binding to an external LDAP context into the <strong>JBoss</strong> JNDI<br />

namespace under the name external/ldap/jboss.


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 39<br />

<br />

<br />

external/ldap/jboss<br />

<br />

java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory<br />

java.naming.provider.url=ldap://ldaphost.jboss.org:389/o=jboss.org<br />

java.naming.security.principal=cn=Directory Manager<br />

java.naming.security.authentication=simple<br />

java.naming.security.credentials=secret<br />

<br />

javax.naming.ldap.InitialLdapContext<br />

<br />

true<br />

<br />

With this configuration, you can access the external LDAP context located at<br />

ldap://ldaphost.jboss.org:389/o=jboss.org from within the <strong>JBoss</strong> VM using the following<br />

code fragment:<br />

InitialContext iniCtx = new InitialContext();<br />

LdapContext ldapCtx = iniCtx.lookup("external/ldap/jboss");<br />

Using the same code fragment outside of the <strong>JBoss</strong> server VM will work in this case because the<br />

RemoteAccess property was set to true. If it were set to false, it would not work because the remote<br />

client would receive a Reference object with an ObjectFactory that would not be able to recreate<br />

the external InitialContext<br />

<br />

<br />

external/fs/usr/local<br />

<br />

java.naming.factory.initial=com.sun.jndi.fscontext.RefFSContextFactory<br />

java.naming.provider.url=file:///usr/local<br />

<br />

javax.naming.IntialContext<br />

<br />

This configuration describes binding a local file system directory /usr/local into the <strong>JBoss</strong> JNDI<br />

namespace under the name external/fs/usr/local.<br />

With this configuration, you can access the external file system context located at<br />

file:///usr/local from within the <strong>JBoss</strong> VM using the following code fragment:<br />

InitialContext iniCtx = new InitialContext();<br />

Context ldapCtx = iniCtx.lookup("external/fs/usr/local");<br />

6.5.4 . The org.jboss.naming.JNDIView MBean<br />

The JNDIView MBean allows the user to view the JNDI namespace tree as it exists in the <strong>JBoss</strong> server<br />

using the JMX agent view interface. To view the <strong>JBoss</strong> JNDI namespace using the JNDIView MBean, you<br />

connect to the JMX Agent View using the http interface. The default settings put this at<br />

http://localhost:8080/jmx-console/. On this page you will see a section that lists the<br />

registered MBeans sorted by domain. It should look something like that shown in Figure 6.4, “The JMX<br />

Console view of the configured <strong>JBoss</strong> MBeans”.


4 0 Chapter 6. The JNDI Naming Service<br />

Figure 6.4 . The JMX Console view of the configured <strong>JBoss</strong> MBeans<br />

Selecting the JNDIView link takes you to the JNDIView MBean view, which will have a list of the JNDIView<br />

MBean operations. This view should look similar to that shown in Figure 6.5, “The JMX Console view of<br />

the JNDIView MBean”.<br />

Figure 6.5. The JMX Console view of the JNDIView MBean<br />

The list operation dumps out the <strong>JBoss</strong> server JNDI namespace as an HTML page using a simple text<br />

view. As an example, invoking the list operation produces the view shown in Figure 6.6, “The JMX<br />

Console view of the JNDIView list operation output”.


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 4 1<br />

Figure 6.6. The JMX Console view of the JNDIView list operation output<br />

6.6. J2EE and JNDI - The <strong>Application</strong> Component Environment<br />

JNDI is a fundamental aspect of the J2EE specifications. One key usage is the isolation of J2EE<br />

component code from the environment in which the code is deployed. Use of the application component's<br />

environment allows the application component to be customized without the need to access or change<br />

the application component's source code. The application component environment is referred to as the<br />

ENC, the enterprise naming context. It is the responsibility of the application component container to<br />

make an ENC available to the container components in the form of JNDI Context. The ENC is utilized by<br />

the participants involved in the life cycle of a J2EE component in the following ways.<br />

<strong>Application</strong> component business logic should be coded to access information from its ENC. The<br />

component provider uses the standard deployment descriptor for the component to specify the<br />

required ENC entries. The entries are declarations of the information and resources the component<br />

requires at runtime.<br />

The container provides tools that allow a deployer of a component to map the ENC references made<br />

by the component developer to the deployment environment entity that satisfies the reference.<br />

The component deployer utilizes the container tools to ready a component for final deployment.<br />

The component container uses the deployment package information to build the complete component<br />

ENC at runtime<br />

The complete specification regarding the use of JNDI in the J2EE platform can be found in section 5 of<br />

the J2EE 1.4 specification.<br />

An application component instance locates the ENC using the JNDI API. An application component<br />

instance creates a javax.naming.InitialContext object by using the no argument constructor<br />

and then looks up the naming environment under the name java:comp/env. The application<br />

component's environment entries are stored directly in the ENC, or in its subcontexts. Example 6.4, “ENC<br />

access sample code” illustrates the prototypical lines of code a component uses to access its ENC.<br />

Example 6.4 . ENC access sample code<br />

// Obtain the application component's ENC<br />

Context iniCtx = new InitialContext();<br />

Context compEnv = (Context) iniCtx.lookup("java:comp/env");


4 2 Chapter 6. The JNDI Naming Service<br />

An application component environment is a local environment that is accessible only by the component<br />

when the application server container thread of control is interacting with the application component.<br />

This means that an EJB Bean1 cannot access the ENC elements of EJB Bean2, and vice versa.<br />

Similarly, Web application Web1 cannot access the ENC elements of Web application Web2 or Bean1 or<br />

Bean2 for that matter. Also, arbitrary client code, whether it is executing inside of the application server<br />

VM or externally cannot access a component's java:comp JNDI context. The purpose of the ENC is to<br />

provide an isolated, read-only namespace that the application component can rely on regardless of the<br />

type of environment in which the component is deployed. The ENC must be isolated from other<br />

components because each component defines its own ENC content. Components A and B, for example,<br />

may define the same name to refer to different objects. For example, EJB Bean1 may define an<br />

environment entry java:comp/env/red to refer to the hexadecimal value for the RGB color for red,<br />

while Web application Web1 may bind the same name to the deployment environment language locale<br />

representation of red.<br />

There are three commonly used levels of naming scope in <strong>JBoss</strong>: names under java:comp, names<br />

under java:, and any other name. As discussed, the java:comp context and its subcontexts are only<br />

available to the application component associated with that particular context. Subcontexts and object<br />

bindings directly under java: are only visible within the <strong>JBoss</strong> server virtual machine and not to remote<br />

clients. Any other context or object binding is available to remote clients, provided the context or object<br />

supports serialization. You'll see how the isolation of these naming scopes is achieved in the<br />

Section 6.2, “The <strong>JBoss</strong> Naming Service Architecture”.<br />

An example of where the restricting a binding to the java: context is useful would be a<br />

javax.sql.DataSource connection factory that can only be used inside of the <strong>JBoss</strong> server where<br />

the associated database pool resides. On the other hand, an EJB home interface would be bound to a<br />

globally visible name that should accessible by remote client.<br />

6.6.1. ENC Usage Conventions<br />

JNDI is used as the API for externalizing a great deal of information from an application component. The<br />

JNDI name that the application component uses to access the information is declared in the standard<br />

ejb-jar.xml deployment descriptor for EJB components, and the standard web.xml deployment<br />

descriptor for Web components. Several different types of information may be stored in and retrieved<br />

from JNDI including:<br />

Environment entries as declared by the env-entry elements<br />

EJB references as declared by ejb-ref and ejb-local-ref elements.<br />

Resource manager connection factory references as declared by the resource-ref elements<br />

Resource environment references as declared by the resource-env-ref elements<br />

Each type of deployment descriptor element has a JNDI usage convention with regard to the name of the<br />

JNDI context under which the information is bound. Also, in addition to the standard<br />

deploymentdescriptor element, there is a <strong>JBoss</strong> server specific deployment descriptor element that<br />

maps the JNDI name as used by the application component to the deployment environment JNDI name.<br />

6.6.1.1. Environment Entries<br />

Environment entries are the simplest form of information stored in a component ENC, and are similar to<br />

operating system environment variables like those found on Unix or Windows. Environment entries are a<br />

name-to-value binding that allows a component to externalize a value and refer to the value using a<br />

name.<br />

An environment entry is declared using an env-entry element in the standard deployment descriptors.<br />

The env-entry element contains the following child elements:<br />

An optional description element that provides a description of the entry<br />

An env-entry-name element giving the name of the entry relative to java:comp/env<br />

An env-entry-type element giving the Java type of the entry value that must be one of:<br />

java.lang.Byte<br />

java.lang.Boolean<br />

java.lang.Character<br />

java.lang.Double<br />

java.lang.Float


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 4 3<br />

java.lang.Integer<br />

java.lang.Long<br />

java.lang.Short<br />

java.lang.String<br />

An env-entry-value element giving the value of entry as a string<br />

An example of an env-entry fragment from an ejb-jar.xml deployment descriptor is given in<br />

Example 6.5, “An example ejb-jar.xml env-entry fragment”. There is no <strong>JBoss</strong> specific deployment<br />

descriptor element because an env-entry is a complete name and value specification. Example 6.6,<br />

“ENC env-entry access code fragment” shows a sample code fragment for accessing the<br />

maxExemptions and taxRate and env-entry values declared in the deployment descriptor.<br />

Example 6.5. An example ejb-jar.xml env-entry fragment<br />

<br />

<br />

ASessionBean<br />

<br />

<br />

The maximum number of tax exemptions allowed <br />

maxExemptions<br />

java.lang.Integer<br />

15<br />

<br />

<br />

The tax rate <br />

taxRate<br />

java.lang.Float<br />

0.23<br />

<br />

<br />

<br />

Example 6.6. ENC env-entry access code fragment<br />

InitialContext iniCtx = new InitialContext();<br />

Context envCtx = (Context) iniCtx.lookup("java:comp/env");<br />

Integer maxExemptions = (Integer) envCtx.lookup("maxExemptions");<br />

Float taxRate = (Float) envCtx.lookup("taxRate");<br />

6.6.1.2. EJB References<br />

It is common for EJBs and Web components to interact with other EJBs. Because the JNDI name under<br />

which an EJB home interface is bound is a deployment time decision, there needs to be a way for a<br />

component developer to declare a reference to an EJB that will be linked by the deployer. EJB<br />

references satisfy this requirement.<br />

An EJB reference is a link in an application component naming environment that points to a deployed<br />

EJB home interface. The name used by the application component is a logical link that isolates the<br />

component from the actual name of the EJB home in the deployment environment. The J2EE<br />

specification recommends that all references to enterprise beans be organized in the<br />

java:comp/env/ejb context of the application component's environment.<br />

An EJB reference is declared using an ejb-ref element in the deployment descriptor. Each ejb-ref<br />

element describes the interface requirements that the referencing application component has for the<br />

referenced enterprise bean. The ejb-ref element contains the following child elements:<br />

An optional description element that provides the purpose of the reference.<br />

An ejb-ref-name element that specifies the name of the reference relative to the java:comp/env<br />

context. To place the reference under the recommended java:comp/env/ejb context, use an<br />

ejb/link-name form for the ejb-ref-name value.<br />

An ejb-ref-type element that specifies the type of the EJB. This must be either Entity or


4 4 Chapter 6. The JNDI Naming Service<br />

Session.<br />

A home element that gives the fully qualified class name of the EJB home interface.<br />

A remote element that gives the fully qualified class name of the EJB remote interface.<br />

An optional ejb-link element that links the reference to another enterprise bean in the same EJB<br />

JAR or in the same J2EE application unit. The ejb-link value is the ejb-name of the referenced<br />

bean. If there are multiple enterprise beans with the same ejb-name, the value uses the path name<br />

specifying the location of the ejb-jar file that contains the referenced component. The path name<br />

is relative to the referencing ejb-jar file. The <strong>Application</strong> Assembler appends the ejb-name of<br />

the referenced bean to the path name separated by #. This allows multiple beans with the same<br />

name to be uniquely identified.<br />

An EJB reference is scoped to the application component whose declaration contains the ejb-ref<br />

element. This means that the EJB reference is not accessible from other application components at<br />

runtime, and that other application components may define ejb-ref elements with the same ejb-refname<br />

without causing a name conflict. Example 6.7, “An example ejb-jar.xml ejb-ref descriptor fragment”<br />

provides an ejb-jar.xml fragment that illustrates the use of the ejb-ref element. A code sample<br />

that illustrates accessing the ShoppingCartHome reference declared in Example 6.7, “An example<br />

ejb-jar.xml ejb-ref descriptor fragment” is given in Example 6.8, “ENC ejb-ref access code fragment”.<br />

Example 6.7. An example ejb-jar.xml ejb-ref descriptor fragment<br />

<br />

<br />

ShoppingCartBean<br />

<br />

<br />

<br />

ProductBeanUser<br />

<br />

<br />

This is a reference to the store products entity<br />

<br />

ejb/ProductHome<br />

Entity<br />

org.jboss.store.ejb.ProductHome<br />

org.jboss.store.ejb.Product<br />

<br />

<br />

<br />

<br />

ShoppingCartUser<br />

<br />

ejb/ShoppingCartHome<br />

Session<br />

org.jboss.store.ejb.ShoppingCartHome<br />

org.jboss.store.ejb.ShoppingCart<br />

ShoppingCartBean<br />

<br />

<br />

<br />

The Product entity bean <br />

ProductBean<br />

<br />

<br />


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 4 5<br />

Example 6.8. ENC ejb-ref access code fragment<br />

InitialContext iniCtx = new InitialContext();<br />

Context ejbCtx = (Context) iniCtx.lookup("java:comp/env/ejb");<br />

ShoppingCartHome home = (ShoppingCartHome) ejbCtx.lookup("ShoppingCartHome");<br />

6.6.1.3. EJB References with jboss.xml and jboss-web.xml<br />

The <strong>JBoss</strong> specific jboss.xml EJB deployment descriptor affects EJB references in two ways. First,<br />

the jndi-name child element of the session and entity elements allows the user to specify the<br />

deployment JNDI name for the EJB home interface. In the absence of a jboss.xml specification of the<br />

jndi-name for an EJB, the home interface is bound under the ejb-jar.xmlejb-name value. For<br />

example, the session EJB with the ejb-name of ShoppingCartBean in Example 6.7, “An example<br />

ejb-jar.xml ejb-ref descriptor fragment” would have its home interface bound under the JNDI name<br />

ShoppingCartBean in the absence of a jboss.xmljndi-name specification.<br />

The second use of the jboss.xml descriptor with respect to ejb-refs is the setting of the<br />

destination to which a component's ENC ejb-ref refers. The ejb-link element cannot be used to<br />

refer to EJBs in another enterprise application. If your ejb-ref needs to access an external EJB, you<br />

can specify the JNDI name of the deployed EJB home using the jboss.xmlejb-ref/jndi-name<br />

element.<br />

The jboss-web.xml descriptor is used only to set the destination to which a Web application ENC<br />

ejb-ref refers. The content model for the <strong>JBoss</strong> ejb-ref is as follows:<br />

An ejb-ref-name element that corresponds to the ejb-ref-name element in the ejb-jar.xml or<br />

web.xml standard descriptor<br />

A jndi-name element that specifies the JNDI name of the EJB home interface in the deployment<br />

environment<br />

Example 6.9, “An example jboss.xml ejb-ref fragment” provides an example jboss.xml descriptor<br />

fragment that illustrates the following usage points:<br />

The ProductBeanUserejb-ref link destination is set to the deployment name of<br />

jboss/store/ProductHome<br />

The deployment JNDI name of the ProductBean is set to jboss/store/ProductHome<br />

Example 6.9. An example jboss.xml ejb-ref fragment<br />

<br />

<br />

ProductBeanUser<br />

<br />

ejb/ProductHome<br />

jboss/store/ProductHome<br />

<br />

<br />

<br />

ProductBean<br />

jboss/store/ProductHome<br />

<br />

<br />

<br />

6.6.1.4 . EJB Local References<br />

EJB 2.0 added local interfaces that do not use RMI call by value semantics. These interfaces use a call<br />

by reference semantic and therefore do not incur any RMI serialization overhead. An EJB local reference<br />

is a link in an application component naming environment that points to a deployed EJB local home<br />

interface. The name used by the application component is a logical link that isolates the component from


4 6 Chapter 6. The JNDI Naming Service<br />

the actual name of the EJB local home in the deployment environment. The J2EE specification<br />

recommends that all references to enterprise beans be organized in the java:comp/env/ejb context<br />

of the application component's environment.<br />

An EJB local reference is declared using an ejb-local-ref element in the deployment descriptor.<br />

Each ejb-local-ref element describes the interface requirements that the referencing application<br />

component has for the referenced enterprise bean. The ejb-local-ref element contains the<br />

following child elements:<br />

An optional description element that provides the purpose of the reference.<br />

An ejb-ref-name element that specifies the name of the reference relative to the java:comp/env<br />

context. To place the reference under the recommended java:comp/env/ejb context, use an<br />

ejb/link-name form for the ejb-ref-name value.<br />

An ejb-ref-type element that specifies the type of the EJB. This must be either Entity or<br />

Session.<br />

A local-home element that gives the fully qualified class name of the EJB local home interface.<br />

A local element that gives the fully qualified class name of the EJB local interface.<br />

An ejb-link element that links the reference to another enterprise bean in the ejb-jar file or in the<br />

same J2EE application unit. The ejb-link value is the ejb-name of the referenced bean. If there<br />

are multiple enterprise beans with the same ejb-name, the value uses the path name specifying the<br />

location of the ejb-jar file that contains the referenced component. The path name is relative to<br />

the referencing ejb-jar file. The <strong>Application</strong> Assembler appends the ejb-name of the referenced<br />

bean to the path name separated by #. This allows multiple beans with the same name to be<br />

uniquely identified. An ejb-link element must be specified in <strong>JBoss</strong> to match the local reference to<br />

the corresponding EJB.<br />

An EJB local reference is scoped to the application component whose declaration contains the ejblocal-ref<br />

element. This means that the EJB local reference is not accessible from other application<br />

components at runtime, and that other application components may define ejb-local-ref elements<br />

with the same ejb-ref-name without causing a name conflict. Example 6.10, “An example ejb-jar.xml<br />

ejb-local-ref descriptor fragment” provides an ejb-jar.xml fragment that illustrates the use of the<br />

ejb-local-ref element. A code sample that illustrates accessing the ProbeLocalHome reference<br />

declared in Example 6.10, “An example ejb-jar.xml ejb-local-ref descriptor fragment” is given in<br />

Example 6.11, “ENC ejb-local-ref access code fragment”.


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 4 7<br />

Example 6.10. An example ejb-jar.xml ejb-local-ref descriptor fragment<br />

<br />

<br />

Probe<br />

org.jboss.test.perf.interfaces.ProbeHome<br />

org.jboss.test.perf.interfaces.Probe<br />

org.jboss.test.perf.interfaces.ProbeLocalHome<br />

org.jboss.test.perf.interfaces.ProbeLocal<br />

org.jboss.test.perf.ejb.ProbeBean<br />

Stateless<br />

Bean<br />

<br />

<br />

PerfTestSession<br />

org.jboss.test.perf.interfaces.PerfTestSessionHome<br />

org.jboss.test.perf.interfaces.PerfTestSession<br />

org.jboss.test.perf.ejb.PerfTestSessionBean<br />

Stateless<br />

Container<br />

<br />

ejb/ProbeHome<br />

Session<br />

org.jboss.test.perf.interfaces.SessionHome<br />

org.jboss.test.perf.interfaces.Session<br />

Probe<br />

<br />

<br />

ejb/ProbeLocalHome<br />

Session<br />

org.jboss.test.perf.interfaces.ProbeLocalHome<br />

org.jboss.test.perf.interfaces.ProbeLocal<br />

Probe<br />

<br />

<br />

<br />

Example 6.11. ENC ejb-local-ref access code fragment<br />

InitialContext iniCtx = new InitialContext();<br />

Context ejbCtx = (Context) iniCtx.lookup("java:comp/env/ejb");<br />

ProbeLocalHome home = (ProbeLocalHome) ejbCtx.lookup("ProbeLocalHome");<br />

6.6.1.5. Resource Manager Connection Factory References<br />

Resource manager connection factory references allow application component code to refer to resource<br />

factories using logical names called resource manager connection factory references. Resource<br />

manager connection factory references are defined by the resource-ref elements in the standard<br />

deployment descriptors. The Deployer binds the resource manager connection factory references to<br />

the actual resource manager connection factories that exist in the target operational environment using<br />

the jboss.xml and jboss-web.xml descriptors.<br />

Each resource-ref element describes a single resource manager connection factory reference. The<br />

resource-ref element consists of the following child elements:<br />

An optional description element that provides the purpose of the reference.<br />

A res-ref-name element that specifies the name of the reference relative to the java:comp/env<br />

context. The resource type based naming convention for which subcontext to place the res-refname<br />

into is discussed in the next paragraph.<br />

A res-type element that specifies the fully qualified class name of the resource manager connection<br />

factory.<br />

A res-auth element that indicates whether the application component code performs resource<br />

signon programmatically, or whether the container signs on to the resource based on the principal


4 8 Chapter 6. The JNDI Naming Service<br />

mapping information supplied by the Deployer. It must be one of <strong>Application</strong> or Container.<br />

An optional res-sharing-scope element. This currently is not supported by <strong>JBoss</strong>.<br />

The J2EE specification recommends that all resource manager connection factory references be<br />

organized in the subcontexts of the application component's environment, using a different subcontext<br />

for each resource manager type. The recommended resource manager type to subcontext name is as<br />

follows:<br />

JDBC DataSource references should be declared in the java:comp/env/jdbc subcontext.<br />

JMS connection factories should be declared in the java:comp/env/jms subcontext.<br />

JavaMail connection factories should be declared in the java:comp/env/mail subcontext.<br />

URL connection factories should be declared in the java:comp/env/url subcontext.<br />

Example 6.12, “A web.xml resource-ref descriptor fragment” shows an example web.xml descriptor<br />

fragment that illustrates the resource-ref element usage. Example 6.13, “ENC resource-ref access<br />

sample code fragment” provides a code fragment that an application component would use to access<br />

the DefaultMail resource declared by the resource-ref.<br />

Example 6.12. A web.xml resource-ref descriptor fragment<br />

<br />

<br />

<br />

AServlet<br />

<br />

<br />

<br />

<br />

<br />

The default DS<br />

jdbc/DefaultDS<br />

javax.sql.DataSource<br />

Container<br />

<br />

<br />

<br />

Default Mail<br />

mail/DefaultMail<br />

javax.mail.Session<br />

Container<br />

<br />

<br />

<br />

Default QueueFactory<br />

jms/QueueFactory<br />

javax.jms.QueueConnectionFactory<br />

Container<br />

<br />

<br />

Example 6.13. ENC resource-ref access sample code fragment<br />

Context initCtx = new InitialContext();<br />

javax.mail.Session s = (javax.mail.Session)<br />

initCtx.lookup("java:comp/env/mail/DefaultMail");<br />

6.6.1.6. Resource Manager Connection Factory References with jboss.xml and jboss-web.xml<br />

The purpose of the <strong>JBoss</strong> jboss.xml EJB deployment descriptor and jboss-web.xml Web<br />

application deployment descriptor is to provide the link from the logical name defined by the res-refname<br />

element to the JNDI name of the resource factory as deployed in <strong>JBoss</strong>. This is accomplished by<br />

providing a resource-ref element in the jboss.xml or jboss-web.xml descriptor. The <strong>JBoss</strong><br />

resource-ref element consists of the following child elements:


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 4 9<br />

A res-ref-name element that must match the res-ref-name of a corresponding resource-ref<br />

element from the ejb-jar.xml or web.xml standard descriptors<br />

An optional res-type element that specifies the fully qualified class name of the resource manager<br />

connection factory<br />

A jndi-name element that specifies the JNDI name of the resource factory as deployed in <strong>JBoss</strong><br />

A res-url element that specifies the URL string in the case of a resource-ref of type<br />

java.net.URL<br />

Example 6.14, “A sample jboss-web.xml resource-ref descriptor fragment” provides a sample jbossweb.xml<br />

descriptor fragment that shows sample mappings of the resource-ref elements given in<br />

Example 6.12, “A web.xml resource-ref descriptor fragment”.<br />

Example 6.14 . A sample jboss-web.xml resource-ref descriptor fragment<br />

<br />

<br />

<br />

jdbc/DefaultDS<br />

javax.sql.DataSource<br />

java:/DefaultDS<br />

<br />

<br />

mail/DefaultMail<br />

javax.mail.Session<br />

java:/Mail<br />

<br />

<br />

jms/QueueFactory<br />

javax.jms.QueueConnectionFactory<br />

QueueConnectionFactory<br />

<br />

<br />

<br />

6.6.1.7. Resource Environment References<br />

Resource environment references are elements that refer to administered objects that are associated<br />

with a resource (for example, JMS destinations) using logical names. Resource environment references<br />

are defined by the resource-env-ref elements in the standard deployment descriptors. The<br />

Deployer binds the resource environment references to the actual administered objects location in the<br />

target operational environment using the jboss.xml and jboss-web.xml descriptors.<br />

Each resource-env-ref element describes the requirements that the referencing application<br />

component has for the referenced administered object. The resource-env-ref element consists of<br />

the following child elements:<br />

An optional description element that provides the purpose of the reference.<br />

A resource-env-ref-name element that specifies the name of the reference relative to the<br />

java:comp/env context. Convention places the name in a subcontext that corresponds to the<br />

associated resource factory type. For example, a JMS queue reference named MyQueue should have<br />

a resource-env-ref-name of jms/MyQueue.<br />

A resource-env-ref-type element that specifies the fully qualified class name of the referenced<br />

object. For example, in the case of a JMS queue, the value would be javax.jms.Queue.<br />

Example 6.15, “An example ejb-jar.xml resource-env-ref fragment” provides an example resourceref-env<br />

element declaration by a session bean. Example 6.16, “ENC resource-env-ref access code<br />

fragment” gives a code fragment that illustrates how to look up the StockInfo queue declared by the<br />

resource-env-ref.


50 Chapter 6. The JNDI Naming Service<br />

Example 6.15. An example ejb-jar.xml resource-env-ref fragment<br />

<br />

MyBean<br />

<br />

<br />

This is a reference to a JMS queue used in the<br />

processing of Stock info<br />

<br />

jms/StockInfo<br />

javax.jms.Queue<br />

<br />

<br />

<br />

Example 6.16. ENC resource-env-ref access code fragment<br />

InitialContext iniCtx = new InitialContext();<br />

javax.jms.Queue q = (javax.jms.Queue)<br />

envCtx.lookup("java:comp/env/jms/StockInfo");<br />

6.6.1.8. Resource Environment References and jboss.xml, jboss-web.xml<br />

The purpose of the <strong>JBoss</strong> jboss.xml EJB deployment descriptor and jboss-web.xml Web<br />

application deployment descriptor is to provide the link from the logical name defined by the resourceenv-ref-name<br />

element to the JNDI name of the administered object deployed in <strong>JBoss</strong>. This is<br />

accomplished by providing a resource-env-ref element in the jboss.xml or jboss-web.xml<br />

descriptor. The <strong>JBoss</strong> resource-env-ref element consists of the following child elements:<br />

A resource-env-ref-name element that must match the resource-env-ref-name of a<br />

corresponding resource-env-ref element from the ejb-jar.xml or web.xml standard<br />

descriptors<br />

A jndi-name element that specifies the JNDI name of the resource as deployed in <strong>JBoss</strong><br />

Example 6.17, “A sample jboss.xml resource-env-ref descriptor fragment” provides a sample<br />

jboss.xml descriptor fragment that shows a sample mapping for the StockInforesource-envref.<br />

Example 6.17. A sample jboss.xml resource-env-ref descriptor fragment<br />

<br />

MyBean<br />

<br />

<br />

jms/StockInfo<br />

queue/StockInfoQueue<br />

<br />

<br />


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 51<br />

Chapter 7. Web Services<br />

Web services are a key contributing factor in the way Web commerce is conducted today. Web services<br />

enable applications to communicate by sending small and large chunks of data to each other.<br />

A web service is essentially a software application that supports interaction of applications over a<br />

computer network or the world wide web. Web services usually interact through XML documents that<br />

map to an object, computer program, business process or database. To communicate, an application<br />

sends a message in XML document format to a web service which sends this message to the respective<br />

programs. Responses may be received based on requirements, the web service receives and then<br />

sends them in XML document format to the required program or applications. Web services can be used<br />

in many ways, examples include supply chain information management and business integration.<br />

<strong>JBoss</strong>WS is a web service framework included as part of the <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>. It<br />

implements the JAX-WS specification that defines a programming model and run-time architecture for<br />

implementing web services in Java, targeted at the Java <strong>Platform</strong>, <strong>Enterprise</strong> Edition 5 (Java EE 5). Even<br />

though JAX-RPC is still supported (the web service specification for J2EE 1.4), <strong>JBoss</strong>WS does put a<br />

clear focus on JAX-WS.<br />

Warning<br />

JAX-RPC is not supported for <strong>JBoss</strong> Web Services CXF Stack.<br />

7.1. The need for web services<br />

<strong>Enterprise</strong> systems communication may benefit from a wise adoption of web service technologies.<br />

Focusing attention on well designed contracts allows developers to establish an abstract view of their<br />

service capabilities. Considering the standardized way contracts are written, this definitely helps<br />

communication with third-party systems and eventually supports business-to-business integration;<br />

everything is clear and standardized in the contract the provider and consumer agree on. This also<br />

reduces the dependencies between implementations allowing other consumers to easily use the<br />

provided service without major changes.<br />

Other benefits exist for enterprise systems that incorporate web service technologies for internal<br />

heterogenous subsystems communication as web service interoperability boosts service reuse and<br />

composition. Web services eliminates the need to rewrite whole functionalities because they were<br />

developed by another enterprise department using a different software language.<br />

7.2. What web services are not<br />

Web services are not the solution for every software system communication.<br />

Nowadays they are meant to be used for loosely-coupled coarse-grained communication, message<br />

(document) exchange. Recent times has seen many specifications (WS-*) discussed and finally<br />

approved to establish standardized ws-related advanced aspects, including reliable messaging,<br />

message-level security and cross-service transactions. Web service specifications also include the<br />

notion of registries to collect service contract references, to easily discover service implementations.<br />

This all means that the web services technology platform suits complex enterprise communication and is<br />

not simply the latest way of doing remote procedure calls.<br />

7.3. Document/Literal<br />

With document style web services two business partners agree on the exchange of complex business<br />

documents that are well defined in XML schema. For example, one party sends a document describing a<br />

purchase order, the other responds (immediately or later) with a document that describes the status of<br />

the purchase order. The payload of the SOAP message is an XML document that can be validated<br />

against XML schema. The document is defined by the style attribute on the SOAP binding.


52 Chapter 7. Web Services<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

With document style web services the payload of every message is defined by a complex type in XML<br />

schema.<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Therefore, message parts must refer to an element from the schema.<br />

<br />

<br />

<br />

The following message definition is invalid.<br />

<br />

<br />

<br />

7.4. Document/Literal (Bare)<br />

Bare is an implementation detail from the Java domain. Neither in the abstract contract (for instance,<br />

wsdl+schema) nor at the SOAP message level is a bare endpoint recognizable. A bare endpoint or client<br />

uses a Java bean that represents the entire document payload.<br />

@WebService<br />

@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)<br />

public class DocBareServiceImpl<br />

{<br />

@WebMethod<br />

public SubmitBareResponse submitPO(SubmitBareRequest poRequest)<br />

{<br />

...<br />

}<br />

}<br />

The trick is that the Java beans representing the payload contain JAXB annotations that define how the<br />

payload is represented on the wire.


@XmlAccessorType(XmlAccessType.FIELD)<br />

@XmlType(name = "SubmitBareRequest",<br />

namespace="http://soapbinding.samples.jaxws.ws.test.jboss.org/", propOrder = {<br />

"product" })<br />

@XmlRootElement(namespace="http://soapbinding.samples.jaxws.ws.test.jboss.org/",<br />

name = "SubmitPO")<br />

public class SubmitBareRequest<br />

{<br />

@XmlElement(namespace="http://soapbinding.samples.jaxws.ws.test.jboss.org/",<br />

required = true)<br />

private String product;<br />

}<br />

...<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 53<br />

7.5. Document/Literal (Wrapped)<br />

Wrapped is an implementation detail from the Java domain. Neither in the abstract contract (for instance,<br />

wsdl+schema) nor at the SOAP message level is a wrapped endpoint recognizable. A wrapped endpoint<br />

or client uses the individual document payload properties. Wrapped is the default and does not have to<br />

be declared explicitly.<br />

@WebService<br />

public class DocWrappedServiceImpl<br />

{<br />

@WebMethod<br />

@RequestWrapper (className="org.somepackage.SubmitPO")<br />

@ResponseWrapper (className="org.somepackage.SubmitPOResponse")<br />

public String submitPO(String product, int quantity)<br />

{<br />

...<br />

}<br />

}<br />

Note<br />

With <strong>JBoss</strong>WS the request and response wrapper annotations are not required, they will be<br />

generated on demand using sensible defaults.<br />

7.6. RPC/Literal<br />

With RPC there is a wrapper element that names the endpoint operation. Child elements of the RPC<br />

parent are the individual parameters. The SOAP body is constructed based on some simple rules:<br />

The port type operation name defines the endpoint method name<br />

Message parts are endpoint method parameters<br />

RPC is defined by the style attribute on the SOAP binding.<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

With RPC style web services the portType names the operation (i.e. the java method on the endpoint)


54 Chapter 7. Web Services<br />

<br />

<br />

<br />

<br />

<br />

<br />

Operation parameters are defined by individual message parts.<br />

<br />

<br />

<br />

<br />

<br />

<br />

Note<br />

There is no complex type in XML schema that could validate the entire SOAP message payload.<br />

@WebService<br />

@SOAPBinding(style = SOAPBinding.Style.RPC)<br />

public class JSEBean01<br />

{<br />

@WebMethod<br />

@WebResult(name="result")<br />

public String echo(@WebParam(name="String_1") String input)<br />

{<br />

...<br />

}<br />

}<br />

The element names of RPC parameters/return values may be defined using the JAX-WS<br />

Annotations#javax.jws.WebParam and JAX-WS Annotations#javax.jws.WebResult respectively.<br />

7.7. RPC/Encoded<br />

SOAP encoding style is defined by chapter 5 of the SOAP-1.1 specification. It has inherent<br />

interoperability issues that cannot be fixed. The Basic Profile-1.0 prohibits this encoding style in 4.1.7<br />

SOAP encodingStyle Attribute. <strong>JBoss</strong>WS has basic support for RPC/Encoded that is provided as is for<br />

simple interop scenarios with SOAP stacks that do not support literal encoding. Specifically, <strong>JBoss</strong>WS<br />

does not support:-<br />

element references<br />

soap arrays as bean properties<br />

Note<br />

This section should not be used in conjuction with <strong>JBoss</strong> Web Services CXF Stack.<br />

7.8. Web Service Endpoints<br />

JAX-WS simplifies the development model for a web service endpoint a great deal. In short, an endpoint<br />

implementation bean is annotated with JAX-WS annotations and deployed to the server. The server<br />

automatically generates and publishes the abstract contract (for instance, wsdl+schema) for client<br />

consumption. All marshalling/unmarshalling is delegated to JAXB.<br />

7.9. Plain old Java Object (POJO)<br />

Let us take a look at simple POJO endpoint implementation. All endpoint associated metadata are<br />

provided via JSR-181 annotations


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 55<br />

@WebService<br />

@SOAPBinding(style = SOAPBinding.Style.RPC)<br />

public class JSEBean01<br />

{<br />

@WebMethod<br />

public String echo(String input)<br />

{<br />

...<br />

}<br />

}<br />

7.10. The endpoint as a web application<br />

A JAX-WS java service endpoint (JSE) is deployed as a web application.<br />

<br />

<br />

TestService<br />

org.jboss.test.ws.jaxws.samples.jsr181pojo.JSEBean01<br />

<br />

<br />

TestService<br />

/*<br />

<br />

<br />

7.11. Packaging the endpoint<br />

A JSR-181 java service endpoint (JSE) is packaged as a web application in a *.war file.<br />

<br />

<br />

<br />

<br />

<br />

Note<br />

Only the endpoint implementation bean and web.xml file are required.<br />

7.12. Accessing the generated WSDL<br />

A successfully deployed service endpoint will show up in the service endpoint manager. This is also<br />

where you find the links to the generated WSDL.<br />

http://yourhost:8080/jbossws/services<br />

It is also possible to generate the abstract contract off line using jboss tools. For details of that see Top<br />

Down (Using wsconsume)<br />

7.13. EJB3 Stateless Session Bean (SLSB)<br />

The JAX-WS programming model support the same set of annotations on EJB3 stateless session<br />

beans as on Plain old Java Object (POJO) endpoints. EJB-2.1 endpoints are supported using the JAX-<br />

RPC progamming model.


56 Chapter 7. Web Services<br />

@Stateless<br />

@Remote(EJB3RemoteInterface.class)<br />

@RemoteBinding(jndiBinding = "/ejb3/EJB3EndpointInterface")<br />

@WebService<br />

@SOAPBinding(style = SOAPBinding.Style.RPC)<br />

public class EJB3Bean01 implements EJB3RemoteInterface<br />

{<br />

@WebMethod<br />

public String echo(String input)<br />

{<br />

...<br />

}<br />

}<br />

Above you see an EJB-3.0 stateless session bean that exposes one method both on the remote<br />

interface and as an endpoint operation.<br />

Packaging the endpoint<br />

A JSR-181 EJB service endpoint is packaged as an ordinary ejb deployment.<br />

<br />

<br />

<br />

<br />

<br />

<br />

Accessing the generated WSDL<br />

A successfully deployed service endpoint will show up in the service endpoint manager. This is also<br />

where you will find the links to the generated WSDL.<br />

http://yourhost:8080/jbossws/services<br />

It is also possible to generate the abstract contract offline using JbossWS tools. For details of that<br />

please see Top Down (Using wsconsume)<br />

7.14. Endpoint Provider<br />

JAX-WS services typically implement a native Java service endpoint interface (SEI), perhaps mapped<br />

from a WSDL port type, either directly or via the use of annotations.<br />

Java SEIs provide a high level Java-centric abstraction that hides the details of converting between Java<br />

objects and their XML representations for use in XML-based messages. However, in some cases it is<br />

desirable for services to be able to operate at the XML message level. The Provider interface offers an<br />

alternative to SEIs and may be implemented by services wishing to work at the XML message level.<br />

A Provider based service instance’s invoke method is called for each message received for the service.<br />

@WebServiceProvider<br />

@ServiceMode(value = Service.Mode.PAYLOAD)<br />

public class ProviderBeanPayload implements Provider<br />

{<br />

public Source invoke(Source req)<br />

{<br />

// Access the entire request PAYLOAD and return the response PAYLOAD<br />

}<br />

}<br />

Service.Mode.PAYLOAD is the default and does not have to be declared explicitly. You can also use<br />

Service.Mode.MESSAGE to access the entire SOAP message (for example, with MESSAGE the Provider<br />

can also see SOAP Headers)


7.15. WebServiceContext<br />

The WebServiceContext is treated as an injectable resource that can be set at the time an endpoint<br />

is initialized. The WebServiceContext object will then use thread-local information to return the<br />

correct information regardless of how many threads are concurrently being used to serve requests<br />

addressed to the same endpoint object.<br />

@WebService<br />

public class EndpointJSE<br />

{<br />

@Resource<br />

WebServiceContext wsCtx;<br />

@WebMethod<br />

public String testGetMessageContext()<br />

{<br />

SOAPMessageContext jaxwsContext =<br />

(SOAPMessageContext)wsCtx.getMessageContext();<br />

return jaxwsContext != null ? "pass" : "fail";<br />

}<br />

...<br />

@WebMethod<br />

public String testGetUserPrincipal()<br />

{<br />

Principal principal = wsCtx.getUserPrincipal();<br />

return principal.getName();<br />

}<br />

}<br />

@WebMethod<br />

public boolean testIsUserInRole(String role)<br />

{<br />

return wsCtx.isUserInRole(role);<br />

}<br />

7.16. Web Service Clients<br />

7.16.1. Service<br />

Service is an abstraction that represents a WSDL service. A WSDL service is a collection of related<br />

ports, each of which consists of a port type bound to a particular protocol and available at a particular<br />

endpoint address.<br />

For most clients, you will start with a set of stubs generated from the WSDL. One of these will be the<br />

service, and you will create objects of that class in order to work with the service (see "static case"<br />

below).<br />

7.16.1.1. Service Usage<br />

Static case<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 57<br />

Most clients will start with a WSDL file, and generate some stubs using jbossws tools like wsconsume.<br />

This usually gives a mass of files, one of which is the top of the tree. This is the service implementation<br />

class.<br />

The generated implementation class can be recognised as it will have two public constructors, one with<br />

no arguments and one with two arguments, representing the wsdl location (a java.net.URL) and the<br />

service name (a javax.xml.namespace.QName) respectively.<br />

Usually you will use the no-argument constructor. In this case the WSDL location and service name are<br />

those found in the WSDL. These are set implicitly from the WebServiceClient annotation that decorates<br />

the generated class.<br />

The following code snippet shows the generated constructors from the generated class:


58 Chapter 7. Web Services<br />

// Generated Service Class<br />

@WebServiceClient(name="StockQuoteService",<br />

targetNamespace="http://example.com/stocks",<br />

wsdlLocation="http://example.com/stocks.wsdl")<br />

public class StockQuoteService extends javax.xml.ws.Service<br />

{<br />

public StockQuoteService()<br />

{<br />

super(new URL("http://example.com/stocks.wsdl"), new<br />

QName("http://example.com/stocks", "StockQuoteService"));<br />

}<br />

}<br />

public StockQuoteService(String wsdlLocation, QName serviceName)<br />

{<br />

super(wsdlLocation, serviceName);<br />

}<br />

...<br />

Section Dynamic Proxy explains how to obtain a port from the service and how to invoke an operation on<br />

the port. If you need to work with the XML payload directly or with the XML representation of the entire<br />

SOAP message, have a look at Dispatch.<br />

Dynamic case<br />

In the dynamic case, when nothing is generated, a web service client uses Service.create to create<br />

Service instances, the following code illustrates this process.<br />

URL wsdlLocation = new URL("http://example.org/my.wsdl");<br />

QName serviceName = new QName("http://example.org/sample", "MyService");<br />

Service service = Service.create(wsdlLocation, serviceName);<br />

This is not the recommended way to use <strong>JBoss</strong>WS.<br />

7.16.1.2. Handler Resolver<br />

JAX-WS provides a flexible plug-in framework for message processing modules, known as handlers, that<br />

may be used to extend the capabilities of a JAX-WS runtime system. Handler Framework describes the<br />

handler framework in detail. A Service instance provides access to a HandlerResolver via a pair of<br />

getHandlerResolver and setHandlerResolver methods that may be used to configure a set of<br />

handlers on a per-service, per-port or per-protocol binding basis.<br />

When a Service instance is used to create a proxy or a Dispatch instance then the handler resolver<br />

currently registered with the service is used to create the required handler chain. Subsequent changes<br />

to the handler resolver configured for a Service instance do not affect the handlers on previously<br />

created proxies, or Dispatch instances.<br />

7.16.1.3. Executor<br />

Service instances can be configured with a java.util.concurrent.Executor. The executor will<br />

then be used to invoke any asynchronous callbacks requested by the application. The setExecutor<br />

and getExecutor methods of Service can be used to modify and retrieve the executor configured for<br />

a service.<br />

7.16.2. Dynamic Proxy<br />

You can create an instance of a client proxy using one of getPort methods on the Service .


**<br />

* The getPort method returns a proxy. A service client<br />

* uses this proxy to invoke operations on the target<br />

* service endpoint. The serviceEndpointInterface<br />

* specifies the service endpoint interface that is supported by<br />

* the created dynamic proxy instance.<br />

*/<br />

public T getPort(QName portName, Class serviceEndpointInterface)<br />

{<br />

...<br />

}<br />

/**<br />

* The getPort method returns a proxy. The parameter<br />

* serviceEndpointInterface specifies the service<br />

* endpoint interface that is supported by the returned proxy.<br />

* In the implementation of this method, the JAX-WS<br />

* runtime system takes the responsibility of selecting a protocol<br />

* binding (and a port) and configuring the proxy accordingly.<br />

* The returned proxy should not be reconfigured by the client.<br />

*<br />

*/<br />

public T getPort(Class serviceEndpointInterface)<br />

{<br />

...<br />

}<br />

The Service Endpoint Interface (SEI) is usually generated using tools. For details see Top Down (Using<br />

wsconsume).<br />

A generated static Service usually also offers typed methods to get ports. These methods also return<br />

dynamic proxies that implement the SEI.<br />

@WebServiceClient(name = "TestEndpointService", targetNamespace =<br />

"http://org.jboss.ws/wsref",<br />

wsdlLocation = "http://localhost.localdomain:8080/jaxws-samples-webserviceref?<br />

wsdl")<br />

public class TestEndpointService extends Service<br />

{<br />

...<br />

}<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 59<br />

public TestEndpointService(URL wsdlLocation, QName serviceName) {<br />

super(wsdlLocation, serviceName);<br />

}<br />

@WebEndpoint(name = "TestEndpointPort")<br />

public TestEndpoint getTestEndpointPort()<br />

{<br />

return (TestEndpoint)super.getPort(TESTENDPOINTPORT, TestEndpoint.class);<br />

}<br />

7.16.3. WebServiceRef<br />

The WebServiceRef annotation is used to declare a reference to a Web service. It follows the<br />

resource pattern exemplified by the javax.annotation.Resource annotation in JSR-250 [5]<br />

There are two uses to the WebServiceRef annotation:<br />

1. To define a reference whose type is a generated service class. In this case, the type and value<br />

element will both refer to the generated service class type. Moreover, if the reference type can be<br />

inferred by the field or method declaration then the annotation is applied to the type, and value<br />

elements may have the default value (Object.class, that is). If the type cannot be inferred, then<br />

at least the type element must be present with a non-default value.<br />

2. To define a reference whose type is a SEI. In this case, the type element may be present with its<br />

default value if the type of the reference can be inferred from the annotated field and method<br />

declaration, but the value element must always be present and refer to a generated service class<br />

type (a subtype of javax.xml.ws.Service). The wsdlLocation element, if present, overrides<br />

theWSDL location information specified in the WebService annotation of the referenced<br />

generated service class.


60 Chapter 7. Web Services<br />

public class EJB3Client implements EJB3Remote<br />

{<br />

@WebServiceRef<br />

public TestEndpointService service4;<br />

}<br />

@WebServiceRef<br />

public TestEndpoint port3;<br />

WebServiceRef Customization<br />

In <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5.0 we offer a number of overrides and extensions to the<br />

WebServiceRef annotation. These include:<br />

define the port that should be used to resolve a container-managed port<br />

define default Stub property settings for Stub objects<br />

define the URL of a final WSDL document to be used<br />

Example:<br />

<br />

OrganizationService<br />

file:/wsdlRepository/organization-service.wsdl<br />

<br />

..<br />

<br />

OrganizationService<br />

Secure Client Config<br />

META-INF/jbossws-client-config.xml<br />

META-INF/jbossws-client-handlers.xml<br />

<br />

<br />

SecureService<br />

org.jboss.tests.ws.jaxws.webserviceref.SecureEndpointService<br />

{http://org.jboss.ws/wsref}SecureEndpointService<br />

<br />

org.jboss.tests.ws.jaxws.webserviceref.SecureEndpoint<br />

{http://org.jboss.ws/wsref}SecureEndpointPort<br />

<br />

javax.xml.ws.security.auth.username<br />

kermit<br />

<br />

<br />

javax.xml.ws.security.auth.password<br />

thefrog<br />

<br />

<br />

<br />

7.16.4 . Dispatch<br />

XML Web Services use XML messages for communication between services and service clients. The<br />

higher level JAX-WS APIs are designed to hide the details of converting between Java method<br />

invocations and the corresponding XML messages, but in some cases operating at the XML message<br />

level is desirable. The Dispatch interface provides support for this mode of interaction.<br />

Dispatch supports two usage modes, identified by the constants javax.xml.ws.Service.Mode.MESSAGE<br />

and javax.xml.ws.Service.Mode.PAYLOAD respectively:<br />

Message<br />

In this mode, client applications work directly with protocol-specific message structures. For example,<br />

when used with a SOAP protocol binding, a client application would work directly with a SOAP message.


Message Payload<br />

In this mode, client applications work with the payload of messages rather than the messages<br />

themselves. For example, when used with a SOAP protocol binding, a client application would work with<br />

the contents of the SOAP Body rather than the SOAP message as a whole.<br />

Dispatch is a low level API that requires clients to construct messages or message payloads as XML<br />

and requires an intimate knowledge of the desired message or payload structure. Dispatch is a generic<br />

class that supports input and output of messages or message payloads of any type.<br />

Service service = Service.create(wsdlURL, serviceName);<br />

Dispatch dispatch = service.createDispatch(portName, StreamSource.class,<br />

Mode.PAYLOAD);<br />

String payload = "";<br />

dispatch.invokeOneWay(new StreamSource(new StringReader(payload)));<br />

payload = "";<br />

Source retObj = (Source)dispatch.invoke(new StreamSource(new<br />

StringReader(payload)));<br />

7.16.5. Asynchronous Invocations<br />

The BindingProvider interface represents a component that provides a protocol binding for use by<br />

clients, it is implemented by proxies and is extended by the Dispatch interface.<br />

BindingProvider instances may provide asynchronous operation capabilities. When used,<br />

asynchronous operation invocations are decoupled from the BindingProvider instance at invocation<br />

time such that the response context is not updated when the operation completes. Instead a separate<br />

response context is made available using the Response interface.<br />

public void testInvokeAsync() throws Exception<br />

{<br />

URL wsdlURL = new URL("http://" + getServerHost() + ":8080/jaxws-samplesasynchronous?wsdl");<br />

QName serviceName = new QName(targetNS, "TestEndpointService");<br />

Service service = Service.create(wsdlURL, serviceName);<br />

TestEndpoint port = service.getPort(TestEndpoint.class);<br />

}<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 61<br />

Response response = port.echoAsync("Async");<br />

// access future<br />

String retStr = (String) response.get();<br />

assertEquals("Async", retStr);<br />

7.16.6. Oneway Invocations<br />

@Oneway indicates that the given web method has only an input message and no output. Typically, a<br />

one-way method returns the thread of control to the calling application prior to executing the actual<br />

business method.


62 Chapter 7. Web Services<br />

@WebService (name="PingEndpoint")<br />

@SOAPBinding(style = SOAPBinding.Style.RPC)<br />

public class PingEndpointImpl<br />

{<br />

private static String feedback;<br />

...<br />

@WebMethod<br />

@Oneway<br />

public void ping()<br />

{<br />

log.info("ping");<br />

feedback = "ok";<br />

}<br />

...<br />

@WebMethod<br />

public String feedback()<br />

{<br />

log.info("feedback");<br />

return feedback;<br />

}<br />

}<br />

7.17. <strong>Common</strong> API<br />

This sections describes concepts that apply equally to Web Service Endpoints and Web Service Clients<br />

7.17.1. Handler Framework<br />

The handler framework is implemented by a JAX-WS protocol binding in both client and server side<br />

runtimes. Proxies, and Dispatch instances, known collectively as binding providers, each use protocol<br />

bindings to bind their abstract functionality to specific protocols.<br />

Client and server-side handlers are organized into an ordered list known as a handler chain. The<br />

handlers within a handler chain are invoked each time a message is sent or received. Inbound<br />

messages are processed by handlers prior to binding provider processing. Outbound messages are<br />

processed by handlers after any binding provider processing.<br />

Handlers are invoked with a message context that provides methods to access and modify inbound and<br />

outbound messages and to manage a set of properties. Message context properties may be used to<br />

facilitate communication between individual handlers and between handlers and client and service<br />

implementations. Different types of handlers are invoked with different types of message context.<br />

7.17.1.1. Logical Handler<br />

Handlers that only operate on message context properties and message payloads. Logical handlers are<br />

protocol agnostic and are unable to affect protocol specific parts of a message. Logical handlers are<br />

handlers that implement javax.xml.ws.handler.LogicalHandler.<br />

7.17.1.2. Protocol Handler<br />

Handlers that operate on message context properties and protocol specific messages. Protocol<br />

handlers are specific to a particular protocol and may access and change protocol specific aspects of a<br />

message. Protocol handlers are handlers that implement any interface derived from<br />

javax.xml.ws.handler.Handler except javax.xml.ws.handler.LogicalHandler.<br />

7.17.1.3. Service endpoint handlers<br />

On the service endpoint, handlers are defined using the @HandlerChain annotation.<br />

@WebService<br />

@HandlerChain(file = "jaxws-server-source-handlers.xml")<br />

public class SOAPEndpointSourceImpl<br />

{<br />

...<br />

}<br />

The location of the handler chain file supports 2 formats


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 63<br />

1. An absolute java.net.URL in externalForm. (ex: http://myhandlers.foo.com/handlerfile1.xml)<br />

2. A relative path from the source file or class file. (ex: bar/handlerfile1.xml)<br />

7.17.1.4 . Service client handlers<br />

On the client side, handler can be configured using the @HandlerChain annotation on the SEI or<br />

dynamically using the API.<br />

Service service = Service.create(wsdlURL, serviceName);<br />

Endpoint port = (Endpoint)service.getPort(Endpoint.class);<br />

BindingProvider bindingProvider = (BindingProvider)port;<br />

List handlerChain = new ArrayList();<br />

handlerChain.add(new LogHandler());<br />

handlerChain.add(new AuthorizationHandler());<br />

handlerChain.add(new RoutingHandler());<br />

bindingProvider.getBinding().setHandlerChain(handlerChain); // important!<br />

7.17.2. Message Context<br />

MessageContext is the super interface for all JAX-WS message contexts. It extends Map<br />

with additional methods and constants to manage a set of properties that enable handlers in a handler<br />

chain to share processing related state. For example, a handler may use the put method to insert a<br />

property in the message context that one or more other handlers in the handler chain may subsequently<br />

obtain via the get method.<br />

Properties are scoped as either APPLICATION or HANDLER. All properties are available to all handlers<br />

associated with particular endpoint. E.g., if a logical handler puts a property in the message context, that<br />

property will also be available to any protocol handlers in the chain during the execution. APPLICATION<br />

scoped properties are also made available to client applications and service endpoint implementations.<br />

The default scope for a property is HANDLER.<br />

7.17.2.1. Accessing the message context<br />

Users can access the message context in handlers or in endpoints via @WebServiceContext<br />

annotation.<br />

7.17.2.2. Logical Message Context<br />

LogicalMessageContext is passed to Logical Handlers at invocation time. LogicalMessageContext<br />

extends MessageContext with methods to obtain and modify the message payload, it does not provide<br />

access to the protocol specific aspects of a message. A protocol binding defines what component of a<br />

message are available via a logical message context. The SOAP binding defines that a logical handler<br />

deployed in a SOAP binding can access the contents of the SOAP body but not the SOAP headers<br />

whereas the XML/HTTP binding defines that a logical handler can access the entire XML payload of a<br />

message.<br />

7.17.2.3. SOAP Message Context<br />

SOAPMessageContext is passed to SOAP handlers at invocation time. SOAPMessageContext<br />

extends MessageContext with methods to obtain and modify the SOAP message payload.<br />

7.17.3. Fault Handling<br />

An implementation may throw a SOAPFaultException<br />

public void throwSoapFaultException()<br />

{<br />

SOAPFactory factory = SOAPFactory.newInstance();<br />

SOAPFault fault = factory.createFault("this is a fault string!", new<br />

QName("http://foo", "FooCode"));<br />

fault.setFaultActor("mr.actor");<br />

fault.addDetail().addChildElement("test");<br />

throw new SOAPFaultException(fault);<br />

}<br />

or an application specific user exception


64 Chapter 7. Web Services<br />

public void throw<strong>Application</strong>Exception() throws UserException<br />

{<br />

throw new UserException("validation", 123, "Some validation error");<br />

}<br />

Note<br />

In case of the latter <strong>JBoss</strong>WS generates the required fault wrapper beans at runtime if they are<br />

not part of the deployment<br />

7.18. DataBinding<br />

7.18.1. Using JAXB with non annotated classes<br />

JAXB is heavily driven by Java Annotations on the Java Bindings. It currently doesn't support an external<br />

binding configuration.<br />

In order to support this, we built on a JAXB RI feature whereby it allows you to specify a<br />

RuntimeInlineAnnotationReader implementation during JAXBContext creation (see JAXBRIContext).<br />

We call this feature "JAXB Annotation Introduction" and we've made it available for general consumption<br />

i.e. it can be checked out, built and used from SVN:<br />

http://anonsvn.jboss.org/repos/jbossws/projects/jaxbintros/<br />

Complete documentation can be found here:<br />

JAXB Introductions<br />

7.19. Attachments<br />

<strong>JBoss</strong>-WS4EE relied on a deprecated attachments technology called SwA (SOAP with Attachments).<br />

SwA required soap/encoding which is disallowed by the WS-I Basic Profile. <strong>JBoss</strong>WS provides support<br />

for WS-I AP 1.0, and MTOM instead.<br />

7.19.1. MTOM/XOP<br />

This section describes Message Transmission Optimization Mechanism (MTOM) and XML-binary<br />

Optimized Packaging (XOP), a means of more efficiently serializing XML Infosets that have certain types<br />

of content. The related specifications are<br />

SOAP Message Transmission Optimization Mechanism (MTOM)<br />

XML-binary Optimized Packaging (XOP)<br />

7.19.1.1. Supported MTOM parameter types<br />

image/jpeg java.awt.Image<br />

text/xml javax.xml.transform.Source<br />

application/xml javax.xml.transform.Source<br />

application/octet-stream javax.activation.DataHandler<br />

The above table shows a list of supported endpoint parameter types. The recommended approach is to<br />

use the javax.activation.DataHandler classes to represent binary data as service endpoint parameters.<br />

Note<br />

Microsoft endpoints tend to send any data as application/octet-stream. The only Java type that<br />

can easily cope with this ambiguity is javax.activation.DataHandler<br />

7.19.1.2. Enabling MTOM per endpoint


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 65<br />

On the server side MTOM processing is enabled through the @BindingType annotation. <strong>JBoss</strong>WS<br />

does handle SOAP1.1 and SOAP1.2. Both come with or without MTOM flavours:<br />

MTOM enabled service implementations<br />

package org.jboss.test.ws.jaxws.samples.xop.doclit;<br />

import javax.ejb.Remote;<br />

import javax.jws.WebService;<br />

import javax.jws.soap.SOAPBinding;<br />

import javax.xml.ws.BindingType;<br />

@Remote<br />

@WebService(targetNamespace = "http://org.jboss.ws/xop/doclit")<br />

@SOAPBinding(style = SOAPBinding.Style.DOCUMENT, parameterStyle =<br />

SOAPBinding.ParameterStyle.BARE)<br />

@BindingType(value="http://schemas.xmlsoap.org/wsdl/soap/http?mtom=true")<br />

(1)<br />

public interface MTOMEndpoint<br />

{<br />

...<br />

}<br />

1. The MTOM enabled SOAP 1.1 binding ID<br />

MTOM enabled clients<br />

Web service clients can use the same approach described above or rely on the Binding API to enable<br />

MTOM (Excerpt taken from the<br />

org.jboss.test.ws.jaxws.samples.xop.doclit.XOPTestCase):<br />

...<br />

Service service = Service.create(wsdlURL, serviceName);<br />

port = service.getPort(MTOMEndpoint.class);<br />

// enable MTOM<br />

binding = (SOAPBinding)((BindingProvider)port).getBinding();<br />

binding.setMTOMEnabled(true);<br />

Note<br />

You might as well use the <strong>JBoss</strong>WS configuration templates to setup deployment defaults.<br />

7.19.2. SwaRef<br />

WS-I Attachment Profile 1.0 defines mechanism to reference MIME attachment parts using swaRef. In<br />

this mechanism the content of XML element of type wsi:swaRef is sent as MIME attachment and the<br />

element inside SOAP Body holds the reference to this attachment in the CID URI scheme as defined by<br />

RFC 2111.<br />

7.19.2.1. Using SwaRef with JAX-WS endpoints<br />

JAX-WS endpoints delegate all marshalling/unmarshalling to the JAXB API. The most simple way to<br />

enable SwaRef encoding for DataHandler types is to annotate a payload bean with the<br />

@XmlAttachmentRef annotation as shown below:


66 Chapter 7. Web Services<br />

/**<br />

* Payload bean that will use SwaRef encoding<br />

*/<br />

@XmlRootElement<br />

public class DocumentPayload<br />

{<br />

private DataHandler data;<br />

}<br />

public DocumentPayload()<br />

{<br />

}<br />

public DocumentPayload(DataHandler data)<br />

{<br />

this.data = data;<br />

}<br />

@XmlElement<br />

@XmlAttachmentRef<br />

public DataHandler getData()<br />

{<br />

return data;<br />

}<br />

public void setData(DataHandler data)<br />

{<br />

this.data = data;<br />

}<br />

With document wrapped endpoints you may even specify the @XmlAttachmentRef annotation on the<br />

service endpoint interface:<br />

@WebService<br />

public interface DocWrappedEndpoint<br />

{<br />

@WebMethod<br />

DocumentPayload beanAnnotation(DocumentPayload dhw, String test);<br />

}<br />

@WebMethod<br />

@XmlAttachmentRef<br />

DataHandler parameterAnnotation(@XmlAttachmentRef DataHandler data, String test);<br />

The message would then refer to the attachment part by CID:<br />

<br />

<br />

<br />

<br />

cid:0-1180017772935-32455963@ws.jboss.org<br />

Wrapped test<br />

<br />

<br />

<br />

7.19.2.2. Starting from WSDL<br />

If you chose the contract first approach then you need to ensure that any element declaration that<br />

should use SwaRef encoding simply refers to wsi:swaRef schema type:<br />

<br />

Any wsi:swaRef schema type would then be mapped to DataHandler.<br />

7.20. Tools


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 67<br />

The JAX-WS tools provided by <strong>JBoss</strong>WS can be used in a variety of ways. First we will look at serverside<br />

development strategies, and then proceed to the client. When developing a Web Service Endpoint<br />

(the server-side) you have the option of starting from Java (bottom-up development), or from the abstact<br />

contract (WSDL) that defines your service (top-down development). If this is a new service (no existing<br />

contract), the bottom-up approach is the fastest route; you only need to add a few annotations to your<br />

classes to get a service up and running. However, if you are developing a service with an already<br />

defined contract, it is far simpler to use the top-down approach, since the provided tool will generate the<br />

annotated code for you.<br />

Bottom-up use cases:<br />

Exposing an already existing EJB3 bean as a Web Service<br />

Providing a new service, and you want the contract to be generated for you<br />

Top-down use cases:<br />

Replacing the implementation of an existing Web Service without breaking compatibility with older<br />

clients<br />

Exposing a service that conforms to a contract specified by a third party (e.g. a vender that calls you<br />

back using an already defined protocol).<br />

Creating a service that adheres to the XML Schema and WSDL you developed by hand up front<br />

The following JAX-WS command line tools are included in <strong>JBoss</strong>WS:<br />

Command Description<br />

wsprovide Generates JAX-WS portable artifacts, and<br />

provides the abstract contract. Used for bottomup<br />

development.<br />

wsconsume Consumes the abstract contract (WSDL and<br />

Schema files), and produces artifacts for both a<br />

server and client. Used for top-down and client<br />

development<br />

wsrunclient Executes a Java client (that has a main method)<br />

using the <strong>JBoss</strong>WS classpath.<br />

7.20.1. Bottom-Up (Using wsprovide)<br />

The bottom-up strategy involves developing the Java code for your service, and then annotating it using<br />

JAX-WS annotations. These annotations can be used to customize the contract that is generated for<br />

your service. For example, you can change the operation name to map to anything you like. However, all<br />

of the annotations have sensible defaults, so only the @WebService annotation is required.<br />

This can be as simple as creating a single class:<br />

package echo;<br />

@javax.jws.WebService<br />

public class Echo<br />

{<br />

public String echo(String input)<br />

{<br />

return input;<br />

}<br />

}<br />

A JSE or EJB3 deployment can be built using this class, and it is the only Java code needed to deploy on<br />

<strong>JBoss</strong>WS. The WSDL, and all other Java artifacts called "wrapper classes" will be generated for you at<br />

deploy time. This actually goes beyond the JAX-WS specification, which requires that wrapper classes<br />

be generated using an offline tool. The reason for this requirement is purely a vender implementation<br />

problem, and since we do not believe in burdening a developer with a bunch of additional steps, we<br />

generate these as well. However, if you want your deployment to be portable to other application<br />

servers, you will need to use a tool and add the generated classes to your deployment.<br />

This is the primary purpose of the wsprovide tool, to generate portable JAX-WS artifacts. Additionally, it<br />

can be used to "provide" the abstract contract (WSDL file) for your service. This can be obtained by<br />

invoking wsprovide using the "-w" option:


68 Chapter 7. Web Services<br />

$ javac -d . -classpath jboss-jaxws.jar Echo.java<br />

$ wsprovide -w echo.Echo<br />

Generating WSDL:<br />

EchoService.wsdl<br />

Writing Classes:<br />

echo/jaxws/Echo.class<br />

echo/jaxws/EchoResponse.class<br />

Inspecting the WSDL reveals a service called EchoService:<br />

<br />

<br />

<br />

<br />

<br />

As expected, this service defines one operation, "echo":<br />

<br />

<br />

<br />

<br />

<br />

<br />

Note<br />

Remember that when deploying on <strong>JBoss</strong>WS you do not need to run this tool. You only<br />

need it for generating portable artifacts and/or the abstract contract for your service.<br />

Let us create a POJO endpoint for deployment on <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>. A simple<br />

web.xml needs to be created:<br />

<br />

<br />

Echo<br />

echo.Echo<br />

<br />

<br />

Echo<br />

/Echo<br />

<br />

<br />

The web.xml and the single class can now be used to create a WAR:<br />

$ mkdir -p WEB-INF/classes<br />

$ cp -rp echo WEB-INF/classes/<br />

$ cp web.xml WEB-INF<br />

$ jar cvf echo.war WEB-INF<br />

added manifest<br />

adding: WEB-INF/(in = 0) (out= 0)(stored 0%)<br />

adding: WEB-INF/classes/(in = 0) (out= 0)(stored 0%)<br />

adding: WEB-INF/classes/echo/(in = 0) (out= 0)(stored 0%)<br />

adding: WEB-INF/classes/echo/Echo.class(in = 340) (out= 247)(deflated 27%)<br />

adding: WEB-INF/web.xml(in = 576) (out= 271)(deflated 52%)<br />

The war can then be deployed:


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 69<br />

cp echo.war $JBOSS_HOME/server/default/deploy<br />

At deploy time <strong>JBoss</strong>WS will internally invoke wsprovide, which will generate the WSDL. If deployment<br />

was successful, and you are using the default settings, it should be available here:<br />

http://localhost:8080/echo/Echo?wsdl<br />

For a portable JAX-WS deployment, the wrapper classes generated earlier could be added to the<br />

deployment.<br />

7.20.2. Top-Down (Using wsconsume)<br />

The top-down development strategy begins with the abstract contract for the service, which includes the<br />

WSDL file and zero or more schema files. The wsconsume tool is then used to consume this contract,<br />

and produce annotated Java classes (and optionally sources) that define it.<br />

Note<br />

wsconsume seems to have a problem with symlinks on unix systems<br />

Using the WSDL file from the bottom-up example, a new Java implementation that adheres to this service<br />

can be generated. The "-k" option is passed to wsconsume to preserve the Java source files that are<br />

generated, instead of providing just classes:<br />

$ wsconsume -k EchoService.wsdl<br />

echo/Echo.java<br />

echo/EchoResponse.java<br />

echo/EchoService.java<br />

echo/Echo_Type.java<br />

echo/ObjectFactory.java<br />

echo/package-info.java<br />

echo/Echo.java<br />

echo/EchoResponse.java<br />

echo/EchoService.java<br />

echo/Echo_Type.java<br />

echo/ObjectFactory.java<br />

echo/package-info.java<br />

The following table shows the purpose of each generated file:<br />

File Purpose<br />

Echo.java Service Endpoint Interface<br />

Echo_Type.java Wrapper bean for request message<br />

EchoResponse.java Wrapper bean for response message<br />

ObjectFactory.java JAXB XML Registry<br />

package-info.java Holder for JAXB package annotations<br />

EchoService.java Used only by JAX-WS clients<br />

Examining the Service Endpoint Interface reveals annotations that are more explicit than in the class<br />

written by hand in the bottom-up example, however, these evaluate to the same contract:<br />

@WebService(name = "Echo", targetNamespace = "http://echo/")<br />

public interface Echo<br />

{<br />

@WebMethod<br />

@WebResult(targetNamespace = "")<br />

@RequestWrapper(localName = "echo", targetNamespace = "http://echo/", className<br />

= "echo.Echo_Type")<br />

@ResponseWrapper(localName = "echoResponse", targetNamespace = "http://echo/",<br />

className = "echo.EchoResponse")<br />

public String echo(@WebParam(name = "arg0", targetNamespace = "") String arg0);<br />

}<br />

The only missing piece (besides the packaging) is the implementation class, which can now be written


70 Chapter 7. Web Services<br />

The only missing piece (besides the packaging) is the implementation class, which can now be written<br />

using the above interface.<br />

package echo;<br />

@javax.jws.WebService(endpointInterface="echo.Echo")<br />

public class EchoImpl implements Echo<br />

{<br />

public String echo(String arg0)<br />

{<br />

return arg0;<br />

}<br />

}<br />

7.20.3. Client Side<br />

Before going into detail on the client-side it is important to understand the decoupling concept that is<br />

central to Web Services. Web Services are not the best fit for internal RPC, even though they can be<br />

used in this way; there are much better technologies for achieving this (CORBA, and RMI for example).<br />

Web Services were designed specifically for interoperable coarse-grained correspondence. There is no<br />

expectation or guarantee that any party participating in a Web Service interaction will be at any particular<br />

location, running on any particular operating system, or written in any particular programming language.<br />

So because of this, it is important to clearly separate client and server implementations. The only thing<br />

they should have in common is the abstract contract definition. If, for whatever reason, your software<br />

does not adhere to this principal, then you should not be using Web Services. For the above reasons,<br />

the recommended methodology for developing a client is to follow the top-down approach , even if<br />

the client is running on the same server.<br />

Let's repeat the process of the top-down section, although using the deployed WSDL, instead of the one<br />

generated offline by wsprovide. The reason why we do this is just to get the right value for<br />

soap:address. This value must be computed at deploy time, since it is based on container configuration<br />

specifics. You could of course edit the WSDL file yourself, although you need to ensure that the path is<br />

correct.<br />

Offline version:<br />

<br />

<br />

<br />

<br />

<br />

Online version:<br />

<br />

<br />

<br />

<br />

<br />

Using the online deployed version with wsconsume:<br />

$ wsconsume -k http://localhost:8080/echo/Echo?wsdl<br />

echo/Echo.java<br />

echo/EchoResponse.java<br />

echo/EchoService.java<br />

echo/Echo_Type.java<br />

echo/ObjectFactory.java<br />

echo/package-info.java<br />

echo/Echo.java<br />

echo/EchoResponse.java<br />

echo/EchoService.java<br />

echo/Echo_Type.java<br />

echo/ObjectFactory.java<br />

echo/package-info.java<br />

The one class that was not examined in the top-down section, was EchoService.java. Notice how it<br />

stores the location the WSDL was obtained from.


@WebServiceClient(name = "EchoService", targetNamespace = "http://echo/",<br />

wsdlLocation = "http://localhost:8080/echo/Echo?wsdl")<br />

public class EchoService extends Service<br />

{<br />

private final static URL ECHOSERVICE_WSDL_LOCATION;<br />

static<br />

{<br />

URL url = null;<br />

try<br />

{<br />

url = new URL("http://localhost:8080/echo/Echo?wsdl");<br />

}<br />

catch (MalformedURLException e)<br />

{<br />

e.printStackTrace();<br />

}<br />

ECHOSERVICE_WSDL_LOCATION = url;<br />

}<br />

public EchoService(URL wsdlLocation, QName serviceName)<br />

{<br />

super(wsdlLocation, serviceName);<br />

}<br />

public EchoService()<br />

{<br />

super(ECHOSERVICE_WSDL_LOCATION, new QName("http://echo/", "EchoService"));<br />

}<br />

@WebEndpoint(name = "EchoPort")<br />

public Echo getEchoPort()<br />

{<br />

return (Echo)super.getPort(new QName("http://echo/", "EchoPort"),<br />

Echo.class);<br />

}<br />

}<br />

As you can see, this generated class extends the main client entry point in JAX-WS,<br />

javax.xml.ws.Service. While you can use Service directly, this is far simpler since it provides the<br />

configuration info for you. The only method we really care about is the getEchoPort() method, which<br />

returns an instance of our Service Endpoint Interface. Any Web Services operation can then be<br />

called by just invoking a method on the returned interface.<br />

Note<br />

It is not recommended to refer to a remote WSDL URL in a production application. This causes<br />

network I/O every time you instantiate the Service Object. Instead, use the tool on a saved local<br />

copy, or use the URL version of the constructor to provide a new WSDL location.<br />

All that is left to do, is write and compile the client:<br />

import echo.*;<br />

..<br />

public class EchoClient<br />

{<br />

public static void main(String args[])<br />

{<br />

if (args.length != 1)<br />

{<br />

System.err.println("usage: EchoClient ");<br />

System.exit(1);<br />

}<br />

}<br />

}<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 71<br />

EchoService service = new EchoService();<br />

Echo echo = service.getEchoPort();<br />

System.out.println("Server said: " + echo.echo(args[0]));


72 Chapter 7. Web Services<br />

It can then be easily executed using the wsrunclient tool. This is just a convenience tool that invokes<br />

java with the needed classpath:<br />

$ wsrunclient EchoClient 'Hello World!'<br />

Server said: Hello World!<br />

It is easy to change the endpoint address of your operation at runtime, setting<br />

ENDPOINT_ADDRESS_PROPERTY as shown below:<br />

...<br />

EchoService service = new EchoService();<br />

Echo echo = service.getEchoPort();<br />

/* Set NEW Endpoint Location */<br />

String endpointURL = "http://NEW_ENDPOINT_URL";<br />

BindingProvider bp = (BindingProvider)echo;<br />

bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpointURL);<br />

System.out.println("Server said: " + echo.echo(args[0]));<br />

...<br />

7.20.4 . Command-line & Ant Task Reference<br />

wsconsume reference page<br />

wsprovide reference page<br />

wsrunclient reference page<br />

7.20.5. JAX-WS binding customization<br />

An introduction to binding customizations:<br />

http://java.sun.com/webservices/docs/2.0/jaxws/customizations.html<br />

The schema for the binding customization files can be found here:<br />

binding customization<br />

7.21. Web Service Extensions<br />

7.21.1. WS-Addressing<br />

This section describes how WS-Addressing can be used to provide a stateful service endpoint.<br />

7.21.1.1. Specifications<br />

WS-Addressing is defined by a combination of the following specifications from the W3C<br />

Recommendation. The WS-Addressing API is standardized by JSR-224 - Java API for XML-Based Web<br />

Services (JAX-WS)<br />

Web Services Addressing 1.0 - Core<br />

Web Services Addressing 1.0 - SOAP Binding<br />

7.21.1.2. Addressing Endpoint<br />

Note<br />

The following information should not be used in conjuction with <strong>JBoss</strong> Web Services CXF Stack.<br />

The following endpoint implementation has a set of operation for a typical stateful shopping chart<br />

application.


@WebService(name = "StatefulEndpoint", targetNamespace =<br />

"http://org.jboss.ws/samples/wsaddressing", serviceName = "TestService")<br />

@Addressing(enabled=true, required=true)<br />

@SOAPBinding(style = SOAPBinding.Style.RPC)<br />

public class StatefulEndpointImpl implements StatefulEndpoint, ServiceLifecycle<br />

{<br />

@WebMethod<br />

public void addItem(String item)<br />

{ ... }<br />

}<br />

@WebMethod<br />

public void checkout()<br />

{ ... }<br />

@WebMethod<br />

public String getItems()<br />

{ ... }<br />

It uses the JAX-WS 2.1 defined javax.xml.ws.soap.Addressing annotation to enable the server<br />

side addressing handler.<br />

7.21.1.3. Addressing Client<br />

The client code uses javax.xml.ws.soap.AddressingFeature feature from JAX-WS 2.1 API to<br />

enable the WS-Addressing.<br />

Service service = Service.create(wsdlURL, serviceName);<br />

port1 = (StatefulEndpoint)service.getPort(StatefulEndpoint.class, new<br />

AddressingFeature());<br />

A client connecting to the stateful endpoint<br />

public class AddressingStatefulTestCase extends <strong>JBoss</strong>WSTest<br />

{<br />

...<br />

public void testAddItem() throws Exception<br />

{<br />

port1.addItem("Ice Cream");<br />

port1.addItem("Ferrari");<br />

}<br />

}<br />

port2.addItem("Mars Bar");<br />

port2.addItem("Porsche");<br />

public void testGetItems() throws Exception<br />

{<br />

String items1 = port1.getItems();<br />

assertEquals("[Ice Cream, Ferrari]", items1);<br />

}<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 73<br />

String items2 = port2.getItems();<br />

assertEquals("[Mars Bar, Porsche]", items2);<br />

SOAP message exchange<br />

Below you see the SOAP messages that are beeing exchanged.


74 Chapter 7. Web Services<br />

<br />

<br />

uri:jbossws-samples-wsaddr/TestService<br />

http://org.jboss.ws/addressing/stateful/action<br />

<br />

clientid-1<br />

<br />

<br />

<br />

<br />

Ice Cream<br />

<br />

<br />

<br />

<br />

<br />

http://www.w3.org/2005/08/addressing/anonymous<br />

http://org.jboss.ws/addressing/stateful/actionReply<br />

clientid-1<br />

<br />

<br />

<br />

<br />

<br />

...<br />

<br />

<br />

uri:jbossws-samples-wsaddr/TestService<br />

http://org.jboss.ws/addressing/stateful/action<br />

<br />

clientid-1<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

http://www.w3.org/2005/08/addressing/anonymous<br />

http://org.jboss.ws/addressing/stateful/actionReply<br />

clientid-1<br />

<br />

<br />

<br />

[Ice Cream, Ferrari]<br />

<br />

<br />

<br />

7.21.2. WS-Security<br />

WS-Security addresses message level security. It standardizes authorization, encryption, and digital<br />

signature processing of web services. Unlike transport security models, such as SSL, WS-Security<br />

applies security directly to the elements of the web service message. This increases the flexibility of<br />

your web services, by allowing any message model to be used (for example, point to point, or multi-hop<br />

relay).<br />

This chapter describes how to use WS-Security to sign and encrypt a simple SOAP message.<br />

Specifications<br />

WS-Security is defined by the combination of the following specifications:<br />

SOAP Message Security 1.0<br />

Username Token Profile 1.0<br />

X.509 Token Profile 1.0


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 75<br />

W3C XML Encryption<br />

W3C XML Signature<br />

Basic Security Profile 1.0 (Still in Draft)<br />

7.21.2.1. Endpoint configuration<br />

<strong>JBoss</strong>WS uses handlers to identify ws-security encoded requests and invoke the security components<br />

to sign and encrypt messages. In order to enable security processing, the client and server side must<br />

include a corressponding handler configuration. The preferred way is to reference a predefined JAX-WS<br />

Endpoint Configuration or JAX-WS Client Configuration respectively.<br />

Note<br />

You must setup both the endpoint configuration and the WSSE declarations. These are two<br />

separate steps.<br />

7.21.2.2. Server side WSSE declaration (jboss-wsse-server.xml)<br />

In this example we configure both the client and the server to sign the message body. Both also require<br />

this from each other. So, if you remove either the client or the server security deployment descriptor, you<br />

will notice that the other party will throw a fault explaining that the message did not conform to the proper<br />

security requirements.<br />

<br />

(1) WEB-INF/wsse.keystore<br />

(2) jbossws<br />

(3) WEB-INF/wsse.truststore<br />

(4) jbossws<br />

(5) <br />

(6) <br />

(7) <br />

(8) <br />

<br />

<br />

<br />

1. This specifies that the key store we wish to use is WEB-INF/wsse.keystore, which is located in<br />

our war file.<br />

2. This specifies that the store password is "jbossws". Password can be encypted using the {EXT}<br />

and {CLASS} commands. Please see samples for their usage.<br />

3. This specifies that the trust store we wish to use is WEB-INF/wsse.truststore, which is<br />

located in our war file.<br />

4. This specifies that the trust store password is also "jbossws". Password can be encrypted using<br />

the {EXT} and {CLASS} commands. Please see samples for their usage.<br />

5. Here we start our root config block. The root config block is the default configuration for all<br />

services in this war file.<br />

6. This means that the server must sign the message body of all responses. Type means that we<br />

are using X.509v3 certificate (a standard certificate). The alias option says that the certificate and<br />

key pair to use for signing is in the key store under the "wsse" alias<br />

7. Here we start our optional requires block. This block specifies all security requirements that must<br />

be met when the server receives a message.<br />

8. This means that all web services in this war file require the message body to be signed.<br />

By default an endpoint does not use the WS-Security configuration. Users can use proprietary<br />

@EndpointConfig annotation to set the config name. See JAX-WS_Endpoint_Configuration for the list<br />

of available config names.


76 Chapter 7. Web Services<br />

@WebService<br />

@EndpointConfig(configName = "Standard WSSecurity Endpoint")<br />

public class HelloJavaBean<br />

{<br />

...<br />

}<br />

7.21.2.3. Client side WSSE declaration (jboss-wsse-client.xml)<br />

<br />

(1) <br />

(2) <br />

(3) <br />

(4) <br />

<br />

<br />

<br />

1. Here we start our root config block. The root config block is the default configuration for all web<br />

service clients (Call, Proxy objects).<br />

2. This means that the client must sign the message body of all requests it sends. Type means that<br />

we are to use a X.509v3 certificate (a standard certificate). The alias option says that the<br />

certificate/key pair to use for signing is in the key store under the "wsse" alias<br />

3. Here we start our optional requires block. This block specifies all security requirements that must<br />

be met when the client receives a response.<br />

4. This means that all web service clients must receive signed response messages.<br />

7.21.2.3.1. Client side key store configuration<br />

We did not specify a key store or trust store, because client apps instead use the wsse System<br />

properties instead. If this was a web or ejb client (meaning a webservice client in a war or ejb jar file),<br />

then we would have specified them in the client descriptor.<br />

Here is an excerpt from the <strong>JBoss</strong>WS samples:<br />

<br />

<br />

<br />

<br />

<br />

<br />

SOAP message exchange<br />

Below you see the incomming SOAP message with the details of the security headers ommited. The idea<br />

is, that the SOAP body is still plain text, but it is signed in the security header and therefore can not be<br />

manipulated in transit.


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 77<br />

<br />

<br />

<br />

...<br />

<br />

...<br />

<br />

<br />

...<br />

<br />

<br />

<br />

<br />

<br />

<br />

Kermit<br />

<br />

<br />

<br />

<br />

7.21.2.4 . Installing the BouncyCastle JCE provider<br />

The information below has originaly been provided by The Legion of the Bouncy Castle.<br />

The provider can be configured as part of your environment via static registration by adding an entry to<br />

the java.security properties file (found in $JAVA_HOME/jre/lib/security/java.security,<br />

where $JAVA_HOME is the location of your JDK and JRE distribution). You will find detailed instructions in<br />

the file but basically it comes down to adding a line:<br />

security.provider.=org.bouncycastle.jce.provider.BouncyCastleProvider<br />

Where is the preference you want the provider at.<br />

Note<br />

Issues may arise if the Sun provided providers are not first.<br />

Where users will put the provider jar is mostly up to them, although with jdk5 the best (and in some<br />

cases only) place to have it is in $JAVA_HOME/jre/lib/ext. Under Windows there will normally be a<br />

JRE and a JDK install of Java. If user think he have installed it correctly and it still doesn't work then with<br />

high probability the provider installation is not used.<br />

7.21.2.5. Username Token AuthenticationJBOSSCC-50<br />

If you need to authenticate clients through a Username Token, the JAAS integration will verify the<br />

received token against the configured <strong>JBoss</strong> JAAS Security Domain.


78 Chapter 7. Web Services<br />

Example 7.1. Basic Username Token Configuration<br />

To implement this feature, you must append a element to jboss-wsseclient.xml<br />

that contains the following information.<br />

<br />

<br />

(1) <br />

(2) <br />

<br />

<br />

Line (2) specifies that a element must be present in the message and that the message<br />

can not be older than 300 seconds. The seconds limitation is used to prevent replay attacks.<br />

You must then specify the same element and seconds attribute in the jboss-wsseserver.xml<br />

file so both headers match. You must also specify the element to enforce<br />

this condition.<br />

<br />

<br />

<br />

<br />

<br />

<br />

Warning<br />

This example configuration results in simple text user information being sent in SOAP headers.<br />

You should strongly consider implementing <strong>JBoss</strong>WS Secure Transport<br />

Password Digest, Nonces, and Timestamp<br />

Example 7.1, “Basic Username Token Configuration” results in the client password being sent as plain<br />

text. You can use a combination of digested passwords, nonces, and timestamps to provide further<br />

protection from replay attacks.<br />

To enable password digesting, you must implement the following items as described in Example 7.2,<br />

“Enable Password Digesting”:


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 79<br />

Example 7.2. Enable Password Digesting<br />

In the element of the jboss-wsse-client.xml file:<br />

enable the digestPassword attribute<br />

enable the nonces and timestamps attributes.<br />

<br />

<br />

(3) <br />

<br />

<br />

<br />

In the login-config.xml file, you must also implement the UsernameTokenCallback module option.<br />

Example 7.3. UsernameTokenCallback Module<br />

<br />

<br />

<br />

META-INF/jbosswsusers.properties<br />

META-INF/jbosswsroles.properties<br />

SHA<br />

BASE64<br />

false<br />

true<br />

org.jboss.ws.extensions.security.auth.callback.UsernameT<br />

okenCallback<br />

anonymous<br />

<br />

<br />

<br />

You may wish to use a more sophisticated custom login module to provide more security against replay<br />

attacks. You can use your own custom login module provided you implement the following:<br />

plug the UsernameTokenCallback callback into your login module<br />

extend the org.jboss.security.auth.spi.UsernamePasswordLoginModule<br />

set the hash attributes (hashAlgorithm, hashEncoding, hashUserPassword,<br />

hashStorePassword) as shown in Example 7.3, “UsernameTokenCallback Module”.<br />

Advanced Tuning - Nonce Factory<br />

The way nonces are created, and subsequently checked and stored on the server side, influences<br />

overall security against replay attacks. Currently <strong>JBoss</strong>WS ships with a basic implementation of a nonce<br />

store that does not cache the received tokens on the server side.<br />

More complex implementation can be plugged into your modules by implementing the NonceFactory<br />

and NonceStore interfaces. You can find these interfaces in the<br />

org.jboss.ws.extensions.security.nonce package.<br />

Once included, you specify your factory class through the element in the jbosswsse-server.xml<br />

file.


80 Chapter 7. Web Services<br />

Advanced Tuning - Timestamp Verification<br />

If a Timestamp is present in the wsse:Security header, header verification does not allow for any<br />

tolerance whatsoever in the time comparisons. If the message appears to have been created even<br />

slightly in the future or if the message has just expired it will be rejected. A new element called<br />

is available for the wsse configuration. Example 7.4, “<br />

Configuration” describes the required attributes for the element.<br />

Example 7.4 . Configuration<br />

The element attributes allow you to specify the tolerance in seconds that is<br />

used when verifying the 'Created' or 'Expires' element of the 'Timestamp' header.<br />

<br />

<br />

<br />

createdTolerance<br />

Number of seconds in the future a message will be accepted. The default value is 0<br />

expiresTolerance<br />

Number of seconds a message is rejected after being classed as expired. The default value<br />

is 0.<br />

warnCreated<br />

Specifies whether to log a warning message if a message is accepted with a 'Created' value<br />

in the future. The default value is true.<br />

warnExpires<br />

Specifies whether to log a warning message if a message is accepted with an 'Expired' value<br />

in the past. The default value is true.<br />

Note<br />

The warnCreated and warnExpires attributes can be used to identify accepted messages that<br />

would normally be rejected. You can use this data to identify clients that are out of sync with the<br />

server time, without rejecting the client messages.<br />

7.21.2.5.1. Secure Transport<br />

7.21.2.6. X509 Certificate TokenJBOSSCC-50<br />

By using X509v3 certificates, you can both sign and encrypt messages.<br />

Encryption<br />

To configure encryption, you must specify the items in Example 7.5, “X509 Encryption Configuration”.<br />

The configuration is the same for clients and servers.


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 81<br />

Example 7.5. X509 Encryption Configuration<br />

<br />

(1) WEB-INF/bob-sign_enc.jks<br />

password<br />

jks<br />

WEB-INF/wsse10.truststore<br />

password<br />

<br />

<br />

(2) <br />

(3) <br />

(4) <br />

<br />

<br />

<br />

<br />

<br />

The server configuration includes the following encryption information:<br />

1. Keystore and Truststore information: location of each store, the password, and type of store.<br />

2. Signature configuration: you must provide the certificate and key pair aliases to use.<br />

includeTimestamp specifies whether the timestamp is signed to prevent tampering.<br />

3. Encryption configuration: you must provide the certificate and key pair aliases to use. Refer to<br />

Algorithms for more information.<br />

4. Optional security requirements: incoming messages must be both signed, and encrypted.<br />

Dynamic Encryption<br />

When replying to multiple clients, a service provider must encrypt a message according to its destination<br />

using the correct public key. The <strong>JBoss</strong>WS native implementation of WS-Security obtains the correct key<br />

to use from the signature received (and verified) in the incoming message.


82 Chapter 7. Web Services<br />

Example 7.6. Dynamic Encryption Configuration<br />

To configure dynamic encryption, do not specify any encryption alias on the server side (1), and<br />

declare that a signature is required (2).<br />

<br />

WEB-INF/bob-sign_enc.jks<br />

password<br />

jks<br />

WEB-INF/wsse10.truststore<br />

password<br />

<br />

<br />

<br />

(1) <br />

<br />

(2) <br />

<br />

<br />

<br />

<br />

Algorithms<br />

Asymmetric and symmetric encryption is performed whenever the element is declared.<br />

Message data are encrypted using a generated symmetric secured key. This key is written in the SOAP<br />

header after being encrypted (wrapped) with the receiver public key. You can set both the encryption<br />

and key wrap algorithms.<br />

The supported encryption algorithms include:<br />

AES 128 (aes-128) (default)<br />

AES 192 (aes-192)<br />

AES 256 (aes-256)<br />

Triple DES (triple-des)<br />

The supported key-wrap algorithms include:<br />

RSA v1.5 (rsa_15) (default)<br />

RSA OAEP (rsa_oaep)<br />

Note<br />

The Unlimited Strength Java(TM) Cryptography Extension installation might be required to run<br />

some strong algorithms (for example, aes-256). Your country may impose limitations on the<br />

allowed cryptographic strength in applications. It is your responsibility to select the encryption<br />

level suitable for your jurisdiction.<br />

Encryption Token Reference<br />

For interoperability reasons, you may need to configure the type of reference to encryption token to be<br />

used. For example, Microsoft Indigo does not support direct reference to local binary security tokens<br />

which are the default reference type used by <strong>JBoss</strong>WS.<br />

To configure this reference, you specify the tokenReference attribute in the element. The


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 83<br />

values for the tokenReference attribute are:<br />

directReference (default)<br />

keyIdentifier - specifies the token data by means of an X509 SubjectKeyIdentifier reference.<br />

x509IssuerSerial - uniquely identifies an end entity certificate by its X509 Issuer and Serial<br />

Number<br />

Note<br />

Complete information about X509 Token Profiles are available in the WSS X501 Certificate Token<br />

Profile 1.0 document, which can be obtained from the Oasis.org docs portal.<br />

Targets Configuration<br />

<strong>JBoss</strong>WS gives you precise control over elements that must be signed or encrypted. This allows you to<br />

encrypt important data only (such as credit card numbers) instead of other, security-trivial, information<br />

exchanged by the same service (email addresses, for example). To configure this, you must specify the<br />

Qualified Name (qname) of the SOAP elements to encrypt. The default behavior is to encrypt the whole<br />

SOAP body.<br />

<br />

<br />

{http://www.my-company.com/cc}CardNumber<br />

{http://www.my-company.com/cc}CardExpiration<br />

{http://www.mycompany.com/cc}CustomerData<br />

<br />

<br />

Payload Carriage Returns<br />

Signature verification errors can occur in signed message payloads that contain carriage returns (\r)<br />

due to the way the special character is parsed by XML parsers. To prevent this issue, you can choose<br />

to implement custom encoding before sending the payload. Users can either encrypt the message, or<br />

force <strong>JBoss</strong>WS to perform canonical normalization of messages.<br />

The org.jboss.ws.DOMContentCanonicalNormalization property can normalize the payload if set to true<br />

in the MessageContext. The property must be set just before the invocation on the client side and in the<br />

endpoint implementation.<br />

7.21.2.7. JAAS IntegrationJBOSSCC-50<br />

The WS-Security implementation allows users to achieve J2EE declarative security through JAAS<br />

integration. The calling user's identity and credentials are derived from the wsse headers of the<br />

incoming message, according to the parameters provided in the server wsse configuration file.<br />

Authentication and authorization is subsequently achieved delegating to the JAAS login modules<br />

configured for the specified security domain.<br />

Username Token<br />

Username Token Profile provides a mean of specifying the caller's username and password. The wsse<br />

server configuration file can be used to have those information used when performing authentication and<br />

authorization through configured login module.


84 Chapter 7. Web Services<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Note<br />

Prior to <strong>JBoss</strong>Ws 3.0.2 Native the username token was always used to set principal and<br />

credential of the caller whenever specified. This means that for backward compatibility reasons,<br />

this behavior is obtained also when no authenticate tag at all is specified and the username token<br />

is used.<br />

X.509 Certificate Token<br />

In previous versions of <strong>JBoss</strong>WS, the username token was always used to set the principal and<br />

credential of the caller whenever specified. This behavior is retained for backward compatibility reasons<br />

where no element is specified and the username token is used.<br />

<br />

META-INF/bob-sign.jks<br />

password<br />

jks<br />

META-INF/wsse10.truststore<br />

password<br />

<br />

<br />

<br />

<br />

<br />

<br />

(1) <br />

<br />

<br />

<br />

The optional certificatePrincipal attribute (1) specifies the class used to retrieve the principal from<br />

the X.509 certificate's attributes. The selected class must extend CertificatePrincipal. The<br />

default class used when no attribute is specified is<br />

org.jboss.security.auth.certs.SubjectDNMapping.<br />

The configured security domain must have a correctly configured BaseCertLoginModule, as described in<br />

Example 7.7, “BaseCertLoginModule Security Domain”.


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 85<br />

Example 7.7. BaseCertLoginModule Security Domain<br />

The following code sample shows a security domain with a CertRolesLoginModule that also<br />

enables authorization (using the specified jbossws-roles.properties file).<br />

<br />

<br />

<br />

jbossws-roles.properties<br />

anonymous<br />

java:/jaas/<strong>JBoss</strong>WSCert<br />

<br />

<br />

<br />

The BaseCertLoginModule uses a central keystore to authenticate users. This store is configured<br />

through the org.jboss.security.plugins.JaasSecurityDomain MBean as shown in<br />

Example 7.8, “BaseCertLoginModule Keystore”.<br />

Example 7.8. BaseCertLoginModule Keystore<br />

<br />

<br />

<br />

<br />

resource:META-INF/keystore.jks<br />

password<br />

jboss.security:service=JaasSecurityManager<br />

<br />

At authentication time, the specified CertificatePrincipal mapping class accesses the keystore<br />

using the principal obtained from the associated wsse header. If a certificate is found and is the same as<br />

the one specified in the wsse header, the user is successfully authenticated.<br />

7.21.2.8. POJO Endpoint Authentication and AuthorizationJBOSSCC-50<br />

The credentials obtained by WS-Security are generally used for EJB endpoints, or for POJO endpoints<br />

when they make a call to another secured resource. It is now possible to enable authentication and<br />

authorization checking for POJO endpoints.<br />

Important<br />

Authentication and Authorization should not be enabled for EJB based endpoints because the<br />

EJB container handles the security requirements of the deployed bean.<br />

Procedure 7.1. Enabling POJO Authentication and Authorization<br />

This procedure describes the additional configuration required to enable authentication and<br />

authorization for POJO endpoints.<br />

1. Define Security Domain in Web Archive<br />

You must define a security domain in the WAR containing the POJO.<br />

Specify a in the jboss-web deployment descriptor within the /WEB-INF folder.


86 Chapter 7. Web Services<br />

<br />

java:/jaas/<strong>JBoss</strong>WS<br />

<br />

2. Configure the jboss-wsse-server.xml element<br />

Specify an element within the element.<br />

The element can be defined globally, be port-specific, or operation-specific.<br />

The element must contain either the element or one or more <br />

elements. Each element must contain the name of a valid RoleName.<br />

You can choose to implement two types of authentication: unchecked, and role-based<br />

authentication.<br />

Unchecked Authentication<br />

The authentication step is performed to validate the user's username and password, but no<br />

further role checking takes place. If the user's username and password are invalid, the request is<br />

rejected.<br />

Example 7.9. Unchecked Authentication<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Role-based Authentication<br />

The user is authenticated using their username and password as per Unchecked Authentication.<br />

Once the user's username and password is verified, user credentials are checked again to<br />

ensure at least of of the roles specified in the element is assigned to the user.<br />

Note<br />

Authentication and authorization proceeds even if no username and password, or<br />

certificate was provided in the request message. In this scenario, authentication may<br />

proceed if the security domain's login module has been configured with an anonymous<br />

identity.<br />

Example 7.10. Role-based Authentication<br />

<br />

<br />

<br />

friend<br />

family<br />

<br />

<br />

<br />

7.21.3. XML Registries<br />

J2EE 5.0 mandates support for Java API for XML Registries (JAXR). Inclusion of a XML Registry with the


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 87<br />

J2EE 5.0 certified <strong>Application</strong> Server is optional. <strong>JBoss</strong> EAP ships a UDDI v2.0 compliant registry, the<br />

Apache jUDDI registry. JAXR Capability Level 0 (UDDI Registries) is also supported through Apache<br />

Scout integration.<br />

Section 7.21.3, “XML Registries” describes how to configure the jUDDI registry in <strong>JBoss</strong> and some<br />

sample code outlines for using JAXR API to publish and query the jUDDI registry.<br />

7.21.3.1. Apache jUDDI Configuration<br />

jUDDI registry configuration happens via a MBean Service that is deployed in the juddi-service.sar<br />

archive in the "all" configuration. The configuration of this service can be done in the jbossservice.xml<br />

of the META-INF directory in the juddi-service.sar<br />

Let us look at the individual configuration items that can be changed.<br />

DataSources configuration<br />

<br />

java:/DefaultDS<br />

Database Tables (Should they be created on start, Should they be dropped on stop, Should they be<br />

dropped on start etc)<br />

<br />

false<br />

<br />

true<br />

<br />

false<br />

JAXR Connection Factory to be bound in JNDI. (Should it be bound? and under what name?)<br />

<br />

true<br />

<br />

JAXR<br />

Other common configuration:<br />

Add authorized users to access the jUDDI registry. (Add a sql insert statement in a single line)<br />

Look at the script META-INF/ddl/juddi_data.ddl for more details. Example for a<br />

user 'jboss'<br />

INSERT INTO PUBLISHER (PUBLISHER_ID,PUBLISHER_NAME,<br />

EMAIL_ADDRESS,IS_ENABLED,IS_ADMIN)<br />

VALUES ('jboss','<strong>JBoss</strong> User','jboss@xxx','true','true');<br />

7.21.3.2. <strong>JBoss</strong> JAXR Configuration<br />

In this section, we will discuss the configuration needed to run the JAXR API. The JAXR configuration<br />

relies on System properties passed to the JVM. The System properties that are needed are:<br />

javax.xml.registry.ConnectionFactoryClass=org.apache.ws.scout.registry.<br />

ConnectionFactoryImpl<br />

jaxr.query.url=http://localhost:8080/juddi/inquiry<br />

jaxr.publish.url=http://localhost:8080/juddi/publish<br />

scout.proxy.transportClass=org.jboss.jaxr.scout.transport.SaajTransport<br />

Please remember to change the hostname from "localhost" to the hostname of the UDDI service/<strong>JBoss</strong><br />

Server.<br />

You can pass the System Properties to the JVM in the following ways:


88 Chapter 7. Web Services<br />

When the client code is running inside <strong>JBoss</strong> (maybe a servlet or an EJB). Then you will need to<br />

pass the System properties in the run.sh or run.bat scripts to the java process via the "-D"<br />

option.<br />

When the client code is running in an external JVM. Then you can pass the properties either as "-D"<br />

options to the java process or explicitly set them in the client code(not recommended).<br />

System.setProperty(propertyname, propertyvalue);<br />

7.21.3.3. JAXR Sample Code<br />

There are two categories of API: JAXR Publish API and JAXR Inquiry API. The important JAXR interfaces<br />

that any JAXR client code will use are the following.<br />

javax.xml.registry.RegistryService From J2EE 5.0 JavaDoc: "This is the principal interface<br />

implemented by a JAXR provider. A registry client can get this interface from a Connection to a<br />

registry. It provides the methods that are used by the client to discover various capability specific<br />

interfaces implemented by the JAXR provider."<br />

javax.xml.registry.BusinessLifeCycleManager From J2EE 5.0 JavaDoc: "The<br />

BusinessLifeCycleManager interface, which is exposed by the Registry Service, implements the<br />

life cycle management functionality of the Registry as part of a business level API. There is no<br />

authentication information provided, because the Connection interface keeps that state and context<br />

on behalf of the client."<br />

javax.xml.registry.BusinessQueryManager From J2EE 5.0 JavaDoc: "The BusinessQueryManager<br />

interface, which is exposed by the Registry Service, implements the business style query interface. It<br />

is also referred to as the focused query interface."<br />

Let us now look at some of the common programming tasks performed while using the JAXR API:<br />

Getting a JAXR Connection to the registry.<br />

String queryurl = System.getProperty("jaxr.query.url",<br />

"http://localhost:8080/juddi/inquiry");<br />

String puburl = System.getProperty("jaxr.publish.url",<br />

"http://localhost:8080/juddi/publish");<br />

..<br />

Properties props = new Properties();<br />

props.setProperty("javax.xml.registry.queryManagerURL", queryurl);<br />

props.setProperty("javax.xml.registry.lifeCycleManagerURL", puburl);<br />

String transportClass = System.getProperty("scout.proxy.transportClass",<br />

"org.jboss.jaxr.scout.transport.SaajTransport");<br />

System.setProperty("scout.proxy.transportClass", transportClass);<br />

// Create the connection, passing it the configuration properties<br />

factory = ConnectionFactory.newInstance();<br />

factory.setProperties(props);<br />

connection = factory.createConnection();<br />

Authentication with the registry.<br />

/**<br />

* Does authentication with the uddi registry<br />

*/<br />

protected void login() throws JAXRException<br />

{<br />

PasswordAuthentication passwdAuth = new PasswordAuthentication(userid,<br />

passwd.toCharArray());<br />

Set creds = new HashSet();<br />

creds.add(passwdAuth);<br />

}<br />

connection.setCredentials(creds);<br />

Save a Business


**<br />

* Creates a Jaxr Organization with 1 or more services<br />

*/<br />

protected Organization createOrganization(String orgname) throws JAXRException<br />

{<br />

Organization org = blm.createOrganization(getIString(orgname));<br />

org.setDescription(getIString("<strong>JBoss</strong> Inc"));<br />

Service service = blm.createService(getIString("JBOSS JAXR Service"));<br />

service.setDescription(getIString("Services of XML Registry"));<br />

//Create serviceBinding<br />

ServiceBinding serviceBinding = blm.createServiceBinding();<br />

serviceBinding.setDescription(blm.createInternationalString("Test Service<br />

Binding"));<br />

//Turn validation of URI off<br />

serviceBinding.setValidateURI(false);<br />

serviceBinding.setAccessURI("http://testjboss.org");<br />

...<br />

// Add the serviceBinding to the service<br />

service.addServiceBinding(serviceBinding);<br />

User user = blm.createUser();<br />

org.setPrimaryContact(user);<br />

PersonName personName = blm.createPersonName("Anil S");<br />

TelephoneNumber telephoneNumber = blm.createTelephoneNumber();<br />

telephoneNumber.setNumber("111-111-7777");<br />

telephoneNumber.setType(null);<br />

PostalAddress address = blm.createPostalAddress("111", "My Drive", "BuckHead",<br />

"GA", "USA", "1111-111", "");<br />

Collection postalAddresses = new ArrayList();<br />

postalAddresses.add(address);<br />

Collection emailAddresses = new ArrayList();<br />

EmailAddress emailAddress = blm.createEmailAddress("anil@apache.org");<br />

emailAddresses.add(emailAddress);<br />

Collection numbers = new ArrayList();<br />

numbers.add(telephoneNumber);<br />

user.setPersonName(personName);<br />

user.setPostalAddresses(postalAddresses);<br />

user.setEmailAddresses(emailAddresses);<br />

user.setTelephoneNumbers(numbers);<br />

ClassificationScheme cScheme = getClassificationScheme("ntis-gov:naics", "");<br />

Key cKey = blm.createKey("uuid:C0B9FE13-324F-413D-5A5B-2004DB8E5CC2");<br />

cScheme.setKey(cKey);<br />

Classification classification = blm.createClassification(cScheme, "Computer<br />

Systems Design and Related Services", "5415");<br />

org.addClassification(classification);<br />

ClassificationScheme cScheme1 = getClassificationScheme("D-U-N-S", "");<br />

Key cKey1 = blm.createKey("uuid:3367C81E-FF1F-4D5A-B202-3EB13AD02423");<br />

cScheme1.setKey(cKey1);<br />

ExternalIdentifier ei = blm.createExternalIdentifier(cScheme1, "D-U-N-S<br />

number", "08-146-6849");<br />

org.addExternalIdentifier(ei);<br />

org.addService(service);<br />

}<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 89<br />

return org;<br />

Query a Business


90 Chapter 7. Web Services<br />

/**<br />

* Locale aware Search a business in the registry<br />

*/<br />

public void searchBusiness(String bizname) throws JAXRException<br />

{<br />

try<br />

{<br />

// Get registry service and business query manager<br />

this.getJAXREssentials();<br />

// Define find qualifiers and name patterns<br />

Collection findQualifiers = new ArrayList();<br />

findQualifiers.add(FindQualifier.SORT_BY_NAME_ASC);<br />

Collection namePatterns = new ArrayList();<br />

String pattern = "%" + bizname + "%";<br />

LocalizedString ls = blm.createLocalizedString(Locale.getDefault(), pattern);<br />

namePatterns.add(ls);<br />

// Find based upon qualifier type and values<br />

BulkResponse response = bqm.findOrganizations(findQualifiers, namePatterns,<br />

null, null, null, null);<br />

}<br />

// check how many organisation we have matched<br />

Collection orgs = response.getCollection();<br />

if (orgs == null)<br />

{<br />

log.debug(" -- Matched 0 orgs");<br />

}<br />

else<br />

{<br />

log.debug(" -- Matched " + orgs.size() + " organizations -- ");<br />

// then step through them<br />

for (Iterator orgIter = orgs.iterator(); orgIter.hasNext();)<br />

{<br />

Organization org = (Organization)orgIter.next();<br />

log.debug("Org name: " + getName(org));<br />

log.debug("Org description: " + getDescription(org));<br />

log.debug("Org key id: " + getKey(org));<br />

checkUser(org);<br />

checkServices(org);<br />

}<br />

}<br />

}<br />

finally<br />

{<br />

connection.close();<br />

}<br />

For more examples of code using the JAXR API, please refer to the resources in the Resources Section.<br />

7.21.3.4 . Troubleshooting<br />

I cannot connect to the registry from JAXR. Please check the inquiry and publish url passed to<br />

the JAXR ConnectionFactory.<br />

I cannot connect to the jUDDI registry. Please check the jUDDI configuration and see if there<br />

are any errors in the server.log. And also remember that the jUDDI registry is available only in the<br />

"all" configuration.<br />

I cannot authenticate to the jUDDI registry. Have you added an authorized user to the jUDDI<br />

database, as described earlier in the chapter?<br />

I would like to view the SOAP messages in transit between the client and the UDDI<br />

Registry. Please use the tcpmon tool to view the messages in transit. TCPMon<br />

7.21.3.5. Resources<br />

JAXR Tutorial and Code Camps<br />

J2EE 1.4 Tutorial<br />

J2EE Web Services by Richard Monson-Haefel


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 91<br />

7.22. <strong>JBoss</strong>WS Extensions<br />

This section describes propriatary <strong>JBoss</strong> extensions to JAX-WS.<br />

7.22.1. Proprietary Annotations<br />

For the set of standard annotations, please have a look at JAX-WS Annotations<br />

7.22.1.1. EndpointConfig<br />

/**<br />

* Defines an endpoint or client configuration.<br />

* This annotation is valid on an endpoint implementaion bean or a SEI.<br />

*/<br />

@Retention(value = RetentionPolicy.RUNTIME)<br />

@Target(value = { ElementType.TYPE })<br />

public @interface EndpointConfig<br />

{<br />

...<br />

/**<br />

* The optional config-name element gives the configuration name that must be<br />

present in<br />

* the configuration given by element config-file.<br />

*<br />

* Server side default: Standard Endpoint<br />

* Client side default: Standard Client<br />

*/<br />

String configName() default "";<br />

...<br />

/**<br />

* The optional config-file element is a URL or resource name for the<br />

configuration.<br />

*<br />

* Server side default: standard-jaxws-endpoint-config.xml<br />

* Client side default: standard-jaxws-client-config.xml<br />

*/<br />

String configFile() default "";<br />

}<br />

7.22.1.2. WebContext


92 Chapter 7. Web Services<br />

/**<br />

* Provides web context specific meta data to EJB based web service endpoints.<br />

*<br />

* @author thomas.diesler@jboss.org<br />

* @since 26-Apr-2005<br />

*/<br />

@Retention(value = RetentionPolicy.RUNTIME)<br />

@Target(value = { ElementType.TYPE })<br />

public @interface WebContext<br />

{<br />

...<br />

/**<br />

* The contextRoot element specifies the context root that the web service<br />

endpoint is deployed to.<br />

* If it is not specified it will be derived from the deployment short name.<br />

*<br />

* Applies to server side port components only.<br />

*/<br />

String contextRoot() default "";<br />

...<br />

/**<br />

* The virtual hosts that the web service endpoint is deployed to.<br />

*<br />

* Applies to server side port components only.<br />

*/<br />

String[] virtualHosts() default {};<br />

/**<br />

* Relative path that is appended to the contextRoot to form fully qualified<br />

* endpoint address for the web service endpoint.<br />

*<br />

* Applies to server side port components only.<br />

*/<br />

String urlPattern() default "";<br />

/**<br />

* The authMethod is used to configure the authentication mechanism for the web<br />

service.<br />

* As a prerequisite to gaining access to any web service which are protected<br />

by an authorization<br />

* constraint, a user must have authenticated using the configured mechanism.<br />

*<br />

* Legal values for this element are "BASIC", or "CLIENT-CERT".<br />

*/<br />

String authMethod() default "";<br />

/**<br />

* The transportGuarantee specifies that the communication<br />

* between client and server should be NONE, INTEGRAL, or<br />

* CONFIDENTIAL. NONE means that the application does not require any<br />

* transport guarantees. A value of INTEGRAL means that the application<br />

* requires that the data sent between the client and server be sent in<br />

* such a way that it can't be changed in transit. CONFIDENTIAL means<br />

* that the application requires that the data be transmitted in a<br />

* fashion that prevents other entities from observing the contents of<br />

* the transmission. In most cases, the presence of the INTEGRAL or<br />

* CONFIDENTIAL flag will indicate that the use of SSL is required.<br />

*/<br />

String transportGuarantee() default "";<br />

/**<br />

* A secure endpoint does not by default publish it's wsdl on an unsecure<br />

transport.<br />

* You can override this behaviour by explicitly setting the secureWSDLAccess<br />

flag to false.<br />

*<br />

* Protect access to WSDL. See http://jira.jboss.org/jira/browse/JBWS-723<br />

*/<br />

boolean secureWSDLAccess() default true;<br />

}<br />

7.22.1.3. SecurityDomain


**<br />

* Annotation for specifying the <strong>JBoss</strong> security domain for an EJB<br />

*/<br />

@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME)<br />

public @interface SecurityDomain<br />

{<br />

/**<br />

* The required name for the security domain.<br />

*<br />

* Do not use the JNDI name<br />

*<br />

* Good: "MyDomain"<br />

* Bad: "java:/jaas/MyDomain"<br />

*/<br />

String value();<br />

}<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 93<br />

/**<br />

* The name for the unauthenticated pricipal<br />

*/<br />

String unauthenticatedPrincipal() default "";<br />

7.23. Web Services Appendix<br />

Note<br />

This information can be used with <strong>JBoss</strong> Web Services CXF Stack.<br />

JAX-WS Endpoint Configuration<br />

JAX-WS Client Configuration<br />

JAX-WS Annotations<br />

7.24. References<br />

1. JSR-224 - Java API for XML-Based Web Services (JAX-WS) 2.0<br />

2. JSR 222 - Java Architecture for XML Binding (JAXB) 2.0<br />

3. JSR-250 - <strong>Common</strong> Annotations for the Java <strong>Platform</strong><br />

4. JSR 181 - Web Services Metadata for the Java <strong>Platform</strong>


94 Chapter 8. <strong>JBoss</strong> AOP<br />

Chapter 8. <strong>JBoss</strong> AOP<br />

<strong>JBoss</strong> AOP is a 100% Pure Java Aspected Oriented Framework usable in any programming<br />

environment or tightly integrated with our application server. Aspects allow you to more easily modularize<br />

your code base when regular object oriented programming just doesn't fit the bill. It can provide a cleaner<br />

separation from application logic and system code. It provides a great way to expose integration points<br />

into your software. Combined with JDK 1.5 Annotations, it also is a great way to expand the Java<br />

language in a clean pluggable way rather than using annotations solely for code generation.<br />

<strong>JBoss</strong> AOP is not only a framework, but also a prepackaged set of aspects that are applied via<br />

annotations, pointcut expressions, or dynamically at runtime. Some of these include caching,<br />

asynchronous communication, transactions, security, remoting, and many many more.<br />

An aspect is a common feature that is typically scattered across methods, classes, object hierarchies, or<br />

even entire object models. It is behavior that looks and smells like it should have structure, but you can't<br />

find a way to express this structure in code with traditional object-oriented techniques.<br />

For example, metrics is one common aspect. To generate useful logs from your application, you have to<br />

(often liberally) sprinkle informative messages throughout your code. However, metrics is something that<br />

your class or object model really shouldn't be concerned about. After all, metrics is irrelevant to your<br />

actual application: it doesn't represent a customer or an account, and it doesn't realize a business rule.<br />

It's simply orthogonal.<br />

8.1. Some key terms<br />

Joinpoint<br />

A joinpoint is any point in your Java program. The call of a method, the execution of a constructor, the<br />

access of a field; all these are joinpoints. You could also think of a joinpoint as a particular Java event,<br />

where an event is a method call, constructor call, field access, etc.<br />

Invocation<br />

An invocation is a <strong>JBoss</strong> AOP class that encapsulates what a joinpiont is at runtime. It could contain<br />

information like which method is being called, the arguments of the method, etc.<br />

Advice<br />

An advice is a method that is called when a particular joinpoint is executed, such as the behavior that is<br />

triggered when a method is called. It could also be thought of as the code that performs the interception.<br />

Another analogy is that an advice is an "event handler".<br />

Pointcut<br />

Pointcuts are AOP's expression language. Just as a regular expression matches strings, a pointcut<br />

expression matches a particular joinpoint.<br />

Introduction<br />

An introduction modifies the type and structure of a Java class. It can be used to force an existing class<br />

to implement an interface or to add an annotation to anything.<br />

Aspect<br />

An aspect is a plain Java class that encapsulates any number of advices, pointcut definitions, mixins, or<br />

any other <strong>JBoss</strong> AOP construct.<br />

Interceptor<br />

An interceptor is an aspect with only one advice, named invoke. It is a specific interface that you can<br />

implement if you want your code to be checked by forcing your class to implement an interface. It also will<br />

be portable and can be reused in other <strong>JBoss</strong> environments like EJBs and JMX MBeans.<br />

In AOP, a feature like metrics is called a crosscutting concern, as it is a behavior that "cuts" across


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 95<br />

multiple points in your object models, yet is distinctly different. As a development methodology, AOP<br />

recommends that you abstract and encapsulate crosscutting concerns.<br />

For example, let's say you wanted to add code to an application to measure the amount of time it would<br />

take to invoke a particular method. In plain Java, the code would look something like the following.<br />

public class BankAccountDAO<br />

{<br />

public void withdraw(double amount)<br />

{<br />

long startTime = System.currentTimeMillis();<br />

try<br />

{<br />

// Actual method body...<br />

}<br />

finally<br />

{<br />

long endTime = System.currentTimeMillis() - startTime;<br />

System.out.println("withdraw took: " + endTime);<br />

}<br />

}<br />

}<br />

While this code works, there are a few problems with this approach:<br />

1. It's extremely difficult to turn metrics on and off, as you have to manually add the code in the<br />

try/finally blocks to each and every method or constructor you want to benchmark.<br />

2. Profiling code should not be combined with your application code. It makes your code more<br />

verbose and difficult to read, since the timings must be enclosed within the try/finally blocks.<br />

3. If you wanted to expand this functionality to include a method or failure count, or even to register<br />

these statistics to a more sophisticated reporting mechanism, you'd have to modify a lot of<br />

different files (again).<br />

This approach to metrics is very difficult to maintain, expand, and extend, because it is dispersed<br />

throughout your entire code base. In many cases, OOP may not always be the best way to add metrics<br />

to a class.<br />

Aspect-oriented programming gives you a way to encapsulate this type of behavior functionality. It allows<br />

you to add behavior such as metrics "around" your code. For example, AOP provides you with<br />

programmatic control to specify that you want calls to BankAccountDAO to go through a metrics aspect<br />

before executing the actual body of that code.<br />

8.2. Creating Aspects in <strong>JBoss</strong> AOP<br />

In short, all AOP frameworks define two things: a way to implement crosscutting concerns, and a<br />

programmatic construct — a programming language or a set of tags to specify how you want to apply<br />

those snippets of code. Let's take a look at how <strong>JBoss</strong> AOP, its cross-cutting concerns, and how you<br />

can implement a metrics aspect in <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>.<br />

The first step in creating a metrics aspect in <strong>JBoss</strong> AOP is to encapsulate the metrics feature in its own<br />

Java class. The following code extracts the try/finally block in our first code example's<br />

BankAccountDAO.withdraw() method into Metrics, an implementation of a <strong>JBoss</strong> AOP Interceptor<br />

class.<br />

The following example code demonstrates implementing metrics in a <strong>JBoss</strong> AOP Interceptor


96 Chapter 8. <strong>JBoss</strong> AOP<br />

01. public class Metrics implements org.jboss.aop.advice.Interceptor<br />

02. {<br />

03. public Object invoke(Invocation invocation) throws Throwable<br />

04. {<br />

05. long startTime = System.currentTimeMillis();<br />

06. try<br />

07. {<br />

08. return invocation.invokeNext();<br />

09. }<br />

10. finally<br />

11. {<br />

12. long endTime = System.currentTimeMillis() - startTime;<br />

13. java.lang.reflect.Method m = ((MethodInvocation)invocation).method;<br />

14. System.out.println("method " + m.toString() + " time: " + endTime +<br />

"ms");<br />

15. }<br />

16. }<br />

17. }<br />

Under <strong>JBoss</strong> AOP, the Metrics class wraps withdraw(): when calling code invokes withdraw(), the<br />

AOP framework breaks the method call into its parts and encapsulates those parts into an Invocation<br />

object. The framework then calls any aspects that sit between the calling code and the actual method<br />

body.<br />

When the AOP framework is done dissecting the method call, it calls Metrics's invoke method at line 3.<br />

Line 8 wraps and delegates to the actual method and uses an enclosing try/finally block to perform<br />

the timings. Line 13 obtains contextual information about the method call from the Invocation object,<br />

while line 14 displays the method name and the calculated metrics.<br />

Having the Metrics code within its own object allows us to easily expand and capture additional<br />

measurements later on. Now that metrics are encapsulated into an aspect, let's see how to apply it.<br />

8.3. Applying Aspects in <strong>JBoss</strong> AOP<br />

To apply an aspect, you define when to execute the aspect code. Those points in execution are called<br />

pointcuts. An analogy to a pointcut is a regular expression. Where a regular expression matches strings,<br />

a pointcut expression matches events or points within your application. For example, a valid pointcut<br />

definition would be, "for all calls to the JDBC method executeQuery(), call the aspect that verifies SQL<br />

syntax."<br />

An entry point could be a field access, or a method or constructor call. An event could be an exception<br />

being thrown. Some AOP implementations use languages akin to queries to specify pointcuts. Others<br />

use tags. <strong>JBoss</strong> AOP uses both.<br />

The following listing demonstrates defining a pointcut for the Metrics example in <strong>JBoss</strong> AOP:<br />

1. <br />

2. <br />

3. <br />

4. <br />

5. <br />

6. <br />

Lines 1-3 define a pointcut that applies the metrics aspect to the specific method<br />

BankAccountDAO.withdraw(). Lines 4-6 define a general pointcut that applies the metrics aspect<br />

to all methods in all classes in the com.mc.billing package. There is also an optional annotation<br />

mapping if you prefer to avoid XML. For more information, see the <strong>JBoss</strong> AOP reference documentation.<br />

<strong>JBoss</strong> AOP has a rich set of pointcut expressions that you can use to define various points or events in<br />

your Java application. Once your points are defined, you can apply aspects to them. You can attach your<br />

aspects to a specific Java class in your application or you can use more complex compositional<br />

pointcuts to specify a wide range of classes within one expression.<br />

With AOP, as this example shows, you can combine all crosscutting behavior into one object and apply it<br />

easily and simply, without complicating your code with features unrelated to business logic. Instead,<br />

common crosscutting concerns can be maintained and extended in one place.


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 97<br />

Note that code within the BankAccountDAO class does not detect that it is being profiled. Profiling is<br />

part of what aspect-oriented programmers deem orthogonal concerns. In the object-oriented<br />

programming code snippet at the beginning of this chapter, profiling was part of the application code.<br />

AOP allows you to remove that code. A modern promise of middleware is transparency, and AOP clearly<br />

delivers.<br />

Orthogonal behavior can also be included after development. In object-oriented code, monitoring and<br />

profiling must be added at development time. With AOP, a developer or an administrator can easily add<br />

monitoring and metrics as needed without touching the code. This is a very subtle but significant part of<br />

AOP, as this separation allows aspects to be layered on top of or below the code that they cut across. A<br />

layered design allows features to be added or removed at will. For instance, perhaps you snap on<br />

metrics only when you're doing some benchmarks, but remove it for production. With AOP, this can be<br />

done without editing, recompiling, or repackaging the code.<br />

8.4. Packaging AOP <strong>Application</strong>s<br />

To deploy an AOP application in <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> you need to package it. AOP is<br />

packaged similarly to SARs (MBeans). You can either deploy an XML file directly in the deploy/<br />

directory with the signature *-aop.xml along with your package (this is how the base-aop.xml,<br />

included in the jboss-aop.deployer file works) or you can include it in the JAR file containing your<br />

classes. If you include your XML file in your JAR, it must have the file extension .aop and a jbossaop.xml<br />

file must be contained in a META-INF directory, for instance: META-INF/jboss-aop.xml.<br />

In the <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5, you must specify the schema used, otherwise your<br />

information will not be parsed correctly. You do this by adding the xmlns="urn:jboss:aopbeans:1:0<br />

attribute to the root aop element, as shown here:<br />

<br />

<br />

If you want to create anything more than a non-trivial example, using the .aop JAR files, you can make<br />

any top-level deployment contain an AOP file containing the XML binding configuration. For instance you<br />

can have an AOP file in an EAR file, or an AOP file in a WAR file. The bindings specified in the META-<br />

INF/jboss-aop.xml file contained in the AOP file will affect all the classes in the whole WAR file.<br />

To pick up an AOP file in an EAR file, it must be listed in the .ear/META-INF/application.xml as<br />

a Java module, as follows:<br />

<br />

<br />

<br />

AOP in <strong>JBoss</strong> example<br />

<br />

example.aop<br />

<br />

<br />

aopexampleejb.jar<br />

<br />

<br />

<br />

aopexample.war<br />

/aopexample<br />

<br />

<br />


98 Chapter 8. <strong>JBoss</strong> AOP<br />

Important<br />

In the <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5, the contents of the .ear file are deployed in the<br />

order they are listed in the application.xml. When using loadtime weaving the bindings listed<br />

in the example.aop file must be deployed before the classes being advised are deployed, so<br />

that the bindings exist in the system before (for example) the ejb and servlet classes are<br />

loaded. This is acheived by listing the AOP file at the start of the application.xml. Other<br />

types of archives are deployed before anything else and so do not require special consideration,<br />

such as .sar and .war files.<br />

8.5. The <strong>JBoss</strong> AspectManager Service<br />

The AspectManager Service can be managed at runtime using the JMX console, which is found at<br />

http://localhost:8080/jmx-console. It is registered under the ObjectName<br />

jboss.aop:service=AspectManager. If you want to configure it on startup you need to edit some<br />

configuration files.<br />

In <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5 the AspectManager Service is configured using a <strong>JBoss</strong><br />

Microcontainer bean. The configuration file is jboss-as/server/xxx/conf/bootstrap/aop.xml.<br />

The AspectManager Service is deployed with the following XML:<br />

<br />

<br />

false<br />

<br />

true<br />

true<br />

org.jboss.test., org.jboss.injbossaop.<br />

org.jboss.<br />

<br />

true<br />

false<br />

<br />

<br />

<br />

<br />

Later we will talk about changing the class of the AspectManager Service. To do this, replace the<br />

contents of the class attribute of the bean element.


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 99<br />

8.6. Loadtime transformation in the <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong><br />

<strong>Platform</strong> Using Sun JDK<br />

The <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> has special integration with JDK to do loadtime<br />

transformations. This section explains how to use it.<br />

If you want to do load-time transformations with <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5 and Sun JDK,<br />

these are the steps you must take.<br />

Set the enableLoadtimeWeaving attribute/property to true. By default, <strong>JBoss</strong> <strong>Application</strong> Server<br />

will not do load-time bytecode manipulation of AOP files unless this is set. If<br />

suppressTransformationErrors is true, failed bytecode transformation will only give an error<br />

warning. This flag is needed because sometimes a <strong>JBoss</strong> deployment will not include all of the<br />

classes referenced.<br />

Copy the pluggable-instrumentor.jar from the lib/ directory of your <strong>JBoss</strong> AOP distribution<br />

to the bin/ directory of your <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>.<br />

Next edit run.sh or run.bat (depending on what OS you're on) and add the following to the<br />

JAVA_OPTS environment variable:<br />

set JAVA_OPTS=%JAVA_OPTS% -Dprogram.name=%PROGNAME% -javaagent:pluggableinstrumentor.jar<br />

Important<br />

The class of the AspectManager Service must be<br />

org.jboss.aop.deployers.AspectManagerJDK5 or<br />

org.jboss.aop.deployment.AspectManagerServiceJDK5 as these are what work with<br />

the -javaagent option.<br />

8.7. JRockit<br />

JRockit also supports the -javaagent switch mentioned in Section 8.6, “Loadtime transformation in the<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> Using Sun JDK”. If you wish to use that, then the steps in<br />

Section 8.6, “Loadtime transformation in the <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> Using Sun JDK” are<br />

sufficient. However, JRockit also comes with its own framework for intercepting when classes are loaded,<br />

which might be faster than the -javaagent switch. If you want to do load-time transformations using<br />

the special JRockit hooks, these are the steps you must take.<br />

Set the enableLoadtimeWeaving attribute/property to true. By default, <strong>JBoss</strong> <strong>Enterprise</strong><br />

<strong>Application</strong> <strong>Platform</strong> will not do load-time bytecode manipulation of AOP files unless this is set. If<br />

suppressTransformationErrors is true, failed bytecode transformation will only give an error<br />

warning. This flag is needed because sometimes a <strong>JBoss</strong> deployment will not include all the classes<br />

referenced.<br />

Copy the jrockit-pluggable-instrumentor.jar from the lib/ directory of your <strong>JBoss</strong> AOP<br />

distribution to the bin/ directory of your the <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> installation.<br />

Next edit run.sh or run.bat (depending on what OS you're on) and add the following to the<br />

JAVA_OPTS and JBOSS_CLASSPATH environment variables:<br />

# Setup <strong>JBoss</strong> specific properties<br />

JAVA_OPTS="$JAVA_OPTS -Dprogram.name=$PROGNAME \<br />

-Xmanagement:class=org.jboss.aop.hook.JRockitPluggableClassPreProcessor"<br />

JBOSS_CLASSPATH="$JBOSS_CLASSPATH:jrockit-pluggable-instrumentor.jar"<br />

Set the class of the AspectManager Service to<br />

org.jboss.aop.deployers.AspectManagerJRockit on <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong><br />

<strong>Platform</strong> 5, or org.jboss.aop.deployment.AspectManagerService as these are what work<br />

with special hooks in JRockit.


100 Chapter 8. <strong>JBoss</strong> AOP<br />

8.8. Improving Loadtime Performance in the <strong>JBoss</strong> <strong>Enterprise</strong><br />

<strong>Application</strong> <strong>Platform</strong> Environment<br />

The same rules apply to the <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> for tuning loadtime weaving<br />

performance as standalone Java. Switches such as pruning, optimized, include and exclude are<br />

configured through the jboss-5.x.x.GA/server/xxx/conf/aop.xml file talked about earlier in this<br />

chapter.<br />

8.9. Scoping the AOP to the classloader<br />

By default all deployments in <strong>JBoss</strong> are global to the whole application server. That means that any EAR,<br />

SAR, or JAR (for example), that is put in the deploy directory can see the classes from any other<br />

deployed archive. Similarly, AOP bindings are global to the whole virtual machine. This global visibility<br />

can be turned off per top-level deployment.<br />

8.9.1. Deploying as part of a scoped classloader<br />

The following process may change in future versions of <strong>JBoss</strong> AOP. If you deploy an AOP file as part of<br />

a scoped archive, the bindings (for instance) applied within the .aop/META-INF/jboss-aop.xml file<br />

will only apply to the classes within the scoped archive and not to anything else in the application server.<br />

Another alternative is to deploy -aop.xml files as part of a service archive (SAR). Again, if the SAR is<br />

scoped, the bindings contained in the -aop.xml files will only apply to the contents of the SAR file. It is<br />

not currently possible to deploy a standalone -aop.xml file and have that attach to a scoped<br />

deployment. Standalone -aop.xml files will apply to classes in the whole application server.<br />

8.9.2. Attaching to a scoped deployment<br />

If you have an application that uses classloader isolation, as long as you have prepared your classes,<br />

you can later attach an AOP file to that deployment. If we have an EAR file scoped using a jbossapp.xml<br />

file, with the scoped loader repository jboss.test:service=scoped:<br />

<br />

<br />

jboss.test:service=scoped<br />

<br />

<br />

We can later deploy an AOP file containing aspects and configuration to attach that deployment to the<br />

scoped EAR. This is done using the loader-repository tag in the AOP file's META-INF/jbossaop.xml<br />

file.<br />

<br />

<br />

jboss.test:service=scoped<br />

<br />

<br />

This has the same effect as deploying the AOP file as part of the EAR as we saw previously, but allows<br />

you to hot deploy aspects into your scoped application.


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 101<br />

Chapter 9. Transaction Management<br />

This chapter presents a brief overview of the main configuration options for the <strong>JBoss</strong> Transaction<br />

Service. For more information, please refer to the <strong>JBoss</strong> Transactions Administration Guide.<br />

9.1. Overview<br />

Transaction support in <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> is provided by <strong>JBoss</strong> Transaction Service,<br />

a mature, modular,standards based, highly configurable transaction manager. By default, the server runs<br />

with the local-only JTA module of <strong>JBoss</strong> Transaction Service installed. This module provides an<br />

implementation of the standard JTA API for use by other internal components, such as the EJB<br />

container, as well as direct use by applications. It is suitable for coordinating ACID transactions that<br />

involve one or more XA Resource managers, such as relational databases or message queues.<br />

Two additional, optional, <strong>JBoss</strong> Transaction Service transaction modules are also shipped with <strong>JBoss</strong><br />

<strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> and may be deployed to provide additional functionality if required.<br />

<strong>JBoss</strong> Transaction Service JTS<br />

A Transaction Manager capable of distributing transaction context on remote IIOP method calls,<br />

creating a single distributed transaction which spans multiple Java Virtual Machines. This is<br />

useful for large-scale applications that span multiple servers, or for standards based<br />

interoperability with transactional business logic running in CORBA based systems. The<br />

functionality of this module can be accessed through the standard JTA API. In this way, it is a<br />

drop-in replacement and does not require changes to transactional business logic. To enable it,<br />

refer to Section 9.8, “Using the JTS Module” for more information.<br />

<strong>JBoss</strong> Transaction Service XTS<br />

A Transaction Manager, based on XML, which implements the WS-AtomicTransaction (WS-AT)<br />

and WS-BusinessActivity (WS-BA) specifications. This additional module uses core transaction<br />

support provided by the JTA or JTS managers, along with web services functionality provided<br />

by <strong>JBoss</strong>WS Native. It is deployed into the server as an application. <strong>Application</strong>s may use WS-<br />

AT to provide standards based, distributed ACID transactions in a manner similar to JTS but<br />

using a Web Services transport, instead of CORBA. The WS-BA implementation compliments<br />

this by providing an alternative, compensation-based transaction model, well suited to<br />

coordinating long-running, loosely coupled business processes. XTS also implements a WS-<br />

Coordination (WS-C) service which is usually accessed internally by the local WS-AT and WS-<br />

BA implementations. However, this WS-C service can also be used to provide remote<br />

coordination for WS-AT and WS-BA transactions created in other <strong>JBoss</strong> server instances or<br />

non-<strong>JBoss</strong> containers. Refer to the <strong>JBoss</strong> Transactions Web Services Programmer's Guide for<br />

more details. To enable XTS, refer to Section 9.9, “Using the XTS Module”.<br />

9.2. Configuration Essentials<br />

Configuration of the default <strong>JBoss</strong>TS JTA is managed though a combination of the transaction<br />

manager's own properties file and the application server's deployment configuration. The configuration<br />

file resides at $JBOSS_HOME/server/[name]/conf/jbossts-properties.xml. It contains<br />

defaults for the most commonly used properties. Many more are detailed in the accompanying <strong>JBoss</strong><br />

Transaction Service Administration Guide. Each setting has a hard-coded default, but the system may<br />

not function properly if a configuratino file does not exist. Additional configuratino is also possible as part<br />

of the Microcontainer beans configuration found in the<br />

$JBOSS_HOME/server/[name]/deploy/transaction-jboss-beans.xml file. This ties the<br />

transaction manager into the overall server configuration, overriding the transaction configuration file<br />

settings with values specific to the application server where appropriate. In particular, it uses the Service<br />

Binding Manager to set port binding information, as well as overriding selected other properties.<br />

Configuration properties are read by the Transaction Service at server initialization, and the server must<br />

be restarted to incorporate any changes made to the configuration files.


102 Chapter 9. Transaction Management<br />

Table 9.1. Most Critical Properties for <strong>JBoss</strong> Transaction Service<br />

Property Name Default Value Description<br />

transactionTimeout 300 seconds the default time, in seconds,<br />

after which a transaction will<br />

time out and be rolled back by.<br />

Adjust this to suit your<br />

environment and workload.<br />

It may come as a surprise that<br />

transactions are processed<br />

asynchronously. This was a<br />

design decision, and needs to<br />

be accounted for by your code.<br />

objectStoreDir The directory where transaction<br />

data is logged. The transaction<br />

log is required to complete<br />

transactions in the case of<br />

system failure, and needs to be<br />

on reliable storage. Normally<br />

one file is generated per<br />

transaction, and each file is a<br />

few kilobytes in size. These are<br />

distributed over a directory tree<br />

for optimal performance. If a<br />

RAID controller is used, it should<br />

be configured for write through<br />

cache, in much the same<br />

manner as database storage<br />

devices. Writing of the<br />

transaction log is automatically<br />

skipped in the case of<br />

transactions that are rolling<br />

back or contain only a single<br />

resource.


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 103<br />

Table 9.2. Additional Properties for <strong>JBoss</strong> Transaction Service<br />

Property Name Default<br />

Value<br />

com.arjuna.common.util.logging.DebugLevel 0x00000000,<br />

which equates<br />

to no logging<br />

Description<br />

determines the internal log<br />

threshold for the transaction<br />

manager codebase. It is<br />

independent of the overall server's<br />

log4 j logging configuration, and<br />

acts to suppress extraneous log<br />

entries from being printed. When<br />

the default value is active, INFO<br />

and WARN messages are still<br />

printed, and this setting provides<br />

optimal performance.<br />

0xffffffff enables full debug<br />

logging. This setting results in<br />

large log files.<br />

Log messages that pass the<br />

internal DebugLevel check are<br />

passed to the server's logging<br />

system for further processing. In<br />

theory, full debugging may be left<br />

on and log4 j can be used to turn<br />

logging on or off, but in reality this<br />

has a performance impact.<br />

com.arjuna.ats.arjuna.coordinator.commitOnePhase YES Determines whether the<br />

transaction manager automatically<br />

applies the one-phase commit<br />

optimization to the transaction<br />

completion protocol, when only a<br />

single resource is registered with<br />

the transaction. Enabled by default<br />

to prevent writing transaction logs<br />

needlessly.<br />

com.arjuna.ats.arjuna.objectstore.transactionSync ON Controls the flushing of transaction<br />

logs to disk during transaction<br />

termination. The default value<br />

results in a<br />

FileDescriptor.sync call for<br />

each committing transaction. This<br />

behavior is required to provide<br />

recovery and ACID properties. If<br />

these features are unimportant to<br />

the application in question, you can<br />

achieve better performance by<br />

disabling this property. This is<br />

discouraged, since it is usually<br />

better to write such applications in<br />

a way that avoids using<br />

transactions at all.<br />

com.arjuna.ats.arjuna.xa.nodeIdentifier<br />

com.arjuna.ats.jta.xaRecoveryNode<br />

These properties determine the<br />

behavior of the transaction<br />

recovery system. They must be<br />

configured correctly to ensure that<br />

transactions are resolved correctly<br />

so that recovery can happen if the<br />

server crashes. Please refer to the<br />

Recovery chapter of the <strong>JBoss</strong><br />

Transactions Administration Guide<br />

for more details.<br />

com.arjuna.ats.arjuna.coordinator.enableStatistics NO Enables gathering of transaction<br />

statistics. The statistics can be<br />

viewed using methods on the


104 Chapter 9. Transaction Management<br />

9.3. Transactional Resources<br />

TransactionManagerService<br />

bean or its corresponding JMX<br />

MBean. Disabled by default.<br />

The Transaction Service coordinates transaction state updates using XAResource implementations,<br />

which are provided by the various resource managers. Resource managers may include databases,<br />

message queues or third-party JCA resource adapters. The list of databases and JDBC drivers which<br />

have been certified on <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> is located at<br />

http://www.jboss.com/products/platforms/application/supportedconfigurations/. Most standards-compliant<br />

JDBC drivers should function correctly, but you should perform extensive testing when using an<br />

uncertified configuration, since interpretations of the XA specifications different from one vendor to<br />

another.<br />

Database connection pools are configured via the application server's Datasource files, which are files<br />

named like -ds.xml. Datasources which use the property automatically interact with<br />

the transaction manager. Connections obtained by looking up such datasource in JNDI and calling<br />

getConnection automatically participate in ongoing transactions. This is the preferred use case when<br />

transactional guarantees for data access are required.<br />

If you are using a database which cannot support XA transactions, you can deploy a connection pool<br />

using . This type of datasource participates in the managed transaction using the<br />

Section 9.4, “Last Resource Commit Optimization (LRCO)”, providing more limited transactional<br />

guarantees. Connections obtained from a do not interact with the transaction<br />

manager, and any work done on such connections must be explicitly committed or rolled back by the<br />

application, using the JDBC API.<br />

Many databases require additional configuration before they can function as XA resource managers.<br />

Vendor-specific information for configuring databases is presented in Appendix A, Vendor-Specific<br />

Datasource Definitions. Refer to your database administrator and the documentation which ships with<br />

your database for additional configuration directives. In addition, please consult the <strong>JBoss</strong> Transactions<br />

Administration Guide for information on setting up XA recovery properly.<br />

<strong>JBoss</strong> Messaging provides an XA-aware driver and can participate in XA transactions. Please consult<br />

the <strong>JBoss</strong> Messaging User Guide for more details.<br />

9.4. Last Resource Commit Optimization (LRCO)<br />

Although the XA transaction protocol is designed to provide ACID properties by using a two-phase<br />

commit protocol, model may not always be appropriate. Sometimes it is necessary to allow a non-XAaware<br />

resource manager to participate in a transaction. This is often the case with data stores that do<br />

not support distributed transactions.<br />

In this situation, you can use a technique known as Last Resource Commit Optimization (LRCO). This is<br />

sometimes called the Last Resource Gambit. The one-phase-aware resource is processed last in the<br />

prepare phase of the transaction, at which time an attempt is made to commit it. If the attempt is<br />

successful, the transaction log is written and the remaining resources go through the phase-two commit.<br />

If the last resource fails to commit, the transaction is rolled back. Although this protocol allows most<br />

transactions to complete normally, some errors can cause an inconsistent transaction outcome. For this<br />

reason, use LRCO as a last resort. When a single is used in a transaction, the<br />

LRCO is automatically applied to it. In other situations, you can designate a last resource by using a<br />

special marker interface. Refer to the <strong>JBoss</strong> Transactions Programmer's Guide for more details.<br />

Using more than a single one-phase resource in the same transaction is not transactionally safe, and is<br />

not recommended. <strong>JBoss</strong> Transaction Service sees an attempt to enlist a second such resource as an<br />

error and terminates the transaction. This type of error is most often found when migrating from a legacy<br />

version of <strong>JBoss</strong> <strong>Application</strong> Server. Whenever possible the should be converted<br />

to an to resolve the difficulty.<br />

9.5. Transaction Timeout Handling<br />

In order to prevent indefinite locking of resources, the transaction manager aborts in-flight transactions


that have not completed after a specified interval, using a set of background processes coordinated by<br />

the TransactionReaper. The reaper rolls back transactions without interrupting any threads that<br />

may be operating within their scope. This prevents instability that results from interrupting threads<br />

executing arbitrary code. Furthermore, it allows for timely abort of transactions where the business logic<br />

thread may be executing non-interruptable operations such as network I/O operations. This approach<br />

may, cause unexpected behavior in code that is not designed to handle multithreaded transactions.<br />

Warning or error messages may be printed from transaction-aware components as a result of the<br />

unexpected change in transaction status. The transaction outcome should usually be unaffected. Any<br />

problems can be minimized by tuning the transaction timeout values. See Chapter 13, Datasource<br />

Configuration for more information.<br />

9.6. Recovery Configuration<br />

To ensure that your configuration is robust, it is important to configure <strong>JBoss</strong> Transaction Service<br />

properly for failure and recovery. This is covered in detail in the <strong>JBoss</strong> Transactions Administration<br />

Guide, in the "Resource Recovery in <strong>JBoss</strong> Transaction Service" chapter.<br />

9.7. Transaction Service FAQ<br />

This section presents some of the most common configuration issues with <strong>JBoss</strong> Transaction Service.<br />

Q:<br />

A:<br />

Q:<br />

A:<br />

Q:<br />

A:<br />

Q:<br />

A:<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 105<br />

I turned on debug logging, but nothing is logged.<br />

<strong>JBoss</strong>TS sends log statements though two levels of filters.<br />

1. Logs go through <strong>JBoss</strong> Transaction Service's own logging abstraction layer.<br />

2. Logs go through <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>'s log4j logging system.<br />

A log statement must pass both filters to be printed. A typical mistake is enabling only one or the<br />

other of the logging systems. See Table 9.2, “Additional Properties for <strong>JBoss</strong> Transaction Service”<br />

for more information.<br />

Why do server logs show WARN Adding multiple last resources is disallowed.,<br />

and why are my transactions are aborted?<br />

You are probably using a and trying to use more than one one-phase<br />

aware participant. This is a configuration to be avoided. See Section 9.4, “Last Resource Commit<br />

Optimization (LRCO)” for more information. If you have further concerns, please contact Global<br />

Support Services.<br />

My server terminated unexpectedly. It is running again, but my logs are filling with<br />

messages like WARN [com.arjuna.ats.jta.logging.loggerI18N]<br />

[com.arjuna.ats.internal.jta.resources.arjunacore.norecoveryxa] Could<br />

not find new XAResource to use for recovering non-serializable<br />

XAResource.<br />

You may not have configured all resource managers for recovery. Refer to the Recovery chapter of<br />

the <strong>JBoss</strong> Transactions Administration Guide for more information on configuring resource<br />

managers for recovery.<br />

My transactions take a long time and sometimes strange things happen. The server log<br />

contains WARN [arjLoggerI18N] [BasicAction_58] - Abort of action id ...<br />

invoked while multiple threads active within it.<br />

Transactions which exceed their timeout may be rolled back. This is done by a background thread,<br />

which can confuse some application code that may be expecting an interrupt. Refer to Section 9.5,<br />

“Transaction Timeout Handling” for more information.<br />

If you have questions besides the ones addressed above, please consult the other <strong>JBoss</strong> Transactions<br />

guides, or contact Global Support Services.


106 Chapter 9. Transaction Management<br />

9.8. Using the JTS Module<br />

If you need transaction propagation betweenb usiness logic in different servers, you can use the JTS<br />

API. Although you can use it directly, it is typical to access it via the standard JTA classes. It is a drop-in<br />

replacement for the default local-only JTA implementation. The necessary classes are already in place,<br />

and you only need to modify the jbossts-properties.xml file to move between the JTA and JTS<br />

modules.<br />

A sample jbossts-properties.xml file is located in the<br />

$JBOSS_HOME/docs/examples/transactions/ directory. Consult the README.txt file in the same<br />

directory for more information about changes that need to be made to other files, including the<br />

transactions-jboss-beans.xml file. An ANT script is provided to perform all of the steps<br />

automatically, but it is recommended to consult the README.txt carefully before running the script, as<br />

well as backing up your existing configuration.<br />

The JTS requires the server configuration to also contain the CORBA ORB service. The "all"<br />

configuration referenced in the examples is a good starting point. The choice of JTS or JTA impacts the<br />

entire server, and JTS does require additional resources. Therefore, only use it when it is needed.<br />

At application start-up, a server that is configured to use JTA outputs log files like this one:<br />

...)<br />

INFO [TransactionManagerService] <strong>JBoss</strong>TS Transaction Service (JTA version -<br />

If JTS is enabled, the message looks like this one:<br />

...)<br />

INFO [TransactionManagerService] <strong>JBoss</strong>TS Transaction Service (JTS version -<br />

9.9. Using the XTS Module<br />

XTS, which is the Web Services component of <strong>JBoss</strong> Transaction Service, can be installed to provide<br />

WS-AT and WS-BA support for web services hosted on the <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>. The module<br />

is packaged as a Service Archive (.sar) located in $JBOSS_HOME/docs/examples/transactions/.<br />

Procedure 9.1. Installing the XTS Module<br />

1. Create a subdirectory in the $JBOSS_HOME/server/[name]/deploy/ directory, called<br />

jbossxts.sar/.<br />

2. Unpack the .sar, which is a ZIP archive, into this new directory.<br />

3. Restart <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> for the module to be active.<br />

The server must use either the JTA or JTS module, as well as <strong>JBoss</strong>WS Native.<br />

Note<br />

XTS is not currently expected to work with other <strong>JBoss</strong>WS backends such as CXF. The default<br />

XTS configuration is suitable for most deployments. It automatically detects information about the<br />

network interfaces and port bindings from the EAP configuration. manual configuration changes<br />

are only necessary for deployments whose applications need to use a transaction coordinator on<br />

a separate host. Consult the <strong>JBoss</strong> Web Service Transactions Programmer's Guide for more<br />

information.<br />

Developers can link against the jbossxts-api.jar file included in the XTS Service Archive, but<br />

should avoid packaging it with their applications, to avoid classloading problems. All other JAR files<br />

contain internal implementation classes and should not be used directly.<br />

Consult $JBOSS_HOME/docs/examples/transactions/README.txt for emore configuration<br />

information. The <strong>JBoss</strong> Web Services Transactions User Guide contains information about using XTS in<br />

your applications.<br />

9.10. Transaction Management Console


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 107<br />

The Transaction Management Console is a simle GUI tool that is included in<br />

$JBOSS_HOME/docs/example/transactions/. It is provided as an unsupported, experimental<br />

prototype. Consult the README.txt file for its capabilities and information about its use.<br />

9.11. Experimental Components<br />

In addition to the supported components of <strong>JBoss</strong> Transaction Service which are included in <strong>JBoss</strong><br />

<strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>, there is ongoing feature work that may eventually find its way into future<br />

releases of the product. In the meantime, these prototype components are available via from the<br />

http://jboss.org Community website.<br />

Warning<br />

There is no guarantee these components will work correctly and they are not covered under the<br />

<strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> support agreement. However, some of the advanced functionality<br />

available may useful for projects in the early stages of development. Users downloading these<br />

prototypes must be aware of the limitations concerning module compatibility, in accordance with<br />

the Section 9.12, “Source Code and Upgrading”.<br />

txbridge<br />

Sometimes you may need the ability to invoke traditional transaction components, such as<br />

EJBs, within the scope of a Web Services transaction. Conversely, some traditional<br />

transactional applications may need to invoke transactional web services. The Transaction<br />

Bridge (txbridge) provides mechanisms for linking these two types of transactional services<br />

together.<br />

BA Framework<br />

The XTS API operates at a very low level, requiring the developer to undertake much of the<br />

transaction infrastructure work involved in WS-BA. The BA Framework provides high-level<br />

annotations that enable <strong>JBoss</strong> Transaction Service to handle this infrastructure. The developer<br />

can then focus more on business logic instead.<br />

9.12. Source Code and Upgrading<br />

Most problems relating to transactions can be diagnosed by Global Support Services, after you provide<br />

debug logging information from the server.<br />

However, you can debug or review the source code yourself, using your own tools. You can download<br />

the source code using the Subversion repository at http://anonsvn.jboss.org/repos/labs/labs/jbosstm/.<br />

<strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> outputs the version of the Transaction Service at start-up, using a string<br />

similar to this one:<br />

INFO [TransactionManagerService] <strong>JBoss</strong>TS Transaction Service (JTA version -<br />

tag:JBOSSTS_4_6_1_GA_CP02) - <strong>JBoss</strong> Inc.<br />

The tag element corresponds to a tree under /tags/ in the Subversion repository. Note that the version<br />

refers to the version of the <strong>JBoss</strong> Transaction Service component used in the <strong>Enterprise</strong> <strong>Application</strong><br />

<strong>Platform</strong>, not the version of EAP itself. If you build <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> from source, you can<br />

also find the version by searching for the string version.jboss.jbossts in the componentmatix/pom.xml<br />

file.<br />

Warning<br />

Installing any version of <strong>JBoss</strong>TS other than those provided with the <strong>Enterprise</strong> <strong>Application</strong><br />

<strong>Platform</strong> you are using is not supported. While some <strong>JBoss</strong> Transaction Service components are<br />

packaged separately, it is unsupported to use different versions than the ones suppolied with<br />

<strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>.


108 Chapter 9. Transaction Management


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 109<br />

Chapter 10. Remoting<br />

The main objective of <strong>JBoss</strong> Remoting is to provide a single API for most network based invocations and<br />

related services that use pluggable transports and data marshallers. The <strong>JBoss</strong> Remoting API provides<br />

the ability for making synchronous and asynchronous remote calls, push and pull callbacks, and<br />

automatic discovery of remoting servers. The intention is to allow for the addition of different transports<br />

to fit different needs, yet still maintain the same API for making the remote invocations and only requiring<br />

configuration changes, not code changes, to fit these different needs.<br />

Out of the box, Remoting supplies multiple transports (bisocket, http, rmi, socket, servlet, and their ssl<br />

enabled counterparts), standard and compressing data marshallers, and a configurable facility for<br />

switching between standard jdk serialization and <strong>JBoss</strong> Serializabion. It is also capable of remote<br />

classloading, has extensive facilities for connection failure notification, performs call by reference<br />

optimization for client/server invocations collocated in a single JVM, and implements multihomed servers.<br />

In the <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>, Remoting supplies the transport layer for the EJB2, EJB3, and<br />

Messaging subsystems. In each case, the configuration of Remoting is largely predetermined and fixed,<br />

but there are times when it is useful to know how to alter a Remoting configuration.<br />

10.1. Background<br />

A Remoting server consists of a Connector, which wraps and configures a transport specific server<br />

invoker. A connector is represented by an InvokerLocator string, such as<br />

socket://bluemonkeydiamond.com:8888/?timeout=10000&serialization=jboss<br />

which indicates that a server using the socket transport is accessible at port 8888 of host<br />

bluemonkeydiamond.com, and that the server is configured to use a socket timeout of 10000 and to use<br />

<strong>JBoss</strong> Serialization. A Remoting client can use an InvokerLocator to connect to a given server.<br />

In the <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>, Remoting servers and clients are created far below the surface<br />

and are accessible only through configuration files. Moreover, when a proxy for a SLSB, for example, is<br />

downloaded from the JNDI directory, it comes with a copy of the InvokerLocator, so that it knows how to<br />

contact the appropriate Remoting server. The important fact to note is that, since the server and<br />

its clients share the InvokerLocator, the parameters in the InvokerLocator serve to<br />

configure both clients and servers.<br />

10.2. <strong>JBoss</strong> Remoting Configuration<br />

There are two kinds of XML files that can be used to create and configure a Remoting Connector. A file<br />

with a name of the form *-service.xml can be used to define a Connector as an MBean, and a file of the<br />

form *-jboss-beans.xml can be used to define a Connector as a POJO.<br />

10.2.1. MBeans<br />

In the <strong>JBoss</strong> Messaging JMS subsystem, a Remoting server is configured in the file remoting-bisocketservice.xml,<br />

which, in abbreviated form, looks like


110 Chapter 10. Remoting<br />

<br />

<br />

<br />

<br />

org.jboss.jms.wireformat.JMSWireFormat<br />

org.jboss.jms.wireformat.JMSWireFormat<br />

${jboss.bind.address}<br />

4457<br />

10000<br />

...<br />

<br />

...<br />

<br />

<br />

<br />

This configuration file tells us several facts, including<br />

This server uses the bisocket transport;<br />

it runs on port 4457 of host ${jboss.bind.address}; and<br />

<strong>JBoss</strong> Messaging uses its own marshalling algorithm.<br />

The InvokerLocator is derived from this file. The important fact to note is that the attribute<br />

"isParam" determines if a parameter is to be included in the InvokerLocator. If "isParam" is<br />

omitted or set to false, the parameter will apply only to the server. In this case, the parameter will not be<br />

transmitted to the client. The InvokerLocator for a Remoting server with a ${jboss.bind.address} of<br />

bluemonkeydiamond.com would be:<br />

bisocket://bluemonkeydiamond.com:4457/?marshaller=<br />

org.jboss.jms.wireformat.JMSWireFormat&<br />

unmarshaller=org.jboss.jms.wireformat.JMSWireFormat<br />

Note that the parameter "callbackTimeout" is not included in the InvokerLocator.<br />

10.2.2. POJOs<br />

The same Connector could be configured by way of the<br />

org.jboss.remoting.ServerConfiguration POJO:


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 111<br />

<br />

@org.jboss.aop.microcontainer.aspects.jmx.JMX<br />

(name="jboss.messaging:service=Connector,transport=bisocket",<br />

exposedInterface=org.jboss.remoting.transport.ConnectorMBean.class,<br />

registerDirectly=true)<br />

<br />

<br />

<br />

<br />

<br />

bisocket<br />

<br />

<br />

<br />

<br />

<br />

serverBindAddress<br />

<br />

<br />

JBMConnector<br />

${host}<br />

<br />

<br />

<br />

<br />

serverBindPort<br />

<br />

<br />

JBMConnector<br />

${port}<br />

<br />

<br />

<br />

...<br />

marshaller<br />

org.jboss.jms.wireformat.JMSWireFormat<br />

unmarshaller<br />

org.jboss.jms.wireformat.JMSWireFormat<br />


112 Chapter 10. Remoting<br />

<br />

<br />

<br />

<br />

JBMConnector:bindingHome1<br />

${host}:${port}<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

JBMConnector:bindingHome2<br />

!${host}:${port}<br />

<br />

<br />

<br />

<br />

which results in a StringBuffer with a value something like (according to the ServiceBindingManager<br />

configuration values for JBMConnector:bindingHome1 and JBMConnector:bindingHome2)<br />

"external.acme.com:5555!internal.acme.com:4444", and (2) replacing the "serverBindAddress" and<br />

"serverBindPort" parameters with<br />

<br />

homes<br />

<br />

<br />

which transforms the StringBuffer into the String "external.acme.com:5555!internal.acme.com:4444" and<br />

injects it into the JBMConnector. The resulting InvokerLocator will look like<br />

bisocket://multihome/?homes=external.acme.com:5555!internal.acme.com:<br />

4444&marshaller=org.jboss.jms.wireformat.JMSWireFormat&<br />

unmarshaller=org.jboss.jms.wireformat.JMSWireFormat<br />

10.4. Address translation<br />

Sometimes a server must be accessed through an address translating firewall, and a Remoting server<br />

can be configured with both a binding address/port and an address/port to be used by a client. Two<br />

more parameters are used: "clientConnectAddress" and "clientConnectPort". The "serverBindAddress"<br />

and "serverBindPort" values are used to create the server, and the values of "clientConnectAddress"<br />

and "clientConnectPort" are used in the InvokerLocator, which tells the client where the server is. There<br />

is also an analogous "connecthomes" parameter for multihome servers. In this case, "homes" is used to<br />

configure the server, and "connecthomes" tells the client where the server is.<br />

10.5. Where are they now?<br />

The actual Remoting configuration files for the supported subsystems are as follows:<br />

EJB2: ${JBOSS_HOME}/server/${CONFIG}/deploy/remoting-jboss-beans.xml<br />

EJB3: ${JBOSS_HOME}/server/${CONFIG}/deploy/ejb3-connectors-jboss-beans.xml<br />

JBM: ${JBOSS_HOME}/server/${CONFIG}/deploy/messaging/remoting-bisocket-service.xml<br />

10.6. Further information.<br />

Additional details may be found in the Remoting Guide at<br />

http://www.jboss.org/jbossremoting/docs/guide/2.5/html/index.html.


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 113<br />

Chapter 11. <strong>JBoss</strong> Messaging<br />

The most current information about using <strong>JBoss</strong> Messaging is always available from the relevant <strong>JBoss</strong><br />

Messaging User Guide at http://www.redhat.com/docs/en-US/<strong>JBoss</strong>_<strong>Enterprise</strong>_<strong>Application</strong>_<strong>Platform</strong>/.


114 Chapter 12. Use Alternative Databases with <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong><br />

Chapter 12. Use Alternative Databases with <strong>JBoss</strong> <strong>Enterprise</strong><br />

<strong>Application</strong> <strong>Platform</strong><br />

12.1. How to Use Alternative Databases<br />

<strong>JBoss</strong> utilizes the Hypersonic database as its default database. While this is good for development and<br />

prototyping, you or your company will probably require another database to be used for production. This<br />

chapter covers configuring <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> to use alternative databases. We<br />

cover the procedures for all officially supported databases on the <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>.<br />

For a complete list of certified databases, refer to<br />

http://www.jboss.com/products/platforms/application/supportedconfigurations/.<br />

Please note that in this chapter, we explain how to use alternative databases to support all services in<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>. This includes all the system level services such as EJB and JMS.<br />

For individual applications (e.g., WAR or EAR) deployed in <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>, you<br />

can still use any backend database by setting up the appropriate data source connection.<br />

Installing the external database is out of the scope of this document. Use the tools provided by your<br />

database vendor to set up an empty database. You will need the database name, connection URL,<br />

username, and password, in order to create the datasource the <strong>Platform</strong> will use to connect to the<br />

database.<br />

12.2. Install JDBC Drivers<br />

To use the selected external database, you must also install the JDBC driver for your database. The<br />

JDBC driver is a JAR file, which must be placed into the JBOSS_HOME/server/PROFILE/lib directory.<br />

Replace PROFILE with the server profile you are using.<br />

This file is loaded when <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> starts up, so if you have the <strong>JBoss</strong><br />

<strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> running, you will need to shut down and restart. Review the list below for<br />

a suitable JDBC driver. For a full list of certified <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> database drivers,<br />

refer to http://www.jboss.com/products/platforms/application/supportedconfigurations/#JEAP5-0. If the<br />

links fail to work, please file a JIRA against this documentation, but be aware that Red Hat does not<br />

control these external links. Contact your database vendor for the most current version of the driver for<br />

your database.<br />

JBDC Driver Download Locations<br />

MySQL<br />

Download from http://www.mysql.com/products/connector/.<br />

PostgreSQL<br />

Oracle<br />

IBM<br />

Sybase<br />

Download from http://jdbc.postgresql.org/.<br />

Download from http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/index.html.<br />

Download from http://www-306.ibm.com/software/data/db2/java/.<br />

Download from the Sybase jConnect product page<br />

http://www.sybase.com/products/allproductsa-z/softwaredeveloperkit/jconnect.


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 115<br />

Microsoft<br />

Sybase jConnect JDBC Driver 7<br />

When using Sybase database with this driver, the MaxParams attribute cannot be set<br />

higher than 481 due to a limitation in the driver's PreparedStatement class.<br />

Download from the MSDN web site http://msdn.microsoft.com/data/jdbc/.<br />

12.2.1. Special Notes on Sybase<br />

Some of the services in <strong>JBoss</strong> uses null values for the default tables that are created. Sybase Adaptive<br />

Server should be configured to allow nulls by default.<br />

sp_dboption db_name, "allow nulls by default", true<br />

Refer to the Sybase manuals for more options.<br />

Additionally, text and image values stored in the database can be very large. When a select list includes<br />

both text and image values, the length limit of the data returned is determined by the @@textsize<br />

global variable. The default setting for this variable depends on the software used to access Adaptive<br />

Server. For the JDBC driver, the default value is 32 kilobytes.<br />

12.2.1.1. Enable JAVA services<br />

To use any Java service (for example; JMS, CMP, timers) configured with Sybase, Java must be enabled<br />

on Sybase Adaptive Server. To do this use:<br />

sp_configure "enable java",1<br />

Refer to the sybase manuals for more information.<br />

If Java is not enabled for Sybase Adaptive Server, the following error message may be echoed in the<br />

console.<br />

com.sybase.jdbc2.jdbc.SybSQLException: Cannot run this command because Java<br />

services are not<br />

enabled. A user with System Administrator (SA) role must reconfigure the<br />

system to enable Java<br />

12.2.1.2. CMP Configuration<br />

To use Container Managed Persistence for user defined Java objects with Sybase Adaptive Server<br />

<strong>Enterprise</strong>, the Java classes should be installed in the database. The system table sysxtypes contains<br />

one row for each extended Java-SQL datatype. This table is only used for Adaptive Servers enabled for<br />

Java. Install Java classes using the installjava program.<br />

installjava -f -S -U -P -<br />

D<br />

Refer to the installjava manual in Sybase for more options.<br />

12.2.1.3. Installing Java Classes<br />

1. You have to be a super-user with required privileges to install Java classes.<br />

2. The JAR file you are trying to install should be created without compression.<br />

3. Java classes that you install and use in the server must be compiled with JDK 1.2.2. If you compile<br />

a class with a later JDK, you will be able to install it in the server using the installjava utility, but<br />

you will get a java.lang.ClassFormatError exception when you attempt to use the class. This is<br />

because Sybase Adaptive Server uses an older JVM internally, and requires the Java classes to<br />

be compiled with the same.


116 Chapter 12. Use Alternative Databases with <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong><br />

12.2.2. Configuring JDBC DataSources<br />

Datasources correspond to the simplified JCA Datasource configuration specifications.<br />

Datasources need to reside in the JBOSS_HOME/server/PROFILE/deploy directory, alongside other<br />

deployable applications and resources. The files use a standard naming scheme of DBNAME-ds.xml.<br />

Example datasources for all certified databases are located in the<br />

$JBOSS_HOME/docs/examples/jca directory. Edit the datasource that corresponds to your database,<br />

and copy it to the deploy/ directory before restarting the application server.<br />

See Chapter 13, Datasource Configuration for information on configuring datasources. As a minimum,<br />

you will need to change the connection-url, user-name, and password to correspond to your<br />

database of choice.<br />

12.3. <strong>Common</strong> Database-Related Tasks<br />

12.3.1. Security and Pooling<br />

Unless the ResourceAdapter has , using multiple security<br />

identities will create subpools for each identity.<br />

Note<br />

The min and max pool size are per subpool, so be careful with these parameters if you have lots<br />

of identities.<br />

12.3.2. Change Database for the JMS Services<br />

The JMS service in the <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> uses relational databases to persist its<br />

messages. For improved performance, we should change the JMS service to take advantage of the<br />

external database. To do that, we need to replace the file<br />

$JBOSS_HOME/server/$PROFILE/deploy/messaging/$DATABASE-persistence-service.xml<br />

with the $DATABASE-persistence-service.xml filename depending on your external database.<br />

MySQL: mysql-persistence-service.xml<br />

PostgreSQL: postgresql-persistence-service.xml<br />

Oracle: oracle-persistence-service.xml<br />

DB2: db2-persistence-service.xml<br />

Sybase: sybase-persistence-service.xml<br />

MS SQL Server: mssql-persistence-service.xml<br />

12.3.3. Support Foreign Keys in CMP Services<br />

Next, we need to go change the $JBOSS_HOME/server/$PROFILE/conf/standardjbosscmpjdbc.xml<br />

file so that the fk-constraint property is true. That is needed for all external databases<br />

we support on the <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>. This file configures the database connection<br />

settings for the EJB2 CMP beans deployed in the <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>.<br />

true<br />

12.3.4 . Specify Database Dialect for Java Persistence API<br />

The Java Persistence API (JPA) entity manager can save EJB3 entity beans to any backend database.<br />

Hibernate provides the JPA implementation in <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>. Hibernate has a<br />

dialect auto-detection mechanism that works for most databases including the dialects for databases<br />

referenced in this appendix which are listed below. If a specific dialect is needed for alternative<br />

databases, you can configure the database dialect in the<br />

$JBOSS_HOME/server/$PROFILE/deployers/ejb3.deployer/META-INF/jpa-deployersjboss-beans.xml<br />

file. To configure this file you need to uncomment the set of tags related to the map<br />

entry hibernate.dialect and change the values to the following based on the database you setup.


Oracle 10g: org.hibernate.dialect.Oracle10gDialect<br />

Oracle 11g: org.hibernate.dialect.Oracle10gDialect<br />

Microsoft SQL Server 2005: org.hibernate.dialect.SQLServerDialect<br />

Microsoft SQL Server 2008: org.hibernate.dialect.SQLServerDialect<br />

PostgresSQL 8.2.3: org.hibernate.dialect.PostgreSQLDialect<br />

PostgresSQL 8.3.7: org.hibernate.dialect.PostgreSQLDialect<br />

MySQL 5.0: org.hibernate.dialect.MySQL5InnoDBDialect<br />

MySQL 5.1: org.hibernate.dialect.MySQL5InnoDBDialect<br />

DB2 9.1: org.hibernate.dialect.DB2Dialect<br />

Sybase ASE 15: org.hibernate.dialect.SybaseASE15Dialect<br />

12.3.5. Change Other <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> Services to use the External<br />

Database<br />

Besides JMS, CMP, and JPA, we still need to hook up the rest of <strong>JBoss</strong> services with the external<br />

database. There are two ways to do it. One is easy but inflexible. The other is flexible but requires more<br />

steps. Now, let's discuss those two approaches respectively.<br />

12.3.5.1. The Easy Way<br />

The easy way is just to change the JNDI name for the external database to DefaultDS. Most <strong>JBoss</strong><br />

services are hard-wired to use the DefaultDS by default. So, by changing the DataSource name, we do<br />

not need to change the configuration for each service individually.<br />

To change the JNDI name, just open the *-ds.xml file for your external database, and change the<br />

value of the jndi-name property to DefaultDS. For instance, in mysql-ds.xml, you would change<br />

MySqlDS to DefaultDS and so on. You will need to remove the<br />

$JBOSS_HOME/server/$PROFILE/deploy/hsqldb-ds.xml file after you are done to avoid<br />

duplicated DefaultDS definition.<br />

In the messaging/$DATABASE-persistence-service.xml file, you should also change the<br />

datasource name in the depends tag for the PersistenceManagers MBean to DefaultDS. For<br />

instance, for mysql-persistence-service.xml file, we change the MySqlDS to DefaultDS.<br />

<br />

jboss.jca:service=DataSourceBinding,name=DefaultDS<br />

12.3.5.2. The More Flexible Way<br />

Changing the external datasource to DefaultDS is convenient. But if you have applications that<br />

assume the DefaultDS always points to the factory-default HSQL DB, that approach could break your<br />

application. Also, changing DefaultDS destination forces all <strong>JBoss</strong> services to use the external<br />

database. What if you want to use the external database only on some services?<br />

A safer and more flexible way to hook up <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> services with the<br />

external DataSource is to manually change the DefaultDS in all standard <strong>JBoss</strong> services to the<br />

DataSource JNDI name defined in your *-ds.xml file (for example, the MySqlDS in mysql-ds.xml,<br />

etc.). Below is a complete list of files that contain DefaultDS. You can update them all to use the<br />

external database on all <strong>JBoss</strong> services or update some of them to use different combination of<br />

DataSources for different services.<br />

$JBOSS_HOME/server/$PROFILE/conf/login-config.xml: This file is used in Java EE<br />

container managed security services.<br />

$JBOSS_HOME/server/$PROFILE/conf/standardjbosscmp-jdbc.xml: This file configures<br />

the CMP beans in the EJB container.<br />

$JBOSS_HOME/server/$PROFILE/deploy/ejb2-timer-service.xml: This file configures<br />

the EJB timer services.<br />

$JBOSS_HOME/server/$PROFILE/deploy/juddi-service.sar/META-INF/jbossservice.xml:<br />

This file configures the UUDI service.


118 Chapter 12. Use Alternative Databases with <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong><br />

$JBOSS_HOME/server/$PROFILE/deploy/juddi-service.sar/juddi.war/WEB-<br />

INF/jboss-web.xml: This file configures the UUDI service.<br />

$JBOSS_HOME/server/$PROFILE/deploy/juddi-service.sar/juddi.war/WEB-<br />

INF/juddi.properties: This file configures the UUDI service.<br />

$JBOSS_HOME/server/$PROFILE/deploy/uuid-key-generator.sar/META-INF/jbossservice.xml:<br />

This file configures the UUDI service.<br />

$JBOSS_HOME/server/$PROFILE/deploy/messaging/messaging-jboss-beans.xml and<br />

$JBOSS_HOME/server/$PROFILE/deploy/messaging/persistence-service.xml: Those<br />

files configure the JMS persistence service as we discussed earlier.<br />

12.3.6. A Special Note About Oracle Databases<br />

In our setup discussed in this chapter, we rely on the <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> to<br />

automatically create needed tables in the external database upon server startup. That works most of the<br />

time. But for databases like Oracle, there might be some minor issues if you try to use the same<br />

database server to back more than one <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> instance.<br />

The Oracle database creates tables of the form schemaname.tablename. The TIMERS and<br />

HILOSEQUENCES tables needed by <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> would not be created on a<br />

schema if the table already existed on a different schema. To work around this issue, you need to edit<br />

the $JBOSS_HOME/server/$PROFILE/deploy/ejb2-timer-service.xml file to change the table<br />

name from TIMERS to something like schemaname2.tablename.<br />

<br />

<br />

<br />

jboss.jca:service=DataSourceBinding,name=DefaultDS<br />

<br />

<br />

<br />

org.jboss.ejb.txtimer.GeneralPurposeDatabasePersistencePlugin<br />

<br />

<br />

TIMERS<br />

<br />

Similarly, you need to change the $JBOSS_HOME/server/$PROFILE/deploy/uuid-keygenerator.sar/META-INF/jboss-service.xml<br />

file to change the table name from<br />

HILOSEQUENCES to something like schemaname2.tablename as well.<br />

<br />

jboss:service=TransactionManager<br />

<br />

<br />

jboss.jca:service=DataSourceBinding,name=DefaultDS<br />

<br />

HILOSEQUENCES<br />

Regression in Oracle JDBC driver 11.1.0.7.0<br />

Oracle JDBC driver version 11.1.0.7.0 causes the <strong>JBoss</strong> Messaging Test Suite to fail with a<br />

SQLException ("Bigger type length than Maximum") on Oracle 11g R1.<br />

This is caused by a regression in Oracle JDBC driver 11.1.0.7.0.<br />

We recommend Oracle JDBC driver version 11.2.0.1.0 for use with Oracle 11g R1, Oracle 11g R2,<br />

Oracle RAC 11g R1 and Oracle RAC 11g R2.


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 119<br />

Chapter 13. Datasource Configuration<br />

You must change your database<br />

The default persistence configuration works out of the box with Hypersonic (HSQLDB) so that the<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Platform</strong>s are able to run "out of the box". However, Hypersonic is not<br />

supported in production and should not be used in a production environment.<br />

Known issues with the Hypersonic Database include:<br />

no transaction isolation<br />

thread and socket leaks (connection.close() does not tidy up resources)<br />

persistence quality (logs commonly become corrupted after a failure, preventing automatic<br />

recovery)<br />

database corruption<br />

stability under load (database processes cease when dealing with too much data)<br />

not viable in clustered environments<br />

Check the "Using Other Databases" chapter of the Getting Started Guide for assistance.<br />

Datasources are defined inside a element. The exact element depends on the type of<br />

datasource required.<br />

13.1. Types of Datasources<br />

Datasource Definitions<br />

<br />

Does not take part in JTA transactions. The java.sql.Driver is used.<br />

<br />

Does not support two phase commit. The java.sql.Driver is used. Suitable for a single<br />

database or a non-XA-aware resource.<br />

<br />

Supports two phase commit. The javax.sql.XADataSource driver is used.<br />

13.2. Datasource Parameters<br />

<strong>Common</strong> Datasource Parameters<br />

<br />

A standard <strong>JBoss</strong> MBean deployment.<br />

<br />

The ObjectName of an MBean service this ConnectionFactory orDataSource<br />

deployment depends upon.<br />

<br />

The JNDI name under which the Datasource should be bound.<br />

<br />

Boolean value indicating whether the jndi-name should be prefixed with java:. This prefix<br />

causes the Datasource to only be accessible from within the <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong><br />

<strong>Platform</strong> virtual machine. Defaults to TRUE.


120 Chapter 13. Datasource Configuration<br />

<br />

The user name used to create the connection to the datasource.<br />

<br />

Note<br />

Not used when security is configured.<br />

The password used to create the connection to the datasource.<br />

Note<br />

Not used when security is configured.<br />

<br />

The default transaction isolation of the connection. If not specified, the database-provided<br />

default is used.<br />

Possible values for <br />

TRANSACTION_READ_UNCOMMITTED<br />

TRANSACTION_READ_COMMITTED<br />

TRANSACTION_REPEATABLE_READ<br />

TRANSACTION_SERIALIZABLE<br />

TRANSACTION_NONE<br />

<br />

An SQL statement that is executed against each new connection. This can be used to set up<br />

the connection schema, for instance.<br />

<br />

An SQL statement that is executed before the connection is checked out from the pool to make<br />

sure it is still valid. If the SQL statement fails, the connection is closed and a new one is created.<br />

<br />

A class that checks whether a connection is valid using a vendor-specific mechanism.<br />

<br />

A class that parses vendor-specific messages to determine whether SQL errors are fatal, and<br />

destroys the connection if so. If empty, no errors are treated as fatal.<br />

<br />

Whether to monitor for unclosed Statements and ResultSets and issue warnings when they<br />

haven't been closed. The default value is NOWARN.<br />

<br />

The number of prepared statements per connection to be kept open and reused in subsequent<br />

requests. They are stored in a Least Recently Used (LRU) cache. The default value is 0,<br />

meaning that no cache is kept.


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 121<br />

<br />

When the is non-zero, determines whether two requests in<br />

the same transaction should return the same statement. Defaults to FALSE.<br />

Example 13.1. Using <br />

The goal is to work around questionable driver behavior, where the driver applies autocommit<br />

semantics to local transactions.<br />

Connection c = dataSource.getConnection(); // auto-commit == false<br />

PreparedStatement ps1 = c.prepareStatement(...);<br />

ResultSet rs1 = ps1.executeQuery();<br />

PreparedStatement ps2 = c.prepareStatement(...);<br />

ResultSet rs2 = ps2.executeQuery();<br />

This assumes that the prepared statements are the same. For some drivers,<br />

ps2.executeQuery() automatically closes rs1, so you actually need two real prepared<br />

statements behind the scenes. This only applies to the auto-commit semantic, where rerunning<br />

the query starts a new transaction automatically. For drivers that follow the<br />

specification, you can set it to TRUE to share the same real prepared statement.<br />

<br />

Whether to enable query timeout based on the length of time remaining until the transaction<br />

times out. Defaults to FALSE.<br />

<br />

The maximum time, in seconds, before a query times out. You can override this value by setting<br />

to TRUE.<br />

><br />

A pointer to the type mapping in conf/standardjbosscmp.xml. A legacy from <strong>JBoss</strong>4.<br />

<br />

Whether to validate the connection when the JCA layer matches a managed connection, such<br />

as when the connection is checked out of the pool. With the addition of <br />

this is not required. It is usually not necessary to specify TRUE for <br />

in conjunction with specifying TRUE for . Defaults to TRUE.<br />

<br />

Whether to attempt to prefill the connection pool to the minimum number of connections. Only<br />

supporting pools (OnePool) support this feature. A warning is logged if the pool does not<br />

support prefilling. Defaults to TRUE.<br />

<br />

Background connection validation reduces the overall load on the RDBMS system when<br />

validating a connection. When using this feature, EAP checks whether the current connection in<br />

the pool a seperate thread (ConnectionValidator). depends<br />

on this value also being set to TRUE. Defaults to FALSE.<br />

<br />

Background connection validation reduces the overall load on the RDBMS system when<br />

validating a connection. Setting this parameter means that <strong>JBoss</strong> will attempt to validate the


122 Chapter 13. Datasource Configuration<br />

current connections in the pool as a separate thread (ConnectionValidator). This<br />

parameter's value defines the interval, in milliseconds, for which the ConnectionValidator<br />

will run. (This value should not be the same as your


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 123<br />

has failed, or begin failover. This is to address performance issues where validation SQL takes<br />

significant time and resources to execute. Defaults to FALSE.<br />

Parameters for javax.sql.XADataSource Usage<br />

<br />

The JDBC driver connection URL string<br />

<br />

The JDBC driver class implementing the java.sql.Driver<br />

<br />

Used to configure the connections retrieved from the java.sql.Driver.<br />

Example 13.2. Example <br />

UTF-8<br />

Parameters for javax.sql.XADataSource Usage<br />

<br />

The class implementing the XADataSource<br />

<br />

Properties used to configure the XADataSource.<br />

Example 13.3. Example Declarations<br />

10<br />

myhost.mydomain.com<br />

1557<br />

mydb<br />

myserver<br />

<br />

The number of seconds passed to XAResource.setTransactionTimeout() when not<br />

zero.<br />

<br />

When set to FALSE, fixes some problems with Oracle databases.<br />

<br />

Pool transactional and non-transactinal connections separately


124 Chapter 13. Datasource Configuration<br />

Warning<br />

Using this option will cause your total pool size to be twice max-pool-size, because<br />

two actual pools will be created.<br />

Used to fix problems with Oracle.<br />

Security Parameters<br />

<br />

Uses the username and password passed on the getConnection or createConnection<br />

request by the application.<br />

<br />

Uses the identified login module configured in conf/login-module.xml.<br />

<br />

Uses the identified login module configured in conf/login-module.xml and other<br />

connection request information supplied by the application, for example JMS Queues and<br />

Topics.<br />

13.3. Datasource Examples<br />

For database-specific examples, see Appendix A, Vendor-Specific Datasource Definitions.<br />

13.3.1. Generic Datasource Example


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 125<br />

Example 13.4 . Generic Datasource Example


126 Chapter 13. Datasource Configuration<br />

<br />

<br />

GenericDS<br />

[jdbc: url for use with Driver class]<br />

[fully qualified class name of java.sql.Driver<br />

implementation]<br />

x<br />

y<br />

<br />

<br />

UTF-8<br />

TRANSACTION_SERIALIZABLE<br />

<br />

5<br />

100<br />

5000<br />

15<br />

<br />

<br />

><br />

<br />

300 <br />

<br />

<br />

MyRealm<br />

<br />

<br />

<br />

myapp.service:service=DoSomethingService<br />

<br />

<br />

<br />

true<br />

<br />

<br />

<br />

GenericXADS<br />

[fully qualified name of class implementing<br />

javax.sql.XADataSource goes here]<br />

SomePropertyValue<br />

SomeOtherValue<br />

x<br />

y<br />

TRANSACTION_SERIALIZABLE<br />

<br />

5


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 127<br />

5<br />

100<br />

5000<br />

15<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

13.3.2. Configuring a DataSource for Remote Usage<br />

<strong>JBoss</strong> EAP supports accessing a DataSource from a remote client. See Example 13.5, “Configuring a<br />

Datasource for Remote Usage” for the change that gives the client the ability to look up the DataSource<br />

from JNDI, which is to specify use-java-context=false.<br />

Example 13.5. Configuring a Datasource for Remote Usage<br />

<br />

<br />

GenericDS<br />

false<br />

...<br />

...<br />

This causes the DataSource to be bound under the JNDI name GenericDS instead of the default of<br />

java:/GenericDS, which restricts the lookup to the same Virtual Machine as the EAP server.<br />

Note<br />

Use of the setting is not recommended in a production environment. It<br />

requires accessing a connection pool remotely and this can cause unexpected problems, since<br />

connections are not serializable. Also, transaction propagation is not supported, since it can lead<br />

to connection leaks if unreliability is present, such as in a system crash or network failure. A<br />

remote session bean facade is the preferred way to access a datasource remotely.<br />

13.3.3. Configuring a Datasource to Use Login Modules<br />

Procedure 13.1. Configuring a Datasource to Use Login Modules<br />

1. Add the to the XML file for the datasource.


128 Chapter 13. Datasource Configuration<br />

<br />

<br />

...<br />

MyDomain<br />

...<br />

<br />

<br />

2. Add an application policy to the login-config.xml file.<br />

The authentication section needs to include the configuration for your login-module. For example,<br />

to encrypt the database password, use the SecureIdentityLoginModule login module.<br />

<br />

<br />

<br />

scott<br />

-170dd0fbd8c13748<br />

jboss.jca:service=LocalTxCM,name=OracleDS<br />

JAAS<br />

<br />

<br />

<br />

3. If you plan to fetch the data source connection from a web application, authentication must be<br />

enabled for the web application, so that the Subject is populated.<br />

4. If users need the ability to connect anonymously, add an additional login module to the applicationpolicy,<br />

to populate the security credentials.<br />

5. Add the UsersRolesLoginModule module to the beginning of the chain. The<br />

usersProperties and rolesProperties parameters can be directed to dummy files.<br />

<br />

nobody<br />

props/users.properties<br />

props/roles.properties<br />


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 129<br />

Chapter 14. Pooling<br />

14.1. Strategy<br />

<strong>JBoss</strong>JCA uses a ManagedConnectionPool to perform the pooling. The<br />

ManagedConnectionPool is made up of subpools depending upon the strategy chosen and other<br />

pooling parameters.<br />

xml mbean Internal Name Description<br />

<br />

ByNothing OnePool A single pool of<br />

equivalent connections<br />

By<strong>Application</strong> PoolByCRI Use the connection<br />

properties from<br />

allocateConnection()<br />

ByContainer PoolBySubject A pool per Subject, e.g.<br />

preconfigured or<br />

EJB/Web login<br />

subjects<br />

<br />

Note<br />

ByContainerAndApplicaton PoolBySubjectAndCri A per Subject and<br />

connection property<br />

combination<br />

The xml names imply this is just about security. This is misleading.<br />

For the Subject always overrides any user/password from<br />

createConnection(user, password) in the CRI:<br />

(<br />

ConnectionRequestInfo<br />

)<br />

14.2. Transaction stickness<br />

You can force the same connection from a (sub-)pool to get reused throughout a transaction with the<br />

flag<br />

Note<br />

This is the only supported behaviour for "local" transactions. This element is deprecated in<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5 where transaction stickiness is enabled by default. XA<br />

users can explicitly enable interleaving with element.<br />

14.3. Workaround for Oracle<br />

Oracle does not like XA connections getting used both inside and outside a JTA transaction. To<br />

workaround the problem you can create separate sub-pools for the different contexts using .<br />

14.4. Pool Access<br />

The pool is designed for concurrent usage.<br />

Upto threads can be inside the pool at the same time (or using connections from a<br />

pool).<br />

Once this limit is reached, threads wait for the to use the pool before<br />

throwing a No Managed Connections Available


130 Chapter 14. Pooling<br />

throwing a No Managed Connections Available<br />

You may want to use the and elements to have the pool<br />

retry to obtain a connection before throwing the exception.<br />

14.5. Pool Filling<br />

The number of connections in the pool is controlled by the pool sizes.<br />

- When the number of connections falls below this size, new connections are<br />

created<br />

- No more than this number of connections are created<br />

- Feature Request has been implemented for 4.0.5. Note: the only pooling strategy that<br />

supports this feature is OnePool?, or ByNothing? pooling criteria.<br />

The pool filling is done by a separate "Pool Filler" thread rather than blocking application threads.<br />

14.6. Idle Connections<br />

You can configure connections to be closed when they are idle. e.g. If you just had a peak period and<br />

now want to reap the unused ones. This is done via the .<br />

Idle checking is done on a separate "Idle Remover" thread on an LRU (least recently used) basis. The<br />

check is done every idle-timeout-minutes divided by 2 for connections unused for idle-timeout-minutes.<br />

The pool itself operates on an MRU (most recently used) basis. This allows the excess connections to<br />

be easily identified.<br />

Should closing idle connections cause the pool to fall below the min-pool-size, new/fresh connections<br />

are created.<br />

Note<br />

If you have long running transactions and you use interleaving (i.e. don't track-connection-by-tx)<br />

make sure the idle timeout is greater than the transaction timeout. When interleaving the<br />

connection is returned to the pool for others to use. If however nobody does use it, it would be a<br />

candidate for removal before the transaction is committed.<br />

14.7. Dead connections<br />

The JDBC protocol does not provide a natural connectionErrorOccured() event when a<br />

connection is broken. To support dead/broken connection checking there are a number of plugins.<br />

14 .7.1. Valid connection checking<br />

The simplest format is to just run a "quick" sql statement:<br />

select 1 from dual<br />

before handing the connection to the application. If this fails, another connection is selected until there<br />

are no more connections at which point new connections are constructed.<br />

The potentially more performant check is to use vendor specific features, e.g. Oracle's or MySQL's<br />

pingDatabase() via the<br />

<br />

14 .7.2. Errors during SQL queries<br />

You can check if a connection broke during a query by the looking the error codes or messages of the<br />

SQLException for FATAL errors rather than normal SQLExceptions. These codes/messages can be<br />

vendor specific, e.g.


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 131<br />

org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter<br />

For FATAL errors, the connection will be closed.<br />

14 .7.3. Changing/Closing/Flushing the pool<br />

change or flush() the pool<br />

closing/undeploying the pool will do a flush first<br />

14 .7.4 . Other pooling<br />

Thirdparty Pools - only if you know what you are doing


132 Chapter 15. Frequently Asked Questions<br />

Chapter 15. Frequently Asked Questions<br />

15.1. I have problems with Oracle XA?<br />

Check that you:<br />

1. You have pad=true for the XidFactory? in conf/jboss-service.xml.<br />

2. You have in your oracle-xa-ds.xml (not necessarily for <strong>JBoss</strong> <strong>Enterprise</strong><br />

<strong>Application</strong> <strong>Platform</strong> 5.x where it is enabled by default and the element is deprecated).<br />

3. You have false in your oracle-xa-ds.xml.<br />

4. You have in your oracle-xa-ds.xml.<br />

5. That your jbosscmp-jdbc.xml is specifying the same version of oracle as the one you use.<br />

6. That the oracle server you connect to has XA.<br />

Configuring Oracle Database for XA Support You can configure Oracle database to support XA<br />

resources. This enables you to use JDBC 2.0-compliant Oracle driver. To XA-initialize Oracle database,<br />

complete the following steps:<br />

Make sure that Oracle JServer is installed with your database. If it is not installed, you must add it using<br />

Oracle Database Configuration Assistant. Choose "Change an Existing DB" and then select the<br />

database to which you want to add Oracle JServer. Choose "Next", then "Oracle JServer" and then<br />

"Finish". If the settings you have made to your database previously, are not suitable or insufficient for<br />

the Oracle JServer installation, the system prompts you to enter additional parameters. The database<br />

configuration file ( init.ora ) is located in \oracle\admin\\pfile directory.<br />

Execute initxa.sql over your database. By default, this script file is located in<br />

\oracle\ora81\javavm\install. If errors occur during the execution of the file, you must execute<br />

the SQL statements from the file manually. Use DBA Studio to create a package and package body<br />

named JAVA_XA in SYS schema, and a synonym of this package (also named JAVA_XA) in PUBLIC<br />

schema.<br />

A slightly more detailed set of instructions can be found at Configuring and using XA distributed<br />

transactions in WebSphere Studio - Oracle Exception section.


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 133<br />

Part III. Clustering Guide


134 Chapter 16. Introduction and Quick Start<br />

Chapter 16. Introduction and Quick Start<br />

Clustering allows you to run an application on several parallel servers (a.k.a cluster nodes) while<br />

providing a single view to application clients. Load is distributed across different servers, and even if one<br />

or more of the servers fails, the application is still accessible via the surviving cluster nodes. Clustering<br />

is crucial for scalable enterprise applications, as you can improve performance by adding more nodes to<br />

the cluster. Clustering is crucial for highly available enterprise applications, as it is the clustering<br />

infrastructure that supports the redundancy needed for high availability.<br />

The <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> comes with clustering support out of the box, as part of the<br />

all configuration. The all configuration includes support for the following:<br />

A scalable, fault-tolerant JNDI implementation (HA-JNDI).<br />

Web tier clustering, including:<br />

High availability for web session state via state replication.<br />

Ability to integrate with hardware and software load balancers, including special integration with<br />

mod_jk and other JK-based software load balancers.<br />

Single Sign-on support across a cluster.<br />

EJB session bean clustering, for both stateful and stateless beans, and for both EJB3 and EJB2.<br />

A distributed cache for JPA/Hibernate entities.<br />

A framework for keeping local EJB2 entity caches consistent across a cluster by invalidating cache<br />

entries across the cluster when a bean is changed on any node.<br />

Distributed JMS queues and topics via <strong>JBoss</strong> Messaging.<br />

Deploying a service or application on multiple nodes in the cluster but having it active on only one<br />

(but at least one) node is called a HA Singleton.<br />

Keeping deployed content in sync on all nodes in the cluster via the Farm service.<br />

In this Clustering Guide we aim to provide you with an in depth understanding of how to use <strong>JBoss</strong><br />

<strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>'s clustering features. In this first part of the guide, the goal is to provide<br />

some basic "Quick Start" steps to encourage you to start experimenting with <strong>JBoss</strong> <strong>Enterprise</strong><br />

<strong>Application</strong> <strong>Platform</strong> Clustering, and then to provide some background information that will allow you to<br />

understand how <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> Clustering works. The next part of the guide then<br />

explains in detail how to use these features to cluster your JEE services. Finally, we provide some more<br />

details about advanced configuration of JGroups and <strong>JBoss</strong> Cache, the core technologies that underlie<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> Clustering.<br />

16.1. Quick Start Guide<br />

The goal of this section is to give you the minimum information needed to let you get started<br />

experimenting with <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> Clustering. Most of the areas touched on in<br />

this section are covered in much greater detail later in this guide.<br />

16.1.1. Initial Preparation<br />

Preparing a set of servers to act as a <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> cluster involves a few<br />

simple steps:<br />

Install <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> on all your servers. In its simplest form, this is<br />

just a matter of unzipping the <strong>JBoss</strong> download onto the filesystem on each server.<br />

If you want to run multiple <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> instances on a single server, you<br />

can either install the full <strong>JBoss</strong> distribution onto multiple locations on your filesystem, or you can<br />

simply make copies of the all configuration. For example, assuming the root of the <strong>JBoss</strong><br />

distribution was unzipped to /var/jboss, you would:<br />

$ cd /var/jboss/server<br />

$ cp -r all node1<br />

$ cp -r all node2<br />

For each node, determine the address to bind sockets to. When you start <strong>JBoss</strong>, whether<br />

clustered or not, you need to tell <strong>JBoss</strong> on what address its sockets should listen for traffic. (The<br />

default is localhost which is secure but isn't very useful, particularly in a cluster.) So, you need to<br />

decide what those addresses will be.<br />

Ensure multicast is working. By default <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> uses UDP multicast


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 135<br />

for most intra-cluster communications. Make sure each server's networking configuration supports<br />

multicast and that multicast support is enabled for any switches or routers between your servers. If<br />

you are planning to run more than one node on a server, make sure the server's routing table<br />

includes a multicast route. See the JGroups documentation at http://www.jgroups.org for more on this<br />

general area, including information on how to use JGroups' diagnostic tools to confirm that multicast<br />

is working.<br />

Note<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> clustering does not require the use of UDP multicast;<br />

the <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> can also be reconfigured to use TCP unicast for intracluster<br />

communication.<br />

Determine a unique integer "ServerPeerID" for each node. This is needed for <strong>JBoss</strong><br />

Messaging clustering, and can be skipped if you will not be running <strong>JBoss</strong> Messaging (i.e. you will<br />

remove JBM from your server configuration's deploy directory). JBM requires that each node in a<br />

cluster has a unique integer id, known as a "ServerPeerID", that should remain consistent across<br />

server restarts. A simple 1, 2, 3, ..., x naming scheme is fine. We'll cover how to use these integer ids<br />

in the next section.<br />

Beyond the above required steps, the following two optional steps are recommended to help ensure that<br />

your cluster is properly isolated from other <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> clusters that may be<br />

running on your network:<br />

Pick a unique name for your cluster. The default name for a <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong><br />

<strong>Platform</strong> cluster is "DefaultPartition". Come up with a different name for each cluster in your<br />

environment, e.g. "QAPartition" or "BobsDevPartition". The use of "Partition" is not required; it's just<br />

a semi-convention. As a small aid to performance try to keep the name short, as it gets included in<br />

every message sent around the cluster. We'll cover how to use the name you pick in the next section.<br />

Pick a unique multicast address for your cluster. By default <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong><br />

<strong>Platform</strong> uses UDP multicast for most intra-cluster communication. Pick a different multicast address<br />

for each cluster you run. Generally a good multicast address is of the form 239.255.x.y. See<br />

http://www.29west.com/docs/THPM/multicast-address-assignment.html for a good discussion on<br />

multicast address assignment. We'll cover how to use the address you pick in the next section.<br />

See Section 25.6.2, “Isolating JGroups Channels” for more on isolating clusters.<br />

16.1.2. Launching a <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> Cluster<br />

The simplest way to start a <strong>JBoss</strong> server cluster is to start several <strong>JBoss</strong> instances on the same local<br />

network, using the -c all command line option for each instance. Those server instances will detect<br />

each other and automatically form a cluster.<br />

Let's look at a few different scenarios for doing this. In each scenario we'll be creating a two node<br />

cluster, where the ServerPeerID for the first node is 1 and for the second node is 2 . We've decided to<br />

call our cluster "DocsPartition" and to use 239.255.100.100 as our multicast address. These<br />

scenarios are meant to be illustrative; the use of a two node cluster shouldn't be taken to mean that is<br />

the best size for a cluster; it's just that's the simplest way to do the examples.<br />

Scenario 1: Nodes on Separate Machines<br />

This is the most common production scenario. Assume the machines are named "node1" and<br />

"node2", while node1 has an IP address of 192.168.0.101 and node2 has an address of<br />

192.168.0.102. Assume the "ServerPeerID" for node1 is 1 and for node2 it's 2. Assume on each<br />

machine <strong>JBoss</strong> is installed in /var/jboss.<br />

On node1, to launch <strong>JBoss</strong>:<br />

$ cd /var/jboss/bin<br />

$ ./run.sh -c all -g DocsPartition -u 239.255.100.100 \<br />

-b 192.168.0.101 -Djboss.messaging.ServerPeerID=1<br />

On node2, it's the same except for a different -b value and ServerPeerID:<br />

$ cd /var/jboss/bin<br />

$ ./run.sh -c all -g DocsPartition -u 239.255.100.100 \<br />

-b 192.168.0.102 -Djboss.messaging.ServerPeerID=2


136 Chapter 16. Introduction and Quick Start<br />

The -c switch says to use the all config, which includes clustering support. The -g switch sets the<br />

cluster name. The -u switch sets the multicast address that will be used for intra-cluster<br />

communication. The -b switch sets the address on which sockets will be bound. The -D switch sets<br />

system property jboss.messaging.ServerPeerID, from which <strong>JBoss</strong> Messaging gets its<br />

unique id.<br />

Scenario 2: Two Nodes on a Single, Multihomed, Server<br />

Running multiple nodes on the same machine is a common scenario in a development environment,<br />

and is also used in production in combination with Scenario 1. (Running all the nodes in a production<br />

cluster on a single machine is generally not recommended, since the machine itself becomes a single<br />

point of failure.) In this version of the scenario, the machine is multihomed, i.e. has more than one IP<br />

address. This allows the binding of each <strong>JBoss</strong> instance to a different address, preventing port<br />

conflicts when the nodes open sockets.<br />

Assume the single machine has the 192.168.0.101 and 192.168.0.102 addresses assigned,<br />

and that the two <strong>JBoss</strong> instances use the same addresses and ServerPeerIDs as in Scenario 1. The<br />

difference from Scenario 1 is we need to be sure each <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> instance has<br />

its own work area. So, instead of using the all config, we are going to use the node1 and node2<br />

configs we copied from all earlier in the previous section.<br />

To launch the first instance, open a console window and:<br />

$ cd /var/jboss/bin<br />

$ ./run.sh -c node1 -g DocsPartition -u 239.255.100.100 \<br />

-b 192.168.0.101 -Djboss.messaging.ServerPeerID=1<br />

For the second instance, it's the same except for different -b and -c values and a different<br />

ServerPeerID:<br />

$ cd /var/jboss/bin<br />

$ ./run.sh -c node2 -g DocsPartition -u 239.255.100.100 \<br />

-b 192.168.0.102 -Djboss.messaging.ServerPeerID=2<br />

Scenario 3: Two Nodes on a Single, Non-Multihomed, Server<br />

This is similar to Scenario 2, but here the machine only has one IP address available. Two<br />

processes can't bind sockets to the same address and port, so we'll have to tell <strong>JBoss</strong> to use<br />

different ports for the two instances. This can be done by configuring the ServiceBindingManager<br />

service by setting the jboss.service.binding.set system property.<br />

To launch the first instance, open a console window and:<br />

$ cd /var/jboss/bin<br />

$ ./run.sh -c node1 -g DocsPartition -u 239.255.100.100 \<br />

-b 192.168.0.101 -Djboss.messaging.ServerPeerID=1 \<br />

-Djboss.service.binding.set=ports-default<br />

For the second instance:<br />

$ cd /var/jboss/bin<br />

$ ./run.sh -c node2 -g DocsPartition -u 239.255.100.100 \<br />

-b 192.168.0.101 -Djboss.messaging.ServerPeerID=2 \<br />

-Djboss.service.binding.set=ports-01<br />

This tells the ServiceBindingManager on the first node to use the standard set of ports (e.g. JNDI on<br />

1099). The second node uses the "ports-01" binding set, which by default for each port has an<br />

offset of 100 from the standard port number (e.g. JNDI on 1199). See the<br />

conf/bindingservice.beans/META-INF/bindings-jboss-beans.xml file for the full<br />

ServiceBindingManager configuration.<br />

Note that this setup is not advised for production use, due to the increased management complexity<br />

that comes with using different ports. But it is a fairly common scenario in development environments<br />

where developers want to use clustering but cannot multihome their workstations.<br />

Note<br />

Including -Djboss.service.binding.set=ports-default on the command line for<br />

node1 isn't technically necessary, since ports-default is the default value. But using a<br />

consistent set of command line arguments across all servers is helpful to people less familiar<br />

with all the details.


That's it; that's all it takes to get a cluster of <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> servers up and<br />

running.<br />

16.1.3. Web <strong>Application</strong> Clustering Quick Start<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> supports clustered web sessions, where a backup copy of each<br />

user's HttpSession state is stored on one or more nodes in the cluster. In case the primary node<br />

handling the session fails or is shut down, any other node in the cluster can handle subsequent<br />

requests for the session by accessing the backup copy. Web tier clustering is discussed in detail in<br />

Chapter 22, HTTP Services.<br />

There are two aspects to setting up web tier clustering:<br />

Configuring an External Load Balancer. Web applications require an external load balancer to<br />

balance HTTP requests across the cluster of <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> instances (see<br />

Section 17.2.2, “External Load Balancer Architecture” for more on why that is). <strong>JBoss</strong> <strong>Enterprise</strong><br />

<strong>Application</strong> <strong>Platform</strong> itself doesn't act as an HTTP load balancer. So, you will need to set up a<br />

hardware or software load balancer. There are many possible load balancer choices, so how to<br />

configure one is really beyond the scope of a Quick Start. But see Section 22.1, “Configuring load<br />

balancing using Apache and mod_jk” for details on how to set up the popular mod_jk software load<br />

balancer.<br />

Configuring Your Web <strong>Application</strong> for Clustering. This aspect involves telling <strong>JBoss</strong> you want<br />

clustering behavior for a particular web app, and it couldn't be simpler. Just add an empty<br />

distributable element to your application's web.xml file:<br />

<br />

<br />

<br />

<br />

Simply doing that is enough to get the default <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> web session<br />

clustering behavior, which is appropriate for most applications. See Section 22.2, “Configuring HTTP<br />

session state replication” for more advanced configuration options.<br />

16.1.4 . EJB Session Bean Clustering Quick Start<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> supports clustered EJB session beans, whereby requests for a<br />

bean are balanced across the cluster. For stateful beans a backup copy of bean state is maintained on<br />

one or more cluster nodes, providing high availability in case the node handling a particular session fails<br />

or is shut down. Clustering of both EJB2 and EJB3 beans is supported.<br />

For EJB3 session beans, simply add the org.jboss.ejb3.annotation.Clustered annotation to<br />

the bean class for your stateful or stateless bean:<br />

@javax.ejb.Stateless<br />

@org.jboss.ejb3.annotation.Clustered<br />

public class MyBean implements MySessionInt {<br />

}<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 137<br />

public void test() {<br />

// Do something cool<br />

}<br />

For EJB2 session beans, or for EJB3 beans where you prefer XML configuration over annotations,<br />

simply add a clustered element to the bean's section in the <strong>JBoss</strong>-specific deployment descriptor,<br />

jboss.xml:


138 Chapter 16. Introduction and Quick Start<br />

<br />

<br />

<br />

example.StatelessSession<br />

example.StatelessSession<br />

true<br />

<br />

<br />

<br />

See Chapter 20, Clustered Session EJBs for more advanced configuration options.<br />

16.1.5. Entity Clustering Quick Start<br />

One of the big improvements in the clustering area in <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5 is the use<br />

of the new Hibernate/<strong>JBoss</strong> Cache integration for second level entity caching that was introduced in<br />

Hibernate 3.3. In the JPA/Hibernate context, a second level cache refers to a cache whose contents are<br />

retained beyond the scope of a transaction. A second level cache may improve performance by reducing<br />

the number of database reads. You should always load test your application with second level caching<br />

enabled and disabled to see whether it has a beneficial impact on your particular application.<br />

If you use more than one <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> instance to run your JPA/Hibernate<br />

application and you use second level caching, you must use a cluster-aware cache. Otherwise a cache<br />

on server A will still hold out-of-date data after activity on server B updates some entities.<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> provides a cluster-aware second level cache based on <strong>JBoss</strong><br />

Cache. To tell <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>'s standard Hibernate-based JPA provider to enable<br />

second level caching with <strong>JBoss</strong> Cache, configure your persistence.xml as follows:<br />

<br />

<br />

<br />

java:/SomeDS<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

That tells Hibernate to use the <strong>JBoss</strong> Cache-based second level cache, but it doesn't tell it what entities<br />

to cache. That can be done by adding the org.hibernate.annotations.Cache annotation to your<br />

entity class:<br />

package org.example.entities;<br />

import java.io.Serializable;<br />

import javax.persistence.Entity;<br />

import org.hibernate.annotations.Cache;<br />

import org.hibernate.annotations.CacheConcurrencyStrategy;<br />

@Entity<br />

@Cache(usage=CacheConcurrencyStrategy.TRANSACTIONAL)<br />

public class Account implements Serializable {<br />

See Chapter 21, Clustered Entity EJBs for more advanced configuration options and details on how to<br />

configure the same thing for a non-JPA Hibernate application.


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 139<br />

Note<br />

Clustering can add significant overhead to a JPA/Hibernate second level cache, so don't assume<br />

that just because second level caching adds a benefit to a non-clustered application that it will be<br />

beneficial to a clustered application. Even if clustered second level caching is beneficial overall,<br />

caching of more frequently modified entity types may be beneficial in a non-clustered scenario but<br />

not in a clustered one. Always load test your application.


14 0 Chapter 17. Clustering Concepts<br />

Chapter 17. Clustering Concepts<br />

In the next section, we discuss basic concepts behind <strong>JBoss</strong>' clustering services. It is helpful that you<br />

understand these concepts before reading the rest of the Clustering Guide.<br />

17.1. Cluster Definition<br />

A cluster is a set of nodes that communicate with each other and work toward a common goal. In a<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> cluster (also known as a “partition”), a node is an <strong>JBoss</strong><br />

<strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> instance. Communication between the nodes is handled by the JGroups<br />

group communication library, with a JGroups Channel providing the core functionality of tracking who is<br />

in the cluster and reliably exchanging messages between the cluster members. JGroups channels with<br />

the same configuration and name have the ability to dynamically discover each other and form a group.<br />

This is why simply executing “run -c all” on two <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> instances on the same<br />

network is enough for them to form a cluster – each <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> starts a Channel<br />

(actually, several) with the same default configuration, so they dynamically discover each other and form<br />

a cluster. Nodes can be dynamically added to or removed from clusters at any time, simply by starting or<br />

stopping a Channel with a configuration and name that matches the other cluster members.<br />

On the same <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> instance, different services can create their own Channel.<br />

In a standard startup of the <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5 all configuration, two different services<br />

create a total of four different channels – <strong>JBoss</strong> Messaging creates two and a core general purpose<br />

clustering service known as HAPartition creates two more. If you deploy clustered web applications,<br />

clustered EJB3 SFSBs or a clustered JPA/Hibernate entity cache, additional channels will be created.<br />

The channels the <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> connects can be divided into three broad categories: a<br />

general purpose channel used by the HAPartition service, channels created by <strong>JBoss</strong> Cache for special<br />

purpose caching and cluster wide state replication, and two channels used by <strong>JBoss</strong> Messaging.<br />

So, if you go to two <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5.0.x instances and execute run -c all, the<br />

channels will discover each other and you'll have a conceptual cluster. It's easy to think of this as a<br />

two node cluster, but it's important to understand that you really have multiple channels, and hence<br />

multiple two node clusters.<br />

On the same network, you may have different sets of servers whose services wish to cluster.<br />

Figure 17.1, “Clusters and server nodes” shows an example network of <strong>JBoss</strong> server instances divided<br />

into three sets, with the third set only having one node. This sort of topology can be set up simply by<br />

configuring the <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> instances such that within a set of nodes meant to form a<br />

cluster the Channel configurations and names match while they differ from any other channel<br />

configurations and names match while they differ from any other channels on the same network. The<br />

<strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> tries to make this is easy as possible, such that servers that are meant<br />

to cluster only need to have the same values passed on the command line to the -g (partition name)<br />

and -u (multicast address) startup switches. For each set of servers, different values should be chosen.<br />

The sections on “JGroups Configuration” and “Isolating JGroups Channels” cover in detail how to<br />

configure the <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> such that desired peers find each other and unwanted<br />

peers do not.<br />

Figure 17.1. Clusters and server nodes


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 14 1<br />

17.2. Service Architectures<br />

The clustering topography defined by the JGroups configuration on each node is of great importance to<br />

system administrators. But for most application developers, the greater concern is probably the cluster<br />

architecture from a client application's point of view. Two basic clustering architectures are used with<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>: client-side interceptors (a.k.a. smart proxies or stubs) and<br />

external load balancers. Which architecture your application will use will depend on what type of client<br />

you have.<br />

17.2.1. Client-side interceptor architecture<br />

Most remote services provided by the <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>, including JNDI, EJB, JMS,<br />

RMI and <strong>JBoss</strong> Remoting, require the client to obtain (for example, to look up and download) a remote<br />

proxy object. The proxy object is generated by the server and it implements the business interface of the<br />

service. The client then makes local method calls against the proxy object. The proxy automatically<br />

routes the call across the network where it is invoked against service objects managed in the server.<br />

The proxy object figures out how to find the appropriate server node, marshal call parameters,<br />

unmarshal call results, and return the result to the caller client. In a clustered environment, the servergenerated<br />

proxy object includes an interceptor that understands how to route calls to multiple nodes in<br />

the cluster.<br />

The proxy's clustering logic maintains up-to-date knowledge about the cluster. For instance, it knows the<br />

IP addresses of all available server nodes, the algorithm to distribute load across nodes (see next<br />

section), and how to failover the request if the target node not available. As part of handling each service<br />

request, if the cluster topology has changed the server node updates the proxy with the latest changes<br />

in the cluster. For instance, if a node drops out of the cluster, each proxy is updated with the new<br />

topology the next time it connects to any active node in the cluster. All the manipulations done by the<br />

proxy's clustering logic are transparent to the client application. The client-side interceptor clustering<br />

architecture is illustrated in Figure 17.2, “The client-side interceptor (proxy) architecture for clustering”.<br />

Figure 17.2. The client-side interceptor (proxy) architecture for clustering<br />

17.2.2. External Load Balancer Architecture<br />

The HTTP-based <strong>JBoss</strong> services do not require the client to download anything. The client (for<br />

example, a web browser) sends in requests and receives responses directly over the wire using the<br />

HTTP protocol). In this case, an external load balancer is required to process all requests and dispatch<br />

them to server nodes in the cluster. The client only needs to know how to contact the load balancer; it<br />

has no knowledge of the <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> instances behind the load balancer. The<br />

load balancer is logically part of the cluster, but we refer to it as “external” because it is not running in<br />

the same process as either the client or any of the <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> instances. It


14 2 Chapter 17. Clustering Concepts<br />

can be implemented either in software or hardware. There are many vendors of hardware load<br />

balancers; the mod_jk Apache module is an excellent example of a software load balancer. An external<br />

load balancer implements its own mechanism for understanding the cluster configuration and provides<br />

its own load balancing and failover policies. The external load balancer clustering architecture is<br />

illustrated in Figure 17.3, “The external load balancer architecture for clustering”.<br />

Figure 17.3. The external load balancer architecture for clustering<br />

A potential problem with an external load balancer architecture is that the load balancer itself may be a<br />

single point of failure. It needs to be monitored closely to ensure high availability of the entire cluster's<br />

services.<br />

17.3. Load Balancing Policies<br />

Both the <strong>JBoss</strong> client-side interceptor (stub) and load balancer use load balancing policies to determine<br />

to which server node a new request should be sent. In this section, let's go over the load balancing<br />

policies available in <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>.<br />

17.3.1. Client-side interceptor architecture<br />

In <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5, the following load balancing options are available when the<br />

client-side interceptor architecture is used. The client-side stub maintains a list of all nodes providing the<br />

target service; the job of the load balance policy is to pick a node from this list for each request. Each<br />

policy has two implementation classes, one meant for use by legacy services like EJB2 that use the<br />

legacy detached invoker architecture, and the other meant for services like EJB3 that use AOP-based<br />

invocations.<br />

Round-Robin: each call is dispatched to a new node, proceeding sequentially through the list of<br />

nodes. The first target node is randomly selected from the list. Implemented by<br />

org.jboss.ha.framework.interfaces.RoundRobin (legacy) and<br />

org.jboss.ha.client.loadbalance.RoundRobin (EJB3).<br />

Random-Robin: for each call the target node is randomly selected from the list. Implemented by<br />

org.jboss.ha.framework.interfaces.RandomRobin (legacy) and<br />

org.jboss.ha.client.loadbalance.RandomRobin (EJB3).<br />

First Available: one of the available target nodes is elected as the main target and is thereafter used<br />

for every call; this elected member is randomly chosen from the list of members in the cluster. When<br />

the list of target nodes changes (because a node starts or dies), the policy will choose a new target<br />

node unless the currently elected node is still available. Each client-side proxy elects its own target<br />

node independently of the other proxies, so if a particular client downloads two proxies for the same<br />

target service (for example, an EJB), each proxy will independently pick its target. This is an example<br />

of a policy that provides “session affinity” or “sticky sessions”, since the target node does not<br />

change once established. Implemented by<br />

org.jboss.ha.framework.interfaces.FirstAvailable (legacy) and<br />

org.jboss.ha.client.loadbalance.aop.FirstAvailable (EJB3).


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 14 3<br />

First Available Identical All Proxies: has the same behavior as the "First Available" policy but the<br />

elected target node is shared by all proxies in the same client-side VM that are associated with the<br />

same target service. So if a particular client downloads two proxies for the same target service (e.g.<br />

an EJB), each proxy will use the same target. Implemented by<br />

org.jboss.ha.framework.interfaces.FirstAvailableIdenticalAllProxies (legacy)<br />

and org.jboss.ha.client.loadbalance.aop.FirstAvailableIdenticalAllProxies<br />

(EJB3).<br />

Each of the above is an implementation of the<br />

org.jboss.ha.framework.interfaces.LoadBalancePolicy interface; users are free to write<br />

their own implementation of this simple interface if they need some special behavior. In later sections<br />

we'll see how to configure the load balance policies used by different services.<br />

17.3.2. External load balancer architecture<br />

New in <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5 are a set of "TransactionSticky" load balance policies.<br />

These extend the standard policies above to add behavior such that all invocations that occur within the<br />

scope of a transaction are routed to the same node (if that node still exists). These are based on the<br />

legacy detached invoker architecture, so they are not available for AOP-based services like EJB3.<br />

Transaction-Sticky Round-Robin: Transaction-sticky variant of Round-Robin. Implemented by<br />

org.jboss.ha.framework.interfaces.TransactionStickyRoundRobin.<br />

Transaction-Sticky Random-Robin: Transaction-sticky variant of Random-Robin. Implemented by<br />

org.jboss.ha.framework.interfaces.TransactionStickyRandomRobin.<br />

Transaction-Sticky First Available: Transaction-sticky variant of First Available. Implemented by<br />

org.jboss.ha.framework.interfaces.TransactionStickyFirstAvailable.<br />

Transaction-Sticky First Available Identical All Proxies: Transaction-sticky variant of First Available<br />

Identical All Proxies. Implemented by<br />

org.jboss.ha.framework.interfaces.TransactionStickyFirstAvailableIdentica<br />

lAllProxies.<br />

Each of the above is an implementation of a simple interface; users are free to write their own<br />

implementations if they need some special behavior. In later sections we'll see how to configure the load<br />

balance policies used by different services.


14 4 Chapter 18. Clustering Building Blocks<br />

Chapter 18. Clustering Building Blocks<br />

The clustering features in <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> are built on top of lower level libraries<br />

that provide much of the core functionality. Figure 18.1, “The <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong><br />

clustering architecture” shows the main pieces:<br />

Figure 18.1. The <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> clustering architecture<br />

JGroups is a toolkit for reliable point-to-point and point-to-multipoint communication. JGroups is used<br />

for all clustering-related communications between nodes in a <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong><br />

cluster.<br />

<strong>JBoss</strong> Cache is a highly flexible clustered transactional caching library. Many <strong>Enterprise</strong> <strong>Application</strong><br />

<strong>Platform</strong> clustering services need to cache some state in memory while (1) ensuring for high availability<br />

purposes that a backup copy of that state is available on another node if it can't otherwise be recreated<br />

(e.g. the contents of a web session) and (2) ensuring that the data cached on each node in the cluster is<br />

consistent. <strong>JBoss</strong> Cache handles these concerns for most <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong><br />

clustered services. <strong>JBoss</strong> Cache uses JGroups to handle its group communication requirements. POJO<br />

Cache is an extension of the core <strong>JBoss</strong> Cache that <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> uses to<br />

support fine-grained replication of clustered web session state. See Section 18.2, “Distributed Caching<br />

with <strong>JBoss</strong> Cache” for more on how <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> uses <strong>JBoss</strong> Cache and POJO<br />

Cache.<br />

HAPartition is an adapter on top of a JGroups channel that allows multiple services to use the channel.<br />

HAPartition also supports a distributed registry of which HAPartition-based services are running on<br />

which cluster members. It provides notifications to interested listeners when the cluster membership<br />

changes or the clustered service registry changes. See Section 18.3, “The HAPartition Service” for more<br />

details on HAPartition.<br />

The other higher level clustering services make use of <strong>JBoss</strong> Cache or HAPartition, or, in the case of<br />

HA-JNDI, both. The exception to this is <strong>JBoss</strong> Messaging's clustering features, which interact with<br />

JGroups directly.<br />

18.1. Group Communication with JGroups<br />

JGroups provides the underlying group communication support for <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong><br />

clusters. Services deployed on <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> which need group communication<br />

with their peers will obtain a JGroups Channel and use it to communicate. The Channel handles such<br />

tasks as managing which nodes are members of the group, detecting node failures, ensuring lossless,<br />

first-in-first-out delivery of messages to all group members, and providing flow control to ensure fast<br />

message senders cannot overwhelm slow message receivers.<br />

The characteristics of a JGroups Channel are determined by the set of protocols that compose it. Each<br />

protocol handles a single aspect of the overall group communication task; for example the UDP protocol<br />

handles the details of sending and receiving UDP datagrams. A Channel that uses the UDP protocol is<br />

capable of communicating with UDP unicast and multicast; alternatively one that uses the TCP protocol<br />

uses TCP unicast for all messages. JGroups supports a wide variety of different protocols (see<br />

Section 25.1, “Configuring a JGroups Channel's Protocol Stack” for details), but the <strong>Enterprise</strong>


<strong>Application</strong> <strong>Platform</strong> ships with a default set of channel configurations that should meet most needs.<br />

By default, UDP multicast is used by all JGroups channels used by the <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong><br />

(except for one TCP-based channel used by <strong>JBoss</strong> Messaging).<br />

18.1.1. The Channel Factory Service<br />

A significant difference in <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5 versus previous releases is that<br />

JGroups Channels needed by clustering services (for example, a channel used by a distributed<br />

HttpSession cache) are no longer configured in detail as part of the consuming service's configuration,<br />

and are no longer directly instantiated by the consuming service. Instead, a new ChannelFactory<br />

service is used as a registry for named channel configurations and as a factory for Channel instances.<br />

A service that needs a channel requests the channel from the ChannelFactory, passing in the name<br />

of the desired configuration.<br />

The ChannelFactory service is deployed in the server/all/deploy/cluster/jgroupschannelfactory.sar.<br />

On startup the ChannelFactory service parses the<br />

server/all/deploy/cluster/jgroups-channelfactory.sar/META-INF/jgroupschannelfactory-stacks.xml<br />

file, which includes various standard JGroups configurations<br />

identified by name (for example, UDP or TCP). Services needing a channel access the channel factory<br />

and ask for a channel with a particular named configuration.<br />

Note<br />

If several services request a channel with the same configuration name from the ChannelFactory,<br />

they are not handed a reference to the same underlying Channel. Each receives its own Channel,<br />

but the channels will have an identical configuration. A logical question is how those channels<br />

avoid forming a group with each other if each, for example, is using the same multicast address<br />

and port. The answer is that when a consuming service connects its Channel, it passes a<br />

unique-to-that-service cluster_name argument to the Channel.connect(String<br />

cluster_name) method. The Channel uses that cluster_name as one of the factors that<br />

determine whether a particular message received over the network is intended for it.<br />

18.1.1.1. Standard Protocol Stack Configurations<br />

The standard protocol stack configurations that ship with <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5 are<br />

described below. Note that not all of these are actually used; many are included as a convenience to<br />

users who may wish to alter the default server configuration. The configurations actually used in a stock<br />

<strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5 all configuration are udp, jbm-control and jbm-data, with all<br />

clustering services other than <strong>JBoss</strong> Messaging using udp.<br />

You can add a new stack configuration by adding a new stack element to the<br />

server/all/deploy/cluster/jgroups-channelfactory.sar/META-INF/jgroupschannelfactory-stacks.xml<br />

file. You can alter the behavior of an existing configuration by editing<br />

this file. Before doing this though, have a look at the other standard configurations the <strong>Enterprise</strong><br />

<strong>Application</strong> <strong>Platform</strong> ships; perhaps one of those meets your needs. Also, please note that before editing<br />

a configuration you should understand what services are using that configuration; make sure the change<br />

you are making is appropriate for all affected services. If the change isn't appropriate for a particular<br />

service, perhaps its better to create a new configuration and change some services to use that new<br />

configuration.<br />

udp<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 14 5<br />

UDP multicast based stack meant to be shared between different channels. Message bundling is<br />

disabled, as it can add latency to synchronous group RPCs. Services that only make asynchronous<br />

RPCs (for example, <strong>JBoss</strong> Cache configured for REPL_ASYNC) and do so in high volume may be<br />

able to improve performance by configuring their cache to use the udp-async stack below. Services<br />

that only make synchronous RPCs (for example <strong>JBoss</strong> Cache configured for REPL_SYNC or<br />

INVALIDATION_SYNC) may be able to improve performance by using the udp-sync stack below,<br />

which does not include flow control.<br />

udp-async<br />

Same as the default udp stack above, except message bundling is enabled in the transport protocol<br />

(enable_bundling=true). Useful for services that make high-volume asynchronous RPCs (e.g.<br />

high volume <strong>JBoss</strong> Cache instances configured for REPL_ASYNC) where message bundling may


14 6 Chapter 18. Clustering Building Blocks<br />

improve performance.<br />

udp-sync<br />

UDP multicast based stack, without flow control and without message bundling. This can be used<br />

instead of udp if (1) synchronous calls are used and (2) the message volume (rate and size) is not<br />

that large. Don't use this configuration if you send messages at a high sustained rate, or you might<br />

run out of memory.<br />

tcp<br />

TCP based stack, with flow control and message bundling. TCP stacks are usually used when IP<br />

multicasting cannot be used in a network (e.g. routers discard multicast).<br />

tcp-sync<br />

TCP based stack, without flow control and without message bundling. TCP stacks are usually used<br />

when IP multicasting cannot be used in a network (e.g.routers discard multicast). This configuration<br />

should be used instead of tcp above when (1) synchronous calls are used and (2) the message<br />

volume (rate and size) is not that large. Don't use this configuration if you send messages at a high<br />

sustained rate, or you might run out of memory.<br />

jbm-control<br />

Stack optimized for the <strong>JBoss</strong> Messaging Control Channel. By default uses the same UDP transport<br />

protocol configuration as is used for the default udp stack defined above. This allows the <strong>JBoss</strong><br />

Messaging Control Channel to use the same sockets, network buffers and thread pools as are used<br />

by the other standard <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> clustered services (see Section 18.1.2,<br />

“The JGroups Shared Transport”)<br />

jbm-data<br />

TCP-based stack optimized for the <strong>JBoss</strong> Messaging Data Channel.<br />

18.1.2. The JGroups Shared Transport<br />

As the number of JGroups-based clustering services running in the <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> has<br />

risen over the years, the need to share the resources (particularly sockets and threads) used by these<br />

channels became a glaring problem. A stock <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5 all configuration will<br />

connect 4 JGroups channels during startup, and a total of 7 or 8 will be connected if distributable web<br />

apps, clustered EJB3 SFSBs and a clustered JPA/Hibernate second level cache are all used. So many<br />

channels can consume a lot of resources, and can be a real configuration nightmare if the network<br />

environment requires configuration to ensure cluster isolation.<br />

Beginning with <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5, JGroups supports sharing of transport protocol<br />

instances between channels. A JGroups channel is composed of a stack of individual protocols, each of<br />

which is responsible for one aspect of the channel's behavior. A transport protocol is a protocol that is<br />

responsible for actually sending messages on the network and receiving them from the network. The<br />

resources that are most desirable for sharing (sockets and thread pools) are managed by the transport<br />

protocol, so sharing a transport protocol between channels efficiently accomplishes JGroups resource<br />

sharing.<br />

To configure a transport protocol for sharing, simply add a singleton_name="someName" attribute<br />

to the protocol's configuration. All channels whose transport protocol configuration uses the same<br />

singleton_name value will share their transport. All other protocols in the stack will not be shared.<br />

Figure 18.2, “Services using a Shared Transport” illustrates 4 services running in a VM, each with its<br />

own channel. Three of the services are sharing a transport; the fourth is using its own transport.


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 14 7<br />

Figure 18.2. Services using a Shared Transport<br />

The protocol stack configurations used by the <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5 ChannelFactory all have<br />

a singleton_name configured. In fact, if you add a stack to the ChannelFactory that doesn't include a<br />

singleton_name, before creating any channels for that stack, the ChannelFactory will synthetically<br />

create a singleton_name by concatenating the stack name to the string "unnamed_", e.g.<br />

unnamed_customStack.<br />

18.2. Distributed Caching with <strong>JBoss</strong> Cache<br />

<strong>JBoss</strong> Cache is a fully featured distributed cache framework that can be used in any application server<br />

environment or standalone. <strong>JBoss</strong> Cache provides the underlying distributed caching support used by<br />

many of the standard clustered services in a <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> cluster, including:<br />

replication of clustered webapp sessions<br />

replication of clustered EJB3 Stateful Session beans<br />

clustered caching of JPA and Hibernate entities<br />

clustered Single Sign-On<br />

the HA-JNDI replicated tree<br />

DistributedStateService<br />

Users can also create their own <strong>JBoss</strong> Cache and POJO Cache instances for custom use by their<br />

applications, see Chapter 26, <strong>JBoss</strong> Cache Configuration and Deployment for more on this.<br />

18.2.1. The <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> CacheManager Service<br />

Many of the standard clustered services in <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> use <strong>JBoss</strong> Cache to<br />

maintain consistent state across the cluster. Different services (e.g. web session clustering or second<br />

level caching of JPA/Hibernate entities) use different <strong>JBoss</strong> Cache instances, with each cache<br />

configured to meet the needs of the service that uses it. In <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 4, each of<br />

these caches was independently deployed in the deploy/ directory, which had a number of<br />

disadvantages:<br />

Caches that end user applications didn't need were deployed anyway, with each creating an<br />

expensive JGroups channel. For example, even if there were no clustered EJB3 SFSBs, a cache to<br />

store them was started.<br />

Caches are internal details of the services that use them. They shouldn't be first-class deployments.<br />

Services would find their cache via JMX lookups. Using JMX for purposes other exposing<br />

management interfaces is just not the <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5 way.<br />

In <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5, the scattered cache deployments have been replaced with a<br />

new CacheManager service, deployed via the<br />

JBOSS_HOME/server/all/deploy/cluster/jboss-cache-manager.sar. The CacheManager<br />

is a factory and registry for <strong>JBoss</strong> Cache instances. It is configured with a set of named <strong>JBoss</strong> Cache<br />

configurations. Services that need a cache ask the cache manager for the cache by name; the cache<br />

manager creates the cache (if not already created) and returns it. The cache manager keeps a<br />

reference to each cache it has created, so all services that request the same cache configuration name<br />

will share the same cache. When a service is done with the cache, it releases it to the cache manager.<br />

The cache manager keeps track of how many services are using each cache, and will stop and destroy<br />

the cache when all services have released it.<br />

18.2.1.1. Standard Cache Configurations<br />

The following standard <strong>JBoss</strong> Cache configurations ship with <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5.<br />

You can add others to suit your needs, or edit these configurations to adjust cache behavior. Additions<br />

or changes are done by editing the deploy/cluster/jboss-cache-manager.sar/META-<br />

INF/jboss-cache-manager-jboss-beans.xml file (see Section 26.2.1, “Deployment Via the<br />

CacheManager Service” for details). Note however that these configurations are specifically optimized<br />

for their intended use, and except as specifically noted in the documentation chapters for each service in<br />

this guide, it is not advisable to change them.<br />

standard-session-cache


14 8 Chapter 18. Clustering Building Blocks<br />

Standard cache used for web sessions.<br />

field-granularity-session-cache<br />

Standard cache used for FIELD granularity web sessions.<br />

sfsb-cache<br />

Standard cache used for EJB3 SFSB caching.<br />

ha-partition<br />

Used by web tier Clustered Single Sign-On, HA-JNDI, Distributed State.<br />

mvcc-entity<br />

A configuration appropriate for JPA/Hibernate entity/collection caching that uses <strong>JBoss</strong> Cache's<br />

MVCC locking (see notes below).<br />

optimistic-entity<br />

A configuration appropriate for JPA/Hibernate entity/collection caching that uses <strong>JBoss</strong> Cache's<br />

optimistic locking (see notes below).<br />

pessimistic-entity<br />

A configuration appropriate for JPA/Hibernate entity/collection caching that uses <strong>JBoss</strong> Cache's<br />

pessimistic locking (see notes below).<br />

mvcc-entity-repeatable<br />

Same as "mvcc-entity" but uses <strong>JBoss</strong> Cache's REPEATABLE_READ isolation level instead of<br />

READ_COMMITTED (see notes below).<br />

pessimistic-entity-repeatable<br />

Same as "pessimistic-entity" but uses <strong>JBoss</strong> Cache's REPEATABLE_READ isolation level instead of<br />

READ_COMMITTED (see notes below).<br />

local-query<br />

A configuration appropriate for JPA/Hibernate query result caching. Does not replicate query results.<br />

DO NOT store the timestamp data Hibernate uses to verify validity of query results in this cache.<br />

replicated-query<br />

A configuration appropriate for JPA/Hibernate query result caching. Replicates query results. DO<br />

NOT store the timestamp data Hibernate uses to verify validity of query result in this cache.<br />

timestamps-cache<br />

A configuration appropriate for the timestamp data cached as part of JPA/Hibernate query result<br />

caching. A replicated timestamp cache is required if query result caching is used, even if the query<br />

results themselves use a non-replicating cache like local-query.<br />

mvcc-shared<br />

A configuration appropriate for a cache that's shared for JPA/Hibernate entity, collection, query result<br />

and timestamp caching. Not an advised configuration, since it requires cache mode REPL_SYNC,<br />

which is the least efficient mode. Also requires a full state transfer at startup, which can be<br />

expensive. Maintained for backwards compatibility reasons, as a shared cache was the only option in<br />

<strong>JBoss</strong> 4. Uses <strong>JBoss</strong> Cache's MVCC locking.<br />

optimistic-shared<br />

A configuration appropriate for a cache that's shared for JPA/Hibernate entity, collection, query result<br />

and timestamp caching. Not an advised configuration, since it requires cache mode REPL_SYNC,<br />

which is the least efficient mode. Also requires a full state transfer at startup, which can be<br />

expensive. Maintained for backwards compatibility reasons, as a shared cache was the only option in<br />

<strong>JBoss</strong> 4. Uses <strong>JBoss</strong> Cache's optimistic locking.<br />

pessimistic-shared<br />

A configuration appropriate for a cache that's shared for JPA/Hibernate entity, collection, query result<br />

and timestamp caching. Not an advised configuration, since it requires cache mode REPL_SYNC,<br />

which is the least efficient mode. Also requires a full state transfer at startup, which can be<br />

expensive. Maintained for backwards compatibility reasons, as a shared cache was the only option in<br />

<strong>JBoss</strong> 4. Uses <strong>JBoss</strong> Cache's pessimistic locking.<br />

mvcc-shared-repeatable<br />

Same as "mvcc-shared" but uses <strong>JBoss</strong> Cache's REPEATABLE_READ isolation level instead of<br />

READ_COMMITTED (see notes below).<br />

pessimistic-shared-repeatable<br />

Same as "pessimistic-shared" but uses <strong>JBoss</strong> Cache's REPEATABLE_READ isolation level instead<br />

of READ_COMMITTED. (see notes below).


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 14 9<br />

Note<br />

For more on <strong>JBoss</strong> Cache's locking schemes, see Section 26.1.4, “Concurrent Access”)<br />

Note<br />

For JPA/Hibernate second level caching, REPEATABLE_READ is only useful if the application<br />

evicts/clears entities from the EntityManager/Hibernate Session and then expects to repeatably<br />

re-read them in the same transaction. Otherwise, the Session's internal cache provides a<br />

repeatable-read semantic.<br />

18.2.1.2. Cache Configuration Aliases<br />

The CacheManager also supports aliasing of caches; i.e. allowing caches registered under one name to<br />

be looked up under a different name. Aliasing is useful for sharing caches between services whose<br />

configuration may specify different cache configuration names. It's also useful for supporting legacy<br />

EJB3 application configurations ported over from <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 4.<br />

Aliases can be configured by editing the "CacheManager" bean in the jboss-cache-managerjboss-beans.xml<br />

file. The following redacted configuration shows the standard aliases in <strong>Enterprise</strong><br />

<strong>Application</strong> <strong>Platform</strong> 5:<br />

<br />

. . .<br />

<br />

<br />

<br />

<br />

<br />

clustered-sso<br />

ha-partition<br />

<br />

<br />

<br />

jboss.cache:service=EJB3SFSBClusteredCache<br />

sfsb-cache<br />

<br />

<br />

<br />

jboss.cache:service=EJB3EntityTreeCache<br />

mvcc-shared<br />

<br />

<br />

<br />

. . .<br />

<br />

18.3. The HAPartition Service<br />

HAPartition is a general purpose service used for a variety of tasks in <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong><br />

clustering. At its core, it is an abstraction built on top of a JGroups Channel that provides support for<br />

making/receiving RPC invocations on/from one or more cluster members. HAPartition allows services<br />

that use it to share a single Channel and multiplex RPC invocations over it, eliminating the configuration<br />

complexity and runtime overhead of having each service create its own Channel. HAPartition also<br />

supports a distributed registry of which clustering services are running on which cluster members. It<br />

provides notifications to interested listeners when the cluster membership changes or the clustered<br />

service registry changes. HAPartition forms the core of many of the clustering services we'll be<br />

discussing in the rest of this guide, including smart client-side clustered proxies, EJB 2 SFSB replication<br />

and entity cache management, farming, HA-JNDI and HA singletons. Custom services can also make use


150 Chapter 18. Clustering Building Blocks<br />

of HAPartition.<br />

The following snippet shows the HAPartition service definition packaged with the standard <strong>JBoss</strong><br />

<strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> distribution. This configuration can be found in the<br />

server/all/deploy/cluster/hapartition-jboss-beans.xml file.<br />

<br />

<br />

ha-partition<br />

<br />

<br />

jboss:service=Naming<br />

@org.jboss.aop.microcontainer.aspects.jmx.JMX<br />

(name="jboss:service=HAPartition,partition=${jboss.partition.name:DefaultPartition}"<br />

, exposedInterface=org.jboss.ha.framework.server.ClusterPartitionMBean.class,<br />

registerDirectly=true)<br />

<br />

<br />

<br />

${jboss.partition.name:DefaultPartition}<br />

<br />

${jboss.bind.address}<br />

<br />

30000<br />

<br />

60000<br />

<br />

<br />

<br />

<br />

@org.jboss.aop.microcontainer.aspects.jmx.JMX<br />

(name="jboss:service=DistributedState,partitionName=${jboss.partition.name:DefaultPa<br />

rtition}",<br />

exposedInterface=org.jboss.ha.framework.server.DistributedStateImplMBean.class,<br />

registerDirectly=true)<br />

<br />

<br />

<br />

<br />

Much of the above is generic; below we'll touch on the key points relevant to end users. There are two<br />

beans defined above, the HAPartitionCacheHandler and the HAPartition itself.<br />

The HAPartition bean itself exposes the following configuration properties:<br />

partitionName is an optional attribute to specify the name of the cluster. Its default value is<br />

DefaultPartition. Use the -g (a.k.a. --partition) command line switch to set this value at server<br />

startup.<br />

nodeAddress is unused and can be ignored.<br />

stateTransferTimeout specifies the timeout (in milliseconds) for initial application state transfer.


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 151<br />

State transfer refers to the process of obtaining a serialized copy of initial application state from<br />

other already-running cluster members at service startup. Its default value is 30000.<br />

methodCallTimeout specifies the timeout (in milliseconds) for obtaining responses to group RPCs<br />

from the other cluster members. Its default value is 60000.<br />

The HAPartitionCacheHandler is a small utility service that helps the HAPartition integrate with<br />

<strong>JBoss</strong> Cache (see Section 18.2.1, “The <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> CacheManager Service”).<br />

HAPartition exposes a child service called DistributedState (see Section 18.3.2, “DistributedState<br />

Service”) that uses <strong>JBoss</strong> Cache; the HAPartitionCacheHandler helps ensure consistent<br />

configuration between the JGroups Channel used by Distributed State's cache and the one used<br />

directly by HAPartition.<br />

cacheConfigName the name of the <strong>JBoss</strong> Cache configuration to use for the HAPartition-related<br />

cache. Indirectly, this also specifies the name of the JGroups protocol stack configuration HAPartition<br />

should use. See Section 26.1.5, “JGroups Integration” for more on how the JGroups protocol stack is<br />

configured.<br />

In order for nodes to form a cluster, they must have the exact same partitionName and the<br />

HAPartitionCacheHandler's cacheConfigName must specify an identical <strong>JBoss</strong> Cache<br />

configuration. Changes in either element on some but not all nodes would prevent proper clustering<br />

behavior.<br />

You can view the current cluster information by pointing your browser to the JMX console of any <strong>JBoss</strong><br />

instance in the cluster (i.e., http://hostname:8080/jmx-console/) and then clicking on the<br />

jboss:service=HAPartition,partition=DefaultPartition MBean (change the MBean<br />

name to reflect your partitionr name if you use the -g startup switch). A list of IP addresses for the<br />

current cluster members is shown in the CurrentView field.<br />

Note<br />

While it is technically possible to put a <strong>JBoss</strong> server instance into multiple HAPartitions at the<br />

same time, this practice is generally not recommended, as it increases management complexity.<br />

18.3.1. DistributedReplicantManager Service<br />

The DistributedReplicantManager (DRM) service is a component of the HAPartition service<br />

made available to HAPartition users via the HAPartition.getDistributedReplicantManager()<br />

method. Generally speaking, <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> users will not directly make use of<br />

the DRM; we discuss it here as an aid to those who want a deeper understanding of how <strong>Enterprise</strong><br />

<strong>Application</strong> <strong>Platform</strong> clustering internals work.<br />

The DRM is a distributed registry that allows HAPartition users to register objects under a given key,<br />

making available to callersthe set of objects registered under that key by the various members of t he<br />

cluster. The DRM also provides a notification mechanism so interested listeners can be notified when<br />

the contents of the registry changes.<br />

There are two main usages for the DRM in <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>:<br />

Clustered Smart Proxies<br />

Here the keys are the names of the various services that need a clustered smart proxy (see<br />

Section 17.2.1, “Client-side interceptor architecture”, e.g. the name of a clustered EJB. The value<br />

object each node stores in the DRM is known as a "target". It's something a smart proxy's transport<br />

layer can use to contact the node (e.g. an RMI stub, an HTTP URL or a <strong>JBoss</strong> Remoting<br />

InvokerLocator). The factory that builds clustered smart proxies accesses the DRM to get the<br />

set of "targets" that should be injected into the proxy to allow it to communicate with all the nodes in<br />

a cluster.<br />

HASingleton<br />

Here the keys are the names of the various services that need to function as High Availablity<br />

Singletons (see the HASingleton chapter). The value object each node stores in the DRM is simply a<br />

String that acts as a token to indicate that the node has the service deployed, and thus is a<br />

candidate to become the "master" node for the HA singleton service.<br />

In both cases, the key under which objects are registered identifies a particular clustered service. It is<br />

useful to understand that every node in a cluster doesn't have to register an object under every key.


152 Chapter 18. Clustering Building Blocks<br />

Only services that are deployed on a particular node will register something under that service's key,<br />

and services don't have to be deployed homogeneously across the cluster. The DRM is thus useful as a<br />

mechanism for understanding a service's "topology" around the cluster — which nodes have the service<br />

deployed.<br />

18.3.2. DistributedState Service<br />

The DistributedState service is a legacy component of the HAPartition service made available to<br />

HAPartition users via the HAPartition.getDistributedState() method. This service provides<br />

coordinated management of arbitary application state around the cluster. It is supported for backwards<br />

compatibility reasons, but new applications should not use it; they should use the much more<br />

sophisticated <strong>JBoss</strong> Cache instead.<br />

In <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5 the DistributedState service actually delegates to an<br />

underlying <strong>JBoss</strong> Cache instance.<br />

18.3.3. Custom Use of HAPartition<br />

Custom services can also use make use of HAPartition to handle interactions with the cluster. Generally<br />

the easiest way to do this is to extend the org.jboss.ha.framework.server.HAServiceImpl<br />

base class, or the org.jboss.ha.jxm.HAServiceMBeanSupport class if JMX registration and<br />

notification support are desired.


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 153<br />

Chapter 19. Clustered JNDI Services<br />

JNDI is one of the most important services provided by the application server. The <strong>JBoss</strong> HA-JNDI (High<br />

Availability JNDI) service brings the following features to JNDI:<br />

Transparent failover of naming operations. If an HA-JNDI naming Context is connected to the HA-<br />

JNDI service on a particular <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> instance, and that service fails or<br />

is shut down, the HA-JNDI client can transparently fail over to another <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong><br />

instance.<br />

Load balancing of naming operations. A HA-JNDI naming Context will automatically load balance its<br />

requests across all the HA-JNDI servers in the cluster.<br />

Automatic client discovery of HA-JNDI servers (using multicast).<br />

Unified view of JNDI trees cluster-wide. A client can connect to the HA-JNDI service running on any<br />

node in the cluster and find objects bound in JNDI on any other node. This is accomplished via two<br />

mechanisms:<br />

Cross-cluster lookups. A client can perform a lookup and the server side HA-JNDI service has the<br />

ability to find things bound in regular JNDI on any node in the cluster.<br />

A replicated cluster-wide context tree. An object bound into the HA-JNDI service will be replicated<br />

around the cluster, and a copy of that object will be available in-VM on each node in the cluster.<br />

JNDI is a key component for many other interceptor-based clustering services: those services register<br />

themselves with JNDI so the client can look up their proxies and make use of their services. HA-JNDI<br />

completes the picture by ensuring that clients have a highly-available means to look up those proxies.<br />

However, it is important to understand that using HA-JNDI (or not) has no effect whatsoever on the<br />

clustering behavior of the objects that are looked up. To illustrate:<br />

If an EJB is not configured as clustered, looking up the EJB via HA-JNDI does not somehow result in<br />

the addition of clustering capabilities (load balancing of EJB calls, transparent failover, state<br />

replication) to the EJB.<br />

If an EJB is configured as clustered, looking up the EJB via regular JNDI instead of HA-JNDI does not<br />

somehow result in the removal of the bean proxy's clustering capabilities.<br />

19.1. How it works<br />

The <strong>JBoss</strong> client-side HA-JNDI naming Context is based on the client-side interceptor architecture (see<br />

the Introduction and Quick Start chapter). The client obtains an HA-JNDI proxy object (via the<br />

InitialContext object) and invokes JNDI lookup services on the remote server through the proxy.<br />

The client specifies that it wants an HA-JNDI proxy by configuring the naming properties used by the<br />

InitialContext object. This is covered in detail in Section 19.2, “Client configuration”. Other than the<br />

need to ensure the appropriate naming properties are provided to the InitialContext, the fact that<br />

the naming Context is using HA-JNDI is completely transparent to the client.<br />

On the server side, the HA-JNDI service maintains a cluster-wide context tree. The cluster wide tree is<br />

always available as long as there is one node left in the cluster. Each node in the cluster also maintains<br />

its own local JNDI context tree. The HA-JNDI service on each node is able to find objects bound into the<br />

local JNDI context tree, and is also able to make a cluster-wide RPC to find objects bound in the local<br />

tree on any other node. An application can bind its objects to either tree, although in practice most<br />

objects are bound into the local JNDI context tree. The design rationale for this architecture is as follows:<br />

It avoids migration issues with applications that assume that their JNDI implementation is local. This<br />

allows clustering to work out-of-the-box with just a few tweaks of configuration files.<br />

In a homogeneous cluster, this configuration actually cuts down on the amount of network traffic. A<br />

homogenous cluster is one where the same types of objects are bound under the same names on<br />

each node.<br />

Designing it in this way makes the HA-JNDI service an optional service since all underlying cluster<br />

code uses a straight new InitialContext to lookup or create bindings.<br />

On the server side, a naming Context obtained via a call to new InitialContext() will be bound to<br />

the local-only, non-cluster-wide JNDI Context. So, all EJB homes and such will not be bound to the<br />

cluster-wide JNDI Context, but rather, each home will be bound into the local JNDI.<br />

When a remote client does a lookup through HA-JNDI, HA-JNDI will delegate to the local JNDI service<br />

when it cannot find the object within the global cluster-wide Context. The detailed lookup rule is as<br />

follows.


154 Chapter 19. Clustered JNDI Services<br />

If the binding is available in the cluster-wide JNDI tree, return it.<br />

If the binding is not in the cluster-wide tree, delegate the lookup query to the local JNDI service and<br />

return the received answer if available.<br />

If not available, the HA-JNDI service asks all other nodes in the cluster if their local JNDI service<br />

owns such a binding and returns the answer from the set it receives.<br />

If no local JNDI service owns such a binding, a NameNotFoundException is finally raised.<br />

In practice, objects are rarely bound in the cluster-wide JNDI tree; rather they are bound in the local JNDI<br />

tree. For example, when EJBs are deployed, their proxies are always bound in local JNDI, not HA-JNDI.<br />

So, an EJB home lookup done through HA-JNDI will always be delegated to the local JNDI instance.<br />

Note<br />

If different beans (even of the same type, but participating in different clusters) use the same<br />

JNDI name, this means that each JNDI server will have a logically different "target" bound under<br />

the same name (JNDI on node 1 will have a binding for bean A and JNDI on node 2 will have a<br />

binding, under the same name, for bean B). Consequently, if a client performs a HA-JNDI query for<br />

this name, the query will be invoked on any JNDI server of the cluster and will return the locally<br />

bound stub. Nevertheless, it may not be the correct stub that the client is expecting to receive! So,<br />

it is always best practice to ensure that across the cluster different names are used for logically<br />

different bindings.<br />

Note<br />

If a binding is only made available on a few nodes in the cluster (for example because a bean is<br />

only deployed on a small subset of nodes in the cluster), the probability is higher that a lookup will<br />

hit a HA-JNDI server that does not own this binding and thus the lookup will need to be forwarded<br />

to all nodes in the cluster. Consequently, the query time will be longer than if the binding would<br />

have been available locally. Moral of the story: as much as possible, cache the result of your JNDI<br />

queries in your client.<br />

Note<br />

You cannot currently use a non-JNP JNDI implementation (i.e. LDAP) for your local JNDI<br />

implementation if you want to use HA-JNDI. However, you can use JNDI federation using the<br />

ExternalContext MBean to bind non-<strong>JBoss</strong> JNDI trees into the <strong>JBoss</strong> JNDI namespace.<br />

Furthermore, nothing prevents you using one centralized JNDI server for your whole cluster and<br />

scrapping HA-JNDI and JNP.<br />

19.2. Client configuration<br />

Configuring a client to use HA-JNDI is a matter of ensuring the correct set of naming environment<br />

properties are available when a new InitialContext is created. How this is done varies depending<br />

on whether the client is running inside <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> itself or is in another VM.<br />

19.2.1. For clients running inside the <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong><br />

If you want to access HA-JNDI from inside the <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>, you must explicitly<br />

configure your InitialContext by passing in JNDI properties to the constructor. The following code<br />

shows how to create a naming Context bound to HA-JNDI:<br />

Properties p = new Properties();<br />

p.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");<br />

p.put(Context.URL_PKG_PREFIXES, "jboss.naming:org.jnp.interfaces");<br />

// HA-JNDI is listening on the address passed to <strong>JBoss</strong> via -b<br />

String bindAddress = System.getProperty("jboss.bind.address", "localhost");<br />

p.put(Context.PROVIDER_URL, bindAddress + ":1100"); // HA-JNDI address and port.<br />

return new InitialContext(p);


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 155<br />

The Context.PROVIDER_URL property points to the HA-JNDI service configured in the<br />

deploy/cluster/hajndi-jboss-beans.xml file (see Section 19.3, “<strong>JBoss</strong> configuration”). By<br />

default this service listens on the interface named via the jboss.bind.address system property,<br />

which itself is set to whatever value you assign to the -b command line option when you start <strong>JBoss</strong><br />

<strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> (or localhost if not specified). The above code shows an example of<br />

accessing this property.<br />

However, this does not work in all cases, especially when running several <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong><br />

<strong>Platform</strong> instances on the same machine and bound to the same IP address, but configured to use<br />

different ports. A safer method is to not specify the Context.PROVIDER_URL but instead allow the<br />

InitialContext to statically find the in-VM HA-JNDI by specifying the jnp.partitionName<br />

property:<br />

Properties p = new Properties();<br />

p.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");<br />

p.put(Context.URL_PKG_PREFIXES, "jboss.naming:org.jnp.interfaces");<br />

// HA-JNDI is registered under the partition name passed to <strong>JBoss</strong> via -g<br />

String partitionName = System.getProperty("jboss.partition.name",<br />

"DefaultPartition");<br />

p.put("jnp.partitionName", partitionName);<br />

return new InitialContext(p);<br />

This example uses the jboss.partition.name system property to identify the partition with which<br />

the HA-JNDI service works. This system property is set to whatever value you assign to the -g<br />

command line option when you start <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> (or DefaultPartition if<br />

not specified).<br />

Do not attempt to simplify things by placing a jndi.properties file in your deployment or by editing<br />

the <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>'s conf/jndi.properties file. Doing either will almost certainly<br />

break things for your application and quite possibly across the server. If you want to externalize your<br />

client configuration, one approach is to deploy a properties file not named jndi.properties, and then<br />

programatically create a Properties object that loads that file's contents.<br />

19.2.1.1. Accessing HA-JNDI Resources from EJBs and WARs -- Environment Naming Context<br />

If your HA-JNDI client is an EJB or servlet, the least intrusive way to configure the lookup of resources is<br />

to bind the resources to the environment naming context of the bean or webapp performing the lookup.<br />

The binding can then be configured to use HA-JNDI instead of a local mapping. Following is an example<br />

of doing this for a JMS connection factory and queue (the most common use case for this kind of thing).<br />

Within the bean definition in the ejb-jar.xml or in the war's web.xml you will need to define two resourceref<br />

mappings, one for the connection factory and one for the destination.<br />

<br />

jms/ConnectionFactory<br />

javax.jms.QueueConnectionFactory<br />

Container<br />

<br />

<br />

jms/Queue<br />

javax.jms.Queue<br />

Container<br />

<br />

Using these examples the bean performing the lookup can obtain the connection factory by looking up<br />

'java:comp/env/jms/ConnectionFactory' and can obtain the queue by looking up<br />

'java:comp/env/jms/Queue'.<br />

Within the <strong>JBoss</strong>-specific deployment descriptor (jboss.xml for EJBs, jboss-web.xml for a WAR) these<br />

references need to be mapped to a URL that makes use of HA-JNDI.


156 Chapter 19. Clustered JNDI Services<br />

<br />

jms/ConnectionFactory<br />

jnp://${jboss.bind.address}:1100/ConnectionFactory<br />

<br />

<br />

jms/Queue<br />

jnp://${jboss.bind.address}:1100/queue/A<br />

<br />

The URL should be the URL to the HA-JNDI server running on the same node as the bean; if the bean is<br />

available the local HA-JNDI server should also be available. The lookup will then automatically query all<br />

of the nodes in the cluster to identify which node has the JMS resources available.<br />

The ${jboss.bind.address} syntax used above tells <strong>JBoss</strong> to use the value of the<br />

jboss.bind.address system property when determining the URL. That system property is itself set<br />

to whatever value you assign to the -b command line option when you start <strong>JBoss</strong> <strong>Enterprise</strong><br />

<strong>Application</strong> <strong>Platform</strong>.<br />

19.2.1.2. Why do this programmatically and not just put this in a jndi.properties file?<br />

The <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>'s internal naming environment is controlled by the<br />

conf/jndi.properties file, which should not be edited.<br />

No other jndi.properties file should be deployed inside the <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> because of the<br />

possibility of its being found on the classpath when it shouldn't and thus disrupting the internal operation<br />

of the server. For example, if an EJB deployment included a jndi.properties configured for HA-JNDI, when<br />

the server binds the EJB proxies into JNDI it will likely bind them into the replicated HA-JNDI tree and not<br />

into the local JNDI tree where they belong.<br />

19.2.1.3. How can I tell if things are being bound into HA-JNDI that shouldn't be?<br />

Go into the the jmx-console and execute the list operation on the jboss:service=JNDIView<br />

mbean. Towards the bottom of the results, the contents of the "HA-JNDI Namespace" are listed.<br />

Typically this will be empty; if any of your own deployments are shown there and you didn't explicitly bind<br />

them there, there's probably an improper jndi.properties file on the classpath. Please visit the following<br />

link for an example: Problem with removing a Node from Cluster.<br />

19.2.2. For clients running outside the <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong><br />

The JNDI client needs to be aware of the HA-JNDI cluster. You can pass a list of JNDI servers (i.e., the<br />

nodes in the HA-JNDI cluster) to the java.naming.provider.url JNDI setting in the<br />

jndi.properties file. Each server node is identified by its IP address and the JNDI port number. The<br />

server nodes are separated by commas (see Section 19.3, “<strong>JBoss</strong> configuration” for how to configure<br />

the servers and ports).<br />

java.naming.provider.url=server1:1100,server2:1100,server3:1100,server4:1100<br />

When initializing, the JNP client code will try to get in touch with each server node from the list, one after<br />

the other, stopping as soon as one server has been reached. It will then download the HA-JNDI stub<br />

from this node.<br />

Note<br />

There is no load balancing behavior in the JNP client lookup process itself. It just goes through<br />

the provider lists and uses the first available server to obtain the stub. The HA-JNDI provider list<br />

only needs to contain a subset of HA-JNDI nodes in the cluster; once the HA-JNDI stub is<br />

downloaded, the stub will include information on all the available servers. A good practice is to<br />

include a set of servers such that you are certain that at least one of those in the list will be<br />

available.<br />

The downloaded smart proxy contains the list of currently running nodes and the logic to load balance<br />

naming requests and to fail-over to another node if necessary. Furthermore, each time a JNDI invocation<br />

is made to the server, the list of targets in the proxy interceptor is updated (only if the list has changed<br />

since the last call).


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 157<br />

If the property string java.naming.provider.url is empty or if all servers it mentions are not<br />

reachable, the JNP client will try to discover a HA-JNDI server through a multicast call on the network<br />

(auto-discovery). See Section 19.3, “<strong>JBoss</strong> configuration” for how to configure auto-discovery on the<br />

JNDI server nodes. Through auto-discovery, the client might be able to get a valid HA-JNDI server node<br />

without any configuration. Of course, for auto-discovery to work, the network segment(s) between the<br />

client and the server cluster must be configured to propagate such multicast datagrams.<br />

Note<br />

By default the auto-discovery feature uses multicast group address 230.0.0.4 and port 1102.<br />

In addition to the java.naming.provider.url property, you can specify a set of other properties.<br />

The following list shows all clustering-related client side properties you can specify when creating a new<br />

InitialContext. (All of the standard, non-clustering-related environment properties used with regular<br />

JNDI are also available.)<br />

java.naming.provider.url: Provides a list of IP addresses and port numbers for HA-JNDI<br />

provider nodes in the cluster. The client tries those providers one by one and uses the first one that<br />

responds.<br />

jnp.disableDiscovery: When set to true, this property disables the automatic discovery<br />

feature. Default is false.<br />

jnp.partitionName: In an environment where multiple HA-JNDI services bound to distinct<br />

clusters (a.k.a. partitions), are running, this property allows you to ensure that your client only<br />

accepts automatic-discovery responses from servers in the desired partition. If you do not use the<br />

automatic discovery feature (i.e. jnp.disableDiscovery is true), this property is not used. By default,<br />

this property is not set and the automatic discovery selects the first HA-JNDI server that responds,<br />

regardless of the cluster partition name.<br />

jnp.discoveryTimeout: Determines how many milliseconds the context will wait for a response<br />

to its automatic discovery packet. Default is 5000 ms.<br />

jnp.discoveryGroup: Determines which multicast group address is used for the automatic<br />

discovery. Default is 230.0.0.4. Must match the value of the AutoDiscoveryAddress configured on the<br />

server side HA-JNDI service. Note that the server side HA-JNDI service by default listens on the<br />

address specified via the -u startup switch, so if -u is used on the server side (as is recommended),<br />

jnp.discoveryGroup will need to be configured on the client side.<br />

jnp.discoveryPort: Determines which multicast port is used for the automatic discovery. Default<br />

is 1102. Must match the value of the AutoDiscoveryPort configured on the server side HA-JNDI<br />

service.<br />

jnp.discoveryTTL: specifies the TTL (time-to-live) for autodiscovery IP multicast packets. This<br />

value represents the number of network hops a multicast packet can be allowed to propagate before<br />

networking equipment should drop the packet. Despite its name, it does not represent a unit of time.<br />

19.3. <strong>JBoss</strong> configuration<br />

The hajndi-jboss-beans.xml file in the JBOSS_HOME/server/all/deploy/cluster directory<br />

includes the following bean to enable HA-JNDI services.


158 Chapter 19. Clustered JNDI Services<br />

<br />

@org.jboss.aop.microcontainer.aspects.jmx.JMX<br />

(name="jboss:service=HAJNDI",<br />

exposedInterface=org.jboss.ha.jndi.HANamingServiceMBean.class)<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

-><br />

<br />

${jboss.bind.address}<br />

<br />

<br />

<br />

<br />

jboss:service=HAJNDI<br />

Port<br />

<br />

<br />

<br />

${jboss.bind.address}<br />

<br />

<br />

jboss:service=HAJNDI<br />

RmiPort<br />

<br />

<br />

<br />

50<br />

<br />

false<br />

<br />

${jboss.bind.address}<br />

<br />

${jboss.partition.udpGroup:230.0.0.4}<br />

1102<br />

<br />

16<br />

<br />

org.jboss.ha.framework.interfaces.RoundRobin<br />


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 159<br />

custom<br />

--><br />

<br />

<br />

You can see that this bean has a number of other services injected into different properties:<br />

HAPartition accepts the core clustering service used manage HA-JNDI's clustered proxies and to<br />

make the group RPCs that find locally bound objects on other nodes. See Section 18.3, “The<br />

HAPartition Service” for more.<br />

distributedTreeManager accepts a handler for the replicated tree. The standard handler uses<br />

<strong>JBoss</strong> Cache to manage the replicated tree. The <strong>JBoss</strong> Cache instance is retrieved using the<br />

injected HAPartitionCacheHandler bean. See Section 18.3, “The HAPartition Service” for more<br />

details.<br />

localNamingInstance accepts the reference to the local JNDI service.<br />

lookupPool accepts the thread pool used to provide threads to handle the bootstrap and auto<br />

discovery lookups.<br />

Besides the above dependency injected services, the available configuration attributes for the HA-JNDI<br />

bean are as follows:<br />

bindAddress specifies the address to which the HA-JNDI server will bind to listen for naming proxy<br />

download requests from JNP clients. The default value is the value of the jboss.bind.address<br />

system property, or localhost if that property is not set. The jboss.bind.address system<br />

property is set if the -b command line switch is used when <strong>JBoss</strong> is started.<br />

port specifies the port to which the HA-JNDI server will bind to listen for naming proxy download<br />

requests from JNP clients. The value is obtained from the ServiceBindingManager bean configured in<br />

conf/bootstrap/bindings.xml. The default value is 1100.<br />

backlog specifies the maximum queue length for incoming connection indications for the TCP server<br />

socket on which the service listens for naming proxy download requests from JNP clients. The<br />

default value is 50.<br />

rmiBindAddress specifies the address to which the HA-JNDI server will bind to listen for RMI<br />

requests (e.g. for JNDI lookups) from naming proxies. The default value is the value of the<br />

jboss.bind.address system property, or localhost if that property is not set. The<br />

jboss.bind.address system property is set if the -b command line switch is used when <strong>JBoss</strong> is<br />

started.<br />

rmiPort specifies the port to which the server will bind to communicate with the downloaded stub.<br />

The value is obtained from the ServiceBindingManager bean configured in<br />

conf/bootstrap/bindings.xml. The default value is 1101. If no value is set, the operating<br />

system automatically assigns a port.<br />

discoveryDisabled is a boolean flag that disables configuration of the auto discovery multicast<br />

listener. The default is false.<br />

autoDiscoveryAddress specifies the multicast address to listen to for JNDI automatic discovery.<br />

The default value is the value of the jboss.partition.udpGroup system property, or 230.0.0.4<br />

if that is not set. The jboss.partition.udpGroup system property is set if the -u command line<br />

switch is used when <strong>JBoss</strong> is started.<br />

autoDiscoveryGroup specifies the port to listen on for multicast JNDI automatic discovery packets.<br />

The default value is 1102.<br />

autoDiscoveryBindAddress sets the interface on which HA-JNDI should listen for auto-discovery<br />

request packets. If this attribute is not specified and a bindAddress is specified, the<br />

bindAddress will be used.<br />

autoDiscoveryTTL specifies the TTL (time-to-live) for autodiscovery IP multicast packets. This<br />

value represents the number of network hops a multicast packet can be allowed to propagate before<br />

networking equipment should drop the packet. Despite its name, it does not represent a unit of time.<br />

loadBalancePolicy specifies the class name of the LoadBalancePolicy implementation that should<br />

be included in the client proxy. See Chapter 16, Introduction and Quick Start the Introduction and<br />

Quick Start chapter for details.<br />

clientSocketFactory is an optional attribute that specifies the fully qualified classname of the<br />

java.rmi.server.RMIClientSocketFactory that should be used to create client sockets.<br />

The default is null.<br />

serverSocketFactory is an optional attribute that specifies the fully qualified classname of the


160 Chapter 19. Clustered JNDI Services<br />

java.rmi.server.RMIServerSocketFactory that should be used to create server sockets.<br />

The default is null.<br />

19.3.1. Adding a Second HA-JNDI Service<br />

It is possible to start several HA-JNDI services that use different HAPartitions. This can be used, for<br />

example, if a node is part of many logical clusters. In this case, make sure that you set a different port or<br />

IP address for each service. For instance, if you wanted to hook up HA-JNDI to the example cluster you<br />

set up and change the binding port, the bean descriptor would look as follows (properties that do not<br />

vary from the standard deployments are omitted):<br />

<br />

<br />

<br />

secondary-ha-partition<br />

<br />

<br />

<br />

jboss:service=Naming<br />

@org.jboss.aop.microcontainer.aspects.jmx.JMX<br />

(name="jboss:service=HAPartition,partition=SecondaryPartition",<br />

exposedInterface=org.jboss.ha.framework.server.ClusterPartitionMBean.class,<br />

registerDirectly=true)<br />

<br />

SecondaryPartition<br />

....<br />

<br />

<br />

@org.jboss.aop.microcontainer.aspects.jmx.JMX<br />

(name="jboss:service=HAJNDI,partitionName=SecondaryPartition",<br />

exposedInterface=org.jboss.ha.jndi.HANamingServiceMBean.class)<br />

<br />

<br />

<br />

<br />

<br />

<br />

56789<br />

56790<br />

56791<br />

.....<br />


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 161<br />

Chapter 20. Clustered Session EJBs<br />

Session EJBs provide remote invocation services. They are clustered based on the client-side<br />

interceptor architecture. The client application for a clustered session bean is the same as the client for<br />

the non-clustered version of the session bean, except for some minor changes. No code change or recompilation<br />

is needed on the client side. Now, let's check out how to configure clustered session beans<br />

in EJB 3.0 and EJB 2.x server applications respectively.<br />

20.1. Stateless Session Bean in EJB 3.0<br />

Clustering stateless session beans is probably the easiest case since no state is involved. Calls can be<br />

load balanced to any participating node (i.e. any node that has this specific bean deployed) of the<br />

cluster.<br />

To cluster a stateless session bean in EJB 3.0, simply annotate the bean class with the @Clustered<br />

annotation. This annotation contains optional parameters for overriding both the load balance policy and<br />

partition to use.<br />

public @interface Clustered<br />

{<br />

String partition() default "${jboss.partition.name:DefaultPartition}";<br />

String loadBalancePolicy() default "LoadBalancePolicy";<br />

}<br />

partition specifies the name of the cluster the bean participates in. While the @Clustered<br />

annotation lets you override the default partition, DefaultPartition, for an individual bean, you<br />

can override this for all beans using the jboss.partition.name system property.<br />

loadBalancePolicy defines the name of a class implementing<br />

org.jboss.ha.client.loadbalance.LoadBalancePolicy, indicating how the bean stub<br />

should balance calls made on the nodes of the cluster. The default value, LoadBalancePolicy is<br />

a special token indicating the default policy for the session bean type. For stateless session beans,<br />

the default policy is org.jboss.ha.client.loadbalance.RoundRobin. You can override the<br />

default value using your own implementation, or choose one from the list of available policies:<br />

org.jboss.ha.client.loadbalance.RoundRobin<br />

Starting with a random target, always favors the next available target in the list, ensuring<br />

maximum load balancing always occurs.<br />

org.jboss.ha.client.loadbalance.RandomRobin<br />

Randomly selects its target without any consideration to previously selected targets.<br />

org.jboss.ha.client.loadbalance.aop.FirstAvailable<br />

Once a target is chosen, always favors that same target; i.e. no further load balancing<br />

occurs. Useful in cases where "sticky session" behavior is desired, e.g. stateful session<br />

beans.<br />

org.jboss.ha.client.loadbalance.aop.FirstAvailableIdenticalAllProxies<br />

Similar to FirstAvailable, except that the favored target is shared across all proxies.<br />

Here is an example of a clustered EJB 3.0 stateless session bean implementation.<br />

@Stateless<br />

@Clustered<br />

public class MyBean implements MySessionInt<br />

{<br />

public void test()<br />

{<br />

// Do something cool<br />

}<br />

}<br />

Rather than using the @Clustered annotation, you can also enable clustering for a session bean in


162 Chapter 20. Clustered Session EJBs<br />

jboss.xml:<br />

<br />

<br />

<br />

NonAnnotationStateful<br />

true<br />

<br />

FooPartition<br />

org.jboss.ha.framework.interfaces.RandomRobin<br />

<br />

<br />

<br />

<br />

Note<br />

The true element is really just an alias for the Clustered<br />

Stateless SessionBean element in the<br />

conf/standardjboss.xml file.<br />

In the bean configuration, only the element is necessary to indicate that the bean needs to<br />

support clustering features. The default values for the optional elements match those<br />

of the corresponding properties from the @Clustered annotation.<br />

20.2. Stateful Session Beans in EJB 3.0<br />

Clustering stateful session beans is more complex than clustering their stateless counterparts since<br />

<strong>JBoss</strong> needs to manage the state information. The state of all stateful session beans are replicated and<br />

synchronized across the cluster each time the state of a bean changes.<br />

20.2.1. The EJB application configuration<br />

To cluster stateful session beans in EJB 3.0, you need to tag the bean implementation class with the<br />

@Clustered annotation, just as we did with the EJB 3.0 stateless session bean earlier. In contrast to<br />

stateless session beans, stateful session bean method invocations are load balanced using<br />

org.jboss.ha.client.loadbalance.aop.FirstAvailable policy, by default. Using this policy,<br />

methods invocations will stick to a randomly chosen node.<br />

The @org.jboss.ejb3.annotation.CacheConfig annotation can also be applied to the bean to<br />

override the default caching behavior. Below is the definition of the @CacheConfig annotation:<br />

public @interface CacheConfig<br />

{<br />

String name() default "";<br />

int maxSize() default 10000;<br />

long idleTimeoutSeconds() default 300;<br />

boolean replicationIsPassivation() default true;<br />

long removalTimeoutSeconds() default 0;<br />

}<br />

name specifies the name of a cache configuration registered with the CacheManager service<br />

discussed in Section 20.2.3, “CacheManager service configuration”. By default, the sfsb-cache<br />

configuration will be used.<br />

maxSize specifies the maximum number of beans that can cached before the cache should start<br />

passivating beans, using an LRU algorithm.<br />

idleTimeoutSeconds specifies the max period of time a bean can go unused before the cache<br />

should passivate it (regardless of whether maxSize beans are cached.)<br />

removalTimeoutSeconds specifies the max period of time a bean can go unused before the<br />

cache should remove it altogether.<br />

replicationIsPassivation specifies whether the cache should consider a replication as being<br />

equivalent to a passivation, and invoke any @PrePassivate and @PostActivate callbacks on the


ean. By default true, since replication involves serializing the bean, and preparing for and recovering<br />

from serialization is a common reason for implementing the callback methods.<br />

Here is an example of a clustered EJB 3.0 stateful session bean implementation.<br />

@Stateful<br />

@Clustered<br />

@CacheConfig(maxSize=5000, removalTimeoutSeconds=18000)<br />

public class MyBean implements MySessionInt<br />

{<br />

private int state = 0;<br />

}<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 163<br />

public void increment()<br />

{<br />

System.out.println("counter: " + (state++));<br />

}<br />

As with stateless beans, the @Clustered annotation can alternatively be omitted and the clustering<br />

configuration instead applied to jboss.xml:<br />

<br />

<br />

<br />

NonAnnotationStateful<br />

true<br />

<br />

5000<br />

18000<br />

<br />

<br />

<br />

<br />

20.2.2. Optimize state replication<br />

As the replication process is a costly operation, you can optimise this behaviour by optionally<br />

implementing the org.jboss.ejb3.cache.Optimized interface in your bean class:<br />

public interface Optimized<br />

{<br />

boolean isModified();<br />

}<br />

Before replicating your bean, the container will check if your bean implements the Optimized interface.<br />

If this is the case, the container calls the isModified() method and will only replicate the bean when<br />

the method returns true. If the bean has not been modified (or not enough to require replication,<br />

depending on your own preferences), you can return false and the replication would not occur.<br />

20.2.3. CacheManager service configuration<br />

<strong>JBoss</strong> Cache provides the session state replication service for EJB 3.0 stateful session beans. The<br />

CacheManager service, described in Section 18.2.1, “The <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong><br />

CacheManager Service” is both a factory and registry of <strong>JBoss</strong> Cache instances. By default, stateful<br />

session beans use the sfsb-cache configuration from the CacheManager, defined as follows:


164 Chapter 20. Clustered Session EJBs<br />

<br />

<br />

<br />

${jboss.partition.name:DefaultPartition}-<br />

SFSBCache<br />

<br />

${jboss.default.jgroups.stack:udp}<br />

true<br />

PESSIMISTIC<br />

REPEATABLE_READ<br />

false<br />

REPL_ASYNC<br />

<br />

17500<br />

<br />

15000<br />

<br />

60000<br />

<br />

false<br />

<br />

false<br />

<br />

0<br />

<br />

0<br />

true<br />

<br />

<br />

<br />

false<br />

<br />

default<br />

17500<br />

<br />

false<br />

true<br />

true<br />

<br />

<br />

<br />

1<br />


a different physical host. If not able to do so<br />

though, it will fall back to colocated nodes. --><br />

true<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

true<br />

false<br />

<br />

<br />

<br />

<br />

${jboss.server.data.dir}${/}sfsb<br />

<br />

false<br />

true<br />

true<br />

false<br />

false<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

5000<br />

<br />

<br />

<br />

/<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Eviction<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 165<br />

The default SFSB cache is configured to support eviction. The EJB3 SFSB container uses the <strong>JBoss</strong><br />

Cache eviction mechanism to manage SFSB passivation. When beans are deployed, the EJB container<br />

will programatically add eviction regions to the cache, one region per bean type.<br />

CacheLoader<br />

A <strong>JBoss</strong> Cache CacheLoader is also configured; again to support SFSB passivation. When beans are<br />

evicted from the cache, the cache loader passivates them to a persistent store; in this case to the<br />

filesystem in the $JBOSS_HOME /server/all/data/sfsb directory. <strong>JBoss</strong> Cache supports a variety<br />

of different CacheLoader implementations that know how to store data to different persistent store types;<br />

see the <strong>JBoss</strong> Cache documentation for details. However, if you change the CacheLoaderConfiguration,<br />

be sure that you do not use a shared store, e.g. a single schema in a shared database. Each node in<br />

the cluster must have its own persistent store, otherwise as nodes independently passivate and activate<br />

clustered beans, they will corrupt each other's data.<br />

Buddy Replication<br />

Using buddy replication, state is replicated to a configurable number of backup servers in the cluster<br />

(a.k.a. buddies), rather than to all servers in the cluster. To enable buddy replication, adjust the following<br />

properties in the buddyReplicationConfig property bean:


166 Chapter 20. Clustered Session EJBs<br />

Set enabled to true.<br />

Use the buddyPoolName to form logical subgroups of nodes within the cluster. If possible, buddies<br />

will be chosen from nodes in the same buddy pool.<br />

Adjust the buddyLocatorConfig.numBuddies property to reflect the number of backup nodes to<br />

which each node should replicate its state.<br />

20.3. Stateless Session Bean in EJB 2.x<br />

To make an EJB 2.x bean clustered, you need to modify its jboss.xml descriptor to contain a<br />

tag.<br />

<br />

<br />

<br />

nextgen.StatelessSession<br />

nextgen.StatelessSession<br />

true<br />

<br />

DefaultPartition<br />

org.jboss.ha.framework.interfaces.RoundRobinorg.jboss.ha.framework.interfaces.RoundRobin<br />

<br />

<br />

<br />

<br />

partition-name specifies the name of the cluster the bean participates in. The default value is<br />

DefaultPartition. The default partition name can also be set system-wide using the<br />

jboss.partition.name system property.<br />

home-load-balance-policy indicates the class to be used by the home stub to balance calls made<br />

on the nodes of the cluster. By default, the proxy will load-balance calls in a RoundRobin fashion.<br />

bean-load-balance-policy Indicates the class to be used by the bean stub to balance calls made<br />

on the nodes of the cluster. By default, the proxy will load-balance calls in a RoundRobin fashion.<br />

20.4. Stateful Session Bean in EJB 2.x<br />

Clustering stateful session beans is more complex than clustering their stateless counterparts since<br />

<strong>JBoss</strong> needs to manage the state information. The state of all stateful session beans are replicated and<br />

synchronized across the cluster each time the state of a bean changes. The <strong>JBoss</strong> <strong>Enterprise</strong><br />

<strong>Application</strong> <strong>Platform</strong> uses the HASessionStateService bean to manage distributed session states<br />

for clustered EJB 2.x stateful session beans. In this section, we cover both the session bean<br />

configuration and the HASessionStateService bean configuration.<br />

20.4 .1. The EJB application configuration<br />

In the EJB application, you need to modify the jboss.xml descriptor file for each stateful session bean<br />

and add the tag.


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 167<br />

<br />

<br />

<br />

nextgen.StatefulSession<br />

nextgen.StatefulSession<br />

True<br />

<br />

DefaultPartition<br />

org.jboss.ha.framework.interfaces.RoundRobinorg.jboss.ha.framework.interfaces.FirstAvailable/HASessionState/Default<br />

<br />

<br />

<br />

<br />

In the bean configuration, only the tag is mandatory to indicate that the bean works in a<br />

cluster. The element is optional and its default attribute values are indicated in the<br />

sample configuration above.<br />

The tag is used to give the JNDI name of the<br />

HASessionStateService to be used by this bean.<br />

The description of the remaining tags is identical to the one for stateless session bean. Actions on the<br />

clustered stateful session bean's home interface are by default load-balanced, round-robin. Once the<br />

bean's remote stub is available to the client, calls will not be load-balanced round-robin any more and will<br />

stay "sticky" to the first node in the list.<br />

20.4 .2. Optimize state replication<br />

As the replication process is a costly operation, you can optimise this behaviour by optionally<br />

implementing in your bean class a method with the following signature:<br />

public boolean isModified();<br />

Before replicating your bean, the container will detect if your bean implements this method. If your bean<br />

does, the container calls the isModified() method and it only replicates the bean when the method<br />

returns true. If the bean has not been modified (or not enough to require replication, depending on your<br />

own preferences), you can return false and the replication would not occur.<br />

20.4 .3. The HASessionStateService configuration<br />

The HASessionStateService bean is defined in the /deploy/cluster/ha-legacyjboss-beans.xml<br />

file.<br />

<br />

@org.jboss.aop.microcontainer.aspects.jmx.JMX<br />

(name="jboss:service=HASessionState",<br />

exposedInterface=org.jboss.ha.hasessionstate.server.<br />

HASessionStateServiceMBean.class,<br />

registerDirectly=true)<br />

<br />

<br />

<br />

/HASessionState/Default<br />

<br />

0<br />


168 Chapter 20. Clustered Session EJBs<br />

The configuration attributes in the HASessionStateService bean are listed below.<br />

HAPartition is a required attribute to inject the HAPartition service that HA-JNDI uses for intracluster<br />

communication.<br />

jndiName is an optional attribute to specify the JNDI name under which this<br />

HASessionStateService bean is bound. The default value is /HAPartition/Default.<br />

beanCleaningDelay is an optional attribute to specify the number of miliseconds after which the<br />

HASessionStateService can clean a state that has not been modified. If a node, owning a bean,<br />

crashes, its brother node will take ownership of this bean. Nevertheless, the container cache of the<br />

brother node will not know about it (because it has never seen it before) and will never delete<br />

according to the cleaning settings of the bean. That is why the HASessionStateService needs to<br />

do this cleanup sometimes. The default value is 30*60*1000 milliseconds (i.e., 30 minutes).<br />

20.4 .4 . Handling Cluster Restart<br />

We have covered the HA smart client architecture in Section 17.2.1, “Client-side interceptor architecture”.<br />

The default HA smart proxy client can only failover as long as one node in the cluster exists. If there is a<br />

complete cluster shutdown, the proxy becomes orphaned and loses knowledge of the available nodes in<br />

the cluster. There is no way for the proxy to recover from this. The proxy needs to look up a fresh set of<br />

targets out of JNDI/HA-JNDI when the nodes are restarted.<br />

RetryInterceptor can be added to the proxy client side interceptor stack to allow for a transparent<br />

recovery from such a restart failure. To enable it for an EJB, setup an invoker-proxy-binding that<br />

includes the RetryInterceptor. Below is an example jboss.xml configuration.<br />

<br />

<br />

nextgen_RetryInterceptorStatelessSession<br />

<br />

<br />

clustered-retry-stateless-rmiinvoker<br />

nextgen_RetryInterceptorStatelessSession<br />

<br />

<br />

true<br />

<br />

<br />

clustered-retry-stateless-rmi-invoker<br />

jboss:service=invoker,type=jrmpha<br />

org.jboss.proxy.ejb.ProxyFactoryHA<br />

<br />

<br />

<br />

org.jboss.proxy.ejb.HomeInterceptor<br />

org.jboss.proxy.SecurityInterceptor<br />

org.jboss.proxy.TransactionInterceptor<br />

org.jboss.proxy.ejb.RetryInterceptor<br />

org.jboss.invocation.InvokerInterceptor<br />

<br />

<br />

org.jboss.proxy.ejb.StatelessSessionInterceptor<br />

org.jboss.proxy.SecurityInterceptor<br />

org.jboss.proxy.TransactionInterceptor<br />

org.jboss.proxy.ejb.RetryInterceptor<br />

org.jboss.invocation.InvokerInterceptor<br />

<br />

<br />

<br />

<br />

<br />

20.4 .5. JNDI Lookup Process<br />

In order to recover the HA proxy, the RetryInterceptor does a lookup in JNDI. This means that internally it<br />

creates a new InitialContext and does a JNDI lookup. But, for that lookup to succeed, the InitialContext<br />

needs to be configured properly to find your naming server. The RetryInterceptor will go through the


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 169<br />

following steps in attempting to determine the proper naming environment properties:<br />

1. It will check its own static retryEnv field. This field can be set by client code via a call to<br />

RetryInterceptor.setRetryEnv(Properties). This approach to configuration has two downsides: first,<br />

it reduces portability by introducing <strong>JBoss</strong>-specific calls to the client code; and second, since a<br />

static field is used only a single configuration per VM is possible.<br />

2. If the retryEnv field is null, it will check for any environment properties bound to a ThreadLocal by<br />

the org.jboss.naming.NamingContextFactory class. To use this class as your naming context<br />

factory, in your jndi.properties set property<br />

java.naming.factory.initial=org.jboss.naming.NamingContextFactory. The advantage of this<br />

approach is use of org.jboss.naming.NamingContextFactory is simply a configuration option in<br />

your jndi.properties file, and thus your java code is unaffected. The downside is the naming<br />

properties are stored in a ThreadLocal and thus are only visible to the thread that originally<br />

created an InitialContext.<br />

3. If neither of the above approaches yield a set of naming environment properties, a default<br />

InitialContext is used. If the attempt to contact a naming server is unsuccessful, by default the<br />

InitialContext will attempt to fall back on multicast discovery to find an HA-JNDI naming server. See<br />

Chapter 19, Clustered JNDI Services for more on multicast discovery of HA-JNDI.<br />

20.4 .6. SingleRetryInterceptor<br />

The RetryInterceptor is useful in many use cases, but a disadvantage it has is that it will continue<br />

attempting to re-lookup the HA proxy in JNDI until it succeeds. If for some reason it cannot succeed, this<br />

process could go on forever, and thus the EJB call that triggered the RetryInterceptor will never return.<br />

For many client applications, this possibility is unacceptable. As a result, <strong>JBoss</strong> doesn't make the<br />

RetryInterceptor part of its default client interceptor stacks for clustered EJBs.<br />

In a previous release, a new flavor of retry interceptor was introduced, the<br />

org.jboss.proxy.ejb.SingleRetryInterceptor. This version works like the RetryInterceptor, but only makes a<br />

single attempt to re-lookup the HA proxy in JNDI. If this attempt fails, the EJB call will fail just as if no retry<br />

interceptor was used. The SingleRetryInterceptor is now part of the default client interceptor stacks for<br />

clustered EJBs.<br />

The downside of the SingleRetryInterceptor is that if the retry attempt is made during a portion of a<br />

cluster restart where no servers are available, the retry will fail and no further attempts will be made.


170 Chapter 21. Clustered Entity EJBs<br />

Chapter 21. Clustered Entity EJBs<br />

In a <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> cluster, entity bean instance caches need to be kept in sync<br />

across all nodes. If an entity bean provides remote services, the service methods need to be load<br />

balanced as well.<br />

21.1. Entity Bean in EJB 3.0<br />

In EJB 3.0, entity beans primarily serve as a persistence data model. They do not provide remote<br />

services. Hence, the entity bean clustering service in EJB 3.0 primarily deals with distributed caching and<br />

replication, instead of load balancing.<br />

21.1.1. Configure the distributed cache<br />

To avoid round trips to the database, you can use a cache for your entities. <strong>JBoss</strong> EJB 3.0 entity beans<br />

are implemented by Hibernate, which has support for a second-level cache. The second-level cache<br />

provides the following functionalities:<br />

If you persist a cache-enabled entity bean instance to the database via the entity manager, the entity<br />

will be inserted into the cache.<br />

If you update an entity bean instance, and save the changes to the database via the entity manager,<br />

the entity will be updated in the cache.<br />

If you remove an entity bean instance from the database via the entity manager, the entity will be<br />

removed from the cache.<br />

If loading a cached entity from the database via the entity manager, and that entity does not exist in<br />

the database, it will be inserted into the cache.<br />

As well as a region for caching entities, the second-level cache also contains regions for caching<br />

collections, queries, and timestamps. The Hibernate setup used for the <strong>JBoss</strong> EJB 3.0 implementation<br />

uses <strong>JBoss</strong> Cache as its underlying second-level cache implementation.<br />

Configuration of a the second-level cache is done via your EJB3 deployment's persistence.xml, like<br />

so:<br />

<br />

<br />

<br />

java:/DefaultDS<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

hibernate.cache.use_second_level_cache<br />

Enables second-level caching of entities and collections.<br />

hibernate.cache.use_query_cache<br />

Enables second-level caching of queries.<br />

hibernate.cache.region.factory_class


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 171<br />

Defines the RegionFactory implementation that dictates region-specific caching behavior.<br />

Hibernate ships with 2 types of <strong>JBoss</strong> Cache-based second-level caches: shared and<br />

multiplexed.<br />

A shared region factory uses the same Cache for all cache regions - much like the legacy<br />

CacheProvider implementation in older Hibernate versions.<br />

Hibernate ships with 2 shared region factory implementations:<br />

org.hibernate.cache.jbc2.Shared<strong>JBoss</strong>CacheRegionFactory<br />

Uses a single <strong>JBoss</strong> Cache configuration, from a newly instantiated CacheManager,<br />

for all cache regions.<br />

Table 21.1. Additional properties for Shared<strong>JBoss</strong>CacheRegionFactory<br />

Property Default Description<br />

hibernate.cache.region.jbc2.cfg.shared treecache.xml The classpath<br />

or filesystem<br />

resource<br />

containing the<br />

<strong>JBoss</strong> Cache<br />

configuration<br />

settings.<br />

hibernate.cache.region.jbc2.cfg.jgroups.stacks org/hibernate/cache/jbc2/builder/jgroupsstacks.xml<br />

org.hibernate.cache.jbc2.JndiShared<strong>JBoss</strong>CacheRegionFactory<br />

Uses a single <strong>JBoss</strong> Cache configuration, from an existing CacheManager bound to<br />

JNDI, for all cache regions.<br />

Table 21.2. Additional properties for JndiShared<strong>JBoss</strong>CacheRegionFactory<br />

Property Default Description<br />

hibernate.cache.region.jbc2.cfg.shared Required JNDI name to which<br />

the shared Cache<br />

instance is bound.<br />

A multiplexed region factory uses separate Cache instances, using optimized configurations for<br />

each cache region.<br />

The classpath<br />

or filesystem<br />

resource<br />

containing the<br />

JGroups<br />

protocol stack<br />

configurations.


172 Chapter 21. Clustered Entity EJBs<br />

Table 21.3. <strong>Common</strong> properties for multiplexed region factory implementations<br />

Property Default Description<br />

hibernate.cache.region.jbc2.cfg.entity optimistic-entity The <strong>JBoss</strong> Cache<br />

configuration used for<br />

the entity cache region.<br />

Alternative<br />

configurations: mvccentity,<br />

pessimistic-entity,<br />

mvcc-entity-repeatable,<br />

optimistic-entityrepeatable,pessimisticentity-repeatable<br />

hibernate.cache.region.jbc2.cfg.collection optimistic-entity The <strong>JBoss</strong> Cache<br />

configuration used for<br />

the collection cache<br />

region. The collection<br />

cache region typically<br />

uses the same<br />

configuration as the<br />

entity cache region.<br />

hibernate.cache.region.jbc2.cfg.query local-query The <strong>JBoss</strong> Cache<br />

configuration used for<br />

the query cache region.<br />

By default, cached query<br />

results are not<br />

replicated. Alternative<br />

configurations:<br />

replicated-query<br />

hibernate.cache.region.jbc2.cfg.ts timestamps-cache The <strong>JBoss</strong> Cache<br />

configuration used for<br />

the timestamp cache<br />

region. If query caching<br />

is used, the<br />

corresponding<br />

timestamp cache must<br />

be replicating, even if<br />

the query cache is nonreplicating.<br />

The<br />

timestamp cache region<br />

must never share the<br />

same cache as the<br />

query cache.<br />

Hibernate ships with 2 shared region factory implementations:<br />

org.hibernate.cache.jbc2.Multiplexed<strong>JBoss</strong>CacheRegionFactory<br />

Uses separate <strong>JBoss</strong> Cache configurations, from a newly instantiated CacheManager,<br />

per cache region.


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 173<br />

Table 21.4 . Additional properties for Multiplexed<strong>JBoss</strong>CacheRegionFactory<br />

Property Default Description<br />

hibernate.cache.region.jbc2.configs org/hibernate/cache/jbc2/builder/jbc2configs.xml<br />

hibernate.cache.region.jbc2.cfg.jgroups.stacks org/hibernate/cache/jbc2/builder/jgroupsstacks.xml<br />

org.hibernate.cache.jbc2.JndiMultiplexed<strong>JBoss</strong>CacheRegionFactory<br />

Uses separate <strong>JBoss</strong> Cache configurations, from a JNDI-bound CacheManager, see<br />

Section 18.2.1, “The <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> CacheManager Service”,<br />

per cache region.<br />

Table 21.5. Additional properties for<br />

JndiMultiplexed<strong>JBoss</strong>CacheRegionFactory<br />

Property Default Description<br />

hibernate.cache.region.jbc2.cachefactory Required JNDI name to which<br />

the CacheManager<br />

instance is bound.<br />

Now, we have <strong>JBoss</strong> Cache configured to support distributed caching of EJB 3.0 entity beans. We still<br />

have to configure individual entity beans to use the cache service.<br />

21.1.2. Configure the entity beans for cache<br />

Next we need to configure which entities to cache. The default is to not cache anything, even with the<br />

settings shown above. We use the @org.hibernate.annotations.Cache annotation to tag entity<br />

beans that needs to be cached.<br />

@Entity<br />

@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL)<br />

public class Account implements Serializable<br />

{<br />

// ... ...<br />

}<br />

A very simplified rule of thumb is that you will typically want to do caching for objects that rarely change,<br />

and which are frequently read. You can fine tune the cache for each entity bean in the appropriate <strong>JBoss</strong><br />

Cache configuration file, e.g. jboss-cache-manager-jboss-beans.xml. For instance, you can<br />

specify the size of the cache. If there are too many objects in the cache, the cache can evict the oldest or<br />

least used objects, depending on configuration, to make room for new objects. Assuming the<br />

region_prefix specified in persistence.xml was myprefix, the default name of the cache region for<br />

the com.mycompany.entities.Account entity bean would be<br />

/myprefix/com/mycompany/entities/Account.<br />

The classpath<br />

or filesystem<br />

resource<br />

containing the<br />

<strong>JBoss</strong> Cache<br />

configuration<br />

settings.<br />

The classpath<br />

or filesystem<br />

resource<br />

containing the<br />

JGroups<br />

protocol stack<br />

configurations.


174 Chapter 21. Clustered Entity EJBs<br />

<br />

... ...<br />

<br />

<br />

5000<br />

<br />

<br />

<br />

/<br />

<br />

<br />

<br />

10000<br />

<br />

1000<br />

<br />

120<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

/myprefix/com/mycompany/entities/Account<br />

<br />

<br />

10000<br />

5000<br />

120<br />

<br />

<br />

<br />

... ...<br />

<br />

<br />

<br />

<br />

<br />

If you do not specify a cache region for an entity bean class, all instances of this class will be cached<br />

using the defaultEvictionRegionConfig as defined above. The @Cache annotation exposes an<br />

optional attribute "region" that lets you specify the cache region where an entity is to be stored, rather<br />

than having it be automatically be created from the fully-qualified class name of the entity class.<br />

@Entity<br />

@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL, region = "Account")<br />

public class Account implements Serializable<br />

{<br />

// ... ...<br />

}<br />

The eviction configuration would then become:


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 175<br />

<br />

... ...<br />

<br />

<br />

5000<br />

<br />

<br />

<br />

/<br />

<br />

<br />

5000<br />

1000<br />

120<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

/myprefix/Account<br />

<br />

<br />

10000<br />

5000<br />

120<br />

<br />

<br />

<br />

... ...<br />

<br />

<br />

<br />

<br />

<br />

21.1.3. Query result caching<br />

The EJB3 Query API also provides means for you to save the results (i.e., collections of primary keys of<br />

entity beans, or collections of scalar values) of specified queries in the second-level cache. Here we<br />

show a simple example of annotating a bean with a named query, also providing the Hibernate-specific<br />

hints that tells Hibernate to cache the query.<br />

First, in persistence.xml you need to tell Hibernate to enable query caching:<br />

<br />

Next, you create a named query associated with an entity, and tell Hibernate you want to cache the<br />

results of that query:<br />

@Entity<br />

@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL, region = "Account")<br />

@NamedQueries(<br />

{<br />

@NamedQuery(<br />

name = "account.bybranch",<br />

query = "select acct from Account as acct where acct.branch = ?1",<br />

hints = { @QueryHint(name = "org.hibernate.cacheable", value = "true") }<br />

)<br />

})<br />

public class Account implements Serializable<br />

{<br />

// ... ...<br />

}<br />

The @NamedQueries, @NamedQuery and @QueryHint annotations are all in the javax.persistence<br />

package. See the Hibernate and EJB3 documentation for more on how to use EJB3 queries and on how<br />

to instruct EJB3 to cache queries.


176 Chapter 21. Clustered Entity EJBs<br />

By default, Hibernate stores query results in <strong>JBoss</strong> Cache in a region named<br />

/org/hibernate/cache/StandardQueryCache. Based on this, you can set up separate<br />

eviction handling for your query results. So, if the region prefix were set to myprefix in<br />

persistence.xml, you could, for example, create this sort of eviction handling:<br />

<br />

... ...<br />

<br />

<br />

5000<br />

<br />

<br />

<br />

/<br />

<br />

<br />

5000<br />

1000<br />

120<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

/myprefix/Account<br />

<br />

<br />

10000<br />

5000<br />

120<br />

<br />

<br />

<br />

<br />

/myprefix/org/hibernate/cache/StandardQueryCache<br />

<br />

<br />

100<br />

600<br />

120<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

The @NamedQuery.hints attribute shown above takes an array of vendor-specific @QueryHints as a<br />

value. Hibernate accepts the "org.hibernate.cacheRegion" query hint, where the value is the name of a<br />

cache region to use instead of the default /org/hibernate/cache/StandardQueryCache. For example:


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 177<br />

@Entity<br />

@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL, region = "Account")<br />

@NamedQueries(<br />

{<br />

@NamedQuery(<br />

name = "account.bybranch",<br />

query = "select acct from Account as acct where acct.branch = ?1",<br />

hints =<br />

{<br />

@QueryHint(name = "org.hibernate.cacheable", value = "true"),<br />

@QueryHint(name = "org.hibernate.cacheRegion", value = "Queries")<br />

}<br />

)<br />

})<br />

public class Account implements Serializable<br />

{<br />

// ... ...<br />

}<br />

The related eviction configuration:<br />

<br />

... ...<br />

<br />

<br />

5000<br />

<br />

<br />

<br />

/<br />

<br />

<br />

5000<br />

1000<br />

120<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

/myprefix/Account<br />

<br />

<br />

10000<br />

5000<br />

120<br />

<br />

<br />

<br />

<br />

/myprefix/Queries<br />

<br />

<br />

100<br />

600<br />

120<br />

<br />

<br />

<br />

... ...<br />

<br />

<br />

<br />

<br />

<br />

21.2. Entity Bean in EJB 2.x<br />

First of all, it is worth noting that clustering 2.x entity beans is a bad thing to do. Its exposes elements


178 Chapter 21. Clustered Entity EJBs<br />

that generally are too fine grained for use as remote objects to clustered remote objects and introduces<br />

data synchronization problems that are non-trivial. Do NOT use EJB 2.x entity bean clustering unless<br />

you fit into the special case situation of read-only, or one read-write node with read-only nodes<br />

synchronized with the cache invalidation services.<br />

To use a clustered entity bean, the application does not need to do anything special, except for looking<br />

up EJB 2.x remote bean references from the clustered HA-JNDI.<br />

To cluster EJB 2.x entity beans, you need to add the element to the application's<br />

jboss.xml descriptor file. Below is a typical jboss.xml file.<br />

<br />

<br />

<br />

nextgen.<strong>Enterprise</strong>Entity<br />

nextgen.<strong>Enterprise</strong>Entity<br />

True<br />

<br />

DefaultPartition<br />

org.jboss.ha.framework.interfaces.RoundRobinorg.jboss.ha.framework.interfaces.FirstAvailable<br />

<br />

<br />

<br />

<br />

The EJB 2.x entity beans are clustered for load balanced remote invocations. All the bean instances are<br />

synchronized to have the same contents on all nodes.<br />

However, clustered EJB 2.x Entity Beans do not have a distributed locking mechanism or a distributed<br />

cache. They can only be synchronized by using row-level locking at the database level (see <br />

in the CMP specification) or by setting the Transaction Isolation Level of your JDBC driver to be<br />

TRANSACTION_SERIALIZABLE. Because there is no supported distributed locking mechanism or<br />

distributed cache Entity Beans use Commit Option "B" by default (see standardjboss.xml and the<br />

container configurations Clustered CMP 2.x EntityBean, Clustered CMP EntityBean, or Clustered BMP<br />

EntityBean). It is not recommended that you use Commit Option "A" unless your Entity Bean is read-only.<br />

Note<br />

If you are using Bean Managed Persistence (BMP), you are going to have to implement<br />

synchronization on your own.


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 179<br />

Chapter 22. HTTP Services<br />

HTTP session replication is used to replicate the state associated with web client sessions to other<br />

nodes in a cluster. Thus, in the event one of your nodes crashes, another node in the cluster will be able<br />

to recover. Two distinct functions must be performed:<br />

Session state replication<br />

Load-balancing HTTP Requests<br />

State replication is directly handled by <strong>JBoss</strong>. When you run <strong>JBoss</strong> in the all configuration, session<br />

state replication is enabled by default. Just configure your web application as in its<br />

web.xml (see Section 22.2, “Configuring HTTP session state replication”), deploy it, and its session<br />

state is automatically replicated across all <strong>JBoss</strong> instances in the cluster.<br />

However, load-balancing is a different story; it is not handled by <strong>JBoss</strong> itself and requires an external<br />

load balancer. This function could be provided by specialized hardware switches or routers (Cisco<br />

LoadDirector for example) or by specialized software running on commodity hardware. As a very<br />

common scenario, we will demonstrate how to set up a software load balancer using Apache httpd and<br />

mod_jk.<br />

Note<br />

A load-balancer tracks HTTP requests and, depending on the session to which the request is<br />

linked, it dispatches the request to the appropriate node. This is called load-balancing with stickysessions<br />

or session affinity: once a session is created on a node, every future request will also<br />

be processed by that same node. Using a load-balancer that supports sticky-sessions but not<br />

configuring your web application for session replication allows you to scale very well by avoiding<br />

the cost of session state replication: each request for a session will always be handled by the<br />

same node. But in case a node dies, the state of all client sessions hosted by this node (the<br />

shopping carts, for example) will be lost and the clients will most probably need to login on<br />

another node and restart with a new session. In many situations, it is acceptable not to replicate<br />

HTTP sessions because all critical state is stored in a database or on the client. In other<br />

situations, losing a client session is not acceptable and, in this case, session state replication is<br />

the price one has to pay.<br />

22.1. Configuring load balancing using Apache and mod_jk<br />

Apache is a well-known web server which can be extended by plugging in modules. One of these<br />

modules, mod_jk has been specifically designed to allow the forwarding of requests from Apache to a<br />

Servlet container. Furthermore, it is also able to load-balance HTTP calls to a set of Servlet containers<br />

while maintaining sticky sessions, which is what is most interesting for us in this section.<br />

22.1.1. Download the software<br />

First of all, make sure that you have Apache installed. You can download Apache directly from Apache<br />

web site at http://httpd.apache.org/. Its installation is pretty straightforward and requires no specific<br />

configuration. As several versions of Apache exist, we advise you to use the latest stable 2.2.x version.<br />

We will assume, for the next sections, that you have installed Apache in the APACHE_HOME directory.<br />

Next, download mod_jk binaries. Several versions of mod_jk exist as well. We strongly advise the use of<br />

mod_jk 1.2.x, as both earlier versions of mod_jk, and mod_jk2, are deprecated, unsupported and no<br />

further development is going on in the community. The mod_jk 1.2.x binary can be downloaded from<br />

http://www.apache.org/dist/jakarta/tomcat-connectors/jk/binaries/. Rename the downloaded file to<br />

mod_jk.so and copy it under APACHE_HOME/modules/.<br />

22.1.2. Configure Apache to load mod_jk<br />

Modify APACHE_HOME/conf/httpd.conf and add a single line at the end of the file:<br />

# Include mod_jk's specific configuration file<br />

Include conf/mod-jk.conf<br />

Next, create a new file named APACHE_HOME/conf/mod-jk.conf:


180 Chapter 22. HTTP Services<br />

# Load mod_jk module<br />

# Specify the filename of the mod_jk lib<br />

LoadModule jk_module modules/mod_jk.so<br />

# Where to find workers.properties<br />

JkWorkersFile conf/workers.properties<br />

# Where to put jk logs<br />

JkLogFile logs/mod_jk.log<br />

# Set the jk log level [debug/error/info]<br />

JkLogLevel info<br />

# Select the log format<br />

JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"<br />

# JkOptions indicates to send SSK KEY SIZE<br />

JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories<br />

# JkRequestLogFormat<br />

JkRequestLogFormat "%w %V %T"<br />

# Mount your applications<br />

JkMount /application/* loadbalancer<br />

# You can use external file for mount points.<br />

# It will be checked for updates each 60 seconds.<br />

# The format of the file is: /url=worker<br />

# /examples/*=loadbalancer<br />

JkMountFile conf/uriworkermap.properties<br />

# Add shared memory.<br />

# This directive is present with 1.2.10 and<br />

# later versions of mod_jk, and is needed for<br />

# for load balancing to work properly<br />

JkShmFile logs/jk.shm<br />

# Add jkstatus for managing runtime data<br />

<br />

JkMount status<br />

Order deny,allow<br />

Deny from all<br />

Allow from 127.0.0.1<br />

<br />

Please note that two settings are very important:<br />

The LoadModule directive must reference the mod_jk library you have downloaded in the previous<br />

section. You must indicate the exact same name with the "modules" file path prefix.<br />

The JkMount directive tells Apache which URLs it should forward to the mod_jk module (and, in turn,<br />

to the Servlet containers). In the above file, all requests with URL path /application/* are sent to<br />

the mod_jk load-balancer. This way, you can configure Apache to serve static contents (or PHP<br />

contents) directly and only use the loadbalancer for Java applications. If you only use mod_jk as a<br />

loadbalancer, you can also forward all URLs (i.e., /*) to mod_jk.<br />

In addition to the JkMount directive, you can also use the JkMountFile directive to specify a mount<br />

points configuration file, which contains multiple Tomcat forwarding URL mappings. You just need to<br />

create a uriworkermap.properties file in the APACHE_HOME/conf directory. The format of the file<br />

is /url=worker_name. To get things started, paste the following example into the file you created:<br />

# Simple worker configuration file<br />

# Mount the Servlet context to the ajp13 worker<br />

/jmx-console=loadbalancer<br />

/jmx-console/*=loadbalancer<br />

/web-console=loadbalancer<br />

/web-console/*=loadbalancer<br />

This will configure mod_jk to forward requests to /jmx-console and /web-console to Tomcat.


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 181<br />

You will most probably not change the other settings in mod_jk.conf. They are used to tell mod_jk<br />

where to put its logging file, which logging level to use and so on.<br />

22.1.3. Configure worker nodes in mod_jk<br />

Next, you need to configure mod_jk workers file conf/workers.properties. This file specifies<br />

where the different Servlet containers are located and how calls should be load-balanced across them.<br />

The configuration file contains one section for each target servlet container and one global section. For<br />

a two nodes setup, the file could look like this:<br />

# Define list of workers that will be used<br />

# for mapping requests<br />

worker.list=loadbalancer,status<br />

# Define Node1<br />

# modify the host as your host IP or DNS name.<br />

worker.node1.port=8009<br />

worker.node1.host=node1.mydomain.com<br />

worker.node1.type=ajp13<br />

worker.node1.ping_mode=A<br />

worker.node1.lbfactor=1<br />

# Define Node2<br />

# modify the host as your host IP or DNS name.<br />

worker.node2.port=8009<br />

worker.node2.host=node2.mydomain.com<br />

worker.node2.type=ajp13<br />

worker.node2.ping_mode=A<br />

worker.node2.lbfactor=1<br />

# Load-balancing behaviour<br />

worker.loadbalancer.type=lb<br />

worker.loadbalancer.balance_workers=node1,node2<br />

worker.loadbalancer.sticky_session=1<br />

#worker.list=loadbalancer<br />

# Status worker for managing load balancer<br />

worker.status.type=status<br />

Basically, the above file configures mod_jk to perform weighted round-robin load balancing with sticky<br />

sessions between two servlet containers (that is, <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> instances)<br />

node1 and node2 listening on port 8009.<br />

In the workers.properties file, each node is defined using the worker.XXX naming convention<br />

where XXX represents an arbitrary name you choose for each of the target Servlet containers. For each<br />

worker, you must specify the host name (or IP address) and the port number of the AJP13 connector<br />

running in the Servlet container.<br />

The lbfactor attribute is the load-balancing factor for this specific worker. It is used to define the<br />

priority (or weight) a node should have over other nodes. The higher this number is for a given worker<br />

relative to the other workers, the more HTTP requests the worker will receive. This setting can be used<br />

to differentiate servers with different processing power.<br />

The ping_mode attribute enables CPing/CPong. It determines when established connections are<br />

probed to determine whether they are still working. In this case, ping_mode is set to A, which means<br />

that the connection is probed once after connecting to the backend, before sending each request to the<br />

backend, and at regular intervals during the internal maintenance cycle.<br />

The last part of the conf/workers.properties file defines the loadbalancer worker. The only thing<br />

you must change is the worker.loadbalancer.balanced_workers line: it must list all workers<br />

previously defined in the same file. Load-balancing will happen over these workers.<br />

The sticky_session property specifies the cluster behavior for HTTP sessions. If you specify<br />

worker.loadbalancer.sticky_session=0, each request will be load balanced between node1<br />

and node2; i.e., different requests for the same session will go to different servers. But when a user<br />

opens a session on one server, it is always necessary to always forward this user's requests to the<br />

same server, as long as that server is available. This is called a "sticky session", as the client is always<br />

using the same server he reached on his first request. To enable session stickiness, you need to set<br />

worker.loadbalancer.sticky_session to 1.


182 Chapter 22. HTTP Services<br />

Note<br />

A non-loadbalanced setup with a single node requires a worker.list=node1 entry.<br />

22.1.4 . Configuring <strong>JBoss</strong> to work with mod_jk<br />

Finally, we must configure the <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> instances on all clustered nodes so<br />

that they can expect requests forwarded from the mod_jk loadbalancer.<br />

On each clustered <strong>JBoss</strong> node, we have to name the node according to the name specified in<br />

workers.properties. For instance, on <strong>JBoss</strong> instance node1, edit the<br />

JBOSS_HOME/server/all/deploy/jbossweb.sar/server.xml file (replace /all with your own<br />

server name if necessary). Locate the element and add an attribute jvmRoute:<br />

<br />

...<br />

<br />

You also need to be sure the AJP connector in server.xml is enabled (i.e., uncommented). It is enabled<br />

by default.<br />

<br />

<br />

At this point, you have a fully working Apache with mod_jk load-balancer setup that will balance call to<br />

the Servlet containers of your cluster while taking care of session stickiness (clients will always use the<br />

same Servlet container).<br />

Note<br />

For more updated information on using mod_jk 1.2 with <strong>JBoss</strong> AS, please refer to the <strong>JBoss</strong> wiki<br />

page at http://www.jboss.org/community/wiki/UsingModjk12With<strong>JBoss</strong>.<br />

22.1.5. Configuring the NSAPI connector on Solaris<br />

This section shows you how to configure the NSAPI connector to use a <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Platform</strong> as a<br />

worker node for a Sun Java System Web Server (SJWS) master node.<br />

Note<br />

Sun Java System Web Server has recently been renamed to the Oracle iPlanet Web Server.<br />

In this section, all of the server instances are on the same machine. To use different machines for each<br />

instance, use the -b switch to bind your instance of <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Platform</strong> to a public IP address.<br />

Remember to edit the workers.properties file on the SJWS machine to reflect these changes in IP<br />

address.<br />

22.1.5.1. Prerequisites<br />

This section assumes that:<br />

Your worker node(s) are already installed with a <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Platform</strong> 5.1 or later. The Native<br />

components are not a requirement of the NSAPI connector. Refer to the Installation Guide for<br />

assistance with this prerequisite.<br />

Your master node is already installed with any of the following technology combinations, and the<br />

appropriate Native binary for its operating system and architecture. Refer to the Installation Guide for<br />

assistance with this prerequisite.<br />

Solaris 9 x86 with Sun Java System Web Server 6.1 SP12


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 183<br />

Solaris 9 SPARC 64 with Sun Java System Web Server 6.1 SP12<br />

Solaris 10 x86 with Sun Java System Web Server 7.0 U8<br />

Solaris 10 SPARC 64 with Sun Java System Web Server 7.0 U8<br />

22.1.5.2. Configure <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Platform</strong> as a Worker Node<br />

This section shows you how to safely configure your <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Platform</strong> instance as a worker<br />

node for use with Sun SJWS.<br />

Procedure 22.1. Configure a <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Platform</strong> instance as a worker node<br />

1. Create a server profile for each worker node<br />

Make a copy of the server profile that you wish to configure as a worker node. (This procedure<br />

uses the default server profile.)<br />

[user@workstation jboss-eap-5.1]$ cd jboss-as/server<br />

[user@workstation server]$ cp -r default/ default-01<br />

[user@workstation server]$ cp -r default/ default-02<br />

2. Give each instance a unique name<br />

Edit the following line in the deploy/jbossweb.sar/server.xml file of each new worker<br />

instance:<br />

<br />

Add a unique jvmRoute value, as shown. This value is the identifier for this node in the cluster.<br />

For the default-01 server profile:<br />

<br />

For the default-02 server profile:<br />

<br />

3. Enable session handling<br />

Edit the following line in the deployers/jbossweb.deployer/META-INF/war-deployersjboss-beans.xml<br />

file of each worker node:<br />

false<br />

This property controls whether special session handling is used to coordinate with mod_jk and<br />

other connector variants. Set this property to true in both worker nodes:<br />

true<br />

4. Start your worker nodes<br />

Start each worker node in a separate command line interface. Ensure that each node is bound to<br />

a different IP address with the -b switch.<br />

[user@workstation jboss-eap-5.1]$ ./jboss-as/bin/run.sh -b 127.0.0.1 -c<br />

default-01<br />

[user@workstation jboss-eap-5.1]$ ./jboss-as/bin/run.sh -b 127.0.0.100 -c<br />

default-02<br />

22.1.5.3. Configure Sun Java System Web Server for Clustering<br />

The procedures in the following sections assume that the contents of the Native zip appropriate for your<br />

operating system and architecture have been extracted to /tmp/connectors/jboss-ep-native-<br />

5.1/. This path is referred to as NATIVE in the procedures that follow. These procedures also assume<br />

that the /tmp/connectors directory is used to store logs, properties files and NSAPI locks.<br />

These procedures also assume that your installation of Sun Java System Web Server is in one of the<br />

following locations, depending on your version of Solaris:


184 Chapter 22. HTTP Services<br />

for Solaris 9 x86 or SPARC 64: /opt/SUNWwbsrv61/<br />

for Solaris 10 x86 or SPARC 64: /opt/SUNWwbsrv70/<br />

This path is referred to as SJWS in the procedures that follow.<br />

Procedure 22.2. Initial clustering configuration<br />

1. Disable servlet mappings<br />

Under Built In Servlet Mappings in the SJWS/PROFILE/config/default-web.xml file, disable<br />

the mappings for the following servlets, as shown in the code sample:<br />

default<br />

invoker<br />

jsp<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

2. Load the required modules and properties<br />

Append the following lines to the SJWS/PROFILE/config/magnus.conf file:<br />

Init fn="load-modules" funcs="jk_init,jk_service"<br />

shlib="NATIVE/lib/nsapi_redirector.so" shlib_flags="(global|now)"<br />

Init fn="jk_init" worker_file="/tmp/connectors/workers.properties"<br />

log_level="debug" log_file="/tmp/connectors/nsapi.log"<br />

shm_file="/tmp/connectors/jk_shm"<br />

These lines define the location of the nsapi_redirector.so module used by the jk_init<br />

and jk_service functions, and the location of the workers.properties file, which defines the<br />

worker nodes and their attributes.<br />

Note<br />

The lib directory in the NATIVE/lib/nsapi_redirector.so path applies only to 32bit<br />

machines. On 64-bit machines, this directory is called lib64.<br />

22.1.5.3.1. Configure a basic cluster with NSAPI<br />

Use the following procedure to configure a basic cluster, where requests for particular paths are<br />

forwarded to particular worker nodes. In Procedure 22.3, “Configure a basic cluster with NSAPI”,<br />

worker02 serves the /nc path, while worker01 serves /status and all other paths defined in the first<br />

part of the obj.conf file.<br />

Procedure 22.3. Configure a basic cluster with NSAPI<br />

1. Define the paths to serve via NSAPI<br />

Edit the SJWS/PROFILE/config/obj.conf file. Define paths that should be served via NSAPI at


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 185<br />

the end of the default Object definition, as shown:<br />

<br />

[...]<br />

NameTrans fn="assign-name" from="/status" name="jknsapi"<br />

NameTrans fn="assign-name" from="/images(|/*)" name="jknsapi"<br />

NameTrans fn="assign-name" from="/css(|/*)" name="jknsapi"<br />

NameTrans fn="assign-name" from="/nc(|/*)" name="jknsapi"<br />

NameTrans fn="assign-name" from="/jmx-console(|/*)" name="jknsapi"<br />

<br />

You can map the path of any application deployed on your <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Platform</strong> instance in<br />

this obj.conf file. In the example code, the /nc path is mapped to an application deployed under<br />

the name nc.<br />

2. Define the worker that serves each path<br />

Edit the SJWS/PROFILE/config/obj.conf file and add the following jknsapi Object definition<br />

after the default Object definition.<br />

<br />

ObjectType fn=force-type type=text/plain<br />

Service fn="jk_service" worker="worker01" path="/status"<br />

Service fn="jk_service" worker="worker02" path="/nc(/*)"<br />

Service fn="jk_service" worker="worker01"<br />

<br />

This jknsapi Object defines the worker nodes used to serve each path that was assigned to<br />

name="jknsapi" in the default Object.<br />

In the example code, the third Service definition does not specify a path value, so the worker<br />

node defined (worker01) serves all of the paths assigned to jknsapi by default. In this case,<br />

the first Service definition in the example code, which assigns the /status path to worker01, is<br />

superfluous.<br />

3. Define the workers and their attributes<br />

Create a workers.properties file in the location you defined in Step 2. Define the list of worker<br />

nodes and each worker node's properties in this file, like so:<br />

# An entry that lists all the workers defined<br />

worker.list=worker01, worker02<br />

# Entries that define the host and port associated with these workers<br />

worker.worker01.host=127.0.0.1<br />

worker.worker01.port=8009<br />

worker.worker01.type=ajp13<br />

worker.worker02.host=127.0.0.100<br />

worker.worker02.port=8009<br />

worker.worker02.type=ajp13<br />

22.1.5.3.2. Configure a Load-balanced Cluster with NSAPI<br />

Procedure 22.4 . Configure a load-balancing cluster with NSAPI<br />

1. Define the paths to serve via NSAPI<br />

Edit the SJWS/PROFILE/config/obj.conf file. Define paths that should be served via NSAPI at<br />

the end of the default Object definition, as shown:<br />

<br />

[...]<br />

NameTrans fn="assign-name" from="/status" name="jknsapi"<br />

NameTrans fn="assign-name" from="/images(|/*)" name="jknsapi"<br />

NameTrans fn="assign-name" from="/css(|/*)" name="jknsapi"<br />

NameTrans fn="assign-name" from="/nc(|/*)" name="jknsapi"<br />

NameTrans fn="assign-name" from="/jmx-console(|/*)" name="jknsapi"<br />

NameTrans fn="assign-name" from="/jkmanager/*" name="jknsapi"<br />

<br />

You can map the path of any application deployed on your <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Platform</strong> instance in<br />

this obj.conf file. In the example code, the /nc path is mapped to an application deployed under


186 Chapter 22. HTTP Services<br />

the name nc.<br />

2. Define the worker that serves each path<br />

Edit the SJWS/PROFILE/config/obj.conf file and add the following jknsapi Object definition<br />

after the default Object definition.<br />

<br />

ObjectType fn=force-type type=text/plain<br />

Service fn="jk_service" worker="status" path="/jkmanager(/*)"<br />

Service fn="jk_service" worker="router"<br />

<br />

This jknsapi Object defines the worker nodes used to serve each path that was assigned to<br />

name="jknsapi" in the default Object.<br />

3. Define the workers and their attributes<br />

Create a workers.properties file in the location you defined in Step 2. Define the list of worker<br />

nodes and each worker node's properties in this file, like so:<br />

# The advanced router LB worker<br />

worker.list=router,status<br />

# Define a worker using ajp13<br />

worker.worker01.port=8009<br />

worker.worker01.host=127.0.0.1<br />

worker.worker01.type=ajp13<br />

worker.worker01.ping_mode=A<br />

worker.worker01.socket_timeout=10<br />

worker.worker01.lbfactor=3<br />

# Define another worker using ajp13<br />

worker.worker02.port=8009<br />

worker.worker02.host=127.0.0.100<br />

worker.worker02.type=ajp13<br />

worker.worker02.ping_mode=A<br />

worker.worker02.socket_timeout=10<br />

worker.worker02.lbfactor=1<br />

# Define the LB worker<br />

worker.router.type=lb<br />

worker.router.balance_workers=worker01,worker02<br />

# Define the status worker<br />

worker.status.type=status<br />

22.1.5.3.3. Restart Sun Java System Web Server<br />

Once your Sun Java System Web Server instance is configured, restart it so that your changes take<br />

effect.<br />

For Sun Java System Web Server 6.1:<br />

SJWS/PROFILE/stop<br />

SJWS/PROFILE/start<br />

For Sun Java System Web Server 7.0:<br />

SJWS/PROFILE/bin/stopserv<br />

SJWS/PROFILE/bin/startserv<br />

22.2. Configuring HTTP session state replication<br />

The preceding discussion has been focused on using mod_jk as a load balancer. The content of the<br />

remainder our discussion of clustering HTTP services in <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> applies<br />

no matter what load balancer is used.<br />

In Section 22.1.3, “Configure worker nodes in mod_jk”, we covered how to use sticky sessions to make<br />

sure that a client in a session always hits the same server node in order to maintain the session state.<br />

However, sticky sessions by themselves are not an ideal solution. If a node goes down, all its session


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 187<br />

data is lost. A better and more reliable solution is to replicate session data across the nodes in the<br />

cluster. This way, if a server node fails or is shut down, the load balancer can fail over the next client<br />

request to any server node and obtain the same session state.<br />

22.2.1. Enabling session replication in your application<br />

To enable replication of your web application you must tag the application as distributable in the<br />

web.xml descriptor. Here's an example:<br />

<br />

<br />

<br />

<br />

You can futher configure session replication using the replication-config element in the jbossweb.xml<br />

file. However, the replication-config element only needs to be set if one or more of the<br />

default values described below is unacceptable. Here is an example:<br />

<br />

<br />

<br />

custom-session-cache<br />

SET<br />

ATTRIBUTE<br />

true<br />

false<br />

30<br />

INSTANT<br />

1000<br />

com.example.CustomSessionNotificationPolicy<br />

<br />

<br />

All of the above configuration elements are optional and can be ommitted if the default value is<br />

acceptable. A couple are commonly used; the rest are very infrequently changed from the defaults. We'll<br />

cover the commonly used ones first.<br />

The replication-trigger element determines when the container should consider that session<br />

data must be replicated across the cluster. The rationale for this setting is that after a mutable object<br />

stored as a session attribute is accessed from the session, in the absence of a setAttribute call the<br />

container has no clear way to know if the object (and hence the session state) has been modified and<br />

needs to be replicated. This element has 3 valid values:<br />

SET_AND_GET is conservative but not optimal (performance-wise): it will always replicate session<br />

data even if its content has not been modified but simply accessed. This setting made (a little) sense<br />

in <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 4 since using it was a way to ensure that every request<br />

triggered replication of the session's timestamp. Since setting max_unreplicated_interval to 0<br />

accomplishes the same thing at much lower cost, using SET_AND_GET makes no sense with<br />

<strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5.<br />

SET_AND_NON_PRIMITIVE_GET is conservative but will only replicate if an object of a nonprimitive<br />

type has been accessed (i.e. the object is not of a well-known immutable JDK type such as<br />

Integer, Long, String, etc.) This is the default value.<br />

SET assumes that the developer will explicitly call setAttribute on the session if the data needs<br />

to be replicated. This setting prevents unnecessary replication and can have a major beneficial<br />

impact on performance, but requires very good coding practices to ensure setAttribute is always<br />

called whenever a mutable object stored in the session is modified.


188 Chapter 22. HTTP Services<br />

In all cases, calling setAttribute marks the session as needing replication.<br />

The replication-granularity element determines the granularity of what gets replicated if the<br />

container determines session replication is needed. The supported values are:<br />

SESSION indicates that the entire session attribute map should be replicated when any attribute is<br />

considered modified. Replication occurs at request end. This option replicates the most data and<br />

thus incurs the highest replication cost, but since all attributes values are always replicated together<br />

it ensures that any references between attribute values will not be broken when the session is<br />

deserialized. For this reason it is the default setting.<br />

ATTRIBUTE indicates that only attributes that the session considers to be potentially modified are<br />

replicated. Replication occurs at request end. For sessions carrying large amounts of data, parts of<br />

which are infrequently updated, this option can significantly increase replication performance.<br />

However, it is not suitable for applications that store objects in different attributes that share<br />

references with each other (e.g. a Person object in the "husband" attribute sharing with another<br />

Person in the "wife" attribute a reference to an Address object). This is because if the attributes<br />

are separately replicated, when the session is deserialized on remote nodes the shared references<br />

will be broken.<br />

FIELD is useful if the classes stored in the session have been bytecode enhanced for use by POJO<br />

Cache. If they have been, the session management layer will detect field level changes within objects<br />

stored to the session, and will replicate only those changes. This is the most performant setting.<br />

Replication is only for individual changed data fields inside session attribute objects. Shared object<br />

references will be preserved across the cluster. Potentially most performant, but requires changes to<br />

your application (this will be discussed later).<br />

The other elements under the replication-config element are much less frequently used.<br />

The cacheName element indicates the name of the <strong>JBoss</strong> Cache configuration that should be used for<br />

storing distributable sessions and replicating them around the cluster. This element lets web<br />

applications that require different caching characteristics specify the use of separate, differently<br />

configured, <strong>JBoss</strong> Cache instances. In <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 4 the cache to use was a<br />

server-wide configuration that could not be changed per web application. The default value is<br />

standard-session-cache if the replication-granularity is not FIELD, fieldgranularity-session-cache<br />

if it is. See Section 22.2.3, “Configuring the <strong>JBoss</strong> Cache instance<br />

used for session state replication” for more details on <strong>JBoss</strong> Cache configuration for web tier clustering.<br />

The replication-field-batch-mode element indicates whether all replication messages<br />

associated with a request will be batched into one message. This is applicable only if replicationgranularity<br />

is FIELD. If replication-field-batch-mode is set to true, fine-grained changes<br />

made to objects stored in the session attribute map will replicate only when the HTTP request is<br />

finished; otherwise they replicate as they occur. Setting this to false is not advised. Default is true.<br />

The useJK element indicates whether the container should assume that a JK-based software load<br />

balancer (e.g. mod_jk, mod_proxy, mod_cluster) is being used for load balancing for this web application.<br />

If set to true, the container will examine the session ID associated with every request and replace the<br />

jvmRoute portion of the session ID if it detects a failover.<br />

The default value is null (i.e. unspecified). In this case the session manager will use the presence or<br />

absence of a jvmRoute configuration on its enclosing <strong>JBoss</strong> Web Engine (see Section 22.1.4,<br />

“Configuring <strong>JBoss</strong> to work with mod_jk”) to determine whether JK is used.<br />

You need only set this to false for web applications whose URL cannot be handled by the JK load<br />

balancer.<br />

The max-unreplicated-interval element configures the maximum interval between requests, in<br />

seconds, after which a request will trigger replication of the session's timestamp regardless of whether<br />

the request has otherwise made the session dirty. Such replication ensures that other nodes in the<br />

cluster are aware of the most recent value for the session's timestamp and won't incorrectly expire an<br />

unreplicated session upon failover. It also results in correct values for<br />

HttpSession.getLastAccessedTime() calls following failover.<br />

A value of 0 means the timestamp will be replicated whenever the session is accessed. A value of -1<br />

means the timestamp will be replicated only if some other activity during the request (e.g. modifying an<br />

attribute) has resulted in other replication work involving the session. A positive value greater than the<br />

HttpSession.getMaxInactiveInterval() value will be treated as probable misconfiguration and<br />

converted to 0; i.e. replicate the metadata on every request. Default value is 60.


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 189<br />

The snapshot-mode element configures when sessions are replicated to the other nodes. Possible<br />

values are INSTANT (the default) and INTERVAL.<br />

The typical value, INSTANT, replicates changes to the other nodes at the end of requests, using the<br />

request processing thread to perform the replication. In this case, the snapshot-interval property is<br />

ignored.<br />

With INTERVAL mode, a background task is created that runs every snapshot-interval<br />

milliseconds, checking for modified sessions and replicating them.<br />

Note that this property has no effect if replication-granularity is set to FIELD. If it is FIELD,<br />

instant mode will be used.<br />

The snapshot-interval element defines how often (in milliseconds) the background task that<br />

replicates modified sessions should be started for this web application. Only meaningful if snapshotmode<br />

is set to interval.<br />

The session-notification-policy element specifies the fully qualified class name of the<br />

implementation of the ClusteredSessionNotificationPolicy interface that should be used to<br />

govern whether servlet specification notifications should be emitted to any registered<br />

HttpSessionListener, HttpSessionAttributeListener and/or<br />

HttpSessionBindingListener.<br />

Event notifications that may make sense in a non-clustered environment may or may not make sense in<br />

a clustered environment; see https://jira.jboss.org/jira/browse/JBAS-5778 for an example of why a<br />

notification may not be desired. Configuring an appropriate<br />

ClusteredSessionNotificationPolicy gives the application author fine-grained control over<br />

what notifications are issued.<br />

In previous releases, the default value if not explicitly set is the<br />

LegacyClusteredSessionNotificationPolicy, which implements the behavior in previous<br />

<strong>JBoss</strong> versions. In <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5, this was changed to<br />

IgnoreUndeployLegacyClusteredSessionNotificationPolicy, which implements the same<br />

behavior except during undeployment, during which no HttpSessionListener and<br />

HttpSessionAttributeListener notifications are sent.<br />

22.2.2. HttpSession Passivation and Activation<br />

Passivation is the process of controlling memory usage by removing relatively unused sessions from<br />

memory while storing them in persistent storage. If a passivated session is requested by a client, it can<br />

be "activated" back into memory and removed from the persistent store. <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong><br />

<strong>Platform</strong> 5 supports passivation of HttpSessions from web applications whose web.xml includes the<br />

distributable tag (i.e. clustered web applications).<br />

Passivation occurs at three points during the lifecycle of a web application:<br />

When the container requests the creation of a new session. If the number of currently active<br />

sessions exceeds a configurable limit, an attempt is made to passivate sessions to make room in<br />

memory.<br />

Periodically (by default every ten seconds) as the <strong>JBoss</strong> Web background task thread runs.<br />

When the web application is deployed and a backup copy of sessions active on other servers is<br />

acquired by the newly deploying web application's session manager.<br />

A session will be passivated if one of the following holds true:<br />

The session has not been in use for longer than a configurable maximum idle time.<br />

The number of active sessions exceeds a configurable maximum and the session has not been in<br />

use for longer than a configurable minimum idle time.<br />

In both cases, sessions are passivated on a Least Recently Used (LRU) basis.<br />

22.2.2.1. Configuring HttpSession Passivation<br />

Session passivation behavior is configured via the jboss-web.xml deployment descriptor in your web<br />

application's WEB-INF directory.


190 Chapter 22. HTTP Services<br />

<br />

<br />

20<br />

<br />

true<br />

60<br />

600<br />

<br />

<br />

max-active-session<br />

Determines the maximum number of active sessions allowed. If the number of sessions managed by<br />

the the session manager exceeds this value and passivation is enabled, the excess will be<br />

passivated based on the configured passivation-min-idle-time. If after passivation is<br />

completed (or if passivation is disabled), the number of active sessions still exceeds this limit,<br />

attempts to create new sessions will be rejected. If set to -1 (the default), there is no limit.<br />

use-session-passivation<br />

Determines whether session passivation will be enabled for the web application. Default is false.<br />

passivation-min-idle-time<br />

Determines the minimum time (in seconds) that a session must have been inactive before the<br />

container will consider passivating it in order to reduce the active session count to obey the value<br />

defined by max-active-sessions. A value of -1 (the default) disables passivating sessions<br />

before passivation-max-idle-time. Neither a value of -1 nor a high value are recommended if<br />

max-active-sessions is set.<br />

passivation-max-idle-time<br />

Determines the maximum time (in seconds) that a session can be inactive before the container<br />

should attempt to passivate it to save memory. Passivation of such sessions will take place<br />

regardless of whether the active session count exceeds max-active-sessions. Should be less<br />

than the web.xml session-timeout setting. A value of -1 (the default) disables passivation<br />

based on maximum inactivity.<br />

The total number of sessions in memory includes sessions replicated from other cluster nodes that are<br />

not being accessed on this node. Take this into account when setting max-active-sessions. The<br />

number of sessions replicated from other nodes will also depend on whether buddy replication is<br />

enabled.<br />

Say, for example, that you have an eight node cluster, and each node handles requests from 100 users.<br />

With total replication, each node would store 800 sessions in memory. With buddy replication enabled,<br />

and the default numBuddies setting (1), each node will store 200 sessions in memory.<br />

22.2.3. Configuring the <strong>JBoss</strong> Cache instance used for session state replication<br />

The container for a distributable web application makes use of <strong>JBoss</strong> Cache to provide HTTP session<br />

replication services around the cluster. The container integrates with the CacheManager service to<br />

obtain a reference to a <strong>JBoss</strong> Cache instance (see Section 18.2.1, “The <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong><br />

<strong>Platform</strong> CacheManager Service”).<br />

The name of the <strong>JBoss</strong> Cache configuration to use is controlled by the cacheName element in the<br />

application's jboss-web.xml (see Section 22.2.1, “Enabling session replication in your application”). In<br />

most cases, though, this does not need to be set as the default values of standard-session-cache<br />

and field-granularity-session-cache (for applications configured for FIELD granularity) are<br />

appropriate.<br />

The <strong>JBoss</strong> Cache configurations in the CacheManager service expose a number of options. See<br />

Chapter 26, <strong>JBoss</strong> Cache Configuration and Deployment and the <strong>JBoss</strong> Cache documentation for a<br />

more complete discussion. The standard-session-cache and field-granularity-sessioncache<br />

configurations are already optimized for the web session replication use case, and most of the<br />

settings should not be altered. Administrators may be interested in altering the following settings:<br />

cacheMode


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 191<br />

The default is REPL_ASYNC, which specifies that a session replication message sent to the cluster<br />

does not wait for responses from other cluster nodes confirming that the message has been<br />

received and processed. The alternative mode, REPL_SYNC, offers a greater degree of confirmation<br />

that session state has been received, but reduces performance significantly. See Section 26.1.2,<br />

“Cache Mode” for further details.<br />

enabled property in the buddyReplicationConfig section<br />

Set to true to enable buddy replication. See Section 26.1.8, “Buddy Replication”. Default is false.<br />

numBuddies property in the buddyReplicationConfig section<br />

Set to a value greater than the default (1) to increase the number of backup nodes onto which<br />

sessions are replicated. Only relevant if buddy replication is enabled. See Section 26.1.8, “Buddy<br />

Replication”.<br />

buddyPoolName property in the buddyReplicationConfig section<br />

A way to specify a preferred replication group when buddy replication is enabled. <strong>JBoss</strong> Cache tries<br />

to pick a buddy who shares the same pool name (falling back to other buddies if not available). Only<br />

relevant if buddy replication is enabled. See Section 26.1.8, “Buddy Replication”.<br />

multiplexerStack<br />

Name of the JGroups protocol stack the cache should use. See Section 18.1.1, “The Channel Factory<br />

Service”.<br />

clusterName<br />

Identifying name JGroups will use for this cache's channel. Only change this if you create a new<br />

cache configuration, in which case this property should have a different value from all other cache<br />

configurations.<br />

If you wish to use a completely new <strong>JBoss</strong> Cache configuration rather than editing one of the existing<br />

ones, please see Section 26.2.1, “Deployment Via the CacheManager Service”.<br />

22.3. Using FIELD-level replication<br />

This feature is deprecated<br />

This feature is deprecated as of <strong>JBoss</strong> <strong>Enterprise</strong> Web <strong>Platform</strong> 5.1, and will be removed in a<br />

future release of <strong>JBoss</strong> <strong>Enterprise</strong> Web <strong>Platform</strong>. Customers are recommended to migrate away<br />

from this feature in existing implementations, and not use it in new implementations.<br />

FIELD-level replication only replicates modified data fields inside objects stored in the session. It can<br />

reduce the data traffic between clustered nodes, and hence improve the performance of the whole<br />

cluster. To use FIELD-level replication, you must first prepare (that is, bytecode enhance) your Java<br />

class to allow the session cache to detect when fields in cached objects have been changed and need<br />

to be replicated.<br />

First, you need to identify the classes that you need to prepare. You can identify these classes by using<br />

annotations, like so:<br />

@org.jboss.cache.pojo.annotation.Replicable<br />

public class Address<br />

{<br />

...<br />

}<br />

If you annotate a class with @Replicable, then all of its subclasses will be automatically annotated as<br />

well. Similarly, you can annotate an interface with @Replicable and all of its implementing classes will<br />

be annotated. For example:


192 Chapter 22. HTTP Services<br />

@org.jboss.cache.aop.InstanceOfAopMarker<br />

public class Person<br />

{<br />

...<br />

}<br />

public class Student extends Person<br />

{<br />

...<br />

}<br />

There is no need to annotate Student. POJO Cache will recognize it as @Replicable because it is a<br />

sub-class of Person.<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5 requires JDK 5 at runtime, but some users may still need to<br />

build their projects using JDK 1.4. In this case, annotating classes can be done via JDK 1.4 style<br />

annotations embedded in JavaDocs. For example:<br />

/**<br />

* Represents a street address.<br />

* @org.jboss.cache.pojo.annotation.Replicable<br />

*/<br />

public class Address<br />

{<br />

...<br />

}<br />

Once you have annotated your classes, you will need to perform a pre-processing step to bytecode<br />

enhance your classes for use by POJO Cache. You need to use the <strong>JBoss</strong> AOP pre-compiler<br />

annotationc and post-compiler aopc to process the above source code before and after they are<br />

compiled by the Java compiler. The annotationc step is only need if the JDK 1.4 style annotations are<br />

used; if JDK 5 annotations are used it is not necessary. Here is an example of how to invoke those<br />

commands from command line.<br />

$ annotationc [classpath] [source files or directories]<br />

$ javac -cp [classpath] [source files or directories]<br />

$ aopc [classpath] [class files or directories]<br />

Please see the <strong>JBoss</strong> AOP documentation for the usage of the pre- and post-compiler. The <strong>JBoss</strong> AOP<br />

project also provides easy to use ANT tasks to help integrate those steps into your application build<br />

process.<br />

Note<br />

You can see a complete example of how to build, deploy, and validate a FIELD-level replicated<br />

web application from this page: http://www.jboss.org/community/wiki/httpsessionfieldlevelexample.<br />

The example bundles the pre- and post-compile tools so you do not need to download <strong>JBoss</strong><br />

AOP separately.<br />

Finally, let's see an example on how to use FIELD-level replication on those data classes. First, we see<br />

some servlet code that reads some data from the request parameters, creates a couple of objects and<br />

stores them in the session:<br />

Person husband = new Person(getHusbandName(request), getHusbandAge(request)); Person<br />

wife = new<br />

Person(getWifeName(request), getWifeAge(request)); Address addr = new Address();<br />

addr.setPostalCode(getPostalCode(request));<br />

husband.setAddress(addr);<br />

wife.setAddress(addr); // husband and wife share the same address!<br />

session.setAttribute("husband", husband); // that's it.<br />

session.setAttribute("wife", wife); // that's it.<br />

Later, a different servlet could update the family's postal code:


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 193<br />

Person wife = (Person)session.getAttribute("wife");<br />

wife.getAddress().setPostalCode(getPostalCode(request));<br />

// this will update and replicate the postal code<br />

Notice that in there is no need to call session.setAttribute() after you make changes to the data<br />

object, and all changes to the fields are automatically replicated across the cluster.<br />

Besides plain objects, you can also use regular Java collections of those objects as session attributes.<br />

POJO Cache automatically figures out how to handle those collections and replicate field changes in<br />

their member objects.<br />

22.4. Using Clustered Single Sign-on (SSO)<br />

<strong>JBoss</strong> supports clustered single sign-on, allowing a user to authenticate to one web application and to<br />

be recognized on all web applications that are deployed on the same virtual host, whether or not they<br />

are deployed on that same machine or on another node in the cluster. Authentication replication is<br />

handled by <strong>JBoss</strong> Cache. Clustered single sign-on support is a <strong>JBoss</strong>-specific extension of the nonclustered<br />

org.apache.catalina.authenticator.SingleSignOn valve that is a standard part<br />

of Tomcat and <strong>JBoss</strong> Web. Both the non-clustered and clustered versions allow users to sign on to any<br />

one of the web apps associated with a virtual host and have their identity recognized by all other web<br />

apps on the same virtual host. The clustered version brings the added benefits of enabling SSO failover<br />

and allowing a load balancer to direct requests for different webapps to different servers, while<br />

maintaining the SSO.<br />

22.4 .1. Configuration<br />

To enable clustered single sign-on, you must add the ClusteredSingleSignOn valve to the<br />

appropriate Host elements of the<br />

JBOSS_HOME/server/all/deploy/jbossweb.sar/server.xml file. The valve element is already<br />

included in the standard file; you just need to uncomment it. The valve configuration is shown here:<br />

<br />

The element supports the following attributes:<br />

className is a required attribute to set the Java class name of the valve implementation to use.<br />

This must be set to org.jboss.web.tomcat.service.sso.ClusteredSingleSign.<br />

cacheConfig is the name of the cache configuration (see Section 18.2.1, “The <strong>JBoss</strong> <strong>Enterprise</strong><br />

<strong>Application</strong> <strong>Platform</strong> CacheManager Service”) to use for the clustered SSO cache. Default is<br />

clustered-sso.<br />

treeCacheName is deprecated; use cacheConfig. Specifies a JMX ObjectName of the <strong>JBoss</strong><br />

Cache MBean to use for the clustered SSO cache. If no cache can be located from the<br />

CacheManager service using the value of cacheConfig, an attempt to locate an mbean registered<br />

in JMX under this ObjectName will be made. Default value is<br />

jboss.cache:service=TomcatClusteringCache.<br />

cookieDomain is used to set the host domain to be used for sso cookies. See Section 22.4.4,<br />

“Configuring the Cookie Domain” for more. Default is "/".<br />

maxEmptyLife is the maximum number of seconds an SSO with no active sessions will be usable<br />

by a request. The clustered SSO valve tracks what cluster nodes are managing sessions related to<br />

an SSO. A positive value for this attribute allows proper handling of shutdown of a node that is the<br />

only one that had handled any of the sessions associated with an SSO. The shutdown invalidates<br />

the local copy of the sessions, eliminating all sessions from the SSO. If maxEmptyLife were zero, the<br />

SSO would terminate along with the local session copies. But, backup copies of the sessions (if they<br />

are from clustered webapps) are available on other cluster nodes. Allowing the SSO to live beyond<br />

the life of its managed sessions gives the user time to make another request which can fail over to a<br />

different cluster node, where it activates the the backup copy of the session. Default is 1800, i.e. 30<br />

minutes.<br />

processExpiresInterval is the minimum number of seconds between efforts by the valve to find<br />

and invalidate SSO's that have exceeded their 'maxEmptyLife'. Does not imply effort will be spent on<br />

such cleanup every 'processExpiresInterval', just that it won't occur more frequently than that. Default<br />

is 60.<br />

requireReauthentication is a flag to determine whether each request needs to be reauthenticated<br />

to the security Realm. If "true", this Valve uses cached security credentials (username and


194 Chapter 22. HTTP Services<br />

password) to reauthenticate to the <strong>JBoss</strong> Web security Realm each request associated with an SSO<br />

session. If false, the valve can itself authenticate requests based on the presence of a valid SSO<br />

cookie, without rechecking with the Realm. Setting to true can allow web applications with different<br />

security-domain configurations to share an SSO. Default is false.<br />

22.4 .2. SSO Behavior<br />

The user will not be challenged as long as they access only unprotected resources in any of the web<br />

applications on the virtual host.<br />

Upon access to a protected resource in any web app, the user will be challenged to authenticate, using<br />

the login method defined for the web app.<br />

Once authenticated, the roles associated with this user will be utilized for access control decisions<br />

across all of the associated web applications, without challenging the user to authenticate themselves to<br />

each application individually.<br />

If the web application invalidates a session (by invoking the<br />

javax.servlet.http.HttpSession.invalidate() method), the user's sessions in all web<br />

applications will be invalidated.<br />

A session timeout does not invalidate the SSO if other sessions are still valid.<br />

22.4 .3. Limitations<br />

There are a number of known limitations to this Tomcat valve-based SSO implementation:<br />

Only useful within a cluster of <strong>JBoss</strong> servers; SSO does not propagate to other resources.<br />

Requires use of container managed authentication (via element in web.xml)<br />

Requires cookies. SSO is maintained via a cookie and URL rewriting is not supported.<br />

Unless requireReauthentication is set to true, all web applications configured for the same<br />

SSO valve must share the same <strong>JBoss</strong> Web Realm and <strong>JBoss</strong> Security security-domain. This<br />

means:<br />

In server.xml you can nest the Realm element inside the Host element (or the surrounding<br />

Engine element), but not inside a context.xml packaged with one of the involved web<br />

applications.<br />

The security-domain configured in jboss-web.xml or jboss-app.xml must be<br />

consistent for all of the web applications.<br />

Even if you set requireReauthentication to true and use a different security-domain<br />

(or, less likely, a different Realm) for different webapps, the varying security integrations must all<br />

accept the same credentials (e.g. username and password).<br />

22.4 .4 . Configuring the Cookie Domain<br />

As noted above the SSO valve supports a cookieDomain configuration attribute. This attribute allows<br />

configuration of the SSO cookie's domain (i.e. the set of hosts to which the browser will present the<br />

cookie). By default the domain is "/", meaning the browser will only present the cookie to the host that<br />

issued it. The cookieDomain attribute allows the cookie to be scoped to a wider domain.<br />

For example, suppose we have a case where two apps, with URLs http://app1.xyz.com and<br />

http://app2.xyz.com, that wish to share an SSO context. These apps could be running on different<br />

servers in a cluster or the virtual host with which they are associated could have multiple aliases. This<br />

can be supported with the following configuration:<br />


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 195<br />

Chapter 23. <strong>JBoss</strong> Messaging Clustering Notes<br />

The most current information about using <strong>JBoss</strong> Messaging in a clustered environment is always<br />

available from the relevant <strong>JBoss</strong> Messaging User Guide at http://www.redhat.com/docs/en-<br />

US/<strong>JBoss</strong>_<strong>Enterprise</strong>_<strong>Application</strong>_<strong>Platform</strong>/.


196 Chapter 24. Clustered Deployment Options<br />

Chapter 24. Clustered Deployment Options<br />

24.1. Clustered Singleton Services<br />

A clustered singleton service (also known as a HA singleton) is a service that is deployed on multiple<br />

nodes in a cluster, but is providing its service on only one of the nodes. The node running the singleton<br />

service is typically called the master node.<br />

Figure 24 .1. Topology before the Master Node fails<br />

When the master fails or is shut down, another master is selected from the remaining nodes and the<br />

service is restarted on the new master. Thus, other than a brief interval when one master has stopped<br />

and another has yet to take over, the service is always being provided by one but only one node.<br />

Figure 24 .2. Topology after the Master Node fails<br />

24 .1.1. HASingleton Deployment Options<br />

The <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> provides support for a number of strategies for helping you<br />

deploy clustered singleton services. In this section we will explore the different strategies. All of the<br />

strategies are built on top of the HAPartition service described in the introduction. They rely on the<br />

HAPartition to provide notifications when different nodes in the cluster start and stop; based on<br />

those notifications each node in the cluster can independently (but consistently) determine if it is now<br />

the master node and needs to begin providing a service.<br />

24 .1.1.1. HASingletonDeployer service<br />

The simplest and most commonly used strategy for deploying an HA singleton is to take an ordinary


deployment (war, ear, jar, whatever you would normally put in deploy) and deploy it in the<br />

$JBOSS_HOME/server/all/deploy-hasingleton directory instead of in deploy. The deployhasingleton<br />

directory does not lie under deploy nor farm directories, so its contents are not<br />

automatically deployed when an <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> instance starts. Instead, deploying the<br />

contents of this directory is the responsibility of a special service, the HASingletonDeployer bean<br />

(which itself is deployed via the deploy/deploy-hasingleton-jboss-beans.xml file). The<br />

HASingletonDeployer service is itself an HA Singleton, one whose provided service, when it becomes<br />

master, is to deploy the contents of deploy-hasingleton; and whose service, when it stops being the<br />

master (typically at server shutdown), is to undeploy the contents of deploy-hasingleton.<br />

So, by placing your deployments in deploy-hasingleton you know that they will be deployed only on<br />

the master node in the cluster. If the master node cleanly shuts down, they will be cleanly undeployed as<br />

part of shutdown. If the master node fails or is shut down, they will be deployed on whatever node takes<br />

over as master.<br />

Using deploy-hasingleton is very simple, but it does have two drawbacks:<br />

There is no hot-deployment feature for services in deploy-hasingleton . Redeploying a service<br />

that has been deployed to deploy-hasingleton requires a server restart.<br />

If the master node fails and another node takes over as master, your singleton service needs to go<br />

through the entire deployment process before it will be providing services. Depending on the<br />

complexity of your service's deployment, and the extent of startup activity in which it engages, this<br />

could take a while, during which time the service is not being provided.<br />

24 .1.1.2. POJO deployments using HASingletonController<br />

If your service is a POJO (i.e., not a J2EE deployment like an ear or war or jar), you can deploy it along<br />

with a service called an HASingletonController in order to turn it into an HA singleton. It is the job of the<br />

HASingletonController to work with the HAPartition service to monitor the cluster and determine if it is<br />

now the master node for its service. If it determines it has become the master node, it invokes a method<br />

on your service telling it to begin providing service. If it determines it is no longer the master node, it<br />

invokes a method on your service telling it to stop providing service. Let's walk through an illustration.<br />

First, we have a POJO that we want to make an HA singleton. The only thing special about it is it needs<br />

to expose a public method that can be called when it should begin providing service, and another that<br />

can be called when it should stop providing service:<br />

public interface HASingletonExampleMBean<br />

{<br />

boolean isMasterNode();<br />

}<br />

public class HASingletonExample implements HASingletonExampleMBean<br />

{<br />

private boolean isMasterNode = false;<br />

}<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 197<br />

public boolean isMasterNode()<br />

{<br />

return isMasterNode;<br />

}<br />

public void startSingleton()<br />

{<br />

isMasterNode = true;<br />

}<br />

public void stopSingleton()<br />

{<br />

isMasterNode = false;<br />

}<br />

We used startSingleton and stopSingleton in the above example, but you could name the<br />

methods anything.<br />

Next, we deploy our service, along with an HASingletonController to control it, most likely packaged in a<br />

.sar file, with the following META-INF/jboss-beans.xml:


198 Chapter 24. Clustered Deployment Options<br />

<br />

<br />

<br />

@org.jboss.aop.microcontainer.aspects.jmx.JMX<br />

(name="jboss:service=HASingletonExample",<br />

exposedInterface=org.jboss.ha.examples.HASingletonExampleMBean.class)<br />

<br />

<br />

@org.jboss.aop.microcontainer.aspects.jmx.JMX<br />

(name="jboss:service=ExampleHASingletonController",<br />

exposedInterface=org.jboss.ha.singleton.HASingletonControllerMBean.class,<br />

registerDirectly=true)<br />

<br />

<br />

startSingleton<br />

stopSingleton<br />

<br />

<br />

Voila! A clustered singleton service.<br />

The primary advantage of this approach over deploy-ha-singleton. is that the above example can be<br />

placed in deploy or farm and thus can be hot deployed and farmed deployed. Also, if our example<br />

service had complex, time-consuming startup requirements, those could potentially be implemented in<br />

create() or start() methods. <strong>JBoss</strong> will invoke create() and start() as soon as the service is deployed; it<br />

doesn't wait until the node becomes the master node. So, the service could be primed and ready to go,<br />

just waiting for the controller to implement startSingleton() at which point it can immediately provide<br />

service.<br />

Although not demonstrated in the example above, the HASingletonController can support an<br />

optional argument for either or both of the target start and stop methods. These are specified using the<br />

targetStartMethodArgument and TargetStopMethodArgument properties, respectively.<br />

Currently, only string values are supported.<br />

24 .1.1.3. HASingleton deployments using a Barrier<br />

Services deployed normally inside deploy or farm that want to be started/stopped whenever the content<br />

of deploy-hasingleton gets deployed/undeployed, (i.e., whenever the current node becomes the master),<br />

need only specify a dependency on the Barrier service:<br />

HASingletonDeployerBarrierController<br />

The way it works is that a BarrierController is deployed along with the HASingletonDeployer and listens<br />

for JMX notifications from it. A BarrierController is a relatively simple MBean that can subscribe to receive<br />

any JMX notification in the system. It uses the received notifications to control the lifecycle of a<br />

dynamically created MBean called the Barrier. The Barrier is instantiated, registered and brought to the<br />

CREATE state when the BarrierController is deployed. After that, the BarrierController starts and stops<br />

the Barrier when matching JMX notifications are received. Thus, other services need only depend on the<br />

Barrier bean using the usual tag, and they will be started and stopped in tandem with the<br />

Barrier. When the BarrierController is undeployed the Barrier is also destroyed.<br />

This provides an alternative to the deploy-hasingleton approach in that we can use farming to distribute<br />

the service, while content in deploy-hasingleton must be copied manually on all nodes.<br />

On the other hand, the barrier-dependent service will be instantiated/created (i.e., any create() method<br />

invoked) on all nodes, but only started on the master node. This is different with the deploy-hasingleton<br />

approach that will only deploy (instantiate/create/start) the contents of the deploy-hasingleton directory<br />

on one of the nodes.<br />

So services depending on the barrier will need to make sure they do minimal or no work inside their<br />

create() step, rather they should use start() to do the work.


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 199<br />

Note<br />

The Barrier controls the start/stop of dependent services, but not their destruction, which<br />

happens only when the BarrierController is itself destroyed/undeployed. Thus using the<br />

Barrier to control services that need to be "destroyed" as part of their normal “undeploy”<br />

operation (like, for example, an EJBContainer) will not have the desired effect.<br />

24 .1.2. Determining the master node<br />

The various clustered singleton management strategies all depend on the fact that each node in the<br />

cluster can independently react to changes in cluster membership and correctly decide whether it is now<br />

the “master node”. How is this done?<br />

For each member of the cluster, the HAPartition service maintains an attribute called the CurrentView,<br />

which is basically an ordered list of the current members of the cluster. As nodes join and leave the<br />

cluster, JGroups ensures that each surviving member of the cluster gets an updated view. You can see<br />

the current view by going into the JMX console, and looking at the CurrentView attribute in the<br />

jboss:service=DefaultPartition mbean. Every member of the cluster will have the same view,<br />

with the members in the same order.<br />

Let's say, for example, that we have a 4 node cluster, nodes A through D, and the current view can be<br />

expressed as {A, B, C, D}. Generally speaking, the order of nodes in the view will reflect the order in<br />

which they joined the cluster (although this is not always the case, and should not be assumed to be the<br />

case).<br />

To further our example, let's say there is a singleton service (i.e. an HASingletonController)<br />

named Foo that's deployed around the cluster, except, for whatever reason, on B. The HAPartition<br />

service maintains across the cluster a registry of what services are deployed where, in view order. So,<br />

on every node in the cluster, the HAPartition service knows that the view with respect to the Foo<br />

service is {A, C, D} (no B).<br />

Whenever there is a change in the cluster topology of the Foo service, the HAPartition service<br />

invokes a callback on Foo notifying it of the new topology. So, for example, when Foo started on D, the<br />

Foo service running on A, C and D all got callbacks telling them the new view for Foo was {A, C, D}. That<br />

callback gives each node enough information to independently decide if it is now the master. The Foo<br />

service on each node uses the HAPartition's HASingletonElectionPolicy to determine if they<br />

are the master, as explained in the Section 24.1.2.1, “HA singleton election policy”.<br />

If A were to fail or shutdown, Foo on C and D would get a callback with a new view for Foo of {C, D}. C<br />

would then become the master. If A restarted, A, C and D would get a callback with a new view for Foo of<br />

{C, D, A}. C would remain the master – there's nothing magic about A that would cause it to become the<br />

master again just because it was before.<br />

24 .1.2.1. HA singleton election policy<br />

The HASingletonElectionPolicy object is responsible for electing a master node from a list of<br />

available nodes, on behalf of an HA singleton, following a change in cluster topology.<br />

public interface HASingletonElectionPolicy<br />

{<br />

ClusterNode elect(List nodes);<br />

}<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> ships with two election policies:<br />

HASingletonElectionPolicySimple<br />

This policy selects a master node based relative age. The desired age is configured via the<br />

position property, which corresponds to the index in the list of available nodes. position =<br />

0, the default, refers to the oldest node; position = 1, refers to the 2nd oldest; etc.<br />

position can also be negative to indicate youngness; imagine the list of available nodes as a<br />

circular linked list. position = -1, refers to the youngest node; position = -2, refers to<br />

the 2nd youngest node; etc.


200 Chapter 24. Clustered Deployment Options<br />

<br />

-1<br />

<br />

PreferredMasterElectionPolicy<br />

This policy extends HASingletonElectionPolicySimple, allowing the configuration of a<br />

preferred node. The preferredMaster property, specified as host:port or address:port,<br />

identifies a specific node that should become master, if available. If the preferred node is not<br />

available, the election policy will behave as described above.<br />

<br />

server1:12345<br />

<br />

24.2. Farming Deployment<br />

The easiest way to deploy an application into the cluster is to use the farming service. Using the farming<br />

service, you can deploy an application (e.g. EAR, WAR, or SAR; either an archive file or in exploded form)<br />

to the all/farm/ directory of any cluster member and the application will be automatically duplicate<br />

across all nodes in the same cluster. If a node joins the cluster later, it will pull in all farm deployed<br />

applications in the cluster and deploy them locally at start-up time. If you delete the application from a<br />

running clustered server node's farm/ directory, the application will be undeployed locally and then<br />

removed from all other clustered server nodes' farm/ directories (triggering undeployment).<br />

Farming is enabled by default in the all configuration in <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> and thus<br />

requires no manual setup. The required farm-deployment-jboss-beans.xml and timestampsjboss-beans.xml<br />

configuration files are located in the deploy/cluster directory. If you want to<br />

enable farming in a custom configuration, simply copy these files to the corresponding <strong>JBoss</strong> deploy<br />

directory $JBOSS_HOME/server/$your_own_config/deploy/cluster. Make sure that your custom<br />

configuration has clustering enabled.<br />

While there is little need to customize the farming service, it can be customized via the<br />

FarmProfileRepositoryClusteringHandler bean, whose properties and default values are<br />

listed below:<br />

<br />

<br />

default<br />

default<br />

farm<br />

false<br />

60000<br />

60000<br />

<br />

<br />

partition is a required attribute to inject the HAPartition service that the farm service uses for intracluster<br />

communication.<br />

profile[Domain|Server|Name] are all used to identify the profile for which this handler is intended.<br />

immutable indicates whether or not this handler allows a node to push content changes to the<br />

cluster. A value of true is equivalent to setting synchronizationPolicy to<br />

org.jboss.system.server.profileservice.repository.clustered.sync.<br />

ImmutableSynchronizationPolicy.<br />

lockTimeout defines the number of milliseconds to wait for cluster-wide lock acquisition.<br />

methodCallTimeout defines the number of milliseconds to wait for invocations on remote cluster<br />

nodes.<br />

synchronizationPolicy decides how to handle content additions, reincarnations, updates, or<br />

removals from nodes attempting to join the cluster or from cluster merges. The policy is consulted on


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 201<br />

the "authoritative" node, i.e. the master node for the service on the cluster. Reincarnation refers to<br />

the phenomenon where a newly started node may contain an application in its farm/ directory that<br />

was previously removed by the farming service but might still exist on the starting node if it was not<br />

running when the removal took place. The default synchronization policy is defined as follows:<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

false<br />

2592000000<br />

<br />

<br />

allow[Join|Merge][Additions|Reincarnations|Updates|Removals] define fixed responses to<br />

requests to allow additions, reincarnations, updates, or removals from joined or merged nodes.<br />

developerMode enables a lenient synchronization policy that allows all changes. Enabling<br />

developer mode is equivalent to setting each of the above properties to true and is intended for<br />

development environments.<br />

removalTrackingTime defines the number of milliseconds for which this policy should<br />

remembered removed items, for use in detecting reincarnations.<br />

timestampService estimates and tracks discrepancies in system clocks for current and past<br />

members of the cluster. Default implementation is defined in timestamps-jboss-beans.xml.


202 Chapter 25. JGroups Services<br />

Chapter 25. JGroups Services<br />

JGroups provides the underlying group communication support for <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong><br />

clusters. The interaction of clustered services with JGroups was covered in Section 18.1, “Group<br />

Communication with JGroups”. This chapter focuses on the details of this interaction, with particular<br />

attention to configuration details and troubleshooting tips.<br />

This chapter is not intended as complete JGroups documentation. If you want to know more about<br />

JGroups, you can consult:<br />

The JGroups project documentation at http://jgroups.org/ug.html<br />

The JGroups wiki pages at jboss.org, rooted at https://www.jboss.org/community/wiki/JGroups<br />

The first section of this chapter covers the many JGroups configuration options in detail. <strong>JBoss</strong><br />

<strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> ships with a set of default JGroups configurations. Most applications will<br />

work with the default configurations out of the box. You will only need to edit these configurations when<br />

you deploy an application with special network or performance requirements.<br />

25.1. Configuring a JGroups Channel's Protocol Stack<br />

The JGroups framework provides services to enable peer-to-peer communications between nodes in a<br />

cluster. Communication occurs over a communication channel. The channel built up from a stack of<br />

network communication protocols, each of which is responsible for adding a particular capability to the<br />

overall behavior of the channel. Key capabilities provided by various protocols include transport, cluster<br />

discovery, message ordering, lossless message delivery, detection of failed peers, and cluster<br />

membership management services.<br />

Figure 25.1, “Protocol stack in JGroups” shows a conceptual cluster with each member's channel<br />

composed of a stack of JGroups protocols.<br />

Figure 25.1. Protocol stack in JGroups<br />

This section of the chapter covers some of the most commonly used protocols, according to the type of<br />

behaviour they add to the channel. We discuss a few key configuration attributes exposed by each<br />

protocol, but since these attributes should be altered only by experts, this chapter focuses on<br />

familiarizing users with the purpose of various protocols.<br />

The JGroups configurations used in <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> appear as nested elements<br />

in the $JBOSS_HOME/server/all/deploy/cluster/jgroups-channelfactory.sar/META-<br />

INF/jgroups-channelfactory-stacks.xml file. This file is parsed by the ChannelFactory<br />

service, which uses the contents to provide correctly configured channels to the clustered services that<br />

require them. See Section 18.1.1, “The Channel Factory Service” for more on the ChannelFactory<br />

service.<br />

The following is an example protocol stack configuration from jgroups-channelfactorystacks.xml:


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 203<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

The element contains all the configuration data for JGroups. This information is used to


204 Chapter 25. JGroups Services<br />

configure a JGroups channel, which is conceptually similar to a socket, and manages communication<br />

between peers in a cluster. Each element within the element defines a particular JGroups<br />

protocol. Each protocol performs one function. The combination of these functions defines the<br />

characteristics of the channel as a whole. The next few sections describe common protocols and explain<br />

the options available to each.<br />

25.1.1. <strong>Common</strong> Configuration Properties<br />

The following property is exposed by all of the JGroups protocols discussed below:<br />

stats whether the protocol should gather runtime statistics on its operations that can be exposed<br />

via tools like the AS's JMX console or the JGroups Probe utility. What, if any, statistics are gathered<br />

depends on the protocol. Default is true.<br />

Note<br />

All of the protocols in the versions of JGroups used in <strong>JBoss</strong> <strong>Application</strong> Server 3.x and 4.x<br />

exposed down_thread and up_thread attributes. The JGroups version included in <strong>JBoss</strong><br />

<strong>Application</strong> Server 5 and later no longer uses those attributes, and a WARN message will be<br />

written to the server log if they are configured for any protocol.<br />

25.1.2. Transport Protocols<br />

The transport protocols send and receive messages to and from the network. They also manage the<br />

thread pools used to deliver incoming messages to addresses higher in the protocol stack. JGroups<br />

supports UDP, TCP and TUNNEL as transport protocols.<br />

Note<br />

The UDP, TCP, and TUNNEL protocols are mutually exclusive. You can only have one transport<br />

protocol in each JGroups Config element<br />

25.1.2.1. UDP configuration<br />

UDP is the preferred transport protocol for JGroups. UDP uses multicast (or, in an unusual configuration,<br />

multiple unicasts) to send and receive messages. If you choose UDP as the transport protocol for your<br />

cluster service, you need to configure it in the UDP sub-element in the JGroups config element. Here<br />

is an example.


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 205<br />

<br />

JGroups transport configurations have a number of attributes available. First we look at the attributes<br />

available to the UDP protocol, followed by the attributes that are also used by the TCP and TUNNEL<br />

transport protocols.<br />

The attributes particular to the UDP protocol are:<br />

ip_mcast specifies whether or not to use IP multicasting. The default is true. If set to false,<br />

multiple unicast packets will be sent instead of one multicast packet. Any packet sent via UDP<br />

protocol are UDP datagrams.<br />

mcast_addr specifies the multicast address (class D) for communicating with the group (i.e., the<br />

cluster). The standard protocol stack configurations in <strong>JBoss</strong> AS use the value of system property<br />

jboss.partition.udpGroup, if set, as the value for this attribute. Using the -u command line<br />

switch when starting <strong>JBoss</strong> <strong>Application</strong> Server sets that value. See Section 25.6.2, “Isolating JGroups<br />

Channels” for information about using this configuration attribute to ensure that JGroups channels<br />

are properly isolated from one another. If this attribute is omitted, the default value is<br />

228.11.11.11.<br />

mcast_port specifies the port to use for multicast communication with the group. See Section 25.6.2,<br />

“Isolating JGroups Channels” for how to use this configuration attribute to ensure JGroups channels<br />

are properly isolated from one another. If this attribute is omitted, the default is 45688.<br />

mcast_send_buf_size, mcast_recv_buf_size, ucast_send_buf_size and<br />

ucast_recv_buf_size define the socket send and receive buffer sizes that JGroups will request<br />

from the operating system. A large buffer size helps to ensure that packets are not dropped due to<br />

buffer overflow. However, socket buffer sizes are limited at the operating system level, so obtaining<br />

the desired buffer may require configuration at the operating system level. See Section 25.6.2.3,<br />

“Improving UDP Performance by Configuring OS UDP Buffer Limits” for further details.<br />

bind_port specifies the port to which the unicast receive socket should be bound. The default is 0;<br />

i.e. use an ephemeral port.<br />

port_range specifies the number of ports to try if the port identified by bind_port is not available.<br />

The default is 1, which specifies that only bind_port will be tried.<br />

ip_ttl specifies time-to-live (TTL) for IP Multicast packets. TTL is the commonly used term in<br />

multicast networking, but is actually something of a misnomer, since the value here refers to how<br />

many network hops a packet will be allowed to travel before networking equipment will drop it.


206 Chapter 25. JGroups Services<br />

tos specifies the traffic class for sending unicast and multicast datagrams.<br />

The attributes that are common to all transport protocols, and thus have the same meanings when used<br />

with TCP or TUNNEL, are:<br />

singleton_name provides a unique name for this transport protocol configuration. Used by the<br />

application server's ChannelFactory to support sharing of a transport protocol instance by<br />

different channels that use the same transport protocol configuration. See Section 18.1.2, “The<br />

JGroups Shared Transport”.<br />

bind_addr specifies the interface on which to receive and send messages. By default, JGroups<br />

uses the value of system property jgroups.bind_addr. This can also be set with the -b<br />

command line switch. See Section 25.6, “Other Configuration Issues” for more on binding JGroups<br />

sockets.<br />

receive_on_all_interfaces specifies whether this node should listen on all interfaces for<br />

multicasts. The default is false. It overrides the bind_addr property for receiving multicasts.<br />

However, bind_addr (if set) is still used to send multicasts.<br />

send_on_all_interfaces specifies whether this node sends UDP packets via all available network<br />

interface controllers, if your machine has multiple network interface controllers available. This means<br />

that the same multicast message is sent N times, so use with care.<br />

receive_interfaces specifies a list of of interfaces on which to receive multicasts. The multicast<br />

receive socket will listen on all of these interfaces. This is a comma-separated list of IP addresses or<br />

interface names, for example, 192.168.5.1,eth1,127.0.0.1.<br />

send_interfaces specifies a list of of interfaces via which to send multicasts. The multicast sender<br />

socket will send on all of these interfaces. This is a comma-separated list of IP addresses or<br />

interface names, for example, 192.168.5.1,eth1,127.0.0.1.This means that the same<br />

multicast message is sent N times, so use with care.<br />

enable_bundling specifies whether to enable message bundling. If true, the tranpsort protocol<br />

queues outgoing messages until max_bundle_size bytes have accumulated, or<br />

max_bundle_time milliseconds have elapsed, whichever occurs first. Then the transport protocol<br />

bundles queued messages into one large message and sends it. The messages are unbundled at<br />

the receiver. The default is false.<br />

Message bundling can have significant performance benefits for channels that are used for high<br />

volume sending of messages where the sender does not block waiting for a response from<br />

recipients (for example, a <strong>JBoss</strong> Cache instance configured for REPL_ASYNC.) It can add<br />

considerable latency to applications where senders need to block waiting for responses, so it is not<br />

recommended for certain situations, such as where a <strong>JBoss</strong> Cache instance is configured for<br />

REPL_SYNC.<br />

loopback specifies whether the thread sending a message to the group should itself carry the<br />

message back up the stack for delivery. (Messages sent to the group are always delivered to the<br />

sending node as well.) If false, the sending thread does not carry the message; the transport<br />

protocol waits to read the message off the network and uses one of the message delivery pool<br />

threads for delivery. The default is false, but true is recommended to ensure that the channel<br />

receives its own messages, in case the network interface goes down.<br />

discard_incompatible_packets specifies whether to discard packets sent by peers that use a<br />

different version of JGroups. Each message in the cluster is tagged with a JGroups version. If<br />

discard_incompatible_packets is set to true, messages received from different versions of<br />

JGroups will be silently discarded. Otherwise, a warning will be logged. In no case will the message<br />

be delivered. The default value is false.<br />

enable_diagnostics specifies that the transport should open a multicast socket on address<br />

diagnostics_addr and port diagnostics_port to listen for diagnostic requests sent by the<br />

JGroups Probe utility.<br />

The various thread_pool attributes configure the behavior of the pool of threads JGroups uses to<br />

carry ordinary incoming messages up the stack. The various attributes provide the constructor<br />

arguments for an instance of java.util.concurrent.ThreadPoolExecutorService. In the<br />

example above, the pool will have a minimum or core size of 8 threads, and a maximum size of 200. If<br />

more than 8 pool threads have been created, a thread returning from carrying a message will wait for<br />

up to 5000 milliseconds to be assigned a new message to carry, after which it will terminate. If no<br />

threads are available to carry a message, the (separate) thread reading messages off the socket will<br />

place messages in a queue; the queue will hold up to 1000 messages. If the queue is full, the thread<br />

reading messages off the socket will discard the message.<br />

The various oob_thread_pool attributes are similar to the thread_pool attributes in that they<br />

configure a java.util.concurrent.ThreadPoolExecutorService used to carry incoming


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 207<br />

messages up the protocol stack. In this case, the pool is used to carry a special type of message<br />

known as an Out-Of-Band (OOB) message. OOB messages are exempt from the ordered-delivery<br />

requirements of protocols like NAKACK and UNICAST and thus can be delivered up the stack even if<br />

NAKACK or UNICAST are queueing up messages from a particular sender. OOB messages are<br />

often used internally by JGroups protocols and can be used by applications as well. For example,<br />

when <strong>JBoss</strong> Cache is in REPL_SYNC mode, it uses OOB messages for the second phase of its twophase-commit<br />

protocol.<br />

25.1.2.2. TCP configuration<br />

Alternatively, a JGroups-based cluster can also work over TCP connections. Compared with UDP, TCP<br />

generates more network traffic when the cluster size increases. TCP is fundamentally a unicast protocol.<br />

To send multicast messages, JGroups uses multiple TCP unicasts. To use TCP as a transport protocol,<br />

you should define a TCP element in the JGroups config element. Here is an example of the TCP<br />

element.<br />

<br />

The following attributes are specific to the TCP element:<br />

start_port and end_port define the range of TCP ports to which the server should bind. The<br />

server socket is bound to the first available port beginning with start_port. If no available port is<br />

found (for example, because the ports are in use by other sockets) before the end_port, the server<br />

throws an exception. If no end_port is provided, or end_port is lower than start_port, no upper<br />

limit is applied to the port range. If start_port is equal to end_port, JGroups is forced to use the<br />

specified port, since start_port fails if the specified port in not available. The default value is<br />

7800. If set to 0, the operating system will select a port. (This will only work for MPING or<br />

TCPGOSSIP discovery protocols. TCCPING requires that nodes and their required ports are listed.)<br />

bind_port in TCP acts as an alias for start_port. If configured internally, it sets start_port.<br />

recv_buf_size, send_buf_size define receive and send buffer sizes. It is good to have a large<br />

receiver buffer size, so packets are less likely to get dropped due to buffer overflow.<br />

conn_expire_time specifies the time (in milliseconds) after which a connection can be closed by<br />

the reaper if no traffic has been received.<br />

reaper_interval specifies interval (in milliseconds) to run the reaper. If both values are 0, no<br />

reaping will be done. If either value is > 0, reaping will be enabled. By default, reaper_interval is 0,<br />

which means no reaper.<br />

sock_conn_timeout specifies max time in millis for a socket creation. When doing the initial<br />

discovery, and a peer hangs, don't wait forever but go on after the timeout to ping other members.<br />

Reduces chances of *not* finding any members at all. The default is 2000.<br />

use_send_queues specifies whether to use separate send queues for each connection. This<br />

prevents blocking on write if the peer hangs. The default is true.<br />

external_addr specifies external IP address to broadcast to other group members (if different to<br />

local address). This is useful when you have use (Network Address Translation) NAT, e.g. a node<br />

on a private network, behind a firewall, but you can only route to it via an externally visible address,<br />

which is different from the local address it is bound to. Therefore, the node can be configured to<br />

broadcast its external address, while still able to bind to the local one. This avoids having to use the<br />

TUNNEL protocol, (and hence a requirement for a central gossip router) because nodes outside the<br />

firewall can still route to the node inside the firewall, but only on its external address. Without setting<br />

the external_addr, the node behind the firewall will broadcast its private address to the other nodes<br />

which will not be able to route to it.<br />

skip_suspected_members specifies whether unicast messages should not be sent to suspected<br />

members. The default is true.<br />

tcp_nodelay specifies TCP_NODELAY. TCP by default nagles messages, that is, conceptually,<br />

smaller messages are bundled into larger ones. If we want to invoke synchronous cluster method<br />

calls, then we need to disable nagling in addition to disabling message bundling (by setting<br />

enable_bundling to false). Nagling is disabled by setting tcp_nodelay to true. The default is<br />

false.


208 Chapter 25. JGroups Services<br />

Note<br />

All of the attributes common to all protocols discussed in the UDP protocol section also apply to<br />

TCP.<br />

25.1.2.3. TUNNEL configuration<br />

The TUNNEL protocol uses an external router process to send messages. The external router is a Java<br />

process that runs the org.jgroups.stack.GossipRouter main class. Each node has to register<br />

with the router. All messages are sent to the router and forwarded on to their destinations. The TUNNEL<br />

approach can be used to set up communication with nodes behind firewalls. A node can establish a TCP<br />

connection to the GossipRouter through the firewall (you can use port 80). This connection is also<br />

used by the router to send messages to nodes behind the firewall, as most firewalls do not permit<br />

outside hosts to initiate a TCP connection to a host inside the firewall. The TUNNEL configuration is<br />

defined in the TUNNEL element within the JGroups element, like so:<br />

<br />

The available attributes in the TUNNEL element are listed below.<br />

router_host specifies the host on which the GossipRouter is running.<br />

router_port specifies the port on which the GossipRouter is listening.<br />

reconnect_interval specifies the interval of time (in milliseconds) for which TUNNEL will attempt to<br />

connect to the GossipRouter if the connection is not established. The default value is 5000.<br />

Note<br />

All of the attributes common to all protocols discussed in the UDP protocol section also apply to<br />

TUNNEL.<br />

25.1.3. Discovery Protocols<br />

When a channel on a node first connects, it must determine which other nodes are running compatible<br />

channels, and which of these nodes is currently acting as the coordinator (the node responsible for<br />

letting new nodes join the group). Discovery protocols are used to find active nodes in the cluster and to<br />

determine which is the coordinator. This information is then provided to the group membership protocol<br />

(GMS), which communicates with the coordinator's GMS to add the newly-connecting node to the group.<br />

(For more information about group membership protocols, see Section 25.1.6, “Group Membership<br />

(GMS)”.)<br />

Discovery protocols also assist merge protocols (see Section 25.5, “Merging (MERGE2)”) to detect<br />

cluster-split situations.<br />

The discovery protocols sit on top of the transport protocol, so you can choose to use different<br />

discovery protocols depending on your transport protocol. These are also configured as sub-elements<br />

in the JGroups element.<br />

25.1.3.1. PING<br />

PING is a discovery protocol that works by either multicasting PING requests to an IP multicast address<br />

or connecting to a gossip router. As such, PING normally sits on top of the UDP or TUNNEL transport<br />

protocols. Each node responds with a packet {C, A}, where C=coordinator's address and A=own<br />

address. After timeout milliseconds or num_initial_members replies, the joiner determines the<br />

coordinator from the responses, and sends a JOIN request to it (handled by). If nobody responds, we<br />

assume we are the first member of a group.<br />

Here is an example PING configuration for IP multicast.<br />


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 209<br />

Here is another example PING configuration for contacting a Gossip Router.<br />

<br />

The available attributes in the PING element are listed below.<br />

timeout specifies the maximum number of milliseconds to wait for any responses. The default is<br />

3000.<br />

num_initial_members specifies the maximum number of responses to wait for unless timeout has<br />

expired. The default is 2.<br />

gossip_host specifies the host on which the GossipRouter is running.<br />

gossip_port specifies the port on which the GossipRouter is listening on.<br />

gossip_refresh specifies the interval (in milliseconds) for the lease from the GossipRouter. The<br />

default is 20000.<br />

initial_hosts is a comma-separated list of addresses or ports (for example,<br />

host1[12345],host2[23456]) which are pinged for discovery. Default is null, meaning<br />

multicast discovery should be used. If initial_hosts is specified, you must list all possible cluster<br />

members, not just a few well-known hosts, or MERGE2 cluster split discovery will not work reliably.<br />

If both gossip_host and gossip_port are defined, the cluster uses the GossipRouter for the initial<br />

discovery. If the initial_hosts is specified, the cluster pings that static list of addresses for<br />

discovery. Otherwise, the cluster uses IP multicasting for discovery.<br />

Note<br />

The discovery phase returns when the timeout ms have elapsed or the<br />

num_initial_members responses have been received.<br />

25.1.3.2. TCPGOSSIP<br />

The TCPGOSSIP protocol only works with a GossipRouter. It works essentially the same way as the<br />

PING protocol configuration with valid gossip_host and gossip_port attributes. It works on top of<br />

both UDP and TCP transport protocols. Here is an example.<br />

<br />

The available attributes in the TCPGOSSIP element are listed below.<br />

timeout specifies the maximum number of milliseconds to wait for any responses. The default is<br />

3000.<br />

num_initial_members specifies the maximum number of responses to wait for unless timeout has<br />

expired. The default is 2.<br />

initial_hosts is a comma-separated list of addresses/ports (for example,<br />

host1[12345],host2[23456]) of GossipRouters to register<br />

25.1.3.3. TCPPING<br />

The TCPPING protocol takes a set of known members and pings them for discovery. This is essentially<br />

a static configuration. It works on top of TCP. Here is an example of the TCPPING configuration element<br />

in the JGroups config element.<br />

<br />

The available attributes in the TCPPING element are listed below.


210 Chapter 25. JGroups Services<br />

timeout specifies the maximum number of milliseconds to wait for any responses. The default is<br />

3000.<br />

num_initial_members specifies the maximum number of responses to wait for unless timeout has<br />

expired. The default is 2.<br />

initial_hosts is a comma-seperated list of addresses (for example,<br />

host1[12345],host2[23456]) for pinging.<br />

port_range specifies the number of consecutive ports to be probed when getting the initial<br />

membership, starting with the port specified in the initial_hosts parameter. Given the current<br />

values of port_range and initial_hosts above, the TCPPING layer will try to connect to<br />

hosta[2300], hosta[2301], hosta[2302], hostb[3400], hostb[3401], hostb[3402],<br />

hostc[4500], hostc[4501], and hostc[4502]. This configuration option allows for multiple<br />

possible ports on the same host to be pinged without having to spell out all possible combinations. If<br />

in your TCP protocol configuration your end_port is greater than your start_port, we<br />

recommend using a TCPPING port_range equal to the difference, to ensure a node is pinged no<br />

matter which port it is bound to within the allowed range.<br />

25.1.3.4 . MPING<br />

MPING uses IP multicast to discover the initial membership. Unlike the other discovery protocols, which<br />

delegate the sending and receiving of discovery messages on the network to the transport protocol,<br />

MPING opens its own sockets to send and receive multicast discovery messages. As a result it can be<br />

used with all transports, but it is most often used with TCP. TCP usually requires TCPPING, which must<br />

explicitly list all possible group members. MPING does not have this requirement, and is typically used<br />

where TCP is required for regular message transport, and UDP multicasting is allowed for discovery.<br />

<br />

The available attributes in the MPING element are listed below.<br />

timeout specifies the maximum number of milliseconds to wait for any responses. The default is<br />

3000.<br />

num_initial_members specifies the maximum number of responses to wait for unless timeout has<br />

expired. The default is 2..<br />

bind_addr specifies the interface on which to send and receive multicast packets. By default<br />

JGroups uses the value of the system property jgroups.bind_addr, which can be set with the -b<br />

command line switch. See Section 25.6, “Other Configuration Issues” for more on binding JGroups<br />

sockets.<br />

bind_to_all_interfaces overrides the bind_addr and uses all interfaces in multihome nodes.<br />

mcast_addr, mcast_port, ip_ttl attributes are the same as related attributes in the UDP protocol<br />

configuration.<br />

25.1.4 . Failure Detection Protocols<br />

The failure detection protocols are used to detect failed nodes. Once a failed node is detected, a<br />

suspect verification phase can occur. If the node is still considered dead after this phase is complete, the<br />

cluster updates its membership view so that further messages are not sent to the failed node. The<br />

service using JGroups is informed that the node is no longer part of the cluster. Failure detection<br />

protocols are configured as sub-elements in the JGroups element.<br />

25.1.4 .1. FD<br />

FD is a failure detection protocol based on 'heartbeat' messages. This protocol requires that each node<br />

periodically ping its neighbour. If the neighbour fails to respond, the calling node sends a SUSPECT<br />

message to the cluster. The current group coordinator can optionally verify that the suspected node is<br />

dead (VERIFY_SUSPECT). If the node is still considered dead after this verification step, the coordinator<br />

updates the cluster's membership view. The following is an example of FD configuration:


The available attributes in the FD element are listed below.<br />

timeout specifies the maximum number of milliseconds to wait for the responses to the are-youalive<br />

messages. The default is 3000.<br />

max_tries specifies the number of missed are-you-alive messages from a node before the node is<br />

suspected. The default is 2.<br />

shun specifies whether a failed node will be forbidden from sending messages to the group without<br />

formally rejoining. A shunned node would need to rejoin the cluster via the discovery process.<br />

JGroups allows applications to configure a channel such that, when a channel is shunned, the<br />

process of rejoining the cluster and transferring state takes place automatically. (This is default<br />

behavior for <strong>JBoss</strong> <strong>Application</strong> Server.)<br />

Note<br />

Regular traffic from a node is proof of life, so heartbeat messages are only sent when no regular<br />

traffic is detected on the node for a long period of time.<br />

25.1.4 .2. FD_SOCK<br />

FD_SOCK is a failure detection protocol based on a ring of TCP sockets created between group<br />

members. Each member in a group connects to its neighbor, with the final member connecting to the first,<br />

forming a ring. Node B becomes suspected when its neighbour, Node A, detects an abnormally closed<br />

TCP socket, presumably due to a crash in Node B. (When nodes intend to leave the group, they inform<br />

their neighbours so that they do not become suspected.)<br />

The simplest FD_SOCK configuration does not take any attribute. You can declare an empty FD_SOCK<br />

element in the JGroups element.<br />

<br />

The attributes available to the FD_SOCK element are listed below.<br />

bind_addr specifies the interface to which the server socket should be bound. By default, JGroups<br />

uses the value of the system property jgroups.bind_addr. This system property can be set with<br />

the -b command line switch. For more information about binding JGroups sockets, see Section 25.6,<br />

“Other Configuration Issues”.<br />

25.1.4 .3. VERIFY_SUSPECT<br />

This protocol verifies whether a suspected member is really dead by pinging that member once again.<br />

This verification is performed by the coordinator of the cluster. The suspected member is dropped from<br />

the cluster group if confirmed to be dead. The aim of this protocol is to minimize false suspicions. Here's<br />

an example.<br />

<br />

The available attributes in the VERIFY_SUSPECT element are listed below.<br />

timeout specifies how long to wait for a response from the suspected member before considering it<br />

dead.<br />

25.1.4 .4 . FD versus FD_SOCK<br />

FD and FD_SOCK, each taken individually, do not provide a solid failure detection layer. Let's look at the<br />

the differences between these failure detection protocols to understand how they complement each<br />

other:<br />

FD<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 211<br />

An overloaded machine might be slow in sending are-you-alive responses.


212 Chapter 25. JGroups Services<br />

A member will be suspected when suspended in a debugger/profiler.<br />

Low timeouts lead to higher probability of false suspicions and higher network traffic.<br />

High timeouts will not detect and remove crashed members for some time.<br />

FD_SOCK:<br />

Suspended in a debugger is no problem because the TCP connection is still open.<br />

High load no problem either for the same reason.<br />

Members will only be suspected when TCP connection breaks, so hung members will not be<br />

detected.<br />

Also, a crashed switch will not be detected until the connection runs into the TCP timeout<br />

(between 2-20 minutes, depending on TCP/IP stack implementation).<br />

A failure detection layer is intended to report real failures promptly, while avoiding false suspicions.<br />

There are two solutions:<br />

1. By default, JGroups configures the FD_SOCK socket with KEEP_ALIVE, which means that TCP<br />

sends a heartbeat on socket on which no traffic has been received in 2 hours. If a host crashed<br />

(or an intermediate switch or router crashed) without closing the TCP connection properly, we<br />

would detect this after 2 hours (plus a few minutes). This is of course better than never closing<br />

the connection (if KEEP_ALIVE is off), but may not be of much help. So, the first solution would be<br />

to lower the timeout value for KEEP_ALIVE. This can only be done for the entire kernel in most<br />

operating systems, so if this is lowered to 15 minutes, this will affect all TCP sockets.<br />

2. The second solution is to combine FD_SOCK and FD; the timeout in FD can be set such that it is<br />

much lower than the TCP timeout, and this can be configured individually per process. FD_SOCK<br />

will already generate a suspect message if the socket was closed abnormally. However, in the<br />

case of a crashed switch or host, FD will make sure the socket is eventually closed and the<br />

suspect message generated. Example:<br />

<br />

<br />

<br />

In this example, a member becomes suspected when the neighbouring socket has been closed<br />

abnormally, in a process crash, for instance, since the operating system closes all sockets. However, if a<br />

host or switch crashes, the sockets will not be closed. FD will suspect the neighbour after sixty seconds<br />

(6000 milliseconds). Note that if this example system were stopped in a breakpoint in the debugger, the<br />

node being debugged will be suspected once the timeout has elapsed.<br />

A combination of FD and FD_SOCK provides a solid failure detection layer, which is why this technique is<br />

used across the JGroups configurations included with <strong>JBoss</strong> <strong>Application</strong> Server.<br />

25.1.5. Reliable Delivery Protocols<br />

Reliable delivery protocols within the JGroups stack ensure that messages are actually delivered, and<br />

delivered in the correct order (First In, First Out, or FIFO) to the destination node. The basis for reliable<br />

message delivery is positive and negative delivery acknowledgments (ACK and NAK). In ACK mode, the<br />

sender resends the message until acknowledgment is received from the receiver. In NAK mode, the<br />

receiver requests retransmission when it discovers a gap.<br />

25.1.5.1. UNICAST<br />

The UNICAST protocol is used for unicast messages. It uses positive acknowlegements (ACK). It is<br />

configured as a sub-element under the JGroups config element. If the JGroups stack is configured<br />

with the TCP transport protocol, UNICAST is not necessary because TCP itself guarantees FIFO<br />

delivery of unicast messages. Here is an example configuration for the UNICAST protocol:<br />

<br />

There is only one configurable attribute in the UNICAST element.<br />

timeout specifies the retransmission timeout (in milliseconds). For instance, if the timeout is<br />

100,200,400,800, the sender resends the message if it has not received an ACK after 100<br />

milliseconds the first time, and the second time it waits for 200 milliseconds before resending, and so<br />

on. A low value for the first timeout allows for prompt retransmission of dropped messages, but<br />

means that messages may be transmitted more than once if they have not actually been lost (that is,


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 213<br />

the message has been sent, but the ACK has not been received before the timeout). High values<br />

(1000,2000,3000) can improve performance if the network is tuned such that UDP datagram loss<br />

is infrequent. High values on networks with frequent losses will be harmful to performance, since<br />

later messages will not be delivered until lost messages have been retransmitted.<br />

25.1.5.2. NAKACK<br />

The NAKACK protocol is used for multicast messages. It uses negative acknowlegements (NAK). Under<br />

this protocol, each message is tagged with a sequence number. The receiver keeps track of the<br />

received sequence numbers and delivers the messages in order. When a gap in the series of received<br />

sequence numbers is detected, the receiver schedules a task to periodically ask the sender to<br />

retransmit the missing message. The task is cancelled if the missing message is received. NAKACK<br />

protocol is configured as the pbcast.NAKACK sub-element under the JGroups element.<br />

Here is an example configuration:<br />

<br />

The configurable attributes in the pbcast.NAKACK element are as follows.<br />

retransmit_timeout specifies the series of timeouts (in milliseconds) after which retransmission is<br />

requested if a missing message has not yet been received.<br />

use_mcast_xmit determines whether the sender should send the retransmission to the entire<br />

cluster rather than just to the node requesting it. This is useful when the sender's network layer<br />

tends to drop packets, avoiding the need to individually retransmit to each node.<br />

max_xmit_size specifies the maximum size (in bytes) for a bundled retransmission, if multiple<br />

messages are reported missing.<br />

discard_delivered_msgs specifies whether to discard delivered messages on the receiver nodes.<br />

By default, nodes save delivered messages so any node can retransmit a lost message in case the<br />

original sender has crashed or left the group. However, if we only ask the sender to resend its<br />

messages, we can enable this option and discard delivered messages.<br />

gc_lag specifies the number of messages to keep in memory for retransmission, even after the<br />

periodic cleanup protocol (see Section 25.4, “Distributed Garbage Collection (STABLE)”) indicates all<br />

peers have received the message. The default value is 20.<br />

25.1.6. Group Membership (GMS)<br />

The group membership service (GMS) protocol in the JGroups stack maintains a list of active nodes. It<br />

handles the requests to join and leave the cluster. It also handles the SUSPECT messages sent by<br />

failure detection protocols. All nodes in the cluster, as well as any interested services like <strong>JBoss</strong> Cache<br />

or HAPartition, are notified if the group membership changes. The group membership service is<br />

configured in the pbcast.GMS sub-element under the JGroups config element. Here is an example<br />

configuration.<br />

<br />

The configurable attributes in the pbcast.GMS element are as follows.<br />

join_timeout specifies the maximum number of milliseconds to wait for a new node JOIN request to<br />

succeed. Retry afterwards.<br />

join_retry_timeout specifies the number of milliseconds to wait after a failed JOIN before trying<br />

again.<br />

print_local_addr specifies whether to dump the node's own address to the standard output when<br />

started.<br />

shun specifies whether a node should shun (that is, disconnect) itself if it receives a cluster view in<br />

which it is not a member node.<br />

disable_initial_coord specifies whether to prevent this node from becoming the cluster coordinator<br />

during the initial connection of the channel. This flag does not prevent a node becoming the<br />

coordinator after the initial channel connection, if the current coordinator leaves the group.


214 Chapter 25. JGroups Services<br />

view_bundling specifies whether multiple JOIN or LEAVE requests arriving at the same time are<br />

bundled and handled together at the same time, resulting in only one new view that incorporates all<br />

changes. This is is more efficient than handling each request separately.<br />

25.1.7. Flow Control (FC)<br />

The flow control (FC) protocol tries to adapt the data sending rate to the data receipt rate among nodes.<br />

If a sender node is too fast, it might overwhelm the receiver node and result in out-of-memory conditions<br />

or dropped packets that have to be retransmitted. In JGroups, flow control is implemented via a creditbased<br />

system. The sender and receiver nodes have the same number of credits (bytes) to start with.<br />

The sender subtracts credits by the number of bytes in messages it sends. The receiver accumulates<br />

credits for the bytes in the messages it receives. When the sender's credit drops to a threshold, the<br />

receivers send some credit to the sender. If the sender's credit is used up, the sender blocks until it<br />

receives credits from the receiver. The flow control protocol is configured in the FC sub-element under<br />

the JGroups config element. Here is an example configuration.<br />

<br />

The configurable attributes in the FC element are as follows.<br />

max_credits specifies the maximum number of credits (in bytes). This value should be smaller than<br />

the JVM heap size.<br />

min_credits specifies the minimum number of bytes that must be received before the receiver will<br />

send more credits to the sender.<br />

min_threshold specifies the percentage of the max_credits that should be used to calculate<br />

min_credits. Setting this overrides the min_credits attribute.<br />

ignore_synchronous_response specifies whether threads that have carried messages up to the<br />

application should be allowed to carry outgoing messages back down through FC without blocking for<br />

credits. Synchronous response refers to the fact that these messages are generally responses to<br />

incoming RPC-type messages. Forbidding JGroups threads to carry messages up to block in FC can<br />

help prevent certain deadlock scenarios, so we recommend setting this to true.<br />

Why is FC needed on top of TCP ? TCP has its own flow control!<br />

FC is required for group communication where group messages must be sent at the highest<br />

speed that the slowest receiver can handle. For example, say we have a cluster comprised of<br />

nodes A, B, C and D. D is slow (perhaps overloaded), while the rest are fast. When A sends a<br />

group message, it does so via TCP connections: A-A (theoretically), A-B, A-C and A-D.<br />

Say A sends 100 million messages to the cluster. TCP's flow control applies to A-B, A-C and A-D<br />

individually, but not to A-BCD as a group. Therefore, A, B and C will receive the 100 million<br />

messages, but D will receive only 1 million. (This is also why NAKACK is required, even though<br />

TCP handles its own retransmission.)<br />

JGroups must buffer all messages in memory in case an original sender S dies and a node<br />

requests retransmission of a message sent by S. Since all members buffer all messages that<br />

they receive, stable messages (messages seen by every node) must sometimes be purged. (The<br />

purging process is managed by the STABLE protocol. For more information, see Section 25.4,<br />

“Distributed Garbage Collection (STABLE)”.)<br />

In the above case, the slow node D will prevent the group from purging messages above 1M, so<br />

every member will buffer 99M messages ! This in most cases leads to OOM exceptions. Note that<br />

- although the sliding window protocol in TCP will cause writes to block if the window is full - we<br />

assume in the above case that this is still much faster for A-B and A-C than for A-D.<br />

So, in summary, even with TCP we need to FC to ensure we send messages at a rate the<br />

slowest receiver (D) can handle.


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 215<br />

So do I always need FC?<br />

This depends on how the application uses the JGroups channel. Referring to the example above,<br />

if there was something about the application that would naturally cause A to slow down its rate of<br />

sending because D wasn't keeping up, then FC would not be needed.<br />

A good example of such an application is one that uses JGroups to make synchronous group<br />

RPC calls. By synchronous, we mean the thread that makes the call blocks waiting for responses<br />

from all the members of the group. In that kind of application, the threads on A that are making<br />

calls would block waiting for responses from D, thus naturally slowing the overall rate of calls.<br />

A <strong>JBoss</strong> Cache cluster configured for REPL_SYNC is a good example of an application that<br />

makes synchronous group RPC calls. If a channel is only used for a cache configured for<br />

REPL_SYNC, we recommend you remove FC from its protocol stack.<br />

And, of course, if your cluster only consists of two nodes, including FC in a TCP-based protocol<br />

stack is unnecessary. There is no group beyond the single peer-to-peer relationship, and TCP's<br />

internal flow control will handle that just fine.<br />

Another case where FC may not be needed is for a channel used by a <strong>JBoss</strong> Cache configured<br />

for buddy replication and a single buddy. Such a channel will in many respects act like a two node<br />

cluster, where messages are only exchanged with one other node, the buddy. (There may be<br />

other messages related to data gravitation that go to all members, but in a properly engineered<br />

buddy replication use case these should be infrequent. But if you remove FC be sure to load test<br />

your application.)<br />

25.2. Fragmentation (FRAG2)<br />

This protocol fragments messages that are larger than a certain size, and reassembles them at the<br />

receiver's side. It works for both unicast and multicast messages. It is configured with the FRAG2 subelement<br />

in the JGroups config element. Here is an example configuration:<br />

<br />

The configurable attributes in the FRAG2 element are as follows.<br />

frag_size specifies the maximum message size (in bytes) before fragmentation occurs. Messages<br />

larger than this size are fragmented. For stacks that use the UDP transport, this value must be lower<br />

than 64 kilobytes (the maximum UDP datagram size). For TCP-based stacks, it must be lower than<br />

the value of max_credits in the FC protocol.<br />

Note<br />

TCP protocol already provides fragmentation, but a JGroups fragmentation protocol is still<br />

required if FC is used. The reason for this is that if you send a message larger than<br />

FC.max_credits, the FC protocol will block forever. So, frag_size within FRAG2 must always<br />

be set to a value lower than that of FC.max_credits.<br />

25.3. State Transfer<br />

The state transfer service transfers the state from an existing node (i.e., the cluster coordinator) to a<br />

newly joining node. It is configured in the pbcast.STATE_TRANSFER sub-element under the JGroups<br />

Config element. It does not have any configurable attribute. Here is an example configuration.<br />

<br />

25.4. Distributed Garbage Collection (STABLE)<br />

In a JGroups cluster, all nodes must store all messages received for potential retransmission in case of<br />

a failure. However, if we store all messages forever, we will run out of memory. The distributed garbage<br />

collection service periodically purges messages that have been seen by all nodes, removing them from<br />

the memory in each node. The distributed garbage collection service is configured in the


216 Chapter 25. JGroups Services<br />

pbcast.STABLE sub-element under the JGroups config element. Here is an example configuration.<br />

<br />

The configurable attributes in the pbcast.STABLE element are as follows.<br />

desired_avg_gossip specifies intervals (in milliseconds) of garbage collection runs. Set this to 0 to<br />

disable interval-based garbage collection.<br />

max_bytes specifies the maximum number of bytes received before the cluster triggers a garbage<br />

collection run. Set to 0 to disable garbage collection based on the bytes received.<br />

stability_delay specifies the maximum time period (in milliseconds) of a random delay introduced<br />

before a node sends its STABILITY message at the end of a garbage collection run. The delay<br />

gives other nodes concurrently running a STABLE task a chance to send first. If used together with<br />

max_bytes, this attribute should be set to a small number.<br />

Note<br />

Set the max_bytes attribute when you have a high traffic cluster.<br />

25.5. Merging (MERGE2)<br />

When a network error occurs, the cluster might be partitioned into several different partitions. JGroups<br />

has a MERGE service that allows the coordinators in partitions to communicate with each other and form<br />

a single cluster back again. The merging service is configured in the MERGE2 sub-element under the<br />

JGroups Config element. Here is an example configuration.<br />

<br />

The configurable attributes in the MERGE2 element are as follows.<br />

max_interval specifies the maximum number of milliseconds to wait before sending a MERGE<br />

message.<br />

min_interval specifies the minimum number of milliseconds to wait before sending a MERGE<br />

message.<br />

JGroups chooses a random value between min_interval and max_interval to periodically send<br />

the MERGE message.<br />

Note<br />

The application state maintained by the application using a channel is not merged by JGroups<br />

during a merge. This must be done by the application.<br />

Note<br />

If MERGE2 is used in conjunction with TCPPING, the initial_hosts attribute must contain all<br />

the nodes that could potentially be merged back, in order for the merge process to work properly.<br />

Otherwise, the merge process may not detect all sub-groups, and may miss those comprised<br />

solely of unlisted members.<br />

25.6. Other Configuration Issues<br />

25.6.1. Binding JGroups Channels to a Particular Interface<br />

In the Transport Protocols section above, we briefly touched on how the interface to which JGroups will


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 217<br />

bind sockets is configured. Let's get into this topic in more depth:<br />

First, it is important to understand that the value set in any bind_addr element in an XML configuration<br />

file will be ignored by JGroups if it finds that the system property jgroups.bind_addr (or a<br />

deprecated earlier name for the same thing, bind.address) has been set. The system property has a<br />

higher priority level than the XML property. If <strong>JBoss</strong> <strong>Application</strong> Server is started with the -b (or --host)<br />

switch, the application server will set jgroups.bind_addr to the specified value. If -b is not set, the<br />

application server will bind most services to localhost by default.<br />

So, what are best practices for managing how JGroups binds to interfaces?<br />

Binding JGroups to the same interface as other services. Simple, just use -b:<br />

./run.sh -b 192.168.1.100 -c all<br />

Binding services (e.g., <strong>JBoss</strong> Web) to one interface, but use a different one for JGroups:<br />

./run.sh -b 10.0.0.100 -Djgroups.bind_addr=192.168.1.100 -c all<br />

Specifically setting the system property overrides the -b value. This is a common usage pattern; put<br />

client traffic on one network, with intra-cluster traffic on another.<br />

Binding services (e.g., <strong>JBoss</strong> Web) to all interfaces. This can be done like this:<br />

./run.sh -b 0.0.0.0 -c all<br />

However, doing this will not cause JGroups to bind to all interfaces! Instead , JGroups will bind to the<br />

machine's default interface. See the Transport Protocols section for how to tell JGroups to receive or<br />

send on all interfaces, if that is what you really want.<br />

Binding services (e.g., <strong>JBoss</strong> Web) to all interfaces, but specify the JGroups interface:<br />

./run.sh -b 0.0.0.0 -Djgroups.bind_addr=192.168.1.100 -c all<br />

Again, specifically setting the system property overrides the -b value.<br />

Using different interfaces for different channels:<br />

./run.sh -b 10.0.0.100 -Djgroups.ignore.bind_addr=true -c all<br />

This setting tells JGroups to ignore the jgroups.bind_addr system property, and instead use<br />

whatever is specfied in XML. You would need to edit the various XML configuration files to set the<br />

various bind_addr attributes to the desired interfaces.<br />

25.6.2. Isolating JGroups Channels<br />

Within <strong>JBoss</strong> <strong>Application</strong> Server, there are a number of services that independently create JGroups<br />

channels — possibly multiple different <strong>JBoss</strong> Cache services (used for HttpSession replication, EJB3<br />

stateful session bean replication and EJB3 entity replication), two <strong>JBoss</strong> Messaging channels, and<br />

HAPartition, the general purpose clustering service that underlies most other <strong>JBoss</strong>HA services.<br />

It is critical that these channels only communicate with their intended peers; not with the channels used<br />

by other services and not with channels for the same service opened on machines not meant to be part<br />

of the group. Nodes improperly communicating with each other is one of the most common issues users<br />

have with <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> clustering.<br />

Whom a JGroups channel will communicate with is defined by its group name and, for UDP-based<br />

channels, its multicast address and port. Isolating a JGroups channel means ensuring that different<br />

channels use different values for the group name, the multicast address and, in some cases, the<br />

multicast port.<br />

25.6.2.1. Isolating sets of <strong>Application</strong> Server instances from each other<br />

This section addresses the issue of having multiple independent clusters running within the same<br />

environment. For example, you might have a production cluster, a staging cluster, and a QA cluster, or<br />

multiple clusters in a QA test lab or development team environment.<br />

To isolate JGroups clusters from other clusters on the network, you must:<br />

Make sure the channels in the various clusters use different group names. This can be controlled


218 Chapter 25. JGroups Services<br />

with the command line arguments used to start <strong>JBoss</strong>; see Section 25.6.2.2.1, “Changing the Group<br />

Name” for more information.<br />

Make sure the channels in the various clusters use different multicast addresses. This is also easy<br />

to control with the command line arguments used to start <strong>JBoss</strong>.<br />

If you are not running on Linux, Windows, Solaris or HP-UX, you may also need to ensure that the<br />

channels in each cluster use different multicast ports. This is more difficult than using different group<br />

names, although it can still be controlled from the command line. See Section 25.6.2.2.3, “Changing<br />

the Multicast Port”. Note that using different ports should not be necessary if your servers are<br />

running on Linux, Windows, Solaris or HP-UX.<br />

25.6.2.2. Isolating Channels for Different Services on the Same Set of AS Instances<br />

This section addresses the usual case: a cluster of three machines, each of which has, for example, an<br />

HAPartition deployed alongside <strong>JBoss</strong> Cache for web session clustering. The HAPartition channels<br />

should not communicate with the <strong>JBoss</strong> Cache channels. Ensuring proper isolation of these channels is<br />

straightforward, and is usually handled by the application server without any alterations on the part of<br />

the user.<br />

To isolate channels for different services from each other on the same set of application server<br />

instances, each channel must have its own group name. The configurations that ship with <strong>JBoss</strong><br />

<strong>Application</strong> Server ensure that this is the case. However, if you create a custom service that uses<br />

JGroups directly, you must use a unique group name. If you create a custom <strong>JBoss</strong> Cache configuration,<br />

ensure that you provide a unique value in the clusterName configuration property.<br />

In releases prior to <strong>JBoss</strong> <strong>Application</strong> Server 5, different channels running in the same application server<br />

also had to use unique multicast ports. With the JGroups shared transport introduced in <strong>JBoss</strong> AS 5<br />

(see Section 18.1.2, “The JGroups Shared Transport”), it is now common for multiple channels to use<br />

the same tranpsort protocol and its sockets. This makes configuration easier, which is one of the main<br />

benefits of the shared transport. However, if you decide to create your own custom JGroups protocol<br />

stack configuration, be sure to configure its transport protocols with a multicast port that is different from<br />

the ports used in other protocol stacks.<br />

25.6.2.2.1. Changing the Group Name<br />

The group name for a JGroups channel is configured via the service that starts the channel. For all the<br />

standard clustered services, we make it easy for you to create unique groups names by simply using the<br />

-g (or --partition) switch when starting <strong>JBoss</strong>:<br />

./run.sh -g QAPartition -b 192.168.1.100 -c all<br />

This switch sets the jboss.partition.name system property, which is used as a component in the<br />

configuration of the group name in all the standard clustering configuration files. For example,<br />

${jboss.partition.name:DefaultPartition}-<br />

SFSBCache<br />

25.6.2.2.2. Changing the multicast address and port<br />

The -u (or --udp) command line switch may be used to control the multicast address used by the<br />

JGroups channels opened by all standard AS services.<br />

/run.sh -u 230.1.2.3 -g QAPartition -b 192.168.1.100 -c all<br />

This switch sets the jboss.partition.udpGroup system property, which is referenced in all of the<br />

standard protocol stack configurations in <strong>JBoss</strong> AS:<br />


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 219<br />

25.6.2.2.3. Changing the Multicast Port<br />

On some operating systems (Mac OS X for example), using different -g and -u values is not sufficient to<br />

isolate clusters; the channels running in the different clusters must also use different multicast ports.<br />

Unfortunately, setting the multicast ports is not as simple as -g and -u. By default, a <strong>JBoss</strong> AS instance<br />

running the all configuration will use up to two different instances of the JGroups UDP transport<br />

protocol, and will therefore open two multicast sockets. You can control the ports those sockets use by<br />

using system properties on the command line. For example,<br />

/run.sh -u 230.1.2.3 -g QAPartition -b 192.168.1.100 -c all \\<br />

-Djboss.jgroups.udp.mcast_port=12345 -<br />

Djboss.messaging.datachanneludpport=23456<br />

The jboss.messaging.datachanneludpport property controls the multicast port used by the<br />

MPING protocol in <strong>JBoss</strong> Messaging's DATA channel. The jboss.jgroups.udp.mcast_port<br />

property controls the multicast port used by the UDP transport protocol shared by all other clustered<br />

services.<br />

The set of JGroups protocol stack configurations included in the<br />

$JBOSS_HOME/server/all/deploy/cluster/jgroups-channelfactory.sar/META-<br />

INF/jgroups-channelfactory-stacks.xml file includes a number of other example protocol<br />

stack configurations that the standard <strong>JBoss</strong> AS distribution doesn't actually use. Those configurations<br />

also use system properties to set any multicast ports. So, if you reconfigure some AS service to use one<br />

of those protocol stack configurations, use the appropriate system property to control the port from the<br />

command line.<br />

Why do I need to change the multicast port if I change the address?<br />

It should be sufficient to just change the address, but unfortunately the handling of multicast<br />

sockets is one area where the JVM fails to hide operating system behavior differences from the<br />

application. The java.net.MulticastSocket class provides different overloaded<br />

constructors. On some operating systems, if you use one constructor variant, packets addressed<br />

to a particular multicast port are delivered to all listeners on that port, regardless of the multicast<br />

address on which they are listening. We refer to this as the promiscuous traffic problem. On most<br />

operating systems that exhibit the promiscuous traffic problem (Linux, Solaris and HP-UX)<br />

JGroups can use a different constructor variant that avoids the problem. However, on some<br />

operating systems with the promiscuous traffic problem (Mac OS X), multicast does not work<br />

properly if the other constructor variant is used. So, on these operating systems the<br />

recommendation is to configure different multicast ports for different clusters.<br />

25.6.2.3. Improving UDP Performance by Configuring OS UDP Buffer Limits<br />

By default, the JGroups channels in <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> use the UDP transport<br />

protocol to take advantage of IP multicast. However, one disadvantage of UDP is it does not come with<br />

the reliable delivery guarantees provided by TCP. The protocols discussed in Section 25.1.5, “Reliable<br />

Delivery Protocols” allow JGroups to guarantee delivery of UDP messages, but those protocols are<br />

implemented in Java, not at the operating system network layer. For peak performance from a UDPbased<br />

JGroups channel it is important to limit the need for JGroups to retransmit messages by limiting<br />

UDP datagram loss.<br />

One of the most common causes of lost UDP datagrams is an undersized receive buffer on the socket.<br />

The UDP protocol's mcast_recv_buf_size and ucast_recv_buf_size configuration attributes are<br />

used to specify the amount of receive buffer JGroups requests from the operating system, but the actual<br />

size of the buffer the operating system provides is limited by operating system-level maximums. These<br />

maximums are often very low:


220 Chapter 25. JGroups Services<br />

Table 25.1. Default Max UDP Buffer Sizes<br />

Operating System Default Max UDP Buffer (in bytes)<br />

Linux 131071<br />

Windows No known limit<br />

Solaris 262144<br />

FreeBSD, Darwin 262144<br />

AIX 1048576<br />

The command used to increase the above limits is operating system-specific. The table below shows<br />

the command required to increase the maximum buffer to 25 megabytes. In all cases, root privileges are<br />

required:<br />

Table 25.2. Commands to Change Max UDP Buffer Sizes<br />

Operating System Command<br />

Linux sysctl -w net.core.rmem_max=26214400<br />

Solaris ndd -set /dev/udp udp_max_buf<br />

26214400<br />

FreeBSD, Darwin sysctl -w<br />

kern.ipc.maxsockbuf=26214400<br />

AIX no -o sb_max=8388608 (AIX will only allow 1<br />

megabyte, 4 megabytes or 8 megabytes).<br />

25.6.3. JGroups Troubleshooting<br />

25.6.3.1. Nodes do not form a cluster<br />

Make sure your machine is set up correctly for IP multicast. There are 2 test programs that can be used<br />

to detect this: McastReceiverTest and McastSenderTest. Go to the $JBOSS_HOME/server/all/lib<br />

directory and start McastReceiverTest, for example:<br />

[lib]$ java -cp jgroups.jar org.jgroups.tests.McastReceiverTest -mcast_addr<br />

224.10.10.10 -port 5555<br />

Then in another window start McastSenderTest:<br />

[lib]$ java -cp jgroups.jar org.jgroups.tests.McastSenderTest -mcast_addr<br />

224.10.10.10 -port 5555<br />

If you want to bind to a specific network interface card (NIC), use -bind_addr 192.168.0.2, where<br />

192.168.0.2 is the IP address of the NIC to which you want to bind. Use this parameter in both the<br />

sender and the receiver.<br />

You should be able to type in the McastSenderTest window and see the output in the<br />

McastReceiverTest window. If not, try to use -ttl 32 in the sender. If this still fails, consult a<br />

system administrator to help you setup IP multicast correctly, and ask the admin to make sure that<br />

multicast will work on the interface you have chosen or, if the machines have multiple interfaces, ask to<br />

be told the correct interface. Once you know multicast is working properly on each machine in your<br />

cluster, you can repeat the above test to test the network, putting the sender on one machine and the<br />

receiver on another.<br />

25.6.3.2. Causes of missing heartbeats in FD<br />

Sometimes a member is suspected by FD because a heartbeat ack has not been received for some time<br />

T (defined by timeout and max_tries). This can have multiple reasons, e.g. in a cluster of A,B,C,D; C can<br />

be suspected if (note that A pings B, B pings C, C pings D and D pings A):<br />

B or C are running at 100% CPU for more than T seconds. So even if C sends a heartbeat ack to B,<br />

B may not be able to process it because it is at 100%<br />

B or C are garbage collecting, same as above.<br />

A combination of the 2 cases above


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 221<br />

The network loses packets. This usually happens when there is a lot of traffic on the network, and<br />

the switch starts dropping packets (usually broadcasts first, then IP multicasts, TCP packets last).<br />

B or C are processing a callback. Let's say C received a remote method call over its channel and<br />

takes T+1 seconds to process it. During this time, C will not process any other messages, including<br />

heartbeats, and therefore B will not receive the heartbeat ack and will suspect C.


222 Chapter 26. <strong>JBoss</strong> Cache Configuration and Deployment<br />

Chapter 26. <strong>JBoss</strong> Cache Configuration and Deployment<br />

<strong>JBoss</strong> Cache provides the underlying distributed caching support used by many of the standard<br />

clustered services in a <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> cluster. You can also deploy <strong>JBoss</strong> Cache<br />

in your own application to handle custom caching requirements. In this chapter we provide some<br />

background on the main configuration options available with <strong>JBoss</strong> Cache, with an emphasis on how<br />

those options relate to the <strong>JBoss</strong> Cache usage by the standard clustered services the <strong>Enterprise</strong><br />

<strong>Application</strong> <strong>Platform</strong> provides. We then discuss the different options available for deploying a custom<br />

cache in the <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>.<br />

Users considering deploying <strong>JBoss</strong> Cache for direct use by their own application are strongly<br />

encouraged to read the <strong>JBoss</strong> Cache documentation available at the Red Hat Documentation portal.<br />

See also Section 18.2, “Distributed Caching with <strong>JBoss</strong> Cache” for information on how the standard<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> clustered services use <strong>JBoss</strong> Cache.<br />

26.1. Key <strong>JBoss</strong> Cache Configuration Options<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> ships with a reasonable set of default <strong>JBoss</strong> Cache<br />

configurations that are suitable for the standard clustered service use cases (e.g. web session<br />

replication or JPA/Hibernate caching). Most applications that involve the standard clustered services just<br />

work out of the box with the default configurations. You only need to tweak them when you are deploying<br />

an application that has special network or performance requirements. In this section we provide a brief<br />

overview of some of the key configuration choices. This is by no means a complete discussion; for full<br />

details users interested in moving beyond the default configurations are encouraged to read the <strong>JBoss</strong><br />

Cache documentation available at http://www.redhat.com/docs/en-<br />

US/<strong>JBoss</strong>_<strong>Enterprise</strong>_<strong>Application</strong>_<strong>Platform</strong>/.<br />

Most <strong>JBoss</strong> Cache configuration examples in this section use the <strong>JBoss</strong> Microcontainer schema for<br />

building up an org.jboss.cache.config.Configuration object graph from XML. <strong>JBoss</strong> Cache<br />

has its own custom XML schema, but the standard <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> CacheManager<br />

service uses the <strong>JBoss</strong> Microcontainer schema to be consistent with most other internal <strong>Enterprise</strong><br />

<strong>Application</strong> <strong>Platform</strong> services.<br />

Before getting into the key configuration options, let's have a look at the most likely place that a user<br />

would encounter them.<br />

26.1.1. Editing the CacheManager Configuration<br />

As discussed in Section 18.2.1, “The <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> CacheManager Service”, the<br />

standard <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> clustered services use the CacheManager service as a<br />

factory for <strong>JBoss</strong> Cache instances. So, cache configuration changes are likely to involve edits to the<br />

CacheManager service.<br />

Note<br />

Users can also use the CacheManager as a factory for custom caches used by directly by their<br />

own applications; see Section 26.2.1, “Deployment Via the CacheManager Service”.<br />

The CacheManager is configured via the<br />

$JBOSS_HOME/server/$PROFILE/deploy/cluster/jboss-cache-manager.sar/META-<br />

INF/jboss-cache-manager-jboss-beans.xml file. The element most likely to be edited is the<br />

"CacheConfigurationRegistry" bean, which maintains a registry of all the named JBC configurations the<br />

CacheManager knows about. Most edits to this file would involve adding a new <strong>JBoss</strong> Cache<br />

configuration or changing a property of an existing one.<br />

The following is a redacted version of the "CacheConfigurationRegistry" bean configuration:


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 223<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

standard-session-cache<br />

<br />

<br />

<br />

<br />

org.jboss.cache.transaction.BatchModeTransactionManagerLookup<br />

<br />

<br />

${jboss.partition.name:DefaultPartition}-<br />

SessionCache<br />

<br />

${jboss.default.jgroups.stack:udp}<br />

true<br />

PESSIMISTIC<br />

REPEATABLE_READ<br />

REPL_ASYNC<br />

.... more details of the standard-session-cache configuration<br />

<br />

<br />

<br />

<br />

field-granularity-session-cache<br />

<br />

<br />

.... details of the field-granularity-standard-session-cache<br />

configuration<br />

<br />

<br />

<br />

... entry elements for the other configurations<br />

<br />

<br />

<br />

The actual <strong>JBoss</strong> Cache configurations are specified using the <strong>JBoss</strong> Microcontainer's schema rather<br />

than one of the standard <strong>JBoss</strong> Cache configuration formats. When <strong>JBoss</strong> Cache parses one of its<br />

standard configuration formats, it creates a Java Bean of type<br />

org.jboss.cache.config.Configuration with a tree of child Java Beans for some of the more<br />

complex sub-configurations (i.e. cache loading, eviction, buddy replication). Rather than delegating this


224 Chapter 26. <strong>JBoss</strong> Cache Configuration and Deployment<br />

task of XML parsing/Java Bean creation to JBC, we let the <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>'s<br />

microcontainer do it directly. This has the advantage of making the microcontainer aware of the<br />

configuration beans, which in later <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5.x releases will be helpful in allowing<br />

external management tools to manage the JBC configurations.<br />

The configuration format should be fairly self-explanatory if you look at the standard configurations the<br />

<strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> ships; they include all the major elements. The types and properties of<br />

the various java beans that make up a <strong>JBoss</strong> Cache configuration can be seen in the <strong>JBoss</strong> Cache<br />

Javadocs. Here is a fairly complete example:


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 225<br />

<br />

<br />

<br />

${jboss.partition.name:DefaultPartition}-<br />

SFSBCache<br />

<br />

${jboss.default.jgroups.stack:udp}<br />

true<br />

PESSIMISTIC<br />

REPEATABLE_READ<br />

REPL_ASYNC<br />

false<br />

<br />

17500<br />

<br />

15000<br />

<br />

60000<br />

<br />

false<br />

<br />

false<br />

<br />

0<br />

<br />

0<br />

true<br />

<br />

<br />

<br />

false<br />

<br />

default<br />

17500<br />

<br />

false<br />

true<br />

true<br />

<br />

<br />

<br />

1<br />

<br />

true<br />

<br />

<br />


226 Chapter 26. <strong>JBoss</strong> Cache Configuration and Deployment<br />

<br />

<br />

<br />

<br />

<br />

true<br />

false<br />

<br />

<br />

<br />

<br />

${jboss.server.data.dir}${/}sfsb<br />

<br />

false<br />

true<br />

true<br />

false<br />

false<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

5000<br />

<br />

<br />

<br />

/<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Basically, the XML specifies the creation of an org.jboss.cache.config.Configuration java<br />

bean and the setting of a number of properties on that bean. Most of the properties are of simple types,<br />

but some, such as buddyReplicationConfig and cacheLoaderConfig take various types java<br />

beans as their values.<br />

Next we'll look at some of the key configuration options.<br />

26.1.2. Cache Mode<br />

<strong>JBoss</strong> Cache's cacheMode configuration attribute combines into a single property two related aspects:<br />

Handling of Cluster Updates<br />

This controls how a cache instance on one node should notify the rest of the cluster when it makes<br />

changes in its local state. There are three options:<br />

Synchronous means the cache instance sends a message to its peers notifying them of the<br />

change(s) and before returning waits for them to acknowledge that they have applied the same<br />

changes. If the changes are made as part of a JTA transaction, this is done as part of a two-phase<br />

commit process during transaction commit. Any locks are held until this acknowledgment is received.<br />

Waiting for acknowledgement from all nodes adds delays, but it ensures consistency around the<br />

cluster. Synchronous mode is needed when all the nodes in the cluster may access the cached data<br />

resulting in a high need for consistency.<br />

Asynchronous means the cache instance sends a message to its peers notifying them of the<br />

change(s) and then immediately returns, without any acknowledgement that they have applied the<br />

same changes. It does not mean sending the message is handled by some other thread besides the


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 227<br />

one that changed the cache content; the thread that makes the change still spends some time<br />

dealing with sending messages to the cluster, just not as much as with synchronous communication.<br />

Asynchronous mode is most useful for cases like session replication, where the cache doing the<br />

sending expects to be the only one that accesses the data and the cluster messages are used to<br />

provide backup copies in case of failure of the sending node. Asynchronous messaging adds a small<br />

risk that a later user request that fails over to another node may see out-of-date state, but for many<br />

session-type applications this risk is acceptable given the major performance benefits asynchronous<br />

mode has over synchronous mode.<br />

Local means the cache instance doesn't send a message at all. A JGroups channel isn't even used<br />

by the cache. <strong>JBoss</strong> Cache has many useful features besides its clustering capabilities and is a very<br />

useful caching library even when not used in a cluster. Also, even in a cluster, some cached data<br />

does not need to be kept consistent around the cluster, in which case Local mode will improve<br />

performance. Caching of JPA/Hibernate query result sets is an example of this; Hibernate's second<br />

level caching logic uses a separate mechanism to invalidate stale query result sets from the second<br />

level cache, so <strong>JBoss</strong> Cache doesn't need to send messages around the cluster for a query result<br />

set cache.<br />

Replication vs. Invalidation<br />

This aspect deals with the content of messages sent around the cluster when a cache changes its local<br />

state, i.e. what should the other caches in the cluster do to reflect the change:<br />

Replication means the other nodes should update their state to reflect the new state on the<br />

sending node. This means the sending node needs to include the changed state, increasing the cost<br />

of the message. Replication is necessary if the other nodes have no other way to obtain the state.<br />

Invalidation means the other nodes should remove the changed state from their local state.<br />

Invalidation reduces the cost of the cluster update messages, since only the cache key of the<br />

changed state needs to be transmitted, not the state itself. However, it is only an option if the<br />

removed state can be retrieved from another source. It is an excellent option for a clustered<br />

JPA/Hibernate entity cache, since the cached state can be re-read from the database.<br />

These two aspects combine to form 5 valid values for the cacheMode configuration attribute:<br />

LOCAL means no cluster messages are needed.<br />

REPL_SYNC means synchronous replication messages are sent.<br />

REPL_ASYNC means asynchronous replication messages are sent.<br />

INVALIDATION_SYNC means synchronous invalidation messages are sent.<br />

INVALIDATION_ASYNC means asynchronous invalidation messages are sent.<br />

26.1.3. Transaction Handling<br />

<strong>JBoss</strong> Cache integrates with JTA transaction managers to allow transactional access to the cache.<br />

When <strong>JBoss</strong> Cache detects the presence of a transaction, any locks are held for the life of the<br />

transaction, changes made to the cache will be reverted if the transaction rolls back, and any clusterwide<br />

messages sent to inform other nodes of changes are deferred and sent in a batch as part of<br />

transaction commit (reducing chattiness).<br />

Integration with a transaction manager is accomplished by setting the<br />

transactionManagerLookupClass configuration attribute; this specifies the fully qualified class<br />

name of a class <strong>JBoss</strong> Cache can use to find the local transaction manager. Inside <strong>JBoss</strong> <strong>Enterprise</strong><br />

<strong>Application</strong> <strong>Platform</strong>, this attribute would have one of two values:<br />

org.jboss.cache.transaction.<strong>JBoss</strong>TransactionManagerLookup<br />

This finds the standard transaction manager running in the application server. Use this for any<br />

custom caches you deploy where you want caching to participate in any JTA transactions.<br />

org.jboss.cache.transaction.BatchModeTransactionManagerLookup<br />

This is used in the cache configurations used for web session and EJB SFSB caching. It specifies a<br />

simple mock TransactionManager that ships with <strong>JBoss</strong> Cache called the<br />

BatchModeTransactionManager. This transaction manager is not a true JTA transaction<br />

manager and should not be used for anything other than <strong>JBoss</strong> Cache. Its usage in <strong>JBoss</strong><br />

<strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> is to get most of the benefits of <strong>JBoss</strong> Cache's transactional behavior<br />

for the session replication use cases, but without getting tangled up with end user transactions that<br />

may run during a request.<br />

26.1.4 . Concurrent Access


228 Chapter 26. <strong>JBoss</strong> Cache Configuration and Deployment<br />

<strong>JBoss</strong> Cache is a thread safe caching API, and uses its own efficient mechanisms of controlling<br />

concurrent access. Concurrency is configured via the nodeLockingScheme and isolationLevel<br />

configuration attributes.<br />

There are three choices for nodeLockingScheme:<br />

MVCC or multi-version concurrency control, is a locking scheme commonly used by modern<br />

database implementations to control fast, safe concurrent access to shared data. <strong>JBoss</strong> Cache 3.x<br />

uses an innovative implementation of MVCC as the default locking scheme. MVCC is designed to<br />

provide the following features for concurrent access:<br />

Readers that don't block writers<br />

Writers that fail fast<br />

It achieves this by using data versioning and copying for concurrent writers. The theory is that<br />

readers continue reading shared state, while writers copy the shared state, increment a version id,<br />

and write that shared state back after verifying that the version is still valid (i.e., another concurrent<br />

writer has not changed this state first).<br />

MVCC is the recommended choice for JPA/Hibernate entity caching.<br />

PESSIMISTIC locking involves threads/transactions acquiring either exclusive or non-exclusive<br />

locks on nodes before reading or writing. Which is acquired depends on the isolationLevel (see<br />

below) but in most cases a non-exclusive lock is acquired for a read and an exclusive lock is<br />

acquired for a write. Pessimistic locking requires considerably more overhead than MVCC and allows<br />

lesser concurrency, since reader threads must block until a write has completed and released its<br />

exclusive lock (potentially a long time if the write is part of a transaction). A write will also be delayed<br />

due to ongoing reads.<br />

Generally MVCC is a better choice than PESSIMISTIC, which is deprecated as of <strong>JBoss</strong> Cache 3.0.<br />

But, for the session caching usage in <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5.0.0, PESSIMISTIC is<br />

still the default. This is largely because for the session use case there are generally not concurrent<br />

threads accessing the same cache location, so the benefits of MVCC are not as great.<br />

OPTIMISTIC locking seeks to improve upon the concurrency available with PESSIMISTIC by creating<br />

a "workspace" for each request/transaction that accesses the cache. Data accessed by the<br />

request/transaction (even reads) is copied into the workspace, which is adds overhead. All data is<br />

versioned; on completion of non-transactional requests or commits of transactions the version of<br />

data in the workspace is compared to the main cache, and an exception is raised if there are are<br />

inconsistencies. Otherwise changes to the workspace are applied to the main cache.<br />

OPTIMISTIC locking is deprecated but is still provided to support backward compatibility. Users are<br />

encouraged to use MVCC instead, which provides the same benefits at lower cost.<br />

The isolationLevel attribute has two possible values READ_COMMITTED and<br />

REPEATABLE_READ which correspond in semantic to database-style isolation levels. Previous<br />

versions of <strong>JBoss</strong> Cache supported all 5 database isolation levels, and if an unsupported isolation level<br />

is configured, it is either upgraded or downgraded to the closest supported level.<br />

REPEATABLE_READ is the default isolation level, to maintain compatibility with previous versions of<br />

<strong>JBoss</strong> Cache. READ_COMMITTED, while providing a slightly weaker isolation, has a significant<br />

performance benefit over REPEATABLE_READ.<br />

26.1.5. JGroups Integration<br />

Each <strong>JBoss</strong> Cache instance internally uses a JGroups Channel to handle group communications.<br />

Inside <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>, we strongly recommend that you use the <strong>Enterprise</strong><br />

<strong>Application</strong> <strong>Platform</strong>'s JGroups Channel Factory service as the source for your cache's Channel. In this<br />

section we discuss how to configure your cache to get it's channel from the Channel Factory; if you wish<br />

to configure the channel in some other way see the <strong>JBoss</strong> Cache documentation.<br />

Caches obtained from the CacheManager Service<br />

This is the simplest approach. The CacheManager service already has a reference to the Channel<br />

Factory service, so the only configuration task is to configure the name of the JGroups protocol stack<br />

configuration to use.<br />

If you are configuring your cache via the CacheManager service's jboss-cache-manager-jbossbeans.xml<br />

file (see Section 26.2.1, “Deployment Via the CacheManager Service”), add the following to<br />

your cache configuration, where the value is the name of the protocol stack configuration.:


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 229<br />

Caches Deployed via a -jboss-beans.xml File<br />

If you are deploying a cache via a <strong>JBoss</strong> Microcontainer -jboss-beans.xml file (see Section 26.2.3,<br />

“Deployment Via a -jboss-beans.xml File”), you need inject a reference to the Channel Factory<br />

service as well as specifying the protocol stack configuration:<br />

<br />

<br />

<br />

<br />

<br />

udp<br />

Caches Deployed via a -service.xml File<br />

If you are deploying a cache MBean via -service.xml file (see Section 26.2.2, “Deployment Via a -<br />

service.xml File”), CacheJmxWrapper is the class of your MBean; that class exposes a<br />

MuxChannelFactory MBean attribute. You dependency inject the Channel Factory service into this<br />

attribute, and set the protocol stack name via the MultiplexerStack attribute:<br />

<br />

udp<br />

26.1.6. Eviction<br />

Eviction allows the cache to control memory by removing data (typically the least frequently used data). If<br />

you wish to configure eviction for a custom cache, see the <strong>JBoss</strong> Cache documentation for all of the<br />

available options. For details on configuring it for JPA/Hibernate caching, see the Eviction chapter in the<br />

"Using <strong>JBoss</strong> Cache as a Hibernate Second Level Cache" guide at<br />

http://www.jboss.org/jbossclustering/docs/hibernate-jbosscache-guide-3.pdf. For web session caches,<br />

eviction should not be configured; the distributable session manager handles eviction itself. For EJB 3<br />

SFSB caches, stick with the eviction configuration in the <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>'s standard<br />

sfsb-cache configuration (see Section 18.2.1, “The <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong><br />

CacheManager Service”). The EJB container will configure eviction itself using the values included in<br />

each bean's configuration.<br />

26.1.7. Cache Loaders<br />

Cache loading allows <strong>JBoss</strong> Cache to store data in a persistent store in addition to what it keeps in<br />

memory. This data can either be an overflow, where the data in the persistent store is not reflected in<br />

memory. Or it can be a superset of what is in memory, where everything in memory is also reflected in<br />

the persistent store, along with items that have been evicted from memory. Which of these two modes is<br />

used depends on the setting of the passivation flag in the <strong>JBoss</strong> Cache cache loader configuration<br />

section. A true value means the persistent store acts as an overflow area written to when data is<br />

evicted from the in-memory cache.<br />

If you wish to configure cache loading for a custom cache, see the <strong>JBoss</strong> Cache documentation for all of<br />

the available options. Do not configure cache loading for a JPA/Hibernate cache, as the database itself<br />

serves as a persistent store; adding a cache loader is just redundant.<br />

The caches used for web session and EJB3 SFSB caching use passivation. Next we'll discuss the<br />

cache loader configuration for those caches in some detail.<br />

26.1.7.1. CacheLoader Configuration for Web Session and SFSB Caches<br />

HttpSession and SFSB passivation rely on <strong>JBoss</strong> Cache's Cache Loader passivation for storing and<br />

retrieving the passivated sessions. Therefore the cache instance used by your webapp's clustered<br />

session manager or your bean's EJB container must be configured to enable Cache Loader passivaton.<br />

In most cases you don't need to do anything to alter the cache loader configurations for the standard<br />

web session and SFSB caches; the standard <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> configurations<br />

should suit your needs. The following is a bit more detail in case you're interested or want to change<br />

from the defaults.<br />

The Cache Loader configuration for the standard-session-cache config serves as a good example:


230 Chapter 26. <strong>JBoss</strong> Cache Configuration and Deployment<br />

<br />

<br />

<br />

true<br />

false<br />

<br />

<br />

<br />

<br />

${jboss.server.data.dir}${/}session<br />

<br />

false<br />

true<br />

true<br />

false<br />

false<br />

<br />

<br />

<br />

<br />

<br />

Some explanation:<br />

passivation property MUST be true<br />

shared property MUST be false. Do not passivate sessions to a shared persistent store,<br />

otherwise if another node activates the session, it will be gone from the persistent store and also<br />

gone from memory on other nodes that have passivated it. Backup copies will be lost.<br />

individualCacheLoaderConfigs property accepts a list of Cache Loader configurations. JBC<br />

allows you to chain cache loaders; see the <strong>JBoss</strong> Cache docs. For the session passivation use case<br />

a single cache loader is sufficient.<br />

class attribute on a cache loader config bean must refer to the configuration class for a cache loader<br />

implementation (e.g. org.jboss.cache.loader.FileCacheLoaderConfig or<br />

org.jboss.cache.loader.JDBCCacheLoaderConfig). See the <strong>JBoss</strong> Cache documentation<br />

for more on the available CacheLoader implementations. If you wish to use JDBCCacheLoader (to<br />

persist to a database rather than the filesystem used by FileCacheLoader) note the comment above<br />

about the shared property. Don't use a shared database, or at least not a shared table in the<br />

database. Each node in the cluster must have its own storage location.<br />

location property for FileCacheLoaderConfig defines the root node of the filesystem tree where<br />

passivated sessions should be stored. The default is to store them in your <strong>JBoss</strong> <strong>Enterprise</strong><br />

<strong>Application</strong> <strong>Platform</strong> configuration's data directory.<br />

async MUST be false to ensure passivated sessions are promptly written to the persistent store.<br />

fetchPersistentState property MUST be true to ensure passivated sessions are included in the<br />

set of session backup copies transferred over from other nodes when the cache starts.<br />

purgeOnStartup should be true to ensure out-of-date session data left over from a previous<br />

shutdown of a server doesn't pollute the current data set.<br />

ignoreModifications should be false<br />

checkCharacterPortability should be false as a minor performance optimization.<br />

26.1.8. Buddy Replication<br />

Buddy Replication is a <strong>JBoss</strong> Cache feature that allows you to suppress replicating your data to all<br />

instances in a cluster. Instead, each instance picks one or more 'buddies' in the cluster, and only<br />

replicates to those specific buddies. This greatly helps scalability as there is no longer a memory and<br />

network traffic impact every time another instance is added to a cluster.<br />

If the cache on another node needs data that it doesn't have locally, it can ask the other nodes in the<br />

cluster to provide it; nodes that have a copy will provide it as part of a process called "data gravitation".<br />

The new node will become the owner of the data, placing a backup copy of the data on its buddies. The<br />

ability to gravitate data means there is no need for all requests for data to occur on a node that has a<br />

copy of it; any node can handle a request for any data. However, data gravitation is expensive and<br />

should not be a frequent occurence; ideally it should only occur if the node that is using some data fails<br />

or is shut down, forcing interested clients to fail over to a different node. This makes buddy replication<br />

primarily useful for session-type applications with session affinity (a.k.a. "sticky sessions") where all


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 231<br />

requests for a particular session are normally handled by a single server.<br />

Buddy replication can be enabled for the web session and EJB3 SFSB caches. Do not add buddy<br />

replication to the cache configurations used for other standard clustering services (e.g. JPA/Hibernate<br />

caching). Services not specifically engineered for buddy replication are highly unlikely to work correctly if<br />

it is introduced.<br />

Configuring buddy replication is fairly straightforward. As an example we'll look at the buddy replication<br />

configuration section from the CacheManager service's standard-session-cache config:<br />

<br />

<br />

<br />

true<br />

<br />

default<br />

17500<br />

<br />

false<br />

true<br />

true<br />

<br />

<br />

<br />

1<br />

<br />

true<br />

<br />

<br />

<br />

<br />

The main things you would be likely to configure are:<br />

buddyReplicationEnabled — true if you want buddy replication; false if data should be<br />

replicated to all nodes in the cluster, in which case none of the other buddy replication configurations<br />

matter.<br />

numBuddies — to how many backup nodes should each node replicate its state.<br />

buddyPoolName — allows logical subgrouping of nodes within the cluster; if possible, buddies will<br />

be chosen from nodes in the same buddy pool.<br />

The ignoreColocatedBuddies switch means that when the cache is trying to find a buddy, it will if<br />

possible not choose a buddy on the same physical host as itself. If the only server it can find is running<br />

on its own machine, it will use that server as a buddy.<br />

Do not change the settings for autoDataGravitation, dataGravitationRemoveOnFind and<br />

dataGravitationSearchBackupTrees. Session replication will not work properly if these are<br />

changed.<br />

26.2. Deploying Your Own <strong>JBoss</strong> Cache Instance<br />

It's quite common for users to deploy their own instances of <strong>JBoss</strong> Cache inside <strong>JBoss</strong> <strong>Enterprise</strong><br />

<strong>Application</strong> <strong>Platform</strong> for custom use by their applications. In this section we describe the various ways<br />

caches can be deployed.<br />

26.2.1. Deployment Via the CacheManager Service<br />

The standard <strong>JBoss</strong> clustered services that use <strong>JBoss</strong> Cache obtain a reference to their cache from the


232 Chapter 26. <strong>JBoss</strong> Cache Configuration and Deployment<br />

<strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>'s CacheManager service (see Section 18.2.1, “The <strong>JBoss</strong> <strong>Enterprise</strong><br />

<strong>Application</strong> <strong>Platform</strong> CacheManager Service”). End user applications can do the same thing; here's how.<br />

Section 26.1.1, “Editing the CacheManager Configuration” shows the configuration of the<br />

CacheManager's "CacheConfigurationRegistry" bean. To add a new configuration, you would add an<br />

additional element inside that bean's newConfigurations :<br />

<br />

.....<br />

<br />

<br />

my-custom-cache<br />

<br />

<br />

.... details of the my-custom-cache configuration<br />

<br />

<br />

<br />

.....<br />

See Section 26.1.1, “Editing the CacheManager Configuration” for an example configuration.<br />

26.2.1.1. Accessing the CacheManager<br />

Once you've added your cache configuration to the CacheManager, the next step is to provide a<br />

reference to the CacheManager to your application. There are three ways to do this:<br />

Dependency Injection<br />

If your application uses the <strong>JBoss</strong> Microcontainer for configuration, the simplest mechanism is to<br />

have it inject the CacheManager into your service.<br />

<br />

<br />

<br />

JNDI Lookup<br />

Alternatively, you can find look up the CacheManger is JNDI. It is bound under<br />

java:CacheManager.<br />

import org.jboss.ha.cachemanager.CacheManager;<br />

public class MyService {<br />

private CacheManager cacheManager;<br />

}<br />

public void start() throws Exception {<br />

Context ctx = new InitialContext();<br />

cacheManager = (CacheManager) ctx.lookup("java:CacheManager");<br />

}<br />

CacheManagerLocator<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> also provides a service locator object that can be used to<br />

access the CacheManager.


import org.jboss.ha.cachemanager.CacheManager;<br />

import org.jboss.ha.framework.server.CacheManagerLocator;<br />

public class MyService {<br />

private CacheManager cacheManager;<br />

public void start() throws Exception {<br />

CacheManagerLocator locator =<br />

CacheManagerLocator.getCacheManagerLocator();<br />

// Locator accepts as param a set of JNDI properties to help in lookup;<br />

// this isn't necessary inside the <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong><br />

cacheManager = locator.getCacheManager(null);<br />

}<br />

}<br />

Once a reference to the CacheManager is obtained; usage is simple. Access a cache by passing in the<br />

name of the desired configuration. The CacheManager will not start the cache; this is the responsibility<br />

of the application. The cache may, however, have been started by another application running in the<br />

cache server; the cache may be shared. When the application is done using the cache, it should not<br />

stop. Just inform the CacheManager that the cache is no longer being used; the manager will stop the<br />

cache when all callers that have asked for the cache have released it.<br />

import org.jboss.cache.Cache;<br />

import org.jboss.ha.cachemanager.CacheManager;<br />

import org.jboss.ha.framework.server.CacheManagerLocator;<br />

public class MyService {<br />

private CacheManager cacheManager;<br />

private Cache cache;<br />

}<br />

public void start() throws Exception {<br />

Context ctx = new InitialContext();<br />

cacheManager = (CacheManager) ctx.lookup("java:CacheManager");<br />

}<br />

// "true" param tells the manager to instantiate the cache if<br />

// it doesn't exist yet<br />

cache = cacheManager.getCache("my-cache-config", true);<br />

cache.start();<br />

public void stop() throws Exception {<br />

cacheManager.releaseCache("my-cache-config");<br />

}<br />

The CacheManager can also be used to access instances of POJO Cache.<br />

import org.jboss.cache.pojo.PojoCache;<br />

import org.jboss.ha.cachemanager.CacheManager;<br />

import org.jboss.ha.framework.server.CacheManagerLocator;<br />

public class MyService {<br />

private CacheManager cacheManager;<br />

private PojoCache pojoCache;<br />

}<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 233<br />

public void start() throws Exception {<br />

Context ctx = new InitialContext();<br />

cacheManager = (CacheManager) ctx.lookup("java:CacheManager");<br />

}<br />

// "true" param tells the manager to instantiate the cache if<br />

// it doesn't exist yet<br />

pojoCache = cacheManager.getPojoCache("my-cache-config", true);<br />

pojoCache.start();<br />

public void stop() throws Exception {<br />

cacheManager.releasePojoCache("my-cache-config");<br />

}


234 Chapter 26. <strong>JBoss</strong> Cache Configuration and Deployment<br />

26.2.2. Deployment Via a -service.xml File<br />

As in <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 4.x, you can also deploy a <strong>JBoss</strong> Cache instance as an<br />

MBean service via a -service.xml file. The primary difference from <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong><br />

<strong>Platform</strong> 4.x is the value of the code attribute in the mbean element. In <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong><br />

<strong>Platform</strong> 4.x, this was org.jboss.cache.TreeCache; in <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> 5.x it<br />

is org.jboss.cache.jmx.CacheJmxWrapper. Here's an example:<br />

<br />

<br />

<br />

<br />

org.jboss.cache.transaction.<strong>JBoss</strong>TransactionManagerLookup<br />

<br />

<br />

udp<br />

Example-EntityCache<br />

REPEATABLE_READ<br />

REPL_SYNC<br />

15000<br />

20000<br />

15000<br />

true<br />

<br />

<br />

The CacheJmxWrapper is not the cache itself (i.e. you can't store stuff in it). Rather, as it's name<br />

implies, it's a wrapper around an org.jboss.cache.Cache that handles integration with JMX.<br />

CacheJmxWrapper exposes the org.jboss.cache.Cache via its CacheJmxWrapperMBean<br />

MBean interfaces Cache attribute; services that need the cache can obtain a reference to it via that<br />

attribute.<br />

26.2.3. Deployment Via a -jboss-beans.xml File<br />

Much like it can deploy MBean services described with a -service.xml, <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong><br />

<strong>Platform</strong> 5 can also deploy services that consist of Plain Old Java Objects (POJOs) if the POJOs are<br />

described using the <strong>JBoss</strong> Microcontainer schema in a -jboss-beans.xml file. You create such a file<br />

and deploy it, either directly in the deploy dir, or packaged in an ear or sar. Following is an example:


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 235<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

udp<br />

Example-EntityCache<br />

REPEATABLE_READ<br />

REPL_SYNC<br />

15000<br />

20000<br />

15000<br />

true<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

false<br />

<br />

<br />

<br />

<br />

<br />

<br />

The bulk of the above is the creation of a <strong>JBoss</strong> Cache Configuration object; this is the same as<br />

what we saw in the configuration of the CacheManager service (see Section 26.1.1, “Editing the<br />

CacheManager Configuration”). In this case we're not using the CacheManager service as a cache<br />

factory, so instead we create our own factory bean and then use it to create the cache (the<br />

"ExampleCache" bean). The "ExampleCache" is then injected into a (fictitious) service that needs it.<br />

An interesting thing to note in the above example is the use of the RuntimeConfig object. External<br />

resources like a TransactionManager and a JGroups ChannelFactory that are visible to the<br />

microcontainer are dependency injected into the RuntimeConfig. The assumption here is that in<br />

some other deployment descriptor in the <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong>, the referenced beans have<br />

already been described.<br />

Using the configuration above, the "ExampleCache" cache will not be visible in JMX. Here's an alternate<br />

approach that results in the cache being bound into JMX:


236 Chapter 26. <strong>JBoss</strong> Cache Configuration and Deployment<br />

<br />

<br />

<br />

<br />

.... same as above<br />

<br />

<br />

@org.jboss.aop.microcontainer.aspects.jmx.JMX<br />

(name="foo:service=ExampleCacheJmxWrapper",<br />

exposedInterface=org.jboss.cache.jmx.CacheJmxWrapperMBean.class,<br />

registerDirectly=true)<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Here the "ExampleCacheJmxWrapper" bean handles the task of creating the cache from the<br />

configuration. CacheJmxWrapper is a <strong>JBoss</strong> Cache class that provides an MBean interface for a<br />

cache. Adding an element binds the <strong>JBoss</strong> Microcontainer @JMX annotation to the bean;<br />

that in turn results in <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> registering the bean in JXM as part of the<br />

deployment process.<br />

The actual underlying org.jboss.cache.Cache instance is available from the CacheJmxWrapper<br />

via its cache property; the example shows how this can be used to inject the cache into the<br />

"ExampleService".


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 237<br />

Part IV. Appendices


238 Vendor-Specific Datasource Definitions<br />

Vendor-Specific Datasource Definitions<br />

This appendix includes datasource definitions for databases supported by <strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong><br />

<strong>Platform</strong>.<br />

A.1. Deployer Location and Naming<br />

All database deployers should be saved to the $JBOSS_HOME/server/default/deploy/oracleds.xml<br />

directory on the server. Each deployer file needs to end with the suffix -ds.xml. For instance,<br />

an Oracle datasource deployer might be named oracle-ds.xml. If files are not named properly, the<br />

are not found by the server.<br />

A.2. DB2<br />

Example A.1. DB2 Local-XA<br />

Copy the $db2_install_dir/java/db2jcc.jar and<br />

$db2_install_dir/java/db2jcc_license_cu.jar files into the<br />

$jboss_install_dir/server/default/lib directory. The db2java.zip file, which is part of the<br />

legacy CLI driver, is normally not required when using the DB2 Universal JDBC driver included in DB2<br />

v8.1 and later.<br />

<br />

<br />

DB2DS<br />

<br />

<br />

jdbc:db2://serveraddress:port/yourdatabase<br />

com.ibm.db2.jcc.DB2Driver<br />

x<br />

y<br />

0<br />

<br />

<br />


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 239<br />

Example A.2. DB2 XA<br />

Copy the $db2_install_dir/java/db2jcc.jar and<br />

$db2_install_dir/java/db2jcc_license_cu.jar files into the<br />

$jboss_install_dir/server/default/lib directory.<br />

The db2java.zip file is required when using the DB2 Universal JDBC driver (type 4) for XA on DB2<br />

v8.1 fixpak 14 (and the corresponding DB2 v8.2 fixpak 7).<br />

<br />

<br />

<br />

DB2XADS<br />

com.ibm.db2.jcc.DB2XADataSource<br />

your_server_address<br />

your_server_port<br />

your_database_name<br />

<br />

4<br />

<br />

<br />

false<br />

your_user<br />

your_password<br />


24 0 Vendor-Specific Datasource Definitions<br />

Example A.3. DB2 on AS/4 00<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

DB2-400<br />

jdbc:as400://[systemname]/[schema];extended<br />

dynamic=true;package=jbpkg;package cache=true;package<br />

library=jboss;errors=full<br />

com.ibm.as400.access.AS400JDBCDriver<br />

[username]<br />

[password]<br />

0<br />

<br />

<br />


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 24 1<br />

Example A.4 . DB2 on AS/4 00 "native"<br />

The Native JDBC driver is shipped as part of the IBM Developer Kit for Java (57xxJV1). It is<br />

implemented by making native method calls to the SQL CLI (Call Level Interface), and it only runs on<br />

the i5/OS JVM. The class name to register is com.ibm.db2.jdbc.app.DB2Driver. The URL<br />

subprotocol is db2. See JDBC FAQKS at http://www-<br />

03.ibm.com/systems/i/software/toolbox/faqjdbc.html#faqA1 for more information.<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

DB2-400<br />

jdbc:db2://[systemname]/[schema];extended<br />

dynamic=true;package=jbpkg;package cache=true;package<br />

library=jboss;errors=full<br />

com.ibm.db2.jdbc.app.DB2Driver<br />

[username]<br />

[password]<br />

0<br />

<br />

<br />


24 2 Vendor-Specific Datasource Definitions<br />

Example A.5. Oracle Local-TX Datasource<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

OracleDS<br />

jdbc:oracle:thin:@youroraclehost:1521:yoursid<br />

<br />

<br />

oracle.jdbc.driver.OracleDriver<br />

x<br />

y<br />

5<br />

100<br />

<br />

<br />

<br />

org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter<br />

<br />

<br />


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 24 3<br />

Example A.6. Oracle XA Datasource<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

XAOracleDS<br />

<br />

false<br />

oracle.jdbc.xa.client.OracleXADataSource<br />

jdbc:oracle:oci8:@tc<br />

scott<br />

tiger<br />

<br />

<br />

<br />

org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter<br />

<br />

<br />


24 4 Vendor-Specific Datasource Definitions<br />

Example A.7. Oracle's Thin JDBC Driver with <strong>Enterprise</strong> RAC<br />

The extra configuration to use Oracle's Thin JDBC driver to connect with <strong>Enterprise</strong> RAC involves the<br />

. The two hostnames provide load balancing and failover to the underlying physical<br />

database.<br />

...<br />

jdbc:oracle:thin:@(description=(address_list=(load_balance=on)(failover=on)(ad<br />

dress=(protocol=tcp)(host=xxxxhost1)(port=1521))(address=(protocol=tcp)(host=xxxxh<br />

ost2)(port=1521)))(connect_data=(service_name=xxxxsid)(failover_mode=(type=select<br />

)(method=basic))))<br />

...<br />

Note<br />

This example has only been tested against Oracle 10g.<br />

A.3.1. Changes in Oracle 10g JDBC Driver<br />

It is no longer necessary to enable the Pad option in your jboss-service.xml file. Further, you no<br />

longer need the .<br />

A.3.2. Type Mapping for Oracle 10g<br />

You need to specify Oracle9i type mapping for Oracle 10g datasource configurations.<br />

Example A.8. Oracle9i Type Mapping<br />

....<br />

<br />

Oracle9i<br />

<br />

....<br />

A.3.3. Retrieving the Underlying Oracle Connection Object<br />

Example A.9. Oracle Connection Object<br />

Connection conn = my<strong>JBoss</strong>Datasource.getConnection();<br />

WrappedConnection wrappedConn = (WrappedConnection)conn;<br />

Connection underlyingConn = wrappedConn.getUnderlyingConnection();<br />

OracleConnection oracleConn = (OracleConnection)underlyingConn;<br />

A.4. Sybase


Example A.10. Sybase Datasource<br />

[ 1]<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 24 5<br />

<br />

<br />

<br />

jdbc/SybaseDB<br />

<br />

jdbc:sybase:Tds:host.at.some.domain:5000/db_name?<br />

JCONNECT_VERSION=6<br />

com.sybase.jdbc2.jdbc.SybDataSource<br />

x<br />

y<br />

org.jboss.resource.adapter.jdbc.vendor.SybaseExceptionSorter<br />

<br />

<br />


24 6 Vendor-Specific Datasource Definitions<br />

Example A.11. Local-TX Datasource Using DataDirect Driver<br />

This example uses the DataDirect Connect for JDBC drivers from http://www.datadirect.com.<br />

<br />

<br />

MerliaDS<br />

jdbc:datadirect:sqlserver://localhost:1433;DatabaseName=jboss<br />

com.ddtek.jdbc.sqlserver.SQLServerDriver<br />

sa<br />

sa<br />


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 24 7<br />

Example A.13. XA Datasource Using Merlia Driver<br />

This example uses the Merlia JDBC Driver drivers from http://www.inetsoftware.de.<br />

<br />

<br />

MerliaXADS<br />

<br />

false<br />

com.inet.tds.DTCDataSource<br />

localhost<br />

pubs<br />

sa<br />

sa<br />


24 8 Vendor-Specific Datasource Definitions<br />

Example A.15. Microsoft SQL Server 2005 Local-TX Datasource<br />

<br />

<br />

<br />

MSSQL2005DS<br />

jdbc:sqlserver://localhost:1433;DatabaseName=pubs<br />

com.microsoft.sqlserver.jdbc.SQLServerDriver<br />

sa<br />

jboss<br />


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 24 9<br />

Example A.17. JSQL Driver<br />

<br />

<br />

<br />

JSQLDS<br />

jdbc:JSQLConnect://localhost:1433/databaseName=testdb<br />

com.jnetdirect.jsql.JSQLDriver<br />

x<br />

y<br />

<br />

<br />

<br />

<br />

A.5.3. jTDS JDBC Driver<br />

jTDS is an open source 100% pure Java (type 4) JDBC 3.0 driver for Microsoft SQL Server (6.5, 7, 2000<br />

and 2005) and Sybase (10, 11, 12, 15). jTDS is based on FreeTDS and is currently the fastest<br />

production-ready JDBC driver for microsoft SQL Server and Sybase. jTDS is 100% JDBC 3.0 compatible,<br />

supporting forward-only and scrollable/updateable ResultSets, concurrent (completely independent)<br />

Statements and implementing all the DatabaseMetaData and ResultSetMetaData methods.<br />

Download jTDS from http://jtds.sourceforge.net/.<br />

Example A.18. jTDS Local-TX Datasource<br />

<br />

<br />

<br />

jtdsDS<br />

jdbc:jtds:sqlserver://localhost:1433;databaseName=pubs<br />

net.sourceforge.jtds.jdbc.Driver<br />

sa<br />

jboss<br />

<br />

TRANSACTION_READ_COMMITTED<br />

10<br />

30<br />

15<br />

5000<br />

select 1<br />

select 1<br />

<br />

<br />

MS SQLSERVER2000<br />

<br />

<br />


250 Vendor-Specific Datasource Definitions<br />

Example A.19. jTDS XA Datasource<br />

<br />

<br />

<br />

jtdsXADS<br />

net.sourceforge.jtds.jdbcx.JtdsDataSource<br />

localhost<br />

pubs<br />

sa<br />

jboss<br />

<br />

true<br />

<br />

<br />

TRANSACTION_READ_COMMITTED<br />

10<br />

30<br />

15<br />

5000<br />

select 1<br />

select 1<br />

<br />

<br />

MS SQLSERVER2000<br />

<br />

<br />

<br />

A.5.4 . "Invalid object name 'JMS_SUBSCRIPTIONS' Exception<br />

If you receive an exception like the one in Example A.20, “JMS_SUBSCRIPTIONS Exception” during<br />

startup, specify a SelectMethod in the connection URL, as shown in Example A.21, “Specifying a<br />

SelectMethod”.<br />

Example A.20. JMS_SUBSCRIPTIONS Exception<br />

17:17:57,167 WARN [ServiceController] Problem starting service<br />

jboss.mq.destination:name=testTopic,service=Topic<br />

org.jboss.mq.SpyJMSException: Error getting durable subscriptions for topic<br />

TOPIC.testTopic; - nested throwable: (java.sql.SQLException: [Microsoft][SQLServer<br />

2000 Driver for JDBC][SQLServer]Invalid object name 'JMS_SUBSCRIPTIONS'.)<br />

at<br />

org.jboss.mq.sm.jdbc.JDBCStateManager.getDurableSubscriptionIdsForTopic(JDBCStateM<br />

anager.java:290)<br />

at<br />

org.jboss.mq.server.JMSDestinationManager.addDestination(JMSDestinationManager.java<br />

:656)


<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 251<br />

Example A.21. Specifying a SelectMethod<br />

jdbc:microsoft:sqlserver://localhost:1433;SelectMethod=cursor;DatabaseName=jb<br />

oss<br />

A.6. MySQL Datasource<br />

A.6.1. Installing the Driver<br />

Procedure A.1. Installing the Driver<br />

1. Download the driver from http://www.mysql.com/products/connector/j/. Make sure to choose the<br />

driver based on your version of MySQL.<br />

2. Expand the driver ZIP or TAR file, and locate the .jar file.<br />

3. Move the .jar file into $JBOSS_HOME/server/config_name/lib.<br />

4. Copy the $JBOSS_HOMEdocs/examples/jca/mysql-ds.xml example datasource deployer file<br />

to $JBOSS_HOME/server/config_name/deploy/, for use as a template.<br />

A.6.2. MySQL Local-TX Datasource<br />

Example A.22. MySQL Local-TX Datasource<br />

This example uses a database hosted on localhost, on port 3306, with autoReconnect enabled.<br />

This is not a recommended configuration, unless you do not need any Transactions support.<br />

<br />

<br />

MySqlDS<br />

jdbc:mysql://localhost:3306/database<br />

com.mysql.jdbc.Driver<br />

username<br />

secret<br />

true<br />

<br />

<br />

mySQL<br />

<br />

<br />

<br />

A.6.3. MySQL Using a Named Pipe


252 Vendor-Specific Datasource Definitions<br />

Example A.23. MySQL Using a Named Pipe<br />

This example uses a database hosted locally, but uses a named pipe instead of TCP/IP.<br />

<br />

<br />

MySQLDS<br />

jdbc:mysql://./database<br />

com.mysql.jdbc.Driver<br />

username<br />

secret<br />

com.mysql.jdbc.NamedPipeSocketFactory<br />

<br />

mySQL<br />

<br />

<br />

<br />

A.7. PostgreSQL<br />

Example A.24 . PostgreSQL Local-TX Datasource<br />

<br />

<br />

<br />

PostgresDS<br />

jdbc:postgresql://[servername]:[port]/[database<br />

name]<br />

org.postgresql.Driver<br />

x<br />

y<br />

<br />

<br />


Example A.25. PostgreSQL XA Datasource<br />

This configuratino works for PostgreSQL 8.x and later.<br />

<br />

<br />

<br />

PostgresDS<br />

org.postgresql.xa.PGXADataSource<br />

[servername]<br />

5432<br />

[database name]<br />

[username]<br />

[password]<br />

<br />

<br />

<br />

A.8. Ingres<br />

Example A.26. Ingres Datasource<br />

[ 2]<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 253<br />

<br />

<br />

<br />

IngresDS<br />

false<br />

com.ingres.jdbc.IngresDriver<br />

jdbc:ingres://localhost:II7/testdb<br />

com.ingres.jdbc.IngresDataSource<br />

localhost<br />

II7<br />

testdb<br />

testuser<br />

testpassword<br />

select count(*) from iitables<br />

select count(*) from iitables<br />

<br />

Ingres<br />

<br />

<br />

<br />

[1] So urce: http://community.jboss.org/wiki/SetUpASybaseDatasource<br />

[2] So urce: http://community.ingres.com


254 Logging Information and Recipes<br />

Logging Information and Recipes<br />

B.1. Log Level Descriptions<br />

Table B.1, “log4j Log Level Definitions” lists the typical meanings for different log levels in log4 j. Your<br />

application may interpret these levels differently, depending on your choices.<br />

Table B.1. log4 j Log Level Definitions<br />

log4 j Level JDK Level Description<br />

FATAL The <strong>Application</strong> Service is likely<br />

to crash.<br />

ERROR SEVERE A definite problem exists.<br />

WARN WARNING Likely to be a problem, but may<br />

be recoverable.<br />

INFO INFO Low-volume detailed logging.<br />

Something of interest, but not a<br />

problem.<br />

DEBUG FINE Low-volume detailed logging.<br />

Information that is probably not<br />

of interest.<br />

FINER Medium-volume detailed logging.<br />

TRACE FINEST High-volume detailed logging.<br />

Note<br />

The more verbose logging levels are not appropriate for production systems, because of the high<br />

level of output they generate.<br />

Example B.1. Restricting Logged Information to a Specific Log Level<br />


Example B.2. Filtering App1 Log Output to a Separate File<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

...<br />

<strong>JBoss</strong> <strong>Enterprise</strong> <strong>Application</strong> <strong>Platform</strong> <strong>Common</strong> <strong>Criteria</strong> <strong>Certification</strong> 5 Administration And Configuration Guide 255<br />

<br />

<br />

<br />

<br />

<br />

<br />

Example B.3. Using TCLMCFilter<br />

<strong>Enterprise</strong> <strong>Platform</strong> 5.1 includes the new class jboss.logging.filter.TCLMCFilter, which<br />

allows you to filter based on the deployment URL.<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

B.3. Redirecting Category Output<br />

When you increase the level of logging for one or more categories, it is often useful to redirect the output<br />

to a seperate file for easier investigation. To do this you add an appender-ref to the category.<br />

Example B.4 . Adding an appender-ref<br />

<br />

<br />

...<br />

<br />

<br />

<br />

<br />

<br />


256 Logging Information and Recipes<br />

All org.jboss.management output goes to the jsr77.log file. The additivity attribute controls<br />

whether output continues to go to the root category appender. If false, output only goes to the<br />

appenders referred to by the category.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!