Tomcat - Maven插件:运行Web应用程序而不是当前项目

7

tomcat7-maven-plugin允许将当前项目作为Web应用程序运行,并且可以指定其他要同时加载到Tomcat中的<webapps>

我的项目不是Web应用程序,但它访问由webapps提供的服务。那么如何在不将项目本身作为Web应用程序运行的情况下部署多个webapps呢?以下Maven代码片段会导致FileNotFoundExceptions,因为找不到context.xml。

<plugin>
  <groupId>org.apache.tomcat.maven</groupId>
  <artifactId>tomcat7-maven-plugin</artifactId>
  <version>2.0</version>
  <executions>
    <execution>
      <id>run-tomcat</id>
      <phase>${tomcat.run.phase}</phase>
      <goals><goal>run-war-only</goal></goals>
      <configuration>
        <webapps>
          <webapp>
            <contextPath>/my/app1</contextPath>
            <groupId>...</groupId> 
            <artifactId>...</artifactId>
            <version>...</version>
            <type>war</type>    
            <asWebapp>true</asWebapp>
          </webapp>
          ... possibly more webapps ...
        </webapps> 
      </configuration>
    </execution>
    <execution>
      <id>tomcat-shutdown</id>
      <phase>${tomcat.shutdown.phase}</phase>
      <goals><goal>shutdown</goal></goals>
    </execution>
  </executions>
</plugin>

解决方法:

即使您的应用程序本身不是Web应用程序,您仍需要为其配置路径上下文文件:

<configuration>
    <path>/my/non/existing/webapp</path>
    <contextFile>src/test/resources/context.xml</contextFile>
    <webapps>
    ...

指定的 context.xml 文件必须存在。即使 web.xml 文件不存在,以下方法对我有效:
<?xml version="1.0" encoding="utf-8"?>
<Context path="/my/non/existing/webapp">
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
</Context>

你能否发布Maven输出的相关日志? - ben75
那么,Dominik,你在发布问题后一个多小时后收到了回复,但你没有礼貌地回复吗? - Matt Byrne
我添加了一个解决问题的变通方法。但我仍然希望有更好的方法来解决这个问题... - dokaspar
Dominik,你在上下文文件中放了什么?当我使用以上配置时,Tomcat7会抛出一个错误"Error starting static Resources"。你遇到过这种情况吗? - Alessandro Giannone
我也需要能够做到这一点...正在寻找解决方案。你是否向Apache Tomcat团队提交了此用例的功能请求? - Travis Schneeberger
2个回答

6

我觉得这可能是滥用了Tomcat Maven插件,但这是我找到的解决方案。顺便说一句,你提供的虚假上下文文件解决方法对我没用,因为我需要运行不同的Web应用程序,而且我的应用程序也是一个Web应用程序。

有一个jira问题可以提供更好的解决方案。请参见https://issues.apache.org/jira/browse/MTOMCAT-228。现在我们来看看我的解决方案...

首先,您需要将war文件复制到目录中。我建议使用target目录,以便可以轻松清理。根据您是要支持run还是run-war目标,取决于您是只复制war文件还是同时复制war并解压缩它。

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-dependency-plugin</artifactId>
  <version>${maven-dependency-plugin.version}</version>
  <executions>
    <execution>
      <id>copy-war</id>
      <goals>
        <goal>copy</goal>
      </goals>
      <configuration>
        <artifactItems>
          <artifactItem>
            <groupId>org.foo</groupId>
            <artifactId>bar</artifactId>
            <version>${bar.version}</version>
            <type>war</type>
            <overWrite>true</overWrite>
            <outputDirectory>${project.build.directory}/bar/</outputDirectory>
          </artifactItem>
        </artifactItems>
        <stripVersion>true</stripVersion>
      </configuration>
    </execution>
    <execution>
      <id>copy-war-unpack</id>
      <goals>
        <goal>unpack</goal>
      </goals>
      <configuration>
        <artifactItems>
          <artifactItem>
            <groupId>org.foo</groupId>
            <artifactId>bar</artifactId>
            <version>${bar.version}</version>
            <type>war</type>
            <overWrite>true</overWrite>
            <outputDirectory>${project.build.directory}/bar/bar</outputDirectory>
          </artifactItem>
        </artifactItems>
      </configuration>
    </execution>
  </executions>
</plugin>

接下来,您需要配置Tomcat插件以查看您在上一步中刚刚复制到的目录或war文件。以下是适用于Tomcat 6和7的配置,除了构件ID外完全相同。

<plugin>
  <groupId>org.apache.tomcat.maven</groupId>
  <artifactId>tomcat6-maven-plugin</artifactId>
  <version>${tomcat6-maven-plugin.version}</version>
  <configuration>
    <port>8090</port>
    <path>${default.rice.context.path}</path>
    <warDirectory>${project.build.directory}/bar/bar.war</warDirectory>
    <warSourceDirectory>${project.build.directory}/bar/bar</warSourceDirectory>
  </configuration>
</plugin>
<plugin>
  <groupId>org.apache.tomcat.maven</groupId>
  <artifactId>tomcat7-maven-plugin</artifactId>
  <version>${tomcat7-maven-plugin.version}</version>
  <configuration>
    <port>8090</port>
    <path>${default.rice.context.path}</path>
    <warDirectory>${project.build.directory}/bar/bar.war</warDirectory>
    <warSourceDirectory>${project.build.directory}/bar/bar</warSourceDirectory>
  </configuration>
</plugin>

明确一点,如果您只想支持tomcat:run,则不需要配置warDirectory或执行copy-war。相反,如果您只想支持tomcat:run-war,则不需要配置warSourceDirectory或执行copy-war-unpack。

最后一点提示,该依赖项复制解决方案还与Jetty Maven插件很好地配合使用,因此如果您想要同时支持tomcat和jetty,则这可能是一个不错的选择。


顺便说一句。我尝试了各种不同的东西,比如外部serverXml文件、上下文文件和各种配置。这是我唯一能够让tomcat插件不部署当前webapp的方法。 - Travis Schneeberger
我尝试了不解压war档案,只使用wsdlFile标签。但是仍然出现相同的错误。:( - Cherry
很棒的解决方案!但是,如果项目类型不是war,则必须强制Tomcat插件跳过使用ignorePackaging=true进行检查。在我的情况下,我正在构建一个需要模拟服务(war)进行一些集成测试的jar。我使用了dependency:copy mojo,并使用了warDirectory=${project.build.directory}/warFile=mywar.war,一切都运行得非常完美。 - jpmelanson

2

我刚想到了一个类似于maven的解决这个问题的方法。我想在这里记录下来,希望能对其他人有所帮助。虽然我还没有测试过这个解决方案,但我认为它应该是可行的。

基本上,如果你想使用jetty或tomcat插件启动一个“不同”的web应用程序而不是当前的应用程序,你可以这样做:

在你的项目中创建另一个maven模块。这个模块将是你想要启动的web应用程序的一个空war覆盖层。然后你可以把所有的jetty或tomcat配置放在这个新模块中(或者只是在父pom下的pluginManagement中集中jetty和tomcat配置)。由于jetty和tomcat是设计用来启动“当前”应用程序的,所以不需要任何特殊的修改配置。


看起来像是一个很棒的技巧,但不幸的是,Tomcat Maven插件的覆盖支持相当有限。请参见例如此线程:https://mail-archives.apache.org/mod_mbox/tomcat-users/201204.mbox/%3CCANyrOm6g=a41ufKBfncxd6PvGSUA1M+-nWURpLDKxpBcDOhgJg@mail.gmail.com%3E - Michał Politowski
哦,是的,我也遇到了覆盖问题。请为众多的覆盖JIRA问题投票支持。我希望他们能在3.0版本中修复这些问题,该版本很可能会支持tomcat 8。https://issues.apache.org/jira/browse/MTOMCAT - Travis Schneeberger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接