HotSwaping code into "mvnDebug tomcat:run"
Asked Answered
J

7

6

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>
Jailhouse answered 4/2, 2014 at 9:29 Comment(18)
techblog.bozho.net/?p=1246Nitaniter
#999237Nitaniter
@Nitaniter Too bad, 1.7 not supported yet in DCEVM.Jailhouse
With non-structural changes the debug mode should work?Nitaniter
Thats what i thought too. If i launch it with eclipse's internal tomcat-instance it works well, but not with mvnDebug tomcat:run.Jailhouse
Check also #9573056Laforge
Is there some specific reason why are you not debugging in your IDE's embedded server? Why are you running the application via maven?Cassel
@PavelHoral because of the pros of a build-management-system and less configuration.Jailhouse
@PeterRader Not sure what you mean by "less configuration". We use Maven in our company and its zero-configuration to make it work inside Eclipse/Tomcat with m2e. Developers just check-out the repository in Eclipse, enable Maven nature and are ready to run/debug it.Cassel
What version of maven-tomcat-plugin you're using? I'm on 2.2 and hot swap from Eclipse works just fine. It seems that you may be using some old plug-in, maybe version 1.1, because newer versions should be referred as tomcat6 or tomcat7, e..g. mvnDebug tomcat7:runCunnilingus
@PavelHoral what about jndi-resources? Endorsed-folder? connectors and loggers? what about global context configuration? native libraries and versioning? Balancer-configuration? We did wrote emails in the past without a connection to any task in the bug-tracker, without any wiki-page, without any documentation. This way we have all at once and it works mutch better, even without hotswap.Jailhouse
@Cunnilingus Hm, maybe you are right, i am using 2.1. Can you define this as an answer?Jailhouse
@PeterRader Not sure what you meant with the "e-mail, task, wiki, ..." comment. But I understand that running in Eclipse is not an option for you (even thou it is superior to running from Maven in my opinion).Cassel
@PavelHoral Sorry for my wrong note. If i merge all the configuration changes into tomcat only to be up-to-date costs about a hour very often.Jailhouse
Have you tried disabling TOmcats own deployment mechanism (which might already be so when running in this way) and run Maven in debug mode so the embedded Tomcat will also run in debug mode? Then you should be able to hotswap.Mirza
@ThorbjørnRavnAndersen Yes, i tried this. Unfortunately hotswap still not working.Jailhouse
I will provide more informations. @Cunnilingus wrote it works great, maybe there is a bug.Jailhouse
Still cant get it to work.Jailhouse
F
8

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

Factual answered 7/2, 2014 at 15:30 Comment(5)
Please provide more information about how this works with maven exactly.Laforge
Drop 365$ per year, because by i am using tools wrong? What is your job? Marketing Specialist at JRebel? ;-)Jailhouse
@PeterRader I assume that you're using Eclipse because IntelliJ is too expensive? :) If you know any jrebel free alternative just let me knowFactual
@JakubK I belive there is no free alternative that nearly reach the top of the art that jrebel has. But hotswap would be enougth for me.Jailhouse
I have a test-version of jrebel, i hate it, it does not work with maven!Jailhouse
P
2

One of the best solutions for your situation is JRebel

  • What you need to do is make the appropriate changes to the framework and integrate it using a jrebel-maven-plugin.
    It allows to reload all the method bodies.
  • Once you are done with the link-up a auto xml configuration file will be generated which will be used as a config file for the plugin.
  • Mention Your Java Agent as well.
  • After the successful test you can also integrate it with a build
Platinous answered 12/2, 2014 at 11:54 Comment(1)
Sorry, i tried this but it does not work well using maven.Jailhouse
C
1

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.

Choate answered 7/2, 2014 at 16:17 Comment(0)
C
1

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.

Cunnilingus answered 11/2, 2014 at 20:11 Comment(1)
[INFO] >>> tomcat7-maven-plugin:2.2:run (default-cli) @ ... but hotswap not working anyway.Jailhouse
P
0

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

Patentee answered 13/2, 2014 at 15:3 Comment(0)
H
0

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

Henshaw answered 14/2, 2014 at 0:20 Comment(1)
I know grails good, but hotswap is more than reload. Thank you anyway.Jailhouse
V
-1

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.

Vibes answered 10/2, 2014 at 16:25 Comment(1)
Downvote? The op asks for something "like a maven-hotswap-plugin" - what's wrong with providing links to such.Mckeon

© 2022 - 2024 — McMap. All rights reserved.