我正在尝试从我在 Tomcat 服务器上运行的 Jersey Web 应用程序创建一个 Docker 映像.我正在 Windows 7 机器上开发.
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.
我已将 Web 应用程序部署在我的开发机器上的本地 Tomcat 8.0.14 应用程序服务器上,一切正常.
I have deployed the web application on a local Tomcat 8.0.14 application server on my development machine and everything works as expected.
为了创建 Docker 映像,我将以下 Dockerfile. 放在与 my-web-app.war 文件相同的目录中.
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 .这已成功完成,并且图像使用 docker images -a 命令显示.
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命令提示符显示服务器已成功启动,当我尝试访问 Web 应用程序时,这也有效:
The command prompt show that the server is successfully started and when I tried to access the web application this also works:
192.168.99.100:8080/my-web-app显示相应的 HTML 欢迎页面.
shows the appropriate HTML welcome page.
当我尝试访问任何实际的 Jersey RESTful Web 服务时,就会出现问题.每当我尝试访问不同于 HTML 页面的内容时,都会收到以下错误消息:
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.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2527) org.apache.tomcat.util.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.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2527) org.apache.tomcat.util.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)我认为创建 WAR 文件可能有问题,但如果是这样,如何将应用程序成功部署在我的本地 Tomcat 服务器上.
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.
如果有任何兴趣,这里是我用来构建 WAR 的 pom.xml 文件:
If this is of any interest here is the pom.xml file I used to build the WAR:
<project xmlns="maven.apache/POM/4.0.0" xmlns:xsi="www.w3/2001/XMLSchema-instance" xsi:schemaLocation="maven.apache/POM/4.0.0 maven.apache/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?
感谢任何帮助.
问候
推荐答案这里有一个深入的概述和解决方案,所有遇到 NoSuchMethodError 的人,尤其是在球衣上下文中.
Here is an indepth overview and a solution to all who encounter NoSuchMethodError especially in jersey context.
问题是
java.lang.NoSuchMethodError: javax.ws.rs.core.Application.getProperties()Ljava/util/Map;
java.lang.NoSuchMethodError: javax.ws.rs.core.Application.getProperties()Ljava/util/Map;
在 Java 中,当 JVM 找不到指定类中指定的方法时,会抛出 NoSuchMethodError.来自 docs.oracle/javase/9/docs/api/java/lang/NoSuchMethodError.html
In Java NoSuchMethodError is thrown when the JVM cant find the method specified in the specified class. From docs.oracle/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.
在您的情况下,JVM 抱怨 javax.ws.rs.core.Application 没有 getProperties() 方法.
In your case JVM is complaining that javax.ws.rs.core.Application doesnot have getProperties() method.
Jesey 2.x 使用 JEE 7.在 JEE 7 版本的 javax.ws.rs.core.Application 中有
Jesey 2.x uses JEE 7. In JEE 7 version of javax.ws.rs.core.Application has
- getClasses()
- getSingeltons()
- getProperties()定义的方法.docs.oracle/javaee/7/api/javax/ws/rs/core/Application.html
- getClasses()
- getSingeltons()
- getProperties() methods defined. docs.oracle/javaee/7/api/javax/ws/rs/core/Application.html
Jesey 1.x 使用 JEE 6.在 JEE 6 版本的 javax.ws.rs.core.Application 只有
Jesey 1.x uses JEE 6. In JEE 6 version of javax.ws.rs.core.Application only has
- getClasses()
- getclass()
但是 getProperties() 没有定义.jersey.github.io/apidocs/1.19.1/jersey/javax/ws/rs/core/Application.html
解决方案
您在 pom.xml 中定义了 jersey 2.x 和 1.x 版本.因此,在您的类路径中同时存在 JEE6 和 7 版本的 javax.ws.rs.core.Application,并且类加载器会加载没有 getProperties() 的 JEE 6 版本的应用程序类已定义,但您的应用程序仍要执行 getProperties().因此出现错误.
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.
从 pom.xml 中删除所有 jersey 1.x 版本并坚持使用 jersey 2.x 版本.类加载器将负责其余的工作.
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.
更多推荐
Jersey Web 应用程序的 Docker 映像
发布评论