HotSwaping code into “mvnDebug tomcat:run”

2020-06-17 06:43发布

Usually i start tomcat using mvnDebug tomcat:run.

After Code-change i need to use mvn tomcat:redeploy.

This is sub-optimal because i often only change content of existing method-bodys.

Can I HotSwap the method's body into the runtime, and hot-redeploy as a fallback?

I have unfortunatally nothing found like a 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>

7条回答
时光不老,我们不散
2楼-- · 2020-06-17 07:21

We generally develop the web applications using grails which already has reload feature, I believe it's done with the spring-loaded plugin. It may be a replacement to jRebel (although I'm not sure if it will work for you, but if you want to save a few hundreds $$, may be worth trying).

So, basically I see the following options:

  • Use the framework which already supports reloading classes (Grails, Play)
  • Use some javaagent like spring-loaded or JRebel
  • Use some javaagent integrated into the IDE (I use IntelliJ IDEA and highly recommend it. Not sure if it works in the free community edition though).

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

查看更多
我欲成王,谁敢阻挡
3楼-- · 2020-06-17 07:25

I'd use the HotSwap functions of Eclipse or IntelliJ. They both work very well for me: Just run maven goal in debug mode (tomcat:run).

查看更多
Lonely孤独者°
4楼-- · 2020-06-17 07:26

There is a maven plugin. It doesn't seem to be maintained. However from short look at the source code I believe you can make it work.

It is based on similar plugin for ant, so alternatively you can use maven antrun to execute this

Nevertheless it is going to have the same capabilities (and limitations) as hotswap in any IDE.

查看更多
闹够了就滚
5楼-- · 2020-06-17 07:27

JRebel is a good option. It isn't cheap but there are open source licences available. The installation instructions for Maven are here: http://zeroturnaround.com/software/jrebel/learn/maven/

We get this working through a specific run profile and embedded Tomcat. This is a specific sub-module that depends on the other projects that build the web application wars. So if you configure something like the following in the runner submodule:

<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>

You can run this with mvn package -Prun which you should be able to shut down with Ctrl+C.

Then, whilst this is running in one terminal, make your code changes, open a new terminal and run mvn compile. With JRebel going the changes should be reflected virtually instantly in your web app.

There should be nothing preventing you from running these same goals through Eclipse's m2e plugin.

查看更多
劳资没心,怎么记你
6楼-- · 2020-06-17 07:32

You can use Jrebel - it works exactly as you expect. You just need to specify javaagent and it will reload all classes and framework changes during runtime. It also works with remote servers

To integrate it with maven project you have to add jrebel-maven-plugin, which will generate all configuration (rebel.xml) files.

Without JRebel you can use standard HotSwap mechanism but it only allows to reload method bodies

查看更多
男人必须洒脱
7楼-- · 2020-06-17 07:41

It seems that you may be using some old version of the maven tomcat plug-in, because newer versions should be referred as tomcat6 or tomcat7, e..g. mvnDebug tomcat7:run. I'm on 2.2 and hot swap from Eclipse works just fine.

To clarify a little more, that's what I see in the command prompt when starting the app with mvn tomcat:run:

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

Notice the 1.1.

And that's what I see when starting the app with mvn tomcat7:run:

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

Notice that this time maven uses tomcat plug-in version 2.2.

查看更多
登录 后发表回答