【问题标题】:HotSwaping code into "mvnDebug tomcat:run"将代码热交换到“mvnDebug tomcat:run”
【发布时间】:2014-02-28 04:29:48
【问题描述】:

通常我使用mvnDebug tomcat:run启动tomcat。

代码更改后我需要使用mvn tomcat:redeploy

这是次优的,因为我经常只更改现有方法体的内容。

我可以将方法的主体热交换到运行时,然后热重新部署作为后备吗?

不幸的是,我找不到像 maven-hotswap-plugin 这样的东西。

faces-config.xml

... <application>
  <view-handler>com.sun.facelets.FaceletViewHandler</view-handler>
  <locale-config>
   <default-locale>de_DE</default-locale>
  </locale-config>
  <resource-bundle>
   <base-name>Message</base-name>
   <var>message</var>
  </resource-bundle>
  <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
 </application>
</faces-config>

web.xml:

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
    <listener-class>
        org.springframework.web.context.request.RequestContextListener
    </listener-class>
</listener>

pom.xml:

<dependencies>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-envers</artifactId>
        <version>4.3.0.Final</version>
    </dependency>
    <dependency>
        <groupId>net.java.dev.ajax4jsf</groupId>
        <artifactId>ajax4jsf</artifactId>
        <version>1.0.6</version>
    </dependency>

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>3.6.6.Final</version>
    </dependency>
    <dependency>
        <groupId>commons-lang</groupId>
        <artifactId>commons-lang</artifactId>
        <version>2.3</version>
    </dependency>
    <dependency>
        <groupId>org.apache.myfaces.core</groupId>
        <artifactId>myfaces-api</artifactId>
        <version>1.2.10</version>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>org.apache.myfaces.core</groupId>
        <artifactId>myfaces-impl</artifactId>
        <version>1.2.10</version>
        <scope>runtime</scope>
    </dependency>

    <dependency>
        <groupId>org.apache.myfaces.tomahawk</groupId>
        <artifactId>tomahawk12</artifactId>
        <version>1.1.9</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>com.sun.facelets</groupId>
        <artifactId>jsf-facelets</artifactId>
        <version>1.1.14</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>3.1.0.GA</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring</artifactId>
        <version>2.5.6</version>
    </dependency>
    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>9.2-1004-jdbc41</version>
    </dependency>

    <dependency>
        <groupId>servletapi</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.4</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.tomcat.maven</groupId>
            <artifactId>tomcat7-maven-plugin</artifactId>
            <version>2.2</version>
            <configuration>
                <contextReloadable>true</contextReloadable>
            </configuration>
        </plugin>
    </plugins>
</build>

【问题讨论】:

  • @Bozho 太糟糕了,DCEVM 还不支持 1.7。
  • 您没有在 IDE 的嵌入式服务器中进行调试是否有特定原因?为什么要通过 maven 运行应用程序?
  • 您使用的是什么版本的 maven-tomcat-plugin?我在 2.2 上,来自 Eclipse 的热交换工作得很好。看来您可能正在使用一些旧插件,可能是 1.1 版,因为较新的版本应该称为 tomcat6 或 tomcat7,例如mvnDebug tomcat7:run

标签: java tomcat maven-3 hotswap


【解决方案1】:

您可以使用Jrebel - 它完全按照您的预期工作。您只需要指定 javaagent,它就会在运行时重新加载所有类和框架更改。它也适用于远程服务器

要将其与 maven 项目集成,您必须添加 jrebel-maven-plugin,这将生成所有配置 (rebel.xml) 文件。

如果没有 JRebel,你可以使用标准的 HotSwap 机制,但它只允许重新加载方法体

【讨论】:

  • 请提供更多关于它如何与 maven 一起工作的信息。
  • 每年下降 365 美元,因为我使用错误的工具?你做什么工作? JRebel 的营销专家? ;-)
  • @PeterRader 我假设您正在使用 Eclipse,因为 IntelliJ 太贵了? :) 如果您知道任何免费的 jrebel 替代品,请告诉我
  • @JakubK 我相信没有几乎达到 jrebel 拥有的艺术顶峰的免费替代品。但是热插拔对我来说已经足够了。
  • 我有一个 jrebel 的测试版,我讨厌它,它不适用于 maven!
【解决方案2】:

JRebelJRebel是适合您情况的最佳解决方案之一

  • 您需要做的是对框架进行适当的更改 并使用 jrebel-maven-plugin 集成它。
    它允许重新加载所有方法体。
  • 完成链接后,将生成一个自动 xml 配置文件,该文件将用作插件的配置文件。
  • 同时提及您的 Java 代理。
  • 测试成功后,您还可以将其与构建集成

【讨论】:

  • 对不起,我试过了,但使用 maven 效果不佳。
【解决方案3】:

JRebel 是一个不错的选择。它并不便宜,但有可用的开源许可证。 Maven的安装说明在这里: http://zeroturnaround.com/software/jrebel/learn/maven/

我们通过特定的运行配置文件和嵌入式 Tomcat 来实现这一点。这是一个特定的子模块,它依赖于构建 Web 应用程序战争的其他项目。因此,如果您在 runner 子模块中配置如下内容:

<profiles>
         <profile>
             <id>run</id>
             <build>
                 <plugins>
                     <plugin>
                         <groupId>org.apache.tomcat.maven</groupId>
                         <artifactId>tomcat7-maven-plugin</artifactId>
                         <executions>
                             <execution>
                                 <id>run-wars</id>
                                 <goals>
                                     <goal>run-war-only</goal>
                                 </goals>
                                 <phase>integration-test</phase>
                             </execution>
                         </executions>
                         <configuration>
                            <warDirectory>theWar</warDirectory>
                            <path>/relativepath</path>
                            <systemProperties>
                            <webapps>
                                <webapp>
                                    <groupId>${project.groupId}</groupId>
                                    <artifactId>myArtifact</artifactId>
                                    <version>${project.version}</version>
                                    <type>war</type>
                                    <asWebapp>true</asWebapp>
                                    <contextPath>myContext</contextPath>
                                 </webapp>
                             </webapps> 
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
</profiles>

您可以使用mvn package -Prun 运行它,您应该可以使用Ctrl+C 关闭它。

然后,当它在一个终端中运行时,更改您的代码,打开一个新终端并运行mvn compile。随着 JRebel 的推出,这些更改应该会立即反映在您的 Web 应用程序中。

应该没有什么可以阻止您通过 Eclipse 的 m2e 插件运行这些相同的目标。

【讨论】:

    【解决方案4】:

    您可能正在使用一些旧版本的 maven tomcat 插件,因为较新的版本应该称为 tomcat6 或 tomcat7,例如mvnDebug tomcat7:run。我在 2.2 上,来自 Eclipse 的热插拔工作得很好。

    为了澄清一点,这就是我在使用mvn tomcat:run 启动应用程序时在命令提示符中看到的内容:

    ...
    [INFO] >>> tomcat-maven-plugin:1.1:run (default-cli) @ tomcatMvnDebug >>>
    ...
    

    注意1.1

    这就是我在使用mvn tomcat7:run 启动应用程序时看到的:

    ...
    [INFO] >>> tomcat7-maven-plugin:2.2:run (default-cli) @ tomcatMvnDebug >>>
    ...
    

    注意这次maven使用的是tomcat插件版本2.2

    【讨论】:

    • [INFO] &gt;&gt;&gt; tomcat7-maven-plugin:2.2:run (default-cli) @ ... 但热插拔仍然无法正常工作。
    【解决方案5】:

    我会使用 Eclipse 或 IntelliJ 的 HotSwap 功能。它们对我来说都很好用:只需在调试模式下运行 maven 目标 (tomcat:run)。

    【讨论】:

      【解决方案6】:

      我们一般使用grails开发web应用,grails已经有reload功能,我相信是用spring-loaded插件完成的。它可能是 jRebel 的替代品(虽然我不确定它是否适合你,但如果你想节省几百美元,可能值得一试)。

      所以,基本上我看到以下选项:

      • 使用已经支持重新加载类的框架(Grails、Play)
      • 使用一些 javaagent,例如 spring-loaded 或 JRebel
      • 使用集成到 IDE 中的一些 javaagent(我使用 IntelliJ IDEA 并强烈推荐它。但不确定它是否适用于免费社区版)。

      https://github.com/spring-projects/spring-loaded

      【讨论】:

      • 我知道 grails 很好,但热插拔不仅仅是重新加载。还是谢谢你。
      【解决方案7】:

      有一个maven plugin。好像没有维护。但是从简短的源代码来看,我相信你可以让它工作。

      它基于类似的plugin for ant,所以你也可以使用maven antrun来执行这个

      尽管如此,它仍将具有与任何 IDE 中的热插拔相同的功能(和限制)。

      【讨论】:

      • 投反对票?该操作要求提供“类似于 maven-hotswap-plugin”的东西 - 提供指向此类的链接有什么问题。
      猜你喜欢
      • 2011-02-27
      • 1970-01-01
      • 1970-01-01
      • 2013-02-15
      • 1970-01-01
      • 2014-09-16
      • 2016-07-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多