【问题标题】:Possible to run two webapps at once when developing with Maven/Eclipse?使用 Maven/Eclipse 开发时可以同时运行两个 Web 应用程序吗?
【发布时间】:2011-07-28 00:07:24
【问题描述】:

问题是:我们为客户构建 web 应用程序。我们还有一个“管理员”webapp,它可以修改一些客户端数据结构。由于数据的性质,两个 webapp 必须在同一个 JVM 中运行。

这在生产中没有问题;您只需将两个 webapps 放在同一个应用服务器中。

不过,我们最近切换到了一种 Maven 方式来布局 web 应用程序,而 Maven 想要每个项目一个 web 应用程序。在 Eclipse 中这是一个问题,因为如果您独立运行不同的 webapp,它们将位于不同的 JVM 中。

我们正在尝试使用 jetty-maven-plugin 进行 webapp 测试,但如果它可以解决这个问题,可以切换到其他东西。

【问题讨论】:

  • 在 eclipse 中,你是在自己的应用服务器上运行每个 webapp 吗?
  • Eclipse 中的独立项目独立运行。当您执行 Run As... 并调用 maven-jetty-webapp 时,它会在自己的 JVM 中启动 Jetty 应用服务器的副本。
  • How do I deploy multiple peer webapps from a parent pom相同的问题,答案很好。

标签: java web-applications maven maven-jetty-plugin


【解决方案1】:

是的,你可以 :) 通过将一个 WAR 模块标识为主模块,将所有其他 WAR 复制到主模块的目标目录中,制作 jetty.xml 并告诉 Maven Jetty 插件使用 jetty.xml 来完成。以下是使用 Maven 依赖插件复制其他 WAR 的方法:

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

您还需要在 POM 中定义 com.foo:bar 依赖项。这是jetty.xml的内容:

<?xml version="1.0"?>

<!-- =========================================================== -->
<!-- Set handler Collection Structure                            -->
<!-- =========================================================== -->
<Set name="handler">
    <New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
        <Set name="handlers">
            <Array type="org.eclipse.jetty.server.Handler">
                <Item>
                    <New class="org.eclipse.jetty.server.handler.ContextHandlerCollection"
                         id="Contexts">
                        <Set name="handlers">
                            <Array type="org.eclipse.jetty.server.Handler">
                                <Item>
                                    <New id="FooWebHandler"
                                         class="org.eclipse.jetty.webapp.WebAppContext"/>
                                </Item>
                            </Array>
                        </Set>
                    </New>
                </Item>
            </Array>
        </Set>
    </New>
</Set>

<Ref id="FooWebHandler">
    <Set name="contextPath">/foo</Set>
    <Set name="war">
        target/bar-${project.version}.war
    </Set>
</Ref>

下面是如何告诉 Maven Jetty 插件使用新的 jetty.xml:

<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty.version}</version>
<configuration>
    <jettyConfig>${basedir}/jetty.xml</jettyConfig>
</configuration>

现在从 Eclipse 启动 jetty:run-war 目标,您应该会看到所有 WAR 部署在一个 Maven Jetty 插件实例中。我从命令行运行它,它在那里工作,YMMV 和 Eclipse。

【讨论】:

  • jetty.xml 非常适合我。我不使用 Jetty Maven 插件,而是直接从 eclipse 运行我的 webapps。但剩下的一个问题是:为什么在 HandlerCollection 中使用带有 ContexthandlerCollection 的双集合结构?离开 HandlerCollection 并直接使用 ContextHandlerCollection 似乎工作正常(反之亦然)。
【解决方案2】:

您可以直接通过 jetty-maven-plugin 完成此操作,无需修改 jetty.xml:

<plugin>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-maven-plugin</artifactId>
    <configuration>
        <scanIntervalSeconds>5</scanIntervalSeconds>
        <webApp>
            <contextPath>/</contextPath>
        </webApp>
       <contextHandlers>
          <contextHandler implementation="org.eclipse.jetty.maven.plugin.JettyWebAppContext">
            <war>${project.basedir}/../secondProject.war</war>
            <contextPath>/cc</contextPath>
          </contextHandler>
        </contextHandlers>  
    </configuration>
    <executions>
        ...
    </executions>
</plugin>

您根本不需要修改 jetty.xml 文件即可成功使用它,也不需要复制 war 文件。 (尽管您可能希望构建第二次战争作为此构建的一部分,请参阅 maven-invoker-plugin)

此处的文档:http://www.eclipse.org/jetty/documentation/9.2.2.v20140723/jetty-maven-plugin.html#running-more-than-one-webapp

【讨论】:

    【解决方案3】:

    这里举一个例子来说明 ccleve 的回答。

    import org.eclipse.jetty.server.Server;
    import org.eclipse.jetty.server.handler.HandlerCollection;
    import org.eclipse.jetty.webapp.WebAppContext;
    import org.eclipse.jetty.xml.XmlConfiguration;
    ...
    public static void main(String[] args) throws Exception {
    ...
    Server server = new Server(port);
    HandlerCollection handlers = new HandlerCollection();
    
    WebAppContext frontEndWebappContext = new WebAppContext(
         "src/main/webapp", "/test"
    );
    handlers.addHandler(frontEndWebappContext);
    
    String serviceWebappBasePath = {absolute_path_to_other_webapp};
    WebAppContext serviceWebappContext = new WebAppContext(
         serviceWebappBasePath + "/main/webapp", "/"
    );
    handlers.addHandler(serviceWebappContext);
    XmlConfiguration conf = new XmlConfiguration(new File(
       serviceWebappBasePath +  "test/webapp/WEB-INF/jetty-web.xml")
    .toURI().toURL().openStream());
    conf.configure(serviceWebappContext);
    
    server.setHandler(handlers);
    server.start();
    
    ...
    

    在这种情况下,前端 webapp 挂载到“/test”,服务 webapp 挂载到“/”。我们还包括服务应用程序的 jetty-web.xml。

    在您的情况下,您将创建的启动器应该位于“src/test”文件夹中,因为它不应该包含在您的战争中,因为您只需要将它用于测试目的。

    你可能还需要在前端 webapp 的 pom 文件中添加对服务 webapp 的依赖:

    <dependency>
     <groupId>{service_group}</groupId>
     <artifactId>{service_artifact_id}</artifactId>
     <version>{service_version}</version>
     <scope>test</scope>
    </dependency>
    

    或/和

    <dependency>
      <groupId>{service_group}</groupId>
      <artifactId>{service_artifact_id}</artifactId>     
      <type>test-jar</type>
      <version>{service_version}</version>
      <scope>test</scope>
    </dependency>
    

    【讨论】:

      【解决方案4】:

      我在 Maven/Jetty 方面没有太多经验;但我确实有在 Eclipse 上使用 Tomcat 的经验;所以我们至少都在 Eclipse 上使用 servlet 做一些事情。

      无论如何,我不知道您是否已经使用 Eclipse 中的任何项目模板创建了项目,但我使用动态 Web 项目模板创建了我的项目。我以前没有做过两个网络应用程序;但是,如果您要创建其中两个项目,然后在 Eclipse 服务器选项卡中,创建一个新服务器并将这两个项目添加到其中,您可能能够实现您的目标。

      当您执行 Run As... 时,您基本上只是在运行 Eclipse 为您的项目设置提供的默认运行配置。但是,如果您将两个项目都部署到开发环境中的一台服务器上,然后选择该服务器并点击启动,它应该只在一个 JVM 上启动它;类似于您的生产环境。

      就像我说的那样;我没有使用 Jetty,也从未使用过 Jetty 的服务器设置指南,所以我不知道这是否适合您。所以我希望这会有所帮助 - 但如果不是,我不会太惊讶。

      【讨论】:

      • 感谢您的建议。它可能会起作用。麻烦的是,我们没有使用 WTP,当我们尝试使用它时,它使其他一些事情在我们的项目中无法使用。这是一个相当重量级的解决方案。此外,我无法让它识别 Maven 工件。
      【解决方案5】:

      回答我自己的问题:

      这似乎是不可能的。我们想出的解决方法是编写一些嵌入式码头代码并从我们的应用程序中启动它。 Jetty 允许您以编程方式添加多个 Web 应用程序。它还允许您为每个 webapp 创建多个资源库,即目录,从而启用覆盖。到目前为止,效果很好。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-20
        • 1970-01-01
        相关资源
        最近更新 更多