Migrating Mule 1.x to 2.0
Introduction
This page describes the major configuration and code changes in Mule 2.0 to help Mule 1.x users understand what has changed between releases. For more information on new features and changes, see Whats New in Mule 2.0.
The principal new feature of Mule 2.0 is a powerful new schema-based configuration style leveraging Spring's Extensible XML Authoring.
The new format looks similar to the Mule 1.x format, and upgrading from Mule 1.x to 2.x is fairly straightforward. This page will help you get started.
Quick Reference
This section provides a quick reference to the changes from 1.x to 2.x.
XML Configuration Changes
| 1.x |
2.x |
| Interceptors |
not supported |
| Mule implementations are attributes |
Mule implementations are elements |
| Mule descriptor implementation is explicitly required |
Service component configuration is optional. PassThroughComponent is default. |
| Endpoint: address or name attribute |
Endpoint: address, name, or new path attribute |
Code Changes
For details on these changes, see What's New in Mule 2.0.
| 1.x |
2.x |
| org.mule.umo.* |
org.mule.api.* in most cases |
| org.mule.providers.* |
org.mule.transport.*. For details on migrating 1.x transports to 2.x, click here. |
| org.mule.extras.* |
org.mule.module.NAME.* |
| package names are singular/plural |
package names are singular |
| MuleClient.receive(...) |
MuleClient.request(...) |
| MuleManager utility class |
MuleContext instance available through life cycle methods or MuleAwareContext implementation. |
| QuickConfigurationBuilder |
No longer supported |
| MuleXMLConfigurationBuilder |
DefaultMuleContextFactory |
| UMOMessage |
MuleMessage |
| MuleMessage |
DefaultMuleMessage |
| UMOEndpoint |
InboundEndpoint or OutboundEndpoint |
| UMOEndpointURI |
EndpointURI |
| MuleEndpoint.getOrCreateEndpointForUri(..., UMOEndpoint.ENDPOINT_TYPE_SENDER) |
new DefaultEndpointFactory().getOutboundEndpoint(...) |
| MuleEndpoint.getOrCreateEndpointForUri(..., UMOEndpoint.ENDPOINT_TYPE_RECEIVER) |
new DefaultEndpointFactory().getInboundEndpoint(...) |
| doPostFunctionalSetUp() |
suitePreSetUp() and doSetUp() |
Example Configuration (Before and After)
To get an overview of the changes, compare the same configuration file in 1.4 and 2.0
Configuration Changes
This section describes the configuration changes in detail.
File Header
Mule configuration files are now based on an XML schema instead of DTDs. Therefore, you must configure the Mule core namespace plus any modules or transports as shown below in this empty configuration file.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mule-configuration PUBLIC "-//MuleSource //DTD mule-configuration XML V1.0//EN"
"http://mule.mulesource.org/dtds/mule-configuration.dtd">
<mule-configuration id="Samples" version="1.0">
</mule-configuration>
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesource.org/schema/mule/core/2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jms="http://www.mulesource.org/schema/mule/jms/2.0"
xsi:schemaLocation="
http://www.mulesource.org/schema/mule/core/2.0 http://www.mulesource.org/schema/mule/core/2.0/mule.xsd
http://www.mulesource.org/schema/mule/jms/2.0 http://www.mulesource.org/schema/mule/jms/2.0/mule-jms.xsd">
</mule>
Note: This page describes the recommended approach of using mule as the default namespace, but you can also use other default namespaces, such as the Spring "beans" namespace.
Connectors
Just as with Mule 1.x, connectors are configured as top-level elements in the Mule configuration, but they now use transport-specific schemas. The connector elements have changed accordingly as shown below:
<connector className="org.mule.providers.vm.VMConnector"/>
<connector className="org.mule.providers.jms.JmsConnector"/>
<vm:connector/>
<jms:connector/>
The new approach provides a huge advantage in that each transport now defines its own syntax for configuring connectors, avoiding class names and untyped properties. Additionally, you can use your favorite IDE's auto-completion feature, making Mule 2.0 fast and easy to configure.
Following is another example illustrating a stdio connector taken from the echo example:
<connector name="SystemStreamConnector" className="org.mule.providers.stream.SystemStreamConnector">
<properties>
<property name="promptMessage" value="Please enter something: "/>
<property name="messageDelayTime" value="1000"/>
</properties>
</connector>
<stdio:connector name="SystemStreamConnector"
promptMessage="Please enter something: "
messageDelayTime="1000"/>
Note: To use a specific transport, you must import its namespace as explained above.
Endpoints
Endpoints are now easier to configure and more context-specific in Mule 2.0, as described below.
Global Endpoints
Global endpoints act as endpoint templates, allowing you to configure and reuse an endpoint configuration for multiple logical endpoints. To configure a global endpoint, you use the "endpoint" element as a top-level element instead of on routers or exception strategies. You can configure all the same elements on a global endpoint as on a logical endpoint, including making them transport-specific.
An <endpoint-identifier> in 1.4 is equivalent to a global endpoint in 2.0 that just has a URI configured.
Notes:
- Be careful defining transformers on global endpoints that are referenced by inbound and outbound endpoints, as transformers are not the same for inbound and outbound endpoints.
- Although logical endpoints inherit and can extend a global endpoint configuration, you cannot extend properties. Properties configured on a logical endpoint will overwrite properties configured on the referenced global endpoint.
Explicit Endpoint Types
You now specify endpoint types explicitly (inbound, outbound, or response). This approach allows endpoints to have more specific configuration. For example, by specifying an endpoint as inbound, you could ensure that pollingFrequency is configured on the inbound file connector but not on its outbound counterpart.
Transport-specific Endpoints
Endpoint configuration has been improved to avoid untyped properties. Some of these properties are cross-transport attributes or elements, whereas others are defined by transport-specific endpoint definitions.
<endpoint address="pop3://bob:secret@localhost:62002" transformers="BytesToMime"/>
<pop3:inbound-endpoint user="bob" password="secret" host="localhost" port="62002">
<email:bytes-to-mime-transformer/>
</pop3:inbound-endpoint>
Services and Components (Formerly MuleDescriptors)
Services and components are now configured differently. Following are the two versions of the Mule Hello example:
<mule-descriptor name="ChitChatUMO" implementation="org.mule.samples.hello.ChitChatter">
<inbound-router>
<endpoint address="vm://chitchatter" transformers="NameStringToChatString"/>
</inbound-router>
<outbound-router>
<router className="org.mule.routing.outbound.OutboundPassThroughRouter">
<endpoint address="stream://System.out" transformers="ChatStringToString" />
</router>
</outbound-router>
</mule-descriptor>
<service name="ChitChatUMO">
<inbound>
<vm:inbound-endpoint path="chitchatter" transformer-refs="NameStringToChatString"/>
</inbound>
<component class="org.mule.samples.hello.ChitChatter"/>
<outbound>
<outbound-pass-through-router>
<stdio:outbound-endpoint system="OUT" transformer-refs="ChatStringToString"/>
</outbound-pass-through-router>
</outbound>
</service>
Following is a description of the changes:
New Nomenclature:
MuleDescriptor is now Service
Implementation is now Component
Extensibility:
A component is abstract, allowing multiple implementation types. By default, Mule includes two implementations: <component/> and <pooled-component/>. Other modules can add other component types.
The <component> and <pooled-component> elements are configured in exactly the same way, except that the <pooled-component> has an additional optional <pooling-profile> child element that can be use to customize the pool behavior. These elements can either use the "class" attribute or define an object-factory as a child element. If you use the "class" attribute, the prototype object factory will be used by default. You can configure components with singleton, prototype, and Spring object factories.
Minimal Configuration:
<component class="org.your.PrototypeComponent"/>
..
<pooled-component class="org.your.PooledPrototypeComponent"/>
Complete Configuration Example:
<spring:bean name="myPooledSpringBeanComponent" class="org.your.PooledSpringBeanComponent" />
..
<pooled-component>
<reflection-entry-point-resolver/>
<spring-object bean="myPooledSpringBeanComponent"/>
<custom-lifecycle-adapter-factory class="org.mule.config.spring.parsers.specific.TestLifecycleAdapterFactory"/>
<binding interface="java.lang.String" method="setMethod">
<outbound-endpoint address="vm://myEndpoint" />
</binding>
<pooling-profile exhaustedAction="WHEN_EXHAUSTED_FAIL"
initialisationPolicy="INITIALISE_ALL" maxActive="1"
maxIdle="2" maxWait="3" />
</pooled-component>
Routers and Filters
Routers and filters also take advantage of the new schema-based configuration. Most are defined in Mule, but specific modules and transports can also contribute routers or filters by defining them in their own namespace.
<router className="org.mule.routing.inbound.SelectiveConsumer"/>
<router className="org.mule.routing.outbound.FilteringOutboundRouter"/>
<router className="org.mule.routing.outbound.MulticastingRouter"/>
<router className="org.my.CustomRouter"/>
<selective-consumer-router/>
<filtering-router/>
<multicasting-router/>
<custom-inbound-router class="org.my.CustomRouter"/>
<global-endpoints>
<endpoint name="CustomerResponses" address="vm://customer.responses"/>
</global-endpoints>
..
<router className="org.mule.routing.outbound.FilteringOutboundRouter">
<global-endpoint name="CustomerResponses"/>
<filter expectedType="org.mule.examples.loanbroker.messages.LoanQuote" className="org.mule.routing.filters.PayloadTypeFilter"/>
</router>
<vm:endpoint name="CustomerResponses" path="customer.responses"/>
..
<filtering-router>
<outbound-endpoint ref="CustomerResponses"/>
<payload-type-filter expectedType="org.mule.examples.loanbroker.messages.LoanQuote"/>
</filtering-router>
(Taken from LoanBroker ESN Example)
Transformers
Transformers also take advantage of the new schema-based configuration. Modules and transports contribute transformers by defining them in their own namespace.
Transformers are now defined directly rather than by specifying class names.
<transformer className="org.mule.transformers.simple.MessagePropertiesTransformer"/>
<transformer className="org.mule.transformers.simple.ByteArrayToObject"/>
<transformer className="org.mule.transformers.xml.XsltTransformer"/>
<transformer className="org.my.CustomTransformer"/>
<message-properties-transformer/>
<byte-array-to-object-transformer/>
<xml:xslt-transformer/>
<custom-transformer class="org.my.CustomTransformer"/>
Custom transformers can still be used with the "custom-transformer" element.
Transformers can be referenced from endpoints using the "transformer-refs" attribute or can be declared inline.
<global-endpoint name="CustomerRequestsREST" transformers="RestRequestToCustomerRequestTransformer"/>
<inbound-endpoint ref="CustomerRequestsREST" transformer-refs="Transformer1 Transformer2"/>
<inbound-endpoint ref="CustomerRequestsREST">
<transformer ref="RestRequestToCustomerRequestTransformer" />
</inbound-endpoint>
<inbound-endpoint ref="IncomingData">
<byte-array-to-object-transformer/>
</inbound-endpoint>
Bridging
Bridging configuration has been simplified in Mule 2.0. To implement a bridge service, you simply configure inbound and outbound routers. Bridging occurs implicitly.
<mule-descriptor name="bridge" implementation="org.mule.components.simple.BridgeComponent">
<inbound-router>
<endpoint address="vm://bridge.inbound"/>
</inbound-router>
<outbound-router>
<router className="org.mule.routing.outbound.OutboundPassThroughRouter">
<endpoint address="vm://bridge.outbound"/>
</router>
</outbound-router>
</mule-descriptor>
<service name="bridge">
<inbound>
<vm:inbound-endpoint path="bridge.inbound"/>
</inbound>
<outbound>
<outbound-pass-through-router>
<vm:outbound-endpoint path="bridge.outbound"/>
</outbound-pass-through-router>
</outbound>
</service>
The "bridge-component" and "pass-through-component" can still be used for backward-compatibility but are no longer needed.
Exception Strategies
Developers now have much finer control over transactions through configuration. Pattern matching filters can be used to match different types of exceptions. For example:
<model>
<default-service-exception-strategy>
<commit-transaction exception-pattern="*">
<jms:outbound-endpoint queue="DLQ"/>
</default-service-exception-strategy>
...
</model>
This configuration tells Mule to keep any current transaction open until after we dispatch to the JMS DLQ (Dead Letter Queue), and then commit the current transaction.
For certain transactions, you may want to roll back the transaction immediately. For example:
<model>
<default-service-exception-strategy>
<commit-transaction exception-pattern="*">
<rollback-transaction exception-pattern"com.acme.a.*,com.acme.b.*"/>
<jms:outbound-endpoint queue="DLQ"/>
</default-service-exception-strategy>
...
</model>
This configuration tells Mule to roll back transactions when there are exceptions with packages com.acme.a and com.acme.b. Otherwise, commit the current transaction. Note that the <rollback-transaction> has priority over the <commit-transaction> element.