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.
Related
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 have a Tomcat 7 Server in Eclipse with two webapps a and b and need to find out how to have application specific configuration files for tomcat that works with Eclipse.
Now I want for each webapp a custom config file, like described here: Apache Tomcat: multiple webapps. So I created a <TomcatDirectory>/conf/Catalina/localhost folder and put the a.xml and b.xml there. This works fine when I run Tomcat from command line.
But where have I to put the application specific configuration files a.xml and b.xml when I run Tomcat from within eclipse?
I already tried to put the files in Eclipse in <EclipseWorkspace>\Servers\<ServerName>\conf\Catalina\localhost\ but WTP does not copy this files to <EclipseWorkspace>\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\conf\Catalina\localhost
Leave them in <TomcatDirectory>/conf/Catalina/localhost
Server > Open > Server Locations
Change from:
Use workspace metadata
To:
Use Tomcat instalation
Now a.xml and b.xml from <TomcatDirectory>/conf/Catalina/localhost will be used.
If it's for development's purpose, you can specify a folder into the "docBase" attribute of context file like this :
<?xml version="1.0" encoding="UTF-8"?>
<Context crossContext="true" docBase="C:/devel/MyApp/web/target/MyApp-web" path="/MyApp" reloadable="true">
<Resource
... />
</Context>
By adding these context files directly into /conf/Catalina/localhost, everything is configured and should work like you want but you'll have to stop the tomcat server every time you'll want to clean and build your project.
What you are looking for is to have context.xml files for two different applications.create context.xml file under web application's (a and b) META-INF folder and you should be able to run both the application with their own context.xml file. In eclipse you should be able to create META-INF folder for your respective web applications in parallel to WEB-INF directory
I have a web application that relies on some resources and parameters to be configured after it is installed, like a JDBC connection.
What I have come up with is providing a META-INF/context.xml which is copied into [engine-name]/[server-name]/[app-name].xml by Tomcat when I deploy the application. This way all I am providing is a war file that can be copied into the appBase folder (webapps).
Tomcat's documentation says if there is such a file it won't be overwritten which is really great, since the changes made after deployment won't be lost.
But there is a subtle issue here:
Since we deploy the application by copying into webapps directory, Tomcat will first uninstall the existing application as well as the configuration file. This way the configuration file will be lost / overwritten which is not desirable.
Tomcat won't modify this behaviour as far as I know.
The question is:
Is there a way to work around this issue by installing the application in a way that Tomcat won't remove the existing configuration file.
Or, is there a better way of packaging the application?
Please note that we don't want to set autoDeploy to false and we cannot use human intervention for the installation (which rules out using Tomcat Manager web application).
If I get the configuration file out of .war file and copy it separately as [engine-name]/[server-name]/[app-name].xml, Tomcat will still associate it with my application and remove it once I copy a new .war file.
Another assumption is: We don't know in advance the values to the configuration. We will only provide a sample configuration (a placeholder, if you wish) while actual configuration will be performed at some time later (not necessarily in the installation time).
Thanks
The solution is simple: don't put configuration in your context.xml.
Here is a solution that we use (which works well for a number of diverse external customers):
We have a single war which will be used in multiple environments, webapp.war. We have three environments, development, integration and production. Integration and production are at the customer site. We don't know passwords and file paths for the client integration and production sites.
We use a combination of two things: JNDI lookup for database stuff and external properties files.
In the context.xml that is delivered in the war, we have a ResourceLink
<ResourceLink name="jdbc/webapp"
global="uk.co.farwell.webapp.datasource.MySqlDataSource" />
This gives a reference to a globally defined data source, which is defined in the server.xml for Tomcat.
<Resource auth="Container"
driverClassName="com.mysql.jdbc.Driver"
name="uk.co.farwell.webapp.datasource.MySqlDataSource"
password="xxx" url="xxx" username="fff" />
So the database details can be changed by editing the server.xml without changing the webapp.war. Crucially, this only needs to be done once for each server, not at redeploy.
In our spring configuration, to define the dataSource we have:
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/webapp" />
For other properties, we have a global application.properties file which is delivered along with the webapp.war, but is not part of the war. This is referenced by a -D on the command line to start Tomcat. -Duk.co.farwell.webapp.applicationDir="/usr/xxx/fff". We pick up the definition and read the properties file. The database stuff could be done this way as well, but we'd lose the pooling done by Tomcat.
Another thing: we don't have to rebuild if servers are moved, or if machines are changed for some reason. This is a matter for the customer and their infrastructure people.
I managed to resolve this issue somehow.
1- Install an exploded WAR directory somewhere outside Tomcat's appBase, let's assume it is in /usr/local/MyApp. [You can use a WAR file for this step instead of WAR directory, if your application runs from an unexploded war.]
2- Copy the context configuration file into [tomcat.conf]/[engine]/[hostname] directory, let's call it MyApp.xml. This file will point to the location of the application:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Context configuration file for my web application -->
<Context docBase="/usr/local/MyApp" privileged="true" antiResourceLocking="false" antiJARLocking="false">
<Resource name="jdbc/myapp-ds" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000" username="XXX" password="XXX"
driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/mydb" />
</Context>
3- You are now free to go and modify the configuration file.
4- Update the application by copying new version of your application in /usr/local/MyApp
Notes:
a) This solution applies to an unexpanded .war file as well, but since we use Spring's Log4JConfigListener it wouldn't run from an unexploded .war file. Tomcat doesn't explode .war files put outside appBase (webapps) folder.
b) This approach doesn't prevent you from having context.xml in /usr/local/MyApp/META-INF/context.xml since it will not be used by Tomcat in this configuration. You can use it in your dev environment, where you dump your .war file into the appBase (webapps) folder.
This is what I've got so far, still looking out for better solutions.
This is how we can manage to externalize webapp context from .WAR File
Place your .WAR file somewhere outside tomcat
Create a $APP_NAME.xml file into $TOMCAT_HOME/conf/[Engine]/[Host]/ directory.
Now file "$APP_NAME.xml" we just created need to have context definition and parameters + Any EnvironmentVariable you want specific to that context.
For e.g. I have an webapp called VirtualWebApp.
I will create file like VirtualWebApp.xml with below context definition :
<Context docBase="/home/appBase/VirtualWebApp" path="/VirtualWebApp" reloadable="true">
<Environment name="webservice.host" type="java.lang.String" value="1.2.3.4" />
<Environment name="webservice.port" type="java.lang.String" value="4040" />
</Context>
To access these environment variables you have to write below code(Just lookup) :
InitialContext initialContext = new javax.naming.InitialContext();
host = (String)initialContext.lookup("java:comp/env/webservice.host");
port = (String)initialContext.lookup("java:comp/env/webservice.port");
By referring to Apache Tomcat 5.5 Documentation:
In the $CATALINA_HOME/conf/context.xml file: the Context element
information will be loaded by all webapps
You could easily try this approach, it might work, but I'm not sure if this is a good solution especially if you are running multiple webapps on Tomcat.
I don't know how to modify Tomcat's behaviour but I could think of 2 different solutions:
different (parameterized) build scripts for each environment, so that you define a parameter called env to your build scripts and depending on the value it places the environment specific context.xml in your WAR during build.
Create an install script for each environment that first redeploys the WAR file (places it in webapps directory) and then makes modifications to the Tomcat installation depending on environment, e.g. different hostname for JDBC DataSource in context.xml.
I make heavy use of the latter approach as it works in enterprise environments. Separation of duties policies often prohibit the dev team from knowing e.g. production database passwords. Option #2 solves this problem because only IT operations have access to the environment specific install scripts after they have been created.
#n0rm1e: not sure if tomcat provides any sort of solution for you problem. But one possible solution can be:-
create an ant script with following steps:
i) Check existence of .xml file in [engine-name]/[server-name] directory. If it exists, take a back up of this/rename it.
ii) copy your war file to tomcat webapps. Restart tomcat server.
iii) copy backup-ed configuration file back to [engine-name]/[server-name] directory
I have java webapp under Tomcat with such sample context:
<Context path="reports" docBase="E:\generatedReports"></Context>
On unix attribute docBase different:
<Context path="reports" docBase="/usr/generatedReports"></Context>
Can I have ONE context.xml (for crossplatform and keeping simple build scripts)?
Value of docBase attribute must be parameter managed in other place?
Technically Yes, you can keep one file and parametrize it when building.
The problem with doing this via build scripts is that context.xml sits outside the webapps and is part of the conf, i.e. the Tomcat installation directory.
You ideally want minimum interference with files in the conf folder and so rather than having it as part of the build and released artifacts, I would suggest you version control it as context.xml.windows and context.xml.unix or something similar.
And yourself or your admin should manually change/edit these files ensuring all changes are justified.
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.