DEV Community

Said Olano
Said Olano

Posted on

Apache Axis: Legacy SOAP Framework Migration (2026-09-01 20:48)

Apache Axis: Legacy SOAP Framework Migration

Apache Axis (and its successor Axis2) powered a generation of SOAP-based web services in the Java ecosystem. While these frameworks served their purpose well, many organizations now face the challenge of maintaining aging Axis deployments that carry security risks, dependency conflicts, and diminishing community support.

This post examines the realities of migrating away from Apache Axis and provides a practical migration strategy.

Why Migrate?

Apache Axis 1.x reached end-of-life years ago, and even Axis2 has seen declining activity. Common motivations for migration include:

  • Security vulnerabilities: Older Axis versions have unpatched CVEs, and the dependency chain (older versions of commons-*, XML parsers) introduces additional risk.
  • Java version compatibility: Axis 1.x struggles on modern JDKs (11, 17, 21) due to removed internal APIs and JAXB/JAX-WS module changes.
  • Maintainability: Generated stubs and WSDL2Java artifacts are brittle and hard to evolve.
  • Ecosystem gravity: Modern frameworks (Spring Boot, JAX-WS RI, Apache CXF) offer better tooling and observability.

Assessing Your Current Deployment

Before writing any code, inventory what you have.

# Find Axis dependencies across a multi-module project
find . -name "pom.xml" -exec grep -l "axis" {} \;

# Identify generated stub packages
grep -r "org.apache.axis" --include="*.java" src/ | wc -l
Enter fullscreen mode Exit fullscreen mode

Document the following:

Aspect Questions to Answer
Contracts Do you have canonical WSDL/XSD files?
Bindings Document/literal or RPC/encoded?
Handlers Custom SOAP handlers for security/logging?
Transport HTTP only, or JMS/other?
Clients Who consumes these services externally?

Warning: RPC/encoded bindings are not WS-I compliant and are poorly supported by modern frameworks. Plan to migrate these to document/literal.

Choosing a Target Framework

The two most common migration targets are Apache CXF and JAX-WS RI (Metro). CXF is generally recommended for its Spring integration, active maintenance, and flexible configuration.

<!-- Apache CXF core dependencies -->
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-frontend-jaxws</artifactId>
    <version>4.0.4</version>
</dependency>
<dependency>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-rt-transports-http</artifactId>
    <version>4.0.4</version>
</dependency>
Enter fullscreen mode Exit fullscreen mode

Migration Strategy: Contract-First

The safest migration preserves your existing WSDL contract so external clients require no changes. This is a contract-first approach.

Step 1: Extract the Canonical WSDL

If you only have Axis-generated stubs, retrieve the published WSDL from the running service:

curl "http://legacy-host:8080/services/OrderService?wsdl" -o OrderService.wsdl
Enter fullscreen mode Exit fullscreen mode

Clean up any Axis-specific namespace quirks and validate against WS-I Basic Profile.

Step 2: Generate CXF Artifacts

Use the CXF wsdl2java tool to regenerate client and server-side code:

wsdl2java -d src/generated -impl -server \
    -p com.example.orders \
    OrderService.wsdl
Enter fullscreen mode Exit fullscreen mode

Wire this into your build for reproducibility:

<plugin>
    <groupId>org.apache.cxf</groupId>
    <artifactId>cxf-codegen-plugin</artifactId>
    <version>4.0.4</version>
    <executions>
        <execution>
            <id>generate-sources</id>
            <phase>generate-sources</phase>
            <configuration>
                <wsdlOptions>
                    <wsdlOption>
                        <wsdl>${basedir}/src/main/resources/OrderService.wsdl</wsdl>
                    </wsdlOption>
                </wsdlOptions>
            </configuration>
            <goals>
                <goal>wsdl2java</goal>
            </goals>
        </execution>
    </executions>
</plugin>
Enter fullscreen mode Exit fullscreen mode

Step 3: Reimplement the Service Endpoint

Move your business logic into a clean JAX-WS annotated implementation. The generated SEI (Service Endpoint Interface) enforces contract fidelity.

@WebService(
    endpointInterface = "com.example.orders.OrderPortType",
    targetNamespace = "http://example.com/orders",
    serviceName = "OrderService"
)
public class OrderServiceImpl implements OrderPortType {

    private final OrderRepository repository;

    public OrderServiceImpl(OrderRepository repository) {
        this.repository = repository;
    }

    @Override
    public OrderResponse getOrder(OrderRequest request) {
        // Business logic migrated from the old Axis skeleton
        Order order = repository.findById(request.getOrderId());
        OrderResponse response = new OrderResponse();
        response.setStatus(order.getStatus());
        response.setTotal(order.getTotal());
        return response;
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 4: Publish the Endpoint

With Spring Boot and CXF, endpoint publishing is declarative:


java
@Configuration
public class WebServiceConfig {

    @Bean
    public ServletR
Enter fullscreen mode Exit fullscreen mode

Top comments (0)