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.
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" />
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?
Try the Spring Loaded JVM agent I've described in the following answer:
https://stackoverflow.com/a/37064672/1034436
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.
Related
Our web application has an appName.xml file in our Tomcat directory structure at <tomcatInstall>/conf/Catalina/localhost/. Its entire text is:
<?xml version="1.0" encoding="UTF-8"?>
<Context crossContext="true">
<Realm className="com.blah.ApDataSourceRealm"
dataSourceName="jdbc/blahDev"
roleNameCol="blahRole"
userCredCol="blahToken"
userNameCol="blahCol"
userRoleTable="blahTable"
userTable="blahTable"
/>
</Context>
I made sure to delete the tomcat 8 install in eclipse and then add it back again; I understand that is what copies all the tomcat installation stuff to the workspace locations. When I attempt to run the server on eclipse, the login page is displayed, but the username/password is always rejected.
I fixed it once by finding the eclipse copy of server.xml in the eclipse-workspace folder tree (...eclipse-workspace/.metadata/.plugins/org.eclipse.wst.server.core/temp1/conf). But the next time I rebooted the computer and ran it again, the login failed, and on checking server.xml, I find that it was overwritten this morning. I assume eclipse overwrites it under some conditions, perhaps on eclipse startup? I put the <Realm ... /> tag into server.xml within <Context ... /> again, and it is working again.
Where should this information go? I'd like to put it somewhere that it won't disappear from eclipse. I don't think we want this realm tag in the actual server.xml (as opposed to the one local to eclipse), because this one is specific to the development environment. So where can it be put on my machine so that it is used by eclipse's Tomcat and yet doesn't interfere with the application's overall source?
One of the way is to put your <Context> configuration in the webapp/META-INF/context.xml.
Reference :
Individual Context elements may be explicitly defined:
In an individual file at /META-INF/context.xml inside the application
files. Optionally (based on the Host's copyXML attribute) this may be
copied to $CATALINA_BASE/conf/[enginename]/[hostname]/ and renamed to
application's base file name plus a ".xml" extension.
In individual
files (with a ".xml" extension) in the
$CATALINA_BASE/conf/[enginename]/[hostname]/ directory. The context
path and version will be derived from the base name of the file (the
file name less the .xml extension). This file will always take
precedence over any context.xml file packaged in the web application's
META-INF directory.
Inside a Host element in the main conf/server.xml.
Default Context elements may be defined that apply to multiple web
applications. Configuration for an individual web application will
override anything configured in one of these defaults
Where should this information go? I'd like to put it somewhere that it
won't disappear from eclipse
So where can it be put on my machine so
that it is used by eclipse's Tomcat and yet doesn't interfere with the
application's overall source?
When you create a Tomcat in Eclipse , a server project will also be created. This project stores the configuration for the created tomcat instance which will be copied to Tomcat instance 's conf folder (i.e. eclipse-workspace/.metadata/.plugins/org.eclipse.wst.server.core/temp1/conf when tomcat starts.
So , if you do not want to add the Realm configuration to your project source codes likes /webapp/META-INF/context.xml , you can add it to the context.xml in the server project.
I am facing a little strange issue while deploying web service to WAR file.
If I deploy the application via Netbeans IDE it is going under \standalone\deployments directory.
However, if I deploy the war file from Admin Console it is always getting deployed at \standalone\tmp directory.
Please guide on this issue. The deployment should go under \standalone\deployments directory only.
The deployment should go under \standalone\deployments directory only
You are quite not right.
It is not an issue. It is what it is.
standalone/deployment folder stand there only for "hot-deployment" functionality available only with standalone mode.
So, Netbeans uses it. You can do the same just by saving EAR or WAR into standalone/deployment and server will pick it. (default scan interval is 5 sec.)
but Admin console or CLI is only (and standard) way to deploy application on domain. In domain mode deployment folder is not in use and there is no deployment scanner.
Then when you use console it goes common way - deploys as on domain regardless is it domain or standalone server.
Updated / follow-up:
In general it is better to keep .properties file(s) out of deployment, in separate location. It is main idea behind them - to be able to change properties without application rebuilding and redeploying. Usually properties are different in different environments (DEV/UAT/PROD)
So there are 2 most popular solutions:
store properties in different location add that location to class path and access them through ClassLoader.getResourceAsStream() mechanism
store properties in different location, pass that location through system (or -D) variable and access them as file. for JBoss you can place your .properties under configuration directory. there is already JBoss variable. Kind of jboss.config.dir (or such, you can find it in Admin console, I do not have JBoss right now).
But of course sometime it still needed to access resources inside WAR/EAR - in that situation it is pretty much the same as first solution above.
Just be sure your .properties file(s) are accessible through to ClassLoader (in class path) and use them from ClassLoader.getResourceAsStream (or if you use Spring point it as "classpath:" not as "file:".
I have a application deployed in Tomcat7 server which deals with multiple database connections.
These database details are retrieved from 'database.properties' and it is referred in hibernate.xml file in WEB-INF folder. These database details are to be changed dynamically and the hibernate xml is also to be updated.
As for now, if I want to update the database details I need to modify the changes in the 2 files mentioned above and the war file needs to be deployed again.
I tried changing the files in tomcat without restarting. I verified that the 'reloadable' property in tomcat server.xml file is set to true. But still the changes are not reflected in the app without restarting the server.
Please let me know if any configurations to be done for modifying these files without restarting the tomcat server.....
--
Suriya
Look at WatchedResource tag. You need to add your files there.
WatchedResource - The auto deployer will monitor the specified static resource of the web application for updates, and will reload the web application if it is updated. The content of this element must be a string.
Look at the configuration in context.xml file
<!-- Default set of monitored resources -->
<WatchedResource>WEB-INF/web.xml</WatchedResource>
Add more files, which you want to monitor the changes to redeploy.
I'm using Wildfly 9.0.0.Alpha1 with Spring STS 3.6.3 and JBoss Tools, i don't find the way for update my changes to static content inside my server without the need of use incremental deploy (I enabled exploded deployment in the wildfly server), so when i do a little change to my resources, I have to refresh the project in eclipse STS so then it makes an incremental deployment, this takes about 15 - 30 seconds which is annoying and a waste of time
There is a way for update a static content in a exploded war without incremental deploy?
You can edit your subsystem entry for undertow, adding a location and file for a path within standalone/tmp. And then you can add symbolic links to that path at runtime every time you want to share additional static content. You can use Files.createSymbolicLink(...) in Java. Just be careful that the attributes of your symbolic links let them be deleted without deleting the targets. Also, make a start script that recreates your subdirectory in tmp as needed before wildly starts. If you have an undertow location that points to a folder that doesn't exist, the location (context, like /static) will not be created. Once created, undertow will serve up any subfolder or file you add to it once location is created at startup. Make sure you add directory-browsing="false" attribute to the file element for the folder if you don't want people to be able to list contents of folder.
I have two applications deployed on tomcat. For each application I have defined their own context in $CATALINA_HOME/conf/Catalina/localhost where JDBC datasource is defined. When I undeploy one of the application using ant script context of this application is deleted, so on the next start of the tomcat application cannot be deployed because it doesnt have JDBC connection defined. Is there any solution to this problem?
I think this is a Tomcat bug. I filed a bug report but the fix is complicated.
Tomcat can deploy application in 3 ways,
Directory, like webapps/myapp.
WAR, like webapps/myapp.war.
Context fragment, which is what you are using.
If you use #3 but the app or war are in webapps, Tomcat will be confused with #1 or #2. When redeploying directory or war, it supposes to remove context fragment.
My workarounds are,
If you use directory, put it somewhere other than APPBASE (webapps). If you use WAR, put it somewhere else also and don't explode it.
We deploy our app using a script. In the script, the fragment is copied over every time after app is undeployed.
Here is a sample fragment for WAR deployment,
<Context docBase="/anywhere/but/webapps/myapp.war"
swallowOutput="true" unpackWAR="false" />
Please notice not every app runs in unpacked mode. You can't read any resources as files from the WAR in unpacked mode.