I am having a simple java maven project which generates some user Ids for a given GET
request. I am using javax.servlet
package.
Everything works fine when I am packaging and deploying the war
file in local jetty
server.
However things are not working when I am using the docker jetty
image and deploying the war
file. I am getting the below error
MacBook-Pro-3:UIDGenerators unbxd$ docker run 0xvoila/uid-generator:latest
2022-07-03 17:50:09.448:INFO :oejs.Server:main: jetty-11.0.11; built: 2022-06-21T21:42:55.454Z; git: 58487315cb75e0f5c81cc6fa50096cbeb3b9554e; jvm 17.0.3 7
2022-07-03 17:50:09.523:INFO :oejdp.ScanningAppProvider:main: Deployment monitor [file:///var/lib/jetty/webapps/]
2022-07-03 17:50:10.234:INFO :oejss.DefaultSessionIdManager:main: Session workerName=node0
2022-07-03 17:50:10.291:WARN :oejw.WebAppContext:main: Failed startup of context o.e.j.w.WebAppContext@4f67eb2a{Archetype Created Web Application,/uid-generator,file:///tmp/jetty-0_0_0_0-8080-uid-generator_war-_uid-generator-any-15856705197144621036/webapp/,UNAVAILABLE}{/var/lib/jetty/webapps/uid-generator.war}
java.lang.NoClassDefFoundError: javax/servlet/http/HttpServlet
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1012)
at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
at java.base/java.net.URLClassLoader.defineClass(URLClassLoader.java:524)
at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:427)
at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:421)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
Here is my pom.xml
file
<?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>org.amit.system</groupId>
<artifactId>UIDGenerators</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>UIDGenerators Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>uid-generator</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<!-- <plugin>-->
<!-- <groupId>org.eclipse.jetty</groupId>-->
<!-- <artifactId>jetty-maven-plugin</artifactId>-->
<!-- <version>9.4.28.v20200408</version>-->
<!-- </plugin>-->
</plugins>
</pluginManagement>
</build>
</project>
Here is my Dockerfile
FROM maven as build
COPY src /home/app/src
COPY pom.xml /home/app
RUN mvn -f /home/app/pom.xml clean package
FROM jetty:latest
COPY --from=build /home/app/target/uid-generator.war /var/lib/jetty/webapps
CMD java -jar "$JETTY_HOME/start.jar"
I tried to debug myself and it seems like javax. servlet
is not present in the jetty
docker image. But in my pom.xml
file I had given javax.servlet
as dependencies.
Can anyone help me with the solution.
UPDATED
Here is the java code
package org.amit.system;
import java.io.IOException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class UIDGenerator extends HttpServlet {
int sequence = 0;
final static int sequenceBits = 12; // max is 4096
final static int maxSequence = (int)Math.pow(2, sequenceBits) - 1;
final static int nodeId = 11;
final static int nodeBits = 10; // max is 1024
public synchronized int generateSequence(long runningMillisecond){
this.sequence = this.sequence 1;
if (this.sequence >= maxSequence && runningMillisecond == System.currentTimeMillis()){
waitOneMillisecond(runningMillisecond);
this.sequence = 0;
}
return this.sequence;
}
private void waitOneMillisecond(long runningMillisecond){
while(runningMillisecond == System.currentTimeMillis()){
continue;
}
}
public int generateNodeId(){
return this.nodeId;
}
public void run(){
int nodeNumber = this.generateNodeId();
long epoch = System.currentTimeMillis();
int sequence = this.generateSequence(epoch);
// System.out.println("Echo before shift " epoch);
epoch = epoch << (this.nodeBits this.sequenceBits);
epoch = epoch | nodeNumber << this.sequenceBits;
epoch = epoch | sequence;
System.out.println("Echo after shift " epoch);
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException
{
int nodeNumber = this.generateNodeId();
long epoch = System.currentTimeMillis();
int sequence = this.generateSequence(epoch);
epoch = epoch << (this.nodeBits this.sequenceBits);
epoch = epoch | nodeNumber << this.sequenceBits;
epoch = epoch | sequence;
response.getOutputStream().print("Echo after shift " epoch);
}
}
CodePudding user response:
Jetty 9 is at End of Community Support.
See: https://github.com/eclipse/jetty.project/issues/7958
You should upgrade, to at least Jetty 10.
The problem you have is the combination of jetty-11.0.11
and javax/servlet/http/HttpServlet
.
Jetty 11 supports Servlet 5.0, which underwent the Jakarta "Big Bang" and changed namespace to jakarta.servlet.*
See Past Question for details (including table in accepted answer for support levels for the combination of Jetty version, Servlet Spec version, EE governing body, and Servlet namespace)
CodePudding user response:
Problem got resolved for me. Actually problem was with my jetty image. Instead of using FROM jetty:latest
, I should be using FROM jetty:9-jre8-openjdk
then only classes and servlet jars
would be available for my application.
Here it the complete Dockerfile
FROM maven as build
COPY src /home/app/src
COPY pom.xml /home/app
RUN mvn -f /home/app/pom.xml clean package
FROM jetty:9-jre8-openjdk
COPY --from=build /home/app/target/root.war /var/lib/jetty/webapps
EXPOSE 8080
CMD java -jar "$JETTY_HOME/start.jar"