JBoss Community Archive (Read Only)

JBoss AS 7.1

JBossWS integration layer with Apache CXF

All JAX-WS functionalities provided by JBossWS on top of JBoss Application Server are currently served through a proper integration of the JBoss Web Services stack with most of the Apache CXF project modules.

Apache CXF is an open source services framework. It allows building and developing services using frontend programming APIs (including JAX-WS), with services speaking a variety of protocols such as SOAP and XML/HTTP over a variety of transports such as HTTP and JMS.

The integration layer (JBossWS-CXF in short hereafter) is mainly meant for:

In order for achieving the goals above, the JBossWS-CXF integration supports the JBoss endpoint deployment and comes with many internal customizations on top of Apache CXF.

In the next sections a list of technical suggestions and notes on the integration is provided; please also refer to the Apache CXF official documentation for in-dept details on the CXF architecture.

Creating a Bus instance

Most of the Apache CXF features are configurable using the org.apache.cxf.Bus class. While for basic JAX-WS usage the user might never need to explicitly deal with Bus, using Apache CXF specific features generally requires getting a handle to a  org.apache.cxf.Bus instance. This can happen on client side as well as in a ws endpoint or handler business code.

New Bus instances are produced by the currently configured org.apache.cxf.BusFactory implementation the following way:

Bus bus = BusFactory.newInstance().createBus();

The algorithm for selecting the actual implementation of BusFactory to be used leverages the Service API, basically looking for optional configurations in META-INF/services/... location using the current thread context classloader. JBossWS-CXF integration comes with his own implementation of BusFactory, org.jboss.wsf.stack.cxf.client.configuration.JBossWSBusFactory, that allows for automatic detection of Spring availability as well as seamless setup of JBossWS customizations on top of Apache CXF. So, assuming the JBossWS-CXF libraries are available in the current thread context classloader, the JBossWSBusFactory is automatically retrieved by the BusFactory.newInstance() call above.

JBossWS users willing to explicitely use functionalities of org.apache.cxf.bus.spring.SpringBusFactory or org.apache.cxf.bus.CXFBusFactory, get the same API with JBossWS additions through JBossWSBusFactory:

String myConfigFile = ...
Bus bus = new JBossWSBusFactory().createBus(myConfigFile);
Map<Class, Object> myExtensions = new HashMap<Class, Object>();
Bus bus = new JBossWSBusFactory().createBus(myExtensions);

Using existing Bus instances

Apache CXF keeps reference to a global default Bus instance as well as to a thread default bus for each thread. That is performed through static members in org.apache.cxf.BusFactory, which also comes with the following methods in the public API:

public static synchronized Bus getDefaultBus()
public static synchronized Bus getDefaultBus(boolean createIfNeeded)
public static synchronized void setDefaultBus(Bus bus)
public static Bus getThreadDefaultBus()
public static Bus getThreadDefaultBus(boolean createIfNeeded)
public static void setThreadDefaultBus(Bus bus)

Please note that the default behaviour of getDefaultBus() / getDefaultBus(true) / getThreadDefaultBus() / getThreadDefaultBus(true) is to create a new Bus instance if that's not set yet. Moreover getThreadDefaultBus() and getThreadDefaultBus(true) first fallback to retrieving the configured global default bus before actually trying creating a new instance (and the created new instance is set as global default bus if that was not there set yet).

The drawback of this mechanism (which is basically fine in JSE environment) is that when running in a JBoss AS container you need to be careful in order not to (mis)use a bus over multiple applications (assuming the Apache CXF classes are loaded by the same classloader, which is currently the case with AS6 and 7).

Here is a list of general suggestions to avoid problems when running in-container:

  • forget about the global default bus; you don't need that, so don't do getDefaultBus() / getDefaultBus(true) / setDefaultBus() in your code;

  • avoid getThreadDefaultBus() / getThreadDefaultBus(true) unless you already know for sure the default bus is already set;

  • keep in mind thread pooling whenever you customize a thread default bus instance (for instance adding bus scope interceptors, ...), as that thread and bus might be later reused; so either shutdown the bus when you're done or explicitly remove it from the BusFactory thread association.

Finally, remember that each time you explictly create a new Bus instance (factory.createBus()) that is set as thread default bus and global default bus if those are not set yet. The JAXWS Provider implementation also creates Bus instances internally, in particular the JBossWS version of JAXWS Provider makes sure the default bus is never internally used and instead a new Bus is created if required.

Server Side Integration Customization

The JBossWS-CXF server side integration takes care of internally creating proper Apache CXF structures (including a Bus instance, of course) for the ws endpoint deployment.

It is possible to customize the JBossWS and CXF integration by incorporating the CXF configuration file to the endpoint deployment archive. In order for that to be possible, JBossWS-CXF requires Spring to be installed in the application server. The Spring Framework libraries installation can be perfomed using the JBossWS-CXF installation or by manually populating the org.springframework.spring module that's in JBoss AS 7 and which the other webservices modules already have an optional dependency on.

The convention is the following:

  • file name must be jbossws-cxf.xml

  • for POJO deployments it is located in WEB-INF directory

  • for EJB3 deployments it is located in META-INF directory

Providing custom CXF configuration to the endpoint deployment is useful in cases when users want to use features that are not part of standard JAX-WS specification (CXF specific) and that can't be setup in the application classes' code. An example are some advanced WS-RM customizations.

Please consider that from a technical point of view, the jbossws-cxf.xml configuration file is basically treated as an addition to the default Apache CXF / JBossWS-CXF configuration. Hence users should be careful when dealing with global configurations (eg. global bus level interceptors) and instead provide those configuration in the deployment in another cxf.xml descriptor, which will be loaded at the same time as the default setup.

JBoss.org Content Archive (Read Only), exported from JBoss Community Documentation Editor at 2020-03-13 13:22:30 UTC, last content change 2012-02-15 13:56:55 UTC.