Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

...

ServiceMix CXF SE

ServiceMix Cxf Se CXF SE component is a JBI Service Engine exposing (annotated) POJO as services on the JBI Bus.

It uses apache cxf Apache CXF internally to perform service invocations and xml marshaling.

Features:

  • jsr181 JSR-181 annotations
  • aegis binding
  • jaxb2 binding
  • JAXB2/Aegis/XMLBeans databinding
  • WSDL wsdl auto generation
  • Java proxy support
  • MTOM / attachments support

Installation

Maven Archetype

You can use Installing the servicemix-cxf-se component can be done in several ways:

  • drop the installer zip in an hotdeploy directory monitored by ServiceMix
  • using ant tasks

Note that when using ant tasks, the component is not started, you will have to start it manually using ant tasks or a console.

Deployment

You can deploy Service Units containing a file named xbean.xml for activating consumer and provider endpoints.

This xml file should respect the given syntax, though this is a spring based xml configuration file
See a full example here.  Note that you have to define the cxf-se namespace with

...


<beans xmlns:cxfse="http://servicemix.apache.org/cxfse/1.0">
    ...
</beans>

-service-unit archetype to create a CXF SE Service Unit (including a sample POJO):

Code Block

mvn archetype:create \
  -DarchetypeGroupId=org.apache.servicemix.tooling \
  -DarchetypeArtifactId=servicemix-cxf-se-service-unit \
  -DarchetypeVersion=2010.01 \
  -DgroupId=your.group.id \
  -DartifactId=your.artifact.id \
  -Dversion=your-version

Once you've customized the service unit, simply install the SU:

Code Block

mvn install
Info

Remember that to be deployable in ServiceMix, the ServiceUnit has to be embedded in a Service Assembly: only the Service Assembly zip file can be deployed in ServiceMix.
To add your SU in a SA, you need to define it in the dependency sets:

Code Block

<dependency>
  <groupId>your.group.id</groupId>
  <artifactId>your.artifact.id</artifactId>
  <version>your-version</version>
</dependency>

Endpoint Configuration

The CXF SE endpoint provides a property named pojo. You can expose any POJO which contains the @WebService annotation.

A simple example follows

Any numbers of endpoints can be specified in the xbean.xml file.

As the main purpose is to expose a POJO, you will have to include the needed class files / jars in the service unit and reference them using the following tags in your xbean.xml configuration file:

Code Block
langxml

<classpath>
  <location>.</location>
</classpath>

This will add the content of the location tags (relative to the unzipped service unit) to the classpath. The previous configuration will just add the class files contained in the service unit, as if it is a plain jar.

If you want to embed jars, just use something like

Code Block
langxml

<classpath>
  <location>lib/foo.jar</location>
</classpath>

Endpoint

A few examples:

Code Block
langxml
      <cxfse:endpoint>
        <cxfse:pojo>
          <bean class="org.apache.cxf.calculator.CalculatorImpl">
          </bean>
        </cxfse:pojo>
      </cxfse:endpoint>

You can use a proxy (see Proxies section of this page):

Code Block
langxml
      <cxfse:endpoint>
        <cxfse:pojo>
          <bean class="org.apache.servicemix.cxfse.GreeterImplForClientProxy" autowire="false">
              <property name="calculator">
                  <cxfse:proxy service="calculator:CalculatorService" context="#context" type="org.apache.cxf.calculator.CalculatorPortType" />
              </property>
          </bean>

        </cxfse:pojo>
      </cxfse:endpoint>
Info
titleEndpoint attributesAttributes
borderStylesolidbgColor='lighbluelightblue'
The annotations used to configure the service. Can be "none", "java5", "jsr181", "commons". If not specified, the annotations type will be discovered by looking at the class.

Name

Type

Description

Required

annotations

String

no

endpoint

String

JBI Endpoint name

no (will be auto-generated if not specified)

interfaceName

QName

Interface QName implemented by the JBI endpoint

no (will be auto-generated if not specified)

mtomEnabled

boolean

Enable MTOM / attachment support

no (defaults to false)

pojo

Object

the instanciated POJO to service requests

one of pojo or pojoClass pojoClass String

the class name of the POJO to service requests

one of pojo or pojoClass

service

QName

JBI Service name

no (will be auto-generated if not specified)

serviceInterface

String

the class name of the interface to expose as a service

no

typeMapping

String

Can be "default", "xmlbeans", "jaxb2". Defaults to "default" (Aegis) if no annotations used, else defaults to "jaxb2"

no

wsdlResource

Spring resource

if set, the wsdl will be retrieved from the given Spring resource

no

useJBIWrapper

boolean

Specifies if the endpoint expects to receive the JBI wrapper in the message received from the NMR

no (defaults to true,Ignore the value of useSOAPEnvelope if useJBIWrapper is true)

useSOAPEnvelope

boolean

Specifies if the endpoint expects soap messages when useJBIWrapper is false

no (defaults to true)

useXmlBeans

boolean

Specifies if the endpoint use xmlbeans databinding to marshell/unmarshell message

no (defaults to false)

useAegis

boolean

Specifies if the endpoint use aegis databinding to marshell/unmarshell message

no (defaults to false), generally we use aegis databinding with simple frontend

pojoService

QName

Specifies the servicemodel service name generated from the pojo

no (will be auto-generated if not specified)

pojoEndpoint

QName

Specifies the servicemodel endpoint name generated from the pojo

no (will be auto-generated if not specified) pojoService and pojoEndpoint can control the servicemodel generated from pojo, it's equivalent to the annotation in java code, but it's useful when you can't change the java code

style

String

The SOAP style to use (document, wrapped, rpc)

no (defaults to "wrapped")

Accessing the JBI bus

The prefered way to access the JBI bus is by retrieving a ComponentContext implementation.
The spring BeanFactory has a parent factory which contains a bean named "context" that you can refer to.

Code Block
langxml

<jsr181:endpoint ...>
  <jsr181:pojo>
    <bean class="xxx">
      <property name="context" ref="context" />
    </bean>
  </jsr181:pojo>
</jsr181:endpoint>

If you want to get ComponentContext implementation injected into your POJO, and send a request to another service from your POJO, you can need add the following method on your POJO:

Code Block
langjava
private javax.jbi.component.ComponentContext context;

public void setContext(javax.jbi.component.ComponentContext context) {
  this.context = context;
}

By this way, the ComponentContext inject into your POJO automatically
You will be able to use the provided DeliveryChannel to send requests.

...

Code Block
langjava
public void myMethod() {
  ServiceMixClient client = new ServiceMixClientFacade(this.context);
  QName service = new QName("http://servicemix.org/cheese/", "receiver");
  EndpointResolver resolver = client.createResolverForService(service);
  client.send(resolver, null, null, "<hello>world</hello>");
}

Lightweight mode

The servicemix-jsr181 component can also be configured in a spring/xbean configuration file, for use in an embedded ServiceMix.
Here is an example of such a configuration:

Wiki Markup
{snippet:id=lightweight|lang=xml|url=servicemix/trunk/deployables/serviceengines/servicemix-jsr181/src/test/resources/org/apache/servicemix/jsr181/spring.xml}
Warning
titleClasspath issues when embedding servicemix-jsr181 component

When using the servicemix.xml configuration file to create jsr181 endpoints, you must include the servicemix-jsr181-xxx.jar in your classpath.
You will find this file inside the component installer (./components/servicemix-jsr181-xxx.zip).
Failing this, an IllegalArgumentException will be thrown with the following message:
Component name: xxxxxx is bound to an object which is not a JBI component, it is of type: javax.xml.namespace.QName
or aanother exception with

You can find a whole context injection test case here

Proxies

You can create java proxies for JBI endpoints, provided that they expose a WSDL.

The basic configuration is the following:

Code Block
langxml

<cxfse:proxy service="calculator:CalculatorService" context="#context" type="org.apache.cxf.calculator.CalculatorPortType" />
Wiki Markup
{snippet:id=proxy|lang=xml|url=servicemix/trunk/deployables/serviceengines/servicemix-jsr181/src/test/resources/org/apache/servicemix/jsr181/spring.xml}

You can use it from one of you client bean, or from inside another component, and call the JBI endpoint as a plain Java object.

Info
titleProxy attributes
borderStylesolidbgColor='lightblue'

Name

Type

Description

Required

type

Class

proxy class type

yes

endpoint

String

JBI Endpoint name

no (will be auto-generated if not specified)

interfaceName

QName

Interface QName implemented by the JBI endpoint

no (will be auto-generated if not specified)

service

QName

JBI Service name

no (will be auto-generated if not specified)

mtomEnabled

boolean

Enable MTOM / attachment support

no (defaults to false)

useJBIWrapper

boolean

Specifies if the endpoint expects to receive the JBI wrapper in the message received from the NMR

no (defaults to true,Ignore the value of useSOAPEnvelope if useJBIWrapper is true)

useSOAPEnvelope

boolean

Specifies if the endpoint expects soap messages when useJBIWrapper is false

no (defaults to true)

From a CXF SE From a jsr181 Service Unit, it could be used as following:

Code Block
langxml

<cxfse:endpoint>
  <cxfse:pojo>
     <bean class="org.apache.servicemix.cxfse.GreeterImplForClientProxy">
       <property name="calculator">
          <cxfse:proxy service="calculator:CalculatorService" context="#context" type="org.apache.cxf.calculator.CalculatorPortType" />
       </property>
     </bean>
 </cxfse:pojo>
</cxfse:endpoint>
Wiki Markup
{snippet:id=proxy|lang=xml|url=servicemix/trunk/deployables/serviceengines/servicemix-jsr181/src/test/resources/proxy/xbean.xml}
Code Block
langjava
private EchoCalculatorPortType echocalculator;

  public void setEchosetCalculator(EchoCalculatorPortType echocalculator) {
        this.echocalculator = echocalculator;
    }

    public CalculatorPortType getCalculator() {
        return calculator;
    }
  public void myMethod() {
    int ret = 0;
    String result = echo.echo("world");
        try {
            
            ret = getCalculator().add(1, 2);
                        
        } catch (Exception e) {
            e.printStackTrace();
        }
    ...
  }

You can find a complete proxy test case here

MTOM support

MTOM is a way to handle large amounts of binary data in your services. Unlike attachments, the XML infoset stays the same. MTOM just "optimizes" any base64Binary data you have in your messages. When MTOM is turned on, this base64 data gets sent as a binary attachment saving time and space.

MTOM support can be turned on using:

Code Block
langxml
<jsr181<cxfse:endpoint mtomEnabled="true" ... />

MTOM is supported for the following classes:

  • DataSource
  • DataHandler
  • Wiki Markupbyte\[\]

If you have a bean with the following method:

...

provided that the JBI message contains an attachment named "binary".

You can find a complete MTOM test case here

Interceptors Configuration

Since cxfse is using Apache CXF internally, so you can configure cxf se endpoint with inteceptors which follow cxf inteceptor api.
example per as below

Code Block
langxml

<cxfse:endpoint>
  <cxfse:inFaultInterceptors>
    <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
  </cxfse:inFaultInterceptors>
  <cxfse:inInterceptors>
    <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
  </cxfse:inInterceptors>
  <cxfse:outFaultInterceptors>
    <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
  </cxfse:outFaultInterceptors>
  <cxfse:outInterceptors>
    <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"/>
  </cxfse:outInterceptors>
  <cxfse:pojo>
    <bean class="org.apache.cxf.calculator.CalculatorImpl">
    </bean>
  </cxfse:pojo>
</cxfse:endpoint>

Can find document for CXF interceptors here