views:

498

answers:

4

I have a source tree for a .war file that I need to modify so that I can add some application-specific configuration info (in this case a jdbc connection string, but I may have other properties-like resources). What are the best practices for where to put configuration info and how to access this from within the Servlet?

I'm guessing this Tomcat configuration reference has something to do with it, but my eyes glaze over when I try to read it.

+2  A: 

Hi Jason. For the specific case of a JDBC connection string, I would recommend using a Tomcat-managed connection pool instead. You can read more about doing this here: http://tomcat.apache.org/tomcat-5.5-doc/jndi-datasource-examples-howto.html

It's more work, but I think in the long run it will serve you better.

Matt Solnit
thanks... you're probably right about the long run, but this is probably the only Tomcat app I will be working on for a long time + I don't have too much spare time to figure out how to tweak my application. The apache docs aren't very clear.
Jason S
this makes a little more sense now after spending time pulling my hair out (alas...) and after looking at the JIRA server.xml. How do I access the DataSource from within my Java app, though? The example page gives an example of JSP but not of Java code.
Jason S
They include a couple examples further down (e.g. in the PostgreSQL section, step 4).
Matt Solnit
There's another example within this question: http://stackoverflow.com/questions/1119817/can-i-set-the-jdbc-isolation-level-from-a-tomcat-context
Matt Solnit
+2  A: 

For web app configuration you can place the config on the classpath somewhere. Then you can get to it from your application with getResourceAsStream or if you prefer Spring:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
  <property name="locations">
    <list>
      <value>classpath:my-config.properties</value>
    </list>
  </property>
</bean>

There are a number of places you can put the properties on the classpath in Tomcat. in order it looks at:

/WEB-INF/classes of your web application 
/WEB-INF/lib/*. jar of your web application 
$CATALINA_HOME/common/classes 
$CATALINA_HOME/common/endorsed/*.jar 
$CATALINA_HOME/common/i18n/*.jar 
$CATALINA_HOME/common/lib / *. jar 
$CATALINA_BASE/shared/classes 
$CATALINA_BASE/shared/lib/*.jar

For example, if you put my-config.properties both in a .jar file and in WEB-INF/classes the one in WEB-INF/classes will be used. You could use this mechanism to default to test config and override prod config on prod servers.

leonm
A: 

Hmm. It looks like the easiest path to getting what I want on the Java side of the application is to use Servlet.getServletConfig().getInitParameter(parameterName) e.g. getInitParameter("myApp.connectionString");

But I don't know where to set this. The Tomcat docs talk about various permutations of context.xml but I want to make sure this parameter only affects my servlet and not any others. I also don't want to locate it within my .war file so that I can keep this parameter independent of the applications (for instance if I install an upgrade).


Update: I figured it out, key/value parameters accessible by ServletContext.getInitParameter() go here (or can go here) in ${CATALINA_HOME}/conf/server.xml:

<Server port=... >
    ...
  <Service name="Catalina" ...>
    <Engine name="Catalina" ...>
      ...
      <Host name="localhost" ...>
        <Context path="/myWarFile">
          <Parameter name="foo" value="123" />
          <Parameter name="bar" value="456" />
           ...
        </Context>
      </Host>
    </Engine>
  </Service>
</Server>

This sets two parameters, "foo" = "123", "bar" = "456" for the servlet myWarFile.war (or more accurately with the URL path /myWarFile) and I can get at them in Java with Servlet.getServletConfig().getInitParameter("foo") or Servlet.getServletConfig().getInitParameter("bar").

I also looked at JIRA's server.xml entry (and what they tell you to set it to for MySQL), they use a Resource rather than a Parameter, not quite sure of the subtleties of this but it seems like it could be more appropriate method.

<Server port=... >
  <Service name="Catalina" ...>
    <Engine name="Catalina" ...>
      <Host name="localhost" ...>
        <Context path="/jira" docBase="${catalina.home}/atlassian-jira" 
            reloadable="false">
          <Resource name="jdbc/JiraDS" auth="Container" type="javax.sql.DataSource"
            username="jirauser"
            password="..."
            driverClassName="com.mysql.jdbc.Driver"
            url="jdbc:mysql://localhost/jiradb1?autoReconnect=true&amp;useUnicode=true&amp;characterEncoding=UTF8"
            maxActive="20"
            validationQuery="select 1"
          />
        </Context>
      </Host>
    </Engine>
  </Service>
</Server>
Jason S
Those parameters are configured inside the servlet tag of the web.xml file, using: init-param, param-name and param-value. http://www.orionserver.com/docs/web.xml.html
rodrigoap
*which* web.xml file? the one in my .war file or in ${CATALINA_HOME}/conf? If the former, I need to not do that, if the latter I don't understand the appropriate syntax.
Jason S
A: 

Hi,

you can add the path to your properties files in your CATALINA_HOME/conf/catalina.properties in the "common" classloader common.loader.

LE GALL Benoît