I have 3 wars in my webapp folder. Two of them are built on services of the third one. I\'m in a testing environment, i.e. I don\'t have control over their architectures, so
That's quite easy to achieve if you don't care hacking a bit of tomcat code and creating your own Host instance
1) Create a subClass of org.apache.catalina.core.StandardHost, say MyHost:
class MyHost extends org.apache.catalina.core.StandardHost{
public MyHost (){
super();
//changing HashMap for a predictable ordered Map :)
this.children = new LinkedHashMap();
}
}
2) register your class on your server's xml Host tag ()
Incredible as it may seem, it solves the problem as long as you have all your web app declared in the correct order inside of Host tag:
<Host>
<context app1>
<context app2>
Thaen app1 will start before app2, no matter which SO you used.
There are three ways to deploy the webapp.war
in Tomcat.
Add Context
element inside a Host
element in the $CATALINA_BASE/conf/server.xml
file.
<Server><Service><Engine><Host>
<Context path="[webappName]" docBase="[webappPath]"/>
</Server></Service></Engine></Host>
Create the $CATALINA_BASE/conf/[engineName]/[hostName]/[webappName].xml
file with content:
<Context docBase="[webappPath]"/>
Add the webapp.war
file directly in the $CATALINA_BASE/webapps/
directory.
The following deployment sequence will occur on Tomcat startup:
1→2→3
Some explanations:
$CATALINA_BASE
Refer the base directory against which most relative paths are resolved. If you have not configured Tomcat for multiple instances by setting a CATALINA_BASE directory, then $CATALINA_BASE will be set to the value of $CATALINA_HOME, the directory into which you have installed Tomcat.
docBase
The pathname to the web application WAR file. You may specify an absolute pathname for this WAR file, or a pathname that is relative to the appBase directory of the owning Host.
engineName:
The name of the engine associated to the context. The default name is Catalina
.
hostName:
The name of the host associated to the context. The default name is localhost
.
Assume that:
a.war
, b.war
and c.war
.b.war
depends on a.war
.c.war
depends on b.war
.Try the following steps:
$CATALINA_BASE/webapps/
directory.create the $CATALINA_BASE/conf/Catalina/localhost/b.xml
file with content:
<Context docBase="b.war"/>
Add Context
element in the $CATALINA_BASE/conf/server.xml
file:
<Server><Service><Engine><Host>
<Context path="a" docBase="a.war"/>
</Server></Service></Engine></Host>
Reference:
Apologies for cross posting (Tomcat - starting webapps in a specific order), but I thought it was relevant here too:
You can define mulitple services in your server.xml, which run on different ports. The services are started sequentially according to the order they appear in the server.xml. This means that you can have - for example - a configuration service running in the first service and then the apps that depend on it in the second (I use the default Catalina one for the rest of them...)
You can see more info here: http://wiki.apache.org/tomcat/FAQ/Miscellaneous#Q27
And this is the service that I include before the Catalina Service:
<Service name="ConfigService">
<Connector port="8081" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8444" />
<Engine name="ConfigServiceEngine" defaultHost="localhost">
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
<Context path="/" reloadable="true" docBase="/path/to/your/service/directory" />
</Host>
</Engine>
</Service>
As you can see, I use docbase rather than appBase, but you should be able t configure a different appBase if you prefer...
NB it's important to change the name of both the service and the engine.
HTH
It is true that tomcat does not provide any way to enforce deployment order.
*Tomcat deploys webapps in following order:*
1.Any Context Descriptors will be deployed first.
2.Exploded web applications not referenced by any Context Descriptor will then be deployed. If they have an associated .WAR file in the appBase and it is newer than the exploded web application, the exploded directory will be removed and the webapp will be redeployed from the .WAR
3.WAR files will be deployed
> Here is a proposed solution:
If you want to specify the deployment order then define a context for your web app in $CATALINA_BASE/conf/[enginename]/[hostname]/MyApp.xml
Tomcat scans $CATALINA_BASE/conf/[enginename]/[hostname]/ by performing File listFiles() which returns a File array sorted by hash value (OS dependent).
You may use the following code to check in which order webapps will be deployed
File file = new File("/opt/tomcat/conf/Catalina/localhost");
File[] files = file.listFiles();
for (File f : files)
{
System.out.println("Filename: " + f.getName());
}
We run multiple tomcats. We can bring up groups of apps independently by putting the first group in one tomcat and the later ones in a second.
This assumes that they are not trying to communicate with each other using the JVM.
From the Tomcat Wiki - What order do webapps start (or How can I change startup order)?
There is no expected startup order. Neither the Servlet spec nor Tomcat define one. You can't rely on the apps starting in any particular order.
Tomcat has never supported specifying load order of webapps. There are other containers like JBoss that do, but Tomcat never has. Any apparent behavior that looks like load ordering via the alphabetical order of the names of the web apps is coincidental and not guaranteed to work in all cases.
What you are probably thinking of is the <load-on-startup/>
element if the web.xml
that specifies order of loading servlets
.
That said there is an elegant solution using a service discovery protocol.
One solution is to use something like ZeroConf and register your services when they start up, and then have the dependent apps look for when these services come available and have them connect and do what ever they need to do when the service is ready. This is how I have been handling multiple dependent services for years now. I have Python, Java and Erlang services all discovering each other via ZeroConf seemlessly.