codecentric / cxf-spring-boot-starter

Enterprise & production ready SOAP webservices powered by Spring Boot & Apache CXF
https://blog.codecentric.de/en/2016/10/spring-boot-apache-cxf-spring-boot-starter/
143 stars 78 forks source link

JakartaEE 9: Use new jakarta.* packages for nearly all JakartaEE WS & XML-type interfaces #95

Open jonashackt opened 3 years ago

jonashackt commented 3 years ago

With the release of the new jakarta libraries from 3.0.0 on all needed interfaces for this framework to work are mostly renamed and transfered to the jakarta.xml.xyz package, which breaks nearly everything. Imports change from

import javax.xml.ws.Endpoint;
import javax.xml.ws.Service;

import javax.jws.WebService;
import javax.xml.ws.WebServiceClient;

import javax.jws.WebMethod;
import javax.xml.bind.JAXB;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSchema;

to

import jakarta.xml.ws.Endpoint;
import jakarta.xml.ws.Service;

import jakarta.jws.WebService;
import jakarta.xml.ws.WebServiceClient;

import jakarta.jws.WebMethod;
import jakarta.xml.bind.*;
import jakarta.xml.bind.annotation.XmlRootElement;
import jakarta.xml.bind.annotation.XmlSchema;
jonashackt commented 3 years ago

We have a huge problem, since the latest Apache CXF cxf-rt-frontend-jaxws developed here https://github.com/apache/cxf doesnt support the newest Jakarta 3.0.0 package names.

Since we need to cast from org.apache.cxf.jaxws.EndpointImpl to jakarta.xml.ws.Endpoint - but CXF only knows javax.xml.ws.Endpoint. For example see https://github.com/codecentric/cxf-spring-boot-starter/blob/migrate-to-jakarta-3.0.0-packages/cxf-spring-boot-starter/src/main/java/de/codecentric/cxf/configuration/XmlValidationConfiguration.java :

@Autowired
    public Endpoint endpoint;

    @PostConstruct
    public void configureInterceptor2Endpoint() {    
        EndpointImpl endpointImpl = (EndpointImpl)endpoint; // we need the implementation here, to configure our Interceptor
        endpointImpl.getOutFaultInterceptors().add(soapInterceptor());
    }

Let's see if there's an issue already (https://issues.apache.org/jira/projects/CXF/issues/CXF-8293?filter=allopenissues) - maybe the 3.5.x comes with the support... See https://issues.apache.org/jira/browse/CXF-8371

jonashackt commented 3 years ago

There's already a CXF PR / Draft: https://github.com/apache/cxf/pull/737

jonashackt commented 3 years ago

An idea from this CXF draft would also be to use the maven-shade-plugin as described in https://github.com/apache/openwebbeans/blob/master/pom.xml#L353 With that we would be able to support both javax and jakarta package names at the same time with minimal effort. I have no glue, if that is working in our case. But it seems to be the cheapest way. And from the discussion in https://github.com/apache/cxf/pull/737 I take it for granted, that both the namespaces will stay for the next 3 years... What do you think @marcopaga ?

The pom.xml configuration for the maven-shade-plugin would look similar to this:

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>${maven-shade-plugin.version}</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <shadedArtifactAttached>true</shadedArtifactAttached>
                            <shadedClassifierName>jakarta</shadedClassifierName>
                            <createDependencyReducedPom>false</createDependencyReducedPom>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
                            </transformers>
                            <artifactSet> <!-- don't include transitive deps -->
                                <includes>
                                    <include>${project.groupId}:${project.artifactId}</include>
                                </includes>
                            </artifactSet>
                            <relocations>
                                <relocation>
                                    <pattern>javax.annotation</pattern>
                                    <shadedPattern>jakarta.annotation</shadedPattern>
                                </relocation>
                                <relocation>
                                    <pattern>javax.el</pattern>
                                    <shadedPattern>jakarta.el</shadedPattern>
                                </relocation>
                                <relocation>
                                    <pattern>javax.enterprise</pattern>
                                    <shadedPattern>jakarta.enterprise</shadedPattern>
                                </relocation>
                                <relocation>
                                    <pattern>javax.decorator</pattern>
                                    <shadedPattern>jakarta.decorator</shadedPattern>
                                </relocation>
                                <relocation>
                                    <pattern>javax.inject</pattern>
                                    <shadedPattern>jakarta.inject</shadedPattern>
                                </relocation>
                                <relocation>
                                    <pattern>javax.interceptor</pattern>
                                    <shadedPattern>jakarta.interceptor</shadedPattern>
                                </relocation>
                                <relocation>
                                    <pattern>javax.servlet</pattern>
                                    <shadedPattern>jakarta.servlet</shadedPattern>
                                </relocation>
                                <relocation>
                                    <pattern>javax.transaction</pattern>
                                    <shadedPattern>jakarta.transaction</shadedPattern>
                                </relocation>
                                <relocation>
                                    <pattern>javax.validation</pattern>
                                    <shadedPattern>jakarta.validation</shadedPattern>
                                </relocation>
                                <relocation>
                                    <pattern>javax.persistence</pattern>
                                    <shadedPattern>jakarta.persistence</shadedPattern>
                                </relocation>
                                <relocation>
                                    <pattern>javax.faces</pattern>
                                    <shadedPattern>jakarta.faces</shadedPattern>
                                </relocation>
                                <relocation>
                                    <pattern>javax.ejb</pattern>
                                    <shadedPattern>jakarta.ejb</shadedPattern>
                                </relocation>
                                <relocation>
                                    <pattern>javax.jms</pattern>
                                    <shadedPattern>jakarta.jms</shadedPattern>
                                </relocation>
                                <!--
                                todo: javax.transaction, it is in the JVM so can have issue repackaging
                                -->
                            </relocations>
                        </configuration>
                    </execution>
                </executions>
            </plugin>