Docker Image of Jersey Web Application

2020-03-31 05:48发布

I'm trying to create a Docker image from my Jersey web application running on a Tomcat server. I'm developing on a Windows 7 machine.

I have deployed the web application on a local Tomcat 8.0.14 application server on my development machine and everything works as expected.

To create the Docker image I put the following Dockerfile. in the same directory as the my-web-app.war file.

FROM tomcat:8.0-jre8
ADD /my-web-app.war /usr/local/tomcat/webapps/
CMD ["catalina.sh", "run"]

After that I'm creating the image with the following command:

docker build -t my-web-app .

This is done sucessfully and the images shows up with the docker images -a command.

After that I start the image through this:

winpty docker run --rm -it -p 8080:8080 my-web-app

The command prompt show that the server is successfully started and when I tried to access the web application this also works:

http://192.168.99.100:8080/my-web-app

shows the appropriate HTML welcome page.

The issue arises when I try to access any of the actual Jersey RESTful web services. Any time I try to access something different than an HTML page I get the following error message:

javax.servlet.ServletException: Servlet.init() for servlet My Web Application threw exception
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:620)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:502)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1132)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:684)
    org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2527)
    org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2516)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    java.lang.Thread.run(Thread.java:748)
root cause

java.lang.NoSuchMethodError: javax.ws.rs.core.Application.getProperties()Ljava/util/Map;
    org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:308)
    org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:337)
    org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:178)
    org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:370)
    javax.servlet.GenericServlet.init(GenericServlet.java:158)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:620)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:502)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1132)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:684)
    org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2527)
    org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2516)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    java.lang.Thread.run(Thread.java:748)

I assume there might be something wrong with the creation of the WAR file but if so how can the application be successfully deployed on my local Tomcat server.

If this is of any interest here is the pom.xml file I used to build the WAR:

<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>my.webapp.host</groupId>
    <artifactId>my-web-app</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>my-web-app</name>

    <build>
        <finalName>my-web-app</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.5.1</version>
                <inherited>true</inherited>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <dependencyManagement>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet</artifactId>
            <version>2.26-b03</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-moxy</artifactId>
            <version>2.26-b03</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-multipart</artifactId>
            <version>2.26-b03</version>
        </dependency>

        <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>javax.servlet-api</artifactId>
          <version>4.0.0-b05</version>
        </dependency>   

        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-json</artifactId>
            <version>1.19.3</version>
        </dependency>

        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-client</artifactId>
            <version>1.19.3</version>
        </dependency>

        <!-- persistence api -->
        <dependency>
            <groupId>org.hibernate.javax.persistence</groupId>
            <artifactId>hibernate-jpa-2.0-api</artifactId>
            <version>1.0.1.Final</version>
        </dependency>

        <dependency>
            <groupId>org.eclipse.persistence</groupId>
            <artifactId>eclipselink</artifactId>
            <version>2.6.4</version>
        </dependency>

        <!-- additional apis -->        
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>

        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

         <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>19.0</version>
        </dependency>

        <!-- own apis -->  
        <dependency>
            <groupId>my.own.utility.api</groupId>
            <artifactId>utility-api</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
    </dependencies>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
</project>

Does anyone know what the issue here is?

Any help is appreciated.

Greetings

1条回答
放我归山
2楼-- · 2020-03-31 06:22

Here is an indepth overview and a solution to all who encounter NoSuchMethodError especially in jersey context.

The problem is

java.lang.NoSuchMethodError: javax.ws.rs.core.Application.getProperties()Ljava/util/Map;

In Java NoSuchMethodError is thrown when the JVM cant find the method specified in the specified class. From https://docs.oracle.com/javase/9/docs/api/java/lang/NoSuchMethodError.html

Thrown if an application tries to call a specified method of a class (either static or instance), and that class no longer has a definition of that method.

In your case JVM is complaining that javax.ws.rs.core.Application doesnot have getProperties() method.

Jesey 2.x uses JEE 7. In JEE 7 version of javax.ws.rs.core.Application has

Jesey 1.x uses JEE 6. In JEE 6 version of javax.ws.rs.core.Application only has

  • getClasses()
  • getclass()

But getProperties() is not defined. https://jersey.github.io/apidocs/1.19.1/jersey/javax/ws/rs/core/Application.html

Solution

You have jersey 2.x and 1.x versions defined in your pom.xml. Therefore there are both JEE6 and 7 versions of javax.ws.rs.core.Application in your classpath and classloader loads JEE 6 version of appliction class which doesnot have getProperties() defined but yor application wants to execute getProperties() anyway. Hence the error.

Remove all jersey 1.x versions from your pom.xml and stick to jersey 2.x version. The classloader will take care of the rest.

查看更多
登录 后发表回答