java.lang.NoSuchMethodError:javax.servlet.ServletContext.getContextPath()Ljava / lang / String在货物

时间:2016-09-08 07:42:50

标签: java maven tomcat maven-cargo cargo-maven2-plugin

我在使用maven-cargo-plugin在嵌入式Tomcat 7上部署Web应用程序时遇到问题。我在webapps pom中创建了一个新的maven配置文件,它通过maven-cargo-plugin创建一个Tomcat容器,然后通过soapui-maven-plugin执行一个soapui测试用例。

webapp连接到某些IBM WebSphere MQ,因此我覆盖了一些容器配置文件:

  • 将MQ作为资源添加到server.xml以进行JNDI查找
  • 通过覆盖web.xml
  • 将我的自定义applicationContext.xml添加到类路径中
  • 在context.xml中添加了连接到MQ所需的资源
  • 将本地安装的IBM Websphere MQClient的lib目录的路径添加到容器common.loader,以便容器可以使用它的库

此外,我通过cargos <file>标记将所需的websphere.mq。*。jar文件和j2ee-1.4.jar从本地WebsSphere Server安装复制到Tomcat容器lib目录。

现在,当我使用此命令启动Maven时(runITs激活创建的配置文件):

clean verify -U -Dhttps.protocols=TLSv1,SSLv3 -DrunITs -X

部署失败,并显示:

INFO] [talledLocalContainer] org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/cargocpc]]
[INFO] [talledLocalContainer]   at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
[INFO] [talledLocalContainer]   at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
[INFO] [talledLocalContainer]   at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
[INFO] [talledLocalContainer]   at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:649)
[INFO] [talledLocalContainer]   at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:1081)
[INFO] [talledLocalContainer]   at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1877)
[INFO] [talledLocalContainer]   at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
[INFO] [talledLocalContainer]   at java.util.concurrent.FutureTask.run(FutureTask.java:262)
[INFO] [talledLocalContainer]   at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
[INFO] [talledLocalContainer]   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
[INFO] [talledLocalContainer]   at java.lang.Thread.run(Thread.java:745)
[INFO] [talledLocalContainer] Caused by: java.lang.NoSuchMethodError: javax.servlet.ServletContext.getClassLoader()Ljava/lang/ClassLoader;
[INFO] [talledLocalContainer]   at org.apache.catalina.startup.WebappServiceLoader.load(WebappServiceLoader.java:90)
[INFO] [talledLocalContainer]   at org.apache.catalina.startup.ContextConfig.processServletContainerInitializers(ContextConfig.java:1577)
[INFO] [talledLocalContainer]   at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1281)
[INFO] [talledLocalContainer]   at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:889)
[INFO] [talledLocalContainer]   at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:386)
[INFO] [talledLocalContainer]   at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
[INFO] [talledLocalContainer]   at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
[INFO] [talledLocalContainer]   at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5412)
[INFO] [talledLocalContainer]   at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
[INFO] [talledLocalContainer]   ... 10 more

我已经尝试过搜索可能的解决方案和f。即尝试了此处提供的解决方案:java.lang.NoSuchMethodError: javax.servlet.ServletContext.getContextPath()Ljava/lang/String;

但我可以排除可能的原因,因为:

  • 我的容器是Tomcat 7,因此支持Servlet API 2.5
  • web.xml符合Servlet API 2.5
  • WEB-INF/libJRE/lib
  • 中没有j2ee.jar或servlet-api.jar文件

确保我的设置符合这三点后,我仍然会收到上述错误。

有谁知道还有什么可能导致这种情况?

2 个答案:

答案 0 :(得分:0)

似乎Tomcat尝试调用此方法,该方法仅存在于servlet-api-3.0或更高版本中。由于我无法确切地知道容器从哪里获得错误的依赖性,因此我使用不同的方法解决了我的问题。

我没有通过maven-cargo-plugin创建基本的Tomcat并覆盖配置文件,而是复制了一个已经正常工作的本地配置,并通过添加

告诉货物使用此配置
<configuration>
    <type>existing</type>
    <home>C:\path\to\tomcat\home</home>
</configuration>

到插件配置

答案 1 :(得分:0)

我不同意接受的答案,因为它将构建绑定到本地计算机上的具体设置。您可以在构建服务器上复制它,但它会很笨拙且容易出错。我个人更喜欢配置构建,所以它没有任何外部依赖。当我们需要运行数据库迁移或者我们想要测试RabbitMQ并且没有可用的嵌入式代理但至少应用程序运行是自包含的时候,我也不得不妥协。

因此,如果我是你,我会深入挖掘并制作一个能够在没有这样的本地文件夹的情况下处理你的用例的配置。由于我缺乏信息(您的货物配置),我无法为您提供工作答案。但我会指出你org.apache.tomcat.maven.tomcat7-maven-plugin。它对我们来说非常好。我在另一个项目中使用了Cargo,我发现tomcat7插件更容易使用。

您可以提供自己的server.xmlRun Tomcat and deploy project with own server.xml

您可以在<dependencies>部分指定(添加/覆盖)依赖项 - 这应该可以解决您的servlet-api版本问题。

您可以添加自定义配置(比如我们放在lib文件夹中的一些属性文件,以便在类路径中获取它们),方法是将它们添加为jar中的依赖项。

这是一种非常通用且简单的方法来启动和运行嵌入式Tomcat。希望能帮到你。

也许给你一些关于tomcat7插件配置的入门知识:

<plugin>
    <groupId>org.apache.tomcat.maven</groupId>
    <artifactId>tomcat7-maven-plugin</artifactId>
    <version>2.2</version>
    <executions>
        <execution>
            <id>tomcat-run</id>
            <phase>pre-integration-test</phase>
            <goals>
                <goal>run-war-only</goal>
            </goals>
            <configuration>
                <webapps>
                    <webapp>
                        <groupId>${project.groupId}</groupId>
                        <artifactId>project-web</artifactId>
                        <version>${project.version}</version>
                        <type>war</type>
                        <asWebapp>true</asWebapp>
                        <contextPath>/project-path</contextPath>
                    </webapp>
                </webapps>
                <protocol>org.apache.coyote.http11.Http11NioProtocol</protocol>
                <port>${app.port}</port>
                <fork>true</fork>
            </configuration>
        </execution>
        <execution>
            <id>tomcat-shutdown</id>
            <phase>post-integration-test</phase>
            <goals>
                <goal>shutdown</goal>
            </goals>
        </execution>
    </executions>
    <dependencies>
        <dependency>
            <groupId>${project.groupId}</groupId>
            <artifactId>project-test-config</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-core</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-websocket</artifactId>
            <version>${tomcat.version}</version>
        </dependency>
        <dependency>
            <groupId>org.jacoco</groupId>
            <artifactId>org.jacoco.agent</artifactId>
            <version>${jacoco.version}</version>
            <classifier>runtime</classifier>
        </dependency>
        <dependency>
            <groupId>javax.websocket</groupId>
            <artifactId>javax.websocket-api</artifactId>
            <version>1.0</version>
        </dependency>
    </dependencies>
</plugin>

也许可以解释一下上面的内容。我们使用JaCoCo收集Sonar的集成测试覆盖率。我们需要一个特定的Tomcat版本(测试它适用于操作提供的版本),我们直接通过<port><protocol>指令覆盖了一些server.xml配置。