Search code examples
mavendeploymentconfigurationjettyjetty-12

Deploying Jakarta EE Application on Jetty 12: from jetty-ee10-maven-plugin to deployment on Jetty, ClassNotFoundException and CDIProvider Issues


I have a jakarta ee project that runs on jetty where I need cdi and faces. During development I used to run this through the jetty-ee10-maven-plugin plugin running a mvn jetty:run. In local performing a mvn jetty:run works fine with no problems.

Now that the project is more or less ready I was confident that exporting the war and deploying it on a jetty webserver 12.0.4 would be easy.

The important parts of my pom.xml are these:

<?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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.test</groupId>
    <artifactId>web</artifactId>
    <version>1.0.7</version>
    <packaging>war</packaging>
    <name>xyz_web</name>

    <properties>
        <maven.compiler.source>21</maven.compiler.source>
        <maven.compiler.target>21</maven.compiler.target>
        <maven.compiler.release>21</maven.compiler.release>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

        <jetty.version>12.0.9</jetty.version>
        <jetty.port>8080</jetty.port>        
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.primefaces</groupId>
            <artifactId>primefaces</artifactId>
            <version>13.0.8</version>
            <classifier>jakarta</classifier>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.primefaces.extensions/primefaces-extensions -->
        <dependency>
            <groupId>org.primefaces.extensions</groupId>
            <artifactId>primefaces-extensions</artifactId>
            <version>13.0.8</version>
            <classifier>jakarta</classifier>
        </dependency>

        <!-- https://mvnrepository.com/artifact/jakarta.platform/jakarta.jakartaee-api -->
        <dependency>
            <groupId>jakarta.platform</groupId>
            <artifactId>jakarta.jakartaee-api</artifactId>
            <version>${jakartaee-api.version}</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>jakarta.servlet</groupId>
            <artifactId>jakarta.servlet-api</artifactId>
            <version>6.0.0</version>
            <scope>provided</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/jakarta.inject/jakarta.inject-api -->
        <dependency>
            <groupId>jakarta.inject</groupId>
            <artifactId>jakarta.inject-api</artifactId>
            <version>2.0.1</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/jakarta.ejb/jakarta.ejb-api -->
        <dependency>
            <groupId>jakarta.ejb</groupId>
            <artifactId>jakarta.ejb-api</artifactId>
            <version>4.0.1</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish</groupId>
            <artifactId>jakarta.faces</artifactId>
            <version>4.0.5</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/jakarta.xml.bind/jakarta.xml.bind-api -->
        <dependency>
            <groupId>jakarta.xml.bind</groupId>
            <artifactId>jakarta.xml.bind-api</artifactId>
            <version>4.0.2</version>
        </dependency>

        <dependency>
            <groupId>org.jboss.weld.servlet</groupId>
            <artifactId>weld-servlet-core</artifactId>
            <version>5.1.2.Final</version>
            <exclusions>
                <exclusion>
                    <groupId>jakarta.el</groupId>
                    <artifactId>jakarta.el-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.omnifaces</groupId>
            <artifactId>omnifaces</artifactId>
            <version>4.3</version>
        </dependency>

        <!-- Other dependencies not related to jetty or server -->
        <!-- Other dependencies not related to jetty or server -->
        <!-- Other dependencies not related to jetty or server -->
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.12.1</version>
                <configuration>
                    <source>${maven.compiler.source}</source>
                    <target>${maven.compiler.target}</target>
                    <release>${maven.compiler.release}</release>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.4.0</version>
                <configuration>
                    <webResources>
                        <resource>
                            <filtering>true</filtering>
                            <directory>src/main/webapp</directory>
                            <includes>
                                <include>**/web.xml</include>
                            </includes>
                        </resource>
                    </webResources>
                    <warSourceDirectory>src/main/webapp</warSourceDirectory>
                    <webXml>${project.build.directory}/web.xml</webXml>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.eclipse.jetty.ee10</groupId>
                <artifactId>jetty-ee10-maven-plugin</artifactId>
                <version>${jetty.version}</version>
                <configuration>
                    <!-- see https://eclipse.dev/jetty/documentation/jetty-12/programming-guide/index.html#jetty-run-goal -->
                    <webApp>
                        <contextPath>/</contextPath>
                    </webApp>
                    <scan>5</scan>
                    <webXml>${project.build.directory}/web.xml</webXml>
                    <httpConnector>
                        <host>0.0.0.0</host>
                        <port>${jetty.port}</port>
                        <idleTimeout>300000</idleTimeout>
                    </httpConnector>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>org.eclipse.jetty.ee10</groupId>
                        <artifactId>jetty-ee10-cdi</artifactId>
                        <version>${jetty.version}</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>

        <!-- Parses all files in the specified directory and replaces properties expressions if found -->
        <resources>
            <resource>
                <directory>${basedir}/src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>${basedir}/src/main/webapp/WEB-INF</directory>
                <includes>
                    <include>web.xml</include>
                </includes>
                <filtering>true</filtering>
                <targetPath>${project.build.directory}</targetPath>
            </resource>
        </resources>
    </build>
</project>

When I deploy my war file on that cloud jetty server I get this error:

Caused by:
java.lang.ClassNotFoundException: jakarta.websocket.server.ServerContainer
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:445)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:593)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
at org.eclipse.jetty.ee10.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:496)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
at com.sun.faces.config.FacesInitializer.handleWebSocketConcerns(FacesInitializer.java:251)
at com.sun.faces.config.FacesInitializer.onStartup(FacesInitializer.java:123)
at org.eclipse.jetty.ee10.servlet.ServletContainerInitializerHolder.doStart(ServletContainerInitializerHolder.java:155)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:93)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:171)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
at org.eclipse.jetty.ee10.servlet.ServletContextHandler$ServletContainerInitializerStarter.doStart(ServletContextHandler.java:3041)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:93)
at org.eclipse.jetty.ee10.servlet.ServletContextHandler.startContext(ServletContextHandler.java:1289)
at org.eclipse.jetty.ee10.webapp.WebAppContext.startContext(WebAppContext.java:1223)
at org.eclipse.jetty.ee10.servlet.ServletContextHandler.lambda$doStart$0(ServletContextHandler.java:1042)
at org.eclipse.jetty.server.handler.ContextHandler$ScopedContext.call(ContextHandler.java:1147)
at org.eclipse.jetty.ee10.servlet.ServletContextHandler.doStart(ServletContextHandler.java:1039)
at org.eclipse.jetty.ee10.webapp.WebAppContext.doStart(WebAppContext.java:496)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:93)
at org.eclipse.jetty.deploy.bindings.StandardStarter.processBinding(StandardStarter.java:40)
at org.eclipse.jetty.deploy.AppLifeCycle.runBindings(AppLifeCycle.java:183)
at org.eclipse.jetty.deploy.DeploymentManager.requestAppGoal(DeploymentManager.java:522)
at org.eclipse.jetty.deploy.DeploymentManager.addApp(DeploymentManager.java:162)
at org.eclipse.jetty.deploy.providers.ScanningAppProvider.pathAdded(ScanningAppProvider.java:293)
at org.eclipse.jetty.deploy.providers.ContextProvider.pathAdded(ContextProvider.java:520)
at org.eclipse.jetty.deploy.providers.ScanningAppProvider$1.pathAdded(ScanningAppProvider.java:69)
at org.eclipse.jetty.util.Scanner.reportAddition(Scanner.java:902)
at org.eclipse.jetty.util.Scanner.reportDifferences(Scanner.java:868)
at org.eclipse.jetty.util.Scanner.scan(Scanner.java:775)
at org.eclipse.jetty.util.Scanner$ScanTask.run(Scanner.java:147)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)

So even if I'm not sure I tried adding this dependency inside of the pom.xml.

<!-- Added to solve "java.lang.ClassNotFoundException: jakarta.websocket.server.ServerContainer" -->
<dependency>
    <groupId>org.glassfish.tyrus.bundles</groupId>
    <artifactId>tyrus-standalone-client</artifactId>
    <version>2.2.0</version>
</dependency>

And now I get this error:

java.lang.IllegalStateException: Unable to locate CDIProvider
at jakarta.enterprise.inject.spi.CDI.findAllProviders(CDI.java:139)
at jakarta.enterprise.inject.spi.CDI.getCDIProvider(CDI.java:92)
at jakarta.enterprise.inject.spi.CDI.current(CDI.java:65)
at org.jboss.weld.module.web.servlet.WeldInitialListener.contextInitialized(WeldInitialListener.java:89)
at org.jboss.weld.servlet.api.helpers.ForwardingServletListener.contextInitialized(ForwardingServletListener.java:34)
at org.jboss.weld.environment.servlet.EnhancedListener.onStartup(EnhancedListener.java:70)
at org.eclipse.jetty.ee10.servlet.ServletContainerInitializerHolder.doStart(ServletContainerInitializerHolder.java:155)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:93)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:171)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
at org.eclipse.jetty.ee10.servlet.ServletContextHandler$ServletContainerInitializerStarter.doStart(ServletContextHandler.java:3041)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:93)
at org.eclipse.jetty.ee10.servlet.ServletContextHandler.startContext(ServletContextHandler.java:1289)
at org.eclipse.jetty.ee10.webapp.WebAppContext.startContext(WebAppContext.java:1223)
at org.eclipse.jetty.ee10.servlet.ServletContextHandler.lambda$doStart$0(ServletContextHandler.java:1042)
at org.eclipse.jetty.server.handler.ContextHandler$ScopedContext.call(ContextHandler.java:1147)
at org.eclipse.jetty.ee10.servlet.ServletContextHandler.doStart(ServletContextHandler.java:1039)
at org.eclipse.jetty.ee10.webapp.WebAppContext.doStart(WebAppContext.java:496)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:93)
at org.eclipse.jetty.deploy.bindings.StandardStarter.processBinding(StandardStarter.java:40)
at org.eclipse.jetty.deploy.AppLifeCycle.runBindings(AppLifeCycle.java:183)
at org.eclipse.jetty.deploy.DeploymentManager.requestAppGoal(DeploymentManager.java:522)
at org.eclipse.jetty.deploy.DeploymentManager.addApp(DeploymentManager.java:162)
at org.eclipse.jetty.deploy.providers.ScanningAppProvider.pathAdded(ScanningAppProvider.java:293)
at org.eclipse.jetty.deploy.providers.ContextProvider.pathAdded(ContextProvider.java:520)
at org.eclipse.jetty.deploy.providers.ScanningAppProvider$1.pathAdded(ScanningAppProvider.java:69)
at org.eclipse.jetty.util.Scanner.reportAddition(Scanner.java:902)
at org.eclipse.jetty.util.Scanner.reportDifferences(Scanner.java:868)
at org.eclipse.jetty.util.Scanner.scan(Scanner.java:775)
at org.eclipse.jetty.util.Scanner$ScanTask.run(Scanner.java:147)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)

I have tried a lot of other configurations, adding many other dependencies but I cannot find what I am missing.

The version of Jetty server on the cloud is 12.0.4. My Jetty Server start.ini file is the following one:

#===========================================================
# Jetty Startup 
#===========================================================

# To disable the warning message, comment the following line
--module=home-base-warning

# --------------------------------------- 
# Module: ext
# Adds all jar files discovered in $JETTY_HOME/lib/ext
# and $JETTY_BASE/lib/ext to the servers classpath.
# --------------------------------------- 
--module=ext


# --------------------------------------- 
# Module: server
# Enables the core Jetty server on the classpath.
# --------------------------------------- 
--module=server

### Common HTTP configuration
## Scheme to use to build URIs for secure redirects
# jetty.httpConfig.secureScheme=https

## Port to use to build URIs for secure redirects
jetty.httpConfig.securePort=443

# --------------------------------------- 
# Module: jsp
# Enables JSP for all webapplications deployed on the server.
# --------------------------------------- 
--module=ee10-jsp
--module=ee9-jsp
--module=ee8-jsp


# --------------------------------------- 
# Module: resources
# Adds the $JETTY_HOME/resources and/or $JETTY_BASE/resources
# directory to the server classpath. Useful for configuration
# property files (eg jetty-logging.properties)
# --------------------------------------- 
--module=resources


# --------------------------------------- 
# Module: deploy
# Enables webapplication deployment from the webapps directory.
# --------------------------------------- 
--module=deploy
jetty.deploy.scanInterval=1

--module=ee10-deploy
jetty.deploy.scanInterval=1

--module=ee9-deploy
jetty.deploy.scanInterval=1

--module=ee8-deploy
jetty.deploy.scanInterval=1

# --------------------------------------- 
# Module: jstl
# Enables JSTL for all webapplications deployed on the server
# --------------------------------------- 
--module=ee10-jstl
--module=ee9-jstl
--module=ee8-jstl

# --------------------------------------- 
# Module: websocket
# Enable websockets for deployed web applications
# --------------------------------------- 
--module=websocket-jetty


# --------------------------------------- 
# Module: http
# Enables a HTTP connector on the server.
# By default HTTP/1 is support, but HTTP2C can
# be added to the connector with the http2c module.
# --------------------------------------- 
--module=http

### HTTP Connector Configuration

## Connector port to listen on
jetty.http.port=80

## HTTP Compliance: RFC7230, RFC7230_LEGACY, RFC2616, RFC2616_LEGACY, LEGACY or CUSTOMn
# jetty.http.compliance=RFC7230_LEGACY
# --------------------------------------- 
# Module: requestlog
# Enables a NCSA style request log.
# --------------------------------------- 
--module=requestlog

## Logging directory (relative to $jetty.base)
jetty.requestlog.dir=../../var/log/jetty

# --------------------------------------- 
# Module: gzip
# Enable GzipHandler for dynamic gzip compression
# for the entire server.
# --------------------------------------- 
--module=gzip

Solution

  • Drop tyrus (it will never work on Jetty anyway, as it conflicts with the built-in Websocket support in Jetty).

    Enable the following jetty-base modules instead ...

    • ee10-websocket-jakarta for jakarta.websocket support.
    • ee10-cdi for environment level CDI support.