Tomcat and Eclipse Zero Turnaround Deployment
Asked Answered
D

3

16

I want to be able to deploy code changes to Tomcat (near instantly), while I'm developing in Eclipse.

So far, I have my output from Eclipse placing the built classes in the WEB-INF/classes folder of my web application.

I also have a reloadable context, with the web.xml as a watched resource. Any edit / save to this file does reload my web app, taking just over one second - much quicker than building a new war file and deploying it in full.

However, what I'd like to do is trigger the redeploy when I edit any source file. As the .class files are being modified in Tomcat, it seems I just need to monitor any changes in the WEB-INF/classes folder and it's children.

I've read that I can add additional watched resources in Tomcat's context.xml but this doesn't seem to be quite what I need - unless it's possible to specify a directory that will be watched (including recursively monitoring sub folders and files)?

<Context>
  <WatchedResource>WEB-INF/web.xml</WatchedResource>
  <WatchedResource>WEB-INF/someother.file</WatchedResource>
  <Manager pathname=""/>
</Context>

So essentially, my question is can I watch the entire classes folder (without including each WatchedResource explicitly) to trigger a redeploy in Tomcat?

If not, can I configure Eclipse to touch the web.xml file, whenever I save a source file in that project? I'm developing on a Windows system. :(


PS I'm not interested in the JRebel product. Any answer should be a free solution.


Update

According to the Tomcat documentation, the classes folder should be monitored by setting the context to reloadable:

Set to true if you want Catalina to monitor classes in /WEB-INF/classes/ and /WEB-INF/lib for changes, and automatically reload the web application if a change is detected.

Only changes to the web.xml seem to trigger a reload. Is this a bug or is my setup incorrect?

Also, I've read about setting the docBase attribute for a given context:

docBase="webapps/someExample"

This appears to be close to what I need, as I could then republish in Eclipse quickly. My only problem is that I require several web apps / servlets to be running in Tomcat concurrently, on the same port etc.

Deft answered 13/6, 2011 at 9:19 Comment(0)
L
5

For these cases I set the eclipse build output to WEB-INF/classes as you have done and create a context file with the docBase set to the webapp folder (parent of WEB-INF) in the project. This is manually placed in conf/Catalina/localhost (assuming default configs for some elements of server.xml). End result is tomcat ends up serving from the development directory. So, change a servlet or other class and it is updated to the classes folder. Save a jsp and it is immediately available.

If project structured like:

src
|-main
  |-webapp
    |-images
    |-js
    |-WEB-INF
      |-jsp
      |-classes

Then context would be like:

<?xml version="1.0" encoding="UTF-8"?>
<Context path="/path" reloadable="true" 
    docBase="<pathtoproject>/src/main/webapp" />
Langlauf answered 16/6, 2011 at 21:8 Comment(4)
Do you know if there is any way to do this with multiple web apps running in Tomcat? (Only one needs to be in the 'build output' path)Deft
I'm not sure I follow you. Do you have multiple, independent web projects that you want to behave in the same way during development? Or, do you have multiple web projects that are using the same shared library and you want to have the shared library compile to a web project classes folder? If the projects are independent, then you just need a context file per project (name the file <path>.xml). If the projects use the same shared code and you want that to compile to the web classes folder, that I'm not sure how you would do.Langlauf
I have multiple web applications that must run in the same instance of Tomcat - I don't need the same 'hot deploy' behaviour from them.Deft
Shouldn't be a problem. You can either use multiple context files that you create and deploy, or, you should be able to use WTP for the one that you don't want to have this "hot deploy" and just use this context for the one where you do. Oh, and if you are using this context, don't use WTP to publish the same app.Langlauf
N
2

Maybe the Web Tools Project of Eclipse with auto-redeploy enabled will help you? Add a server, open properties and under Publishing you will see a radiobutton saying "Automatically publish when resources changes". This will result in a redeploy if classes changes otherwise just overwrites resources. You can install WTP via a built in update site (Eclipse only), so check out your software updates. It is free for most servers but it does not support certain Websphere features?

Nonflammable answered 13/6, 2011 at 9:34 Comment(5)
I'm already using WTP. A full republish of my project would take minutes, that's what I'm trying to avoid.Deft
Is it because of redeploy takes so long? I mean servlet context restart and warming up the caches (spring etc.) takes the time. Or what is taking so much time?Nonflammable
Because there's so many classes and files, the build in Eclipse takes ages to clean and republish. If I modify the classes as I go, then just reload the context, this is much quicker. Also, please see my update. Thanks.Deft
The docBase change is made in conf/context.xml? The reloadable is done also in the same file? Can you post that file?Nonflammable
I haven't made the docBase change, I've just read a little about it, but haven't found any in depth documentation.Deft
M
0

Try the Spring Loaded JVM agent I've described in the following answer: https://mcmap.net/q/238015/-integrating-tomcat-and-eclipse-as-a-hot-deploy-environment

While that has worked for my Spring web application, this should work with vanilla Eclipse + WTP + Tomcat + Dynamic Web Applications since Spring Loaded works on the JVM/classloading level.

You will still need to use the "Automatically publish when resources changes" as mentioned by @toomasr in his answer. However, you must also disable "Module auto reload by default" option as well. If you already added/published modules from Eclipse to Tomcat, then disable "Auto Reload" for each web module (via the Tomcat config page's Modules tab). That should prevent Tomcat from reloading the application when a single class file is updated, which I suspect is what all that reload/wait time is.

Maffick answered 6/5, 2016 at 17:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.