codesmith
codesmith

Reputation: 1451

Tomcat: 1 war, deployed 2x, 2 configs

Simplified situation:

What I want is that each webapp points to a different database. So, the webapp on /a points to database A and the the webapp on /b points to database B.

How would you solve this? (without splitting the war itself)

Upvotes: 5

Views: 210

Answers (3)

John T
John T

Reputation: 335

getContextPath() was suggested, and here is a technique to use it with getInitParameter()

As an example, if you had two contexts: "/dev" and "/prod" - both indentical - and you set up your web.xml file with entries like:

<context-param>
    <param-name>database_ip_prod</param-name>
    <param-value>192.168.1.10</param-value>
</context-param>

<context-param>
    <param-name>database_ip_dev</param-name>
    <param-value>127.0.0.1</param-value>
</context-param>

And with a method like this:

public String getContextInitParam(
        javax.servlet.ServletContext context, String key) {
    key += context.getContextPath().replace("/","_");
    return context.getInitParameter(key);
}

A call like this from a jsp or servlet:

getContextInitParam(request.getServletContext(), "database_ip");

would return 192.168.1.10 on the /prod context, and 127.0.0.1 on the /dev context.

Upvotes: 0

Mehmet Sunkur
Mehmet Sunkur

Reputation: 2423

You can do it by Tomcat's context.xml configuration without splitting your code.

You can define two context for example /a and /b and two different global data sources "sharedDataSourceA" and "sharedDataSourceB". You can bind different global data sources to these contexts with same name like "appDataSource".

<GlobalNamingResources>
  ...
  <Resource name="sharedDataSourceA"
            global="sharedDataSourceA"
            type="javax.sql.DataSource"
            factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
            alternateUsernameAllowed="true"
            username="bar"
            password="barpass"
            ...
<Resource name="sharedDataSourceB"
            global="sharedDataSourceB"
            type="javax.sql.DataSource"
            factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
            alternateUsernameAllowed="true"
            username="bar"
            password="barpass"
            ...
  ...
</GlobalNamingResources>

<Context path="/a"...>
  ...
  <ResourceLink
            name="appDataSource"
            global="sharedDataSourceA"
            type="javax.sql.DataSource"
            factory="org.apache.naming.factory.DataSourceLinkFactory"
            username="foo"
            password="foopass"
  ...
</Context>
<Context path="/b"...>
  ...
  <ResourceLink
            name="appDataSource"
            global="sharedDataSourceA"
            type="javax.sql.DataSource"
  ...
</Context>

Then in your code you can bind datasource to "appDataSource" by jndi lookup. Deploy the same war to /a and /b . They will work on different databases.

Upvotes: 9

LMC
LMC

Reputation: 12822

You could get the current context programmatically and configure the datasource according to the obtained value. For example using javax.servlet.ServletContext.getContextPath().

You could also load a properties file according to context name.

Upvotes: 2

Related Questions