This guide walks you through migrating service providers and consumers from the High-speed Service Framework (HSF) to Apache Dubbo, using Ali-Tomcat for dual registration during the transition. Both HSF and Dubbo services coexist and interoperate through a shared registry, enabling incremental migration without downtime.
Before you begin
Make sure the following components are deployed and running:
| Component | Version | Purpose |
|---|---|---|
| Lightweight configuration center | Latest | Local service registration and discovery |
| Apache Dubbo | 2.7.3 | Target RPC framework |
| EDAS Container | V3.5.5 | Runtime container for HSF services |
| edas-dubbo-extension | 2.0.6 | Bridge between Dubbo and the EDAS registry |
Known limitations
Review these before starting the migration:
HSF call authentication is incompatible with Dubbo. If HSF has call authentication enabled, Dubbo consumers cannot invoke HSF providers. Disable it by adding
-DneedAuth=falseto the HSF provider's JVM arguments.Hessian serialization and JDK 8
LocalDateTime. Older versions of EDAS Container ship a Hessian Lite version that does not supportLocalDateTimeserialization. Upgrade EDAS Container to V3.5.5 to resolve this.Dubbo checks provider availability at startup by default. If the registry has not yet pushed provider addresses, the consumer fails to start. Add
check="false"to<dubbo:reference>to defer this check.
Choose a migration approach
Two approaches are available. The trade-off is stability versus speed:
| Approach | Steps | When to use |
|---|---|---|
| Two-step migration (recommended) | 1. HSF + EDAS registry -> Dubbo + EDAS registry 2. EDAS registry -> Nacos registry | You want a low-risk, incremental migration. Each step can be validated independently. Requires two deployment cycles. |
| Direct migration | HSF + EDAS registry -> Dubbo + Nacos registry (single step) | You have the development capacity to handle HSF-to-Nacos incompatibility. HSF does not natively support Nacos, so custom integration work is required. |
The rest of this guide covers the two-step approach.
How dual registration works
During migration, Dubbo services register in both HSF and Dubbo formats simultaneously. This makes sure that:
Existing HSF consumers discover migrated Dubbo providers because the Dubbo service appears in HSF format in the EDAS registry.
Migrated Dubbo consumers discover existing HSF providers because the Dubbo consumer subscribes to both HSF and Dubbo format data.
This dual-format registration is controlled by a single configuration parameter: <dubbo:parameter key="hsf.enable" value="true"/>.
Sample application structure
The examples in this guide assume that both HSF and Dubbo services implement the same Java interface, com.alibaba.edas.DemoService, defined in a shared module named edas-demo-interface:
edas-demo-interface/
├── pom.xml
└── src
└── main
└── java
└── com
└── alibaba
└── edas
└── DemoService.javaMigrate the service provider
The following steps migrate an HSF provider application (edas-hsf-demo-provider-war) to Dubbo. The application contains:
pom.xml-- Maven dependency configurationDemoServiceImpl.java-- Implementation ofDemoServicehsf-provider-beans.xml-- Spring bean definitions for HSFweb.xml-- WAR deployment descriptor
edas-hsf-demo-provider-war/
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── alibaba
│ │ └── edas
│ │ └── hsf
│ │ └── provider
│ │ └── DemoServiceImpl.java
│ ├── resources
│ │ └── hsf-provider-beans.xml
│ └── webapp
│ └── WEB-INF
│ └── web.xmlStep 1: Update Maven dependencies
Use Spring 4.x or later for HSF services.
Remove the HSF client dependency:
<dependency> <groupId>com.alibaba.edas</groupId> <artifactId>edas-sdk</artifactId> <version>1.5.4</version> </dependency>Add the Dubbo dependencies:
edas-dubbo-extensionregisters Dubbo services with the EDAS registry and handles HSF-format registration and subscription. For a completepom.xmlexample, see the sample code.dubbois the standard Apache Dubbo dependency.
<dependency> <groupId>com.alibaba.edas</groupId> <artifactId>edas-dubbo-extension</artifactId> <version>2.0.5</version> </dependency> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo</artifactId> <version>2.7.3</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> </dependency>
Step 2: Replace the HSF Spring configuration with Dubbo
Rename hsf-provider-beans.xml to dubbo-provider-beans.xml and replace its contents.
Before (hsf-provider-beans.xml):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:hsf="http://www.taobao.com/hsf"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.taobao.com/hsf
http://www.taobao.com/hsf/hsf.xsd" default-autowire="byName">
<bean id="itemService" class="com.alibaba.edas.hsf.provider.DemoServiceImpl" />
<!-- Example of providing a service -->
<hsf:provider id="demoService" interface="com.alibaba.edas.DemoService"
ref="itemService" version="1.0.0">
</hsf:provider>
</beans>After (dubbo-provider-beans.xml):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<dubbo:application name="edas-dubbo-demo-provider"/>
<dubbo:registry id="edas" address="edas://127.0.0.1:8080">
<!-- Register this Dubbo service in HSF format so that HSF consumers can discover it -->
<dubbo:parameter key="hsf.enable" value="true"/>
</dubbo:registry>
<bean id="demoService" class="com.alibaba.edas.dubbo.provider.DemoServiceImpl"/>
<dubbo:service interface="com.alibaba.edas.DemoService" ref="demoService" group="HSF" version="1.0.0"/>
</beans>Configuration details:
| Configuration | Value | Description |
|---|---|---|
| Registry address | edas://127.0.0.1:8080 | Must start with edas://. The IP address and port are placeholders -- EDAS automatically replaces them with the actual service address during deployment. |
hsf.enable parameter | true | Registers the Dubbo service in both HSF and Dubbo formats, making the service visible to existing HSF consumers. |
group and version | HSF / 1.0.0 | Required on <dubbo:service>. Must match the HSF provider's values, or HSF consumers cannot discover the service. |
Step 3: Update web.xml
Replace the Spring context configuration file reference. Change hsf-provider-beans.xml to dubbo-provider-beans.xml:
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:dubbo-provider-beans.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
</web-app>Step 4: Verify locally
Verify service registration
Add the following entry to your hosts file (for example,
/etc/hosts) to point the HSF registry hostname to your local machine:127.0.0.1 jmenv.tbsite.netDownload and start the lightweight configuration center. Extract the package, navigate to the
bindirectory, and run:./startup.shCompile
edas-hsf-demo-provider-warinto a WAR package: The compiled files are stored in thetargetdirectory.mvn clean packageDeploy
edas-hsf-demo-provider.warto Ali-Tomcat, and deployedas-dubbo-demo-provider.warto Apache Tomcat.The two Tomcat instances may have port conflicts. If so, open
conf/server.xmland change ports8005and8080to non-conflicting values.Open the lightweight configuration center at
http://127.0.0.1:8080/#/serviceManagementand find thecom.alibaba.edas.DemoService:1.0.0service. If the service has two registered instances, the Dubbo and HSF services are both registered in HSF format -- dual registration is working correctly.
Verify service calls
Prepare an HSF consumer for testing (
edas-hsf-demo-consumer-war) with this structure: The consumer exposes a servlet that invokes the HSF service upon receiving an HTTP request:edas-hsf-demo-consumer-war/ ├── pom.xml └── src ├── main │ ├── java │ │ └── com │ │ └── alibaba │ │ └── edas │ │ └── hsf │ │ └── consumer │ │ └── IndexServlet.java │ ├── resources │ │ └── hsf-consumer-beans.xml │ └── webapp │ └── WEB-INF │ └── web.xmlpublic class IndexServlet extends HttpServlet { private DemoService demoService; @Override public void init() { WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext()); this.demoService = (DemoService) wac.getBean("demoService"); } @Override public void doGet( HttpServletRequest req, HttpServletResponse resp ) { String result = demoService.sayHello("hsf"); System.out.println("Received: " + result); } }Compile
edas-hsf-demo-consumer-warinto a WAR package and deploy it to a separate Ali-Tomcat instance. Make sure the ports do not conflict.mvn clean packageOpen the lightweight configuration center console. No HSF consumer data appears at this point -- this is expected.
After Ali-Tomcat starts, send a test request:
curl http://localhost:8280/edas-hsf-demo-consumer/index.htmCheck the standard output of the Ali-Tomcat instance running
edas-hsf-demo-consumer.war. If the output shows responses from both the Dubbo and HSF providers, the HSF consumer has called both services:Received: Hello hsf, response from hsf provider: /192.168.XX.XX:62385 Received: Hello hsf, response from dubbo provider: 192.168.XX.XX:20880 Received: Hello hsf, response from hsf provider: /192.168.XX.XX:62385 Received: Hello hsf, response from dubbo provider: 192.168.XX.XX:20880
Migrate the service consumer
The following steps migrate the HSF consumer (edas-hsf-demo-consumer-war) to a Dubbo consumer (edas-dubbo-demo-consumer-war).
Step 1: Update Maven dependencies
Follow the same dependency changes as the service provider: add dubbo and edas-dubbo-extension, and remove edas-sdk. See Step 1 in the provider migration for details.
Step 2: Replace the HSF Spring configuration with Dubbo
Rename hsf-consumer-beans.xml to dubbo-consumer-beans.xml and replace its contents.
Before (hsf-consumer-beans.xml):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:hsf="http://www.taobao.com/hsf"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.taobao.com/hsf
http://www.taobao.com/hsf/hsf.xsd" default-autowire="byName">
<!-- Example of consuming a service -->
<hsf:consumer id="demoService" interface="com.alibaba.edas.DemoService" version="1.0.0">
</hsf:consumer>
</beans>After (dubbo-consumer-beans.xml):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<dubbo:application name="edas-dubbo-demo-consumer"/>
<dubbo:registry id="edas" address="edas://127.0.0.1:8080">
<!-- Subscribe to HSF-format services so this Dubbo consumer can discover HSF providers -->
<dubbo:parameter key="hsf.enable" value="true"/>
</dubbo:registry>
<dubbo:reference id="demoService" interface="com.alibaba.edas.DemoService" group="HSF" version="1.0.0" check="false"/>
</beans>Configuration details:
| Configuration | Value | Description |
|---|---|---|
| Registry address | edas:// | Must start with edas://. |
group and version | HSF / 1.0.0 | Must match the service provider's values. |
check | false | Prevents the consumer from failing at startup if provider addresses have not yet been pushed by the registry. Without this setting, an IllegalStateException occurs when no provider is available. |
hsf.enable parameter | true | Subscribes the Dubbo consumer to HSF-format service data alongside Dubbo-format data. |
Step 3: Update web.xml
Replace hsf-consumer-beans.xml with dubbo-consumer-beans.xml in the contextConfigLocation parameter.
Step 4: Verify locally
Verify service registration
Package the project and deploy it to Apache Tomcat:
Make sure the ports do not conflict with other running Tomcat instances.
mvn clean packageOpen the lightweight configuration center console and confirm that the Dubbo consumer appears as a registered consumer service.
Verify service calls
Send a test request:
curl http://localhost:8280/edas-dubbo-demo-consumer/index.htmCheck the standard output of Apache Tomcat. If the output shows responses from both providers, the Dubbo consumer has called both the HSF and Dubbo services:
Received: Hello dubbo, response from dubbo provider: 192.168.XX.XX:20880 Received: Hello dubbo, response from hsf provider: /192.168.XX.XX:12202 Received: Hello dubbo, response from dubbo provider: 192.168.XX.XX:20880 Received: Hello dubbo, response from hsf provider: /192.168.XX.XX:12202
Deploy to EDAS and verify
The following example uses an Elastic Compute Service (ECS) cluster deployment. Create four applications in Enterprise Distributed Application Service (EDAS):
| Application | Role | Runtime environment |
|---|---|---|
edas-dubbo-demo-provider | Migrated service provider | Apache Tomcat 7.0.91 |
edas-dubbo-demo-consumer | Migrated service consumer | Apache Tomcat 7.0.91 |
edas-hsf-demo-provider | Original HSF provider | EDAS Container V3.5.4 |
edas-hsf-demo-consumer | Original HSF consumer | EDAS Container V3.5.4 |
Deploy the four WAR packages to their respective applications. For instructions, see Deploy applications to EDAS.
Verify that the HSF consumer (
edas-hsf-demo-consumer) can call both HSF and Dubbo providers:curl http://39.106.XX.XXX:8080/index.htmCheck the Ali-Tomcat log at
/home/admin/taobao-tomcat-production-7.0.59.3/logs/catalina.out. If the output shows responses from both providers, the HSF consumer has consumed both HSF and Dubbo services.Verify that the Dubbo consumer (
edas-dubbo-demo-consumer) can call both HSF and Dubbo providers:curl http://192.168.XX.XX:8080/index.htmCheck the Apache Tomcat log at
/home/admin/apache-tomcat-7.0.91/logs/catalina.out. If the output shows responses from both providers, the Dubbo consumer has consumed both HSF and Dubbo services.
FAQ
Dubbo consumer fails to start with "No provider available"
This happens because Dubbo checks for provider addresses at startup by default. If the registry has not yet pushed addresses asynchronously, the startup fails with:
java.lang.IllegalStateException: Failed to check the status of the service com.xxxx.xxxxx.service.xxxxxConfigService. No provider available for the service HSF/com.xxxxx.xxxxx.service.xxxxxxxxxxService:1.0.0 from the url edas://...Add check="false" to your <dubbo:reference>:
<dubbo:reference id="demoService" interface="com.alibaba.edas.DemoService" group="HSF" version="1.0.0" check="false"/>This defers the provider availability check. If your business logic calls the service during initialization, those calls still fail until addresses are available.
HSF consumer gets a NumberFormatException when calling a Dubbo provider
After Dubbo is upgraded to 2.7.x, certain version-parsing logic is incompatible with HSF. The error looks like:
java.lang.NumberFormatException: For input string: ""
at org.apache.dubbo.common.Version.parseInt(Version.java:133)
...Upgrade EDAS Container to V3.5.5. This version includes the HSF-side fix for Dubbo 2.7 compatibility.
Dubbo consumer gets a signature verification error when calling an HSF provider
HSF has a call authentication feature that Dubbo does not support. The error includes:
App [xxxxxxx-...] failed to verify the caller signature [null] for [com.alibaba.edas.DemoService:1.0.0]Add -DneedAuth=false to the JVM arguments of the HSF service provider to disable call authentication.
Dubbo consumer gets a StackOverflowError when calling an HSF provider
Older versions of EDAS Container include a Hessian Lite version that does not support JDK 8 LocalDateTime serialization. The deserialization enters an infinite loop, producing:
java.lang.StackOverflowError: null
at com.alibaba.com.xxxxxx.hessian.io.JavaDeserializer$ByteFieldDeserializer.deserialize(...)
...Upgrade EDAS Container of the HSF provider to V3.5.5 to resolve this issue.