cxfjax-wstomcat9

CXFServlet cannot be cast to class javax.servlet.Servlet


I inheritaded a web service from my predecessor and I had to "actualise" the dependencies. That done, I'm trying to deploy it into Tomcat 9.0.75 and in the Log-File I get this error message:

17-Nov-2023 13:01:19.626 SEVERE [main] org.apache.catalina.core.StandardContext.loadOnStartup Servlet [CXFServlet] in web application [/my-ws] threw load() exception java.lang.ClassCastException: class org.apache.cxf.transport.servlet.CXFServlet cannot be cast to class javax.servlet.Servlet (org.apache.cxf.transport.servlet.CXFServlet is in unnamed module of loader org.apache.catalina.loader.ParallelWebappClassLoader @5b144f61; javax.servlet.Servlet is in unnamed module of loader java.net.URLClassLoader @2b2948e2) at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1020) at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:960) at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4673) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4980) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:683) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:658) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:662) at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1023) at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1910) at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:118) at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:824) at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:474) at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1617) at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:318) at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123) at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:423) at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:366) at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:898) at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:795) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1332) at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1322) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:140) at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:871) at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:249) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.StandardService.startInternal(StandardService.java:428) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:914) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) at org.apache.catalina.startup.Catalina.start(Catalina.java:772) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:347) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:478) 17-Nov-2023 13:04:48.130 INFO [Thread-1] org.apache.catalina.core.ApplicationContext.log Closing Spring root WebApplicationContext

Searching for similar problems and reading the answers, I saw that the problem could be that I have multiple versions of the servlet API in the classpath. Is there a way to find out exactly in which dependencies this happens? What do I have to do? Below is my pom file (if it could help and maybe someone sees on the fly where is the problem...). If something else is needed, let me know.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>iam.webservice</groupId>
    <artifactId>IAM-Web-Services</artifactId>
    <version>2019-1.2</version>

    <packaging>war</packaging>

    <name>IAM Web services</name>
    
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <cxf.version>4.0.3</cxf.version>
        <spring.version>5.3.30</spring.version>
        <jackson.version>2.15.2</jackson.version>
        <mapstruct.version>1.3.1.Final</mapstruct.version>
        <dirx.version>8.9</dirx.version>
        <version.tomcat.maven.plugin>2.2</version.tomcat.maven.plugin>
        <junit.version>4.13.2</junit.version>
        <swagger.ui.version>3.24.3</swagger.ui.version>
        <CATALINA_HOME>D:/IAM/Apache Software Foundation/Tomcat 9</CATALINA_HOME>
        <timestamp>${maven.build.timestamp}</timestamp>
        <maven.build.timestamp.format>yyyy-MM-dd HH:mm</maven.build.timestamp.format>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-java2wadl-plugin</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-rs-client</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-rs-service-description</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-rs-service-description-openapi-v3</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-features-logging</artifactId>
            <version>${cxf.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>${cxf.version}</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.jakarta.rs</groupId>
            <artifactId>jackson-jakarta-rs-base</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.jakarta.rs</groupId>
            <artifactId>jackson-jakarta-rs-json-provider</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.jakarta.rs</groupId>
            <artifactId>jackson-jakarta-rs-xml-provider</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-xml</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
            <version>${jackson.version}</version>
        </dependency>
                
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        
        <!--
        <dependency>
            <groupId>jakarta.platform</groupId>
            <artifactId>jakarta.jakartaee-api</artifactId>
            <version>9.1.0</version>
        </dependency> -->

        <!-- https://mvnrepository.com/artifact/org.mapstruct/mapstruct -->
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>${mapstruct.version}</version>
        </dependency>

        <!-- ******* -->
        <!-- Testing -->
        <!-- ******* -->
        <!-- place rest-assured before the JUnit dependency declaration -->
        <dependency>
        <groupId>io.rest-assured</groupId>
            <artifactId>rest-assured</artifactId>
            <version>5.3.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.assertj</groupId>
            <artifactId>assertj-core</artifactId>
            <version>3.24.2</version>
            <scope>test</scope>
        </dependency>

        <!-- ******* -->
        <!-- Logging -->
        <!-- ******* -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-reload4j</artifactId>
            <version>2.0.7</version>
        </dependency>
        
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>2.0.7</version>
        </dependency>
        
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.20.0</version>
        </dependency>


        <!-- ******* -->
        <!--  DirX   -->
        <!-- ******* -->
        <dependency>
            <groupId>com.siemens.dxm.provisioning</groupId>
            <artifactId>dxm-provisioning</artifactId>
            <version>${dirx.version}</version>
        </dependency>

        <dependency>
            <groupId>com.siemens.dxm.spmlv2</groupId>
            <artifactId>dxm-SPML</artifactId>
            <version>${dirx.version}</version>
        </dependency>

        <dependency>
            <groupId>com.siemens.dirxcommon.logging</groupId>
            <artifactId>dxc-Logging</artifactId>
            <version>${dirx.version}</version>
        </dependency>

        <dependency>
            <groupId>com.siemens.dirxcommon.crypto</groupId>
            <artifactId>dxc-Crypto</artifactId>
            <version>${dirx.version}</version>
        </dependency>

        <dependency>
            <groupId>com.siemens.dxm.connector</groupId>
            <artifactId>dxm-Connector</artifactId>
            <version>${dirx.version}</version>
        </dependency>

        <dependency>
            <groupId>com.siemens.dxm.util</groupId>
            <artifactId>dxm-Util</artifactId>
            <version>${dirx.version}</version>
        </dependency>

        <dependency>
            <groupId>siemens.dxr.service</groupId>
            <artifactId>dxr-Services</artifactId>
            <version>${dirx.version}</version>
        </dependency>
        
        <!-- additional libraries needed by dirx -->
        <dependency>
            <groupId>org.apache.axis</groupId>
            <artifactId>axis</artifactId>
            <version>1.4</version>
        </dependency>

        <dependency>
            <groupId>javax.xml</groupId>
            <artifactId>jaxrpc-api</artifactId>
            <version>1.1</version>
        </dependency>
        <dependency>
            <groupId>org.snmp4j</groupId>
            <artifactId>snmp4j</artifactId>
            <version>3.7.7</version>
        </dependency>

        <dependency>
            <groupId>org.codehaus.castor</groupId>
            <artifactId>castor-xml</artifactId>
            <version>1.4.1</version>
        </dependency>

        <dependency>
            <groupId>net.jmatrix</groupId>
            <artifactId>eproperties</artifactId>
            <version>1.1.5</version>
        </dependency>

        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>4.4.3</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/commons-discovery/commons-discovery -->
        <dependency>
            <groupId>commons-discovery</groupId>
            <artifactId>commons-discovery</artifactId>
            <version>0.5</version>
        </dependency>

        <dependency>
            <groupId>org.jetbrains</groupId>
            <artifactId>annotations</artifactId>
            <version>24.0.1</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.13.0</version>
        </dependency>
        
        <dependency>
            <groupId>commons-validator</groupId>
            <artifactId>commons-validator</artifactId>
            <version>1.7</version>
        </dependency>
        
        <dependency>
            <groupId>jakarta.servlet</groupId>
            <artifactId>jakarta.servlet-api</artifactId>
            <version>6.0.0</version>
        </dependency>

        <dependency>
            <groupId>com.sun.mail</groupId>
            <artifactId>jakarta.mail</artifactId>
            <version>2.0.1</version>
        </dependency>

        <!-- This plugin helps finding the latest plugin or dependency versions for your modules. Open up the terminal and execute this command to find the plugin versions you have to update: mvn versions:display-plugin-updates -->
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>swagger-ui</artifactId>
            <version>5.2.0</version>
        </dependency>
        
        <dependency>
            <groupId>io.swagger.core.v3</groupId>
            <artifactId>swagger-jaxrs2-jakarta</artifactId>
            <version>2.2.15</version>
        </dependency>
        
        <dependency>
            <groupId>io.swagger.core.v3</groupId>
            <artifactId>swagger-jaxrs2-servlet-initializer-jakarta</artifactId>
            <version>2.2.15</version>
        </dependency> 
    </dependencies>

    <build>
        <finalName>my-ws</finalName>

        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>

        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.8.1</version>
                    <configuration>
                        <release>11</release>
                        <fork>true</fork>
                        <executable>C:\Program Files\RedHat\java-11-openjdk\bin\javac</executable>
                        <compilerArgument> -Xlint:unchecked </compilerArgument>
                        <annotationProcessorPaths>
                            <path>
                                <groupId>org.mapstruct</groupId>
                                <artifactId>mapstruct-processor</artifactId>
                                <version>${mapstruct.version}</version>
                            </path>
                        </annotationProcessorPaths>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.tomcat.maven</groupId>
                    <artifactId>tomcat7-maven-plugin</artifactId>
                    <version>${version.tomcat.maven.plugin}</version>
                    <configuration>
                        <path>/${project.build.finalName}</path>
                        <configurationDir>${CATALINA_HOME}</configurationDir>
                        <additionalConfigFilesDir>${CATALINA_HOME}/conf</additionalConfigFilesDir>
                        <uriEncoding>${project.build.sourceEncoding}</uriEncoding>
                        <url>http://localhost:8080/manager/text</url>
                        <username>xxx</username>
                        <password>yyy</password>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.cxf</groupId>
                    <artifactId>cxf-java2wadl-plugin</artifactId>
                    <version>${cxf.version}</version>
                    <executions>
                        <execution>
                            <id>process-classes</id>
                            <phase>process-classes</phase>
                            <goals>
                                <goal>java2wadl</goal>
                            </goals>
                            <configuration>
                                <classResourceNames>
                                    <classResourceName>a.b.c.CustomerService</classResourceName>
                                </classResourceNames>
                                <attachWadl>true</attachWadl>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>3.0.0-M3</version>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-failsafe-plugin</artifactId>
                    <version>3.0.0-M3</version>
                    <executions>
                        <execution>
                            <goals>
                                <goal>integration-test</goal>
                                <goal>verify</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

</project>

In the web.xml the servlet is also defined:

...
<servlet>
        <servlet-name>CXFServlet</servlet-name>
        <display-name>IAM Web Services</display-name>
        <servlet-class>
            org.apache.cxf.transport.servlet.CXFServlet
        </servlet-class>
        <load-on-startup>1</load-on-startup>
...

Solution

  • class org.apache.cxf.transport.servlet.CXFServlet cannot be cast to class javax.servlet.Servlet

    That can happen when an instance of the org.apache.cxf.transport.servlet.CXFServlet class in the current runtime classpath is not assignable as an instance of the javax.servlet.Servlet class in the current runtime classpath.

    According to your pom.xml you're using CXF version 4.x which is the first Jakartified version. I.e. the first version whereby javax.* package has been migrated to jakarta.* package in order to comply the new package names introduced in Jakarta EE 9 (released Dec 2020 already). So, the version 4.x CXFServlet is actually an instance of jakarta.servlet.Servlet instead of javax.servlet.Servlet. The exception being thrown is entirely correct.

    You have basically 2 solutions:

    1. Downgrade CXF to 3.x, the latest version which still uses the old javax package.
    2. Or, upgrade the servletcontainer to a minimum of Servlet 5.0 (Tomcat 10.0.x), preferably to the current latest version of Servlet 6.0 (Tomcat 10.1.x).

    In your specific case, solution #1 is the quickest solution because you apparently have a bunch of other old versioned dependencies (Spring et.al) and you apparently explicitly target the old Tomcat 9.x server. Solution #2, however, is the best long-term solution because, clearly, the javax.* package is a dead end for JEE.