Search code examples
javatomcatenvironment-variablescontext.xml

Tomcat 8 - context.xml use Environment Variable in Datasource


I have a Tomcat 8 project that uses a datasource (see below)

<Resource auth="Container" 
          name="jdbc/JtmDS"  
          driverClassName="org.apache.derby.jdbc.EmbeddedDriver" 
          type="javax.sql.DataSource" 
          username="xfer"
          password="xfer10" 
          url="jdbc:derby:/home/PUID/tm/control/JtmDB"                    
          initialSize="25"
          maxTotal="100" 
          maxIdle="30" 
          maxWaitMillis="10000"                                      
          removeAbandonedOnBorrow="true"
          removeAbandonedTimeout="20" />

This works perfectly well.

However the url is a hard-coded path /home/PUID/tm/control/JtmDB

When this gets into production the PUID part of the path will differ across numerous systems. I have an environment variable set export PUID=abcd The rest of the application is able to use things like System.getenv( ) or ${env:PUID} as and where appropriate.

These all work fine.

My question is very simply: How can I make the PUID value in my context.xml a variable that can be read from an environment variable?


Solution

  • I finally discovered what I actually needed to do here.... Quite simple in the end.

    I passed in a java parameter to Tomcat at runtime as shown below.

    I added the following bits to setenv.sh

    export PUID=abcd
    
    JAVA_OPTS=-Dpuid=${PUID} 
    

    Then edited my context.xml as shown here

    <Resource auth="Container" 
              name="jdbc/JtmDS"  
              driverClassName="org.apache.derby.jdbc.EmbeddedDriver" 
              type="javax.sql.DataSource" 
              username="xfer"
              password="xfer10" 
              url="jdbc:derby:/home/${puid}/tm/control/JtmDB"                    
              initialSize="25"
              maxTotal="100" 
              maxIdle="30" 
              maxWaitMillis="10000"                                      
              removeAbandonedOnBorrow="true"
              removeAbandonedTimeout="20" />
    

    So now my Tomcat installation will read this and be able to use a different path for each different PUID.


    Background: This works because Tomcat will automatically perform variable substition in its configuration files:

    Tomcat configuration files are formatted as schemaless XML; elements and attributes are case-sensitive.

    Apache Ant-style variable substitution is supported; a system property with the name propname may be used in a configuration file using the syntax ${propname}. All system properties are available including those set using the -D syntax, those automatically made available by the JVM and those configured in the $CATALINA_BASE/conf/catalina.properties file.

    Apache Tomcat 9 Configuration Reference - Overview

    The part:

    JAVA_OPTS=-Dpuid=${PUID}
    

    describe above is necessary because Tomcat will only read Java system properties (which are provided by the JVM), but not environment variables (which are provided by the OS/runtime libraries that the JVM is running on). The parameter -D sets a Java system property from the environment variable of the same name.